aboutsummaryrefslogtreecommitdiffstats
path: root/src/pluto/certs.c
diff options
context:
space:
mode:
authorAndreas Steffen <andreas.steffen@strongswan.org>2009-11-10 23:54:04 +0100
committerAndreas Steffen <andreas.steffen@strongswan.org>2009-11-10 23:54:04 +0100
commitf565d0c575f9d7e4a53e10ee447871fea21cb2e3 (patch)
tree950b57b988a21db56ded2da3892cfad4dea6b9d4 /src/pluto/certs.c
parentcc543182bcf79b306188262b5537bc55f89c0965 (diff)
downloadstrongswan-f565d0c575f9d7e4a53e10ee447871fea21cb2e3.tar.bz2
strongswan-f565d0c575f9d7e4a53e10ee447871fea21cb2e3.tar.xz
merged pluto's PGP certificate parsing with charon's
Diffstat (limited to 'src/pluto/certs.c')
-rw-r--r--src/pluto/certs.c205
1 files changed, 139 insertions, 66 deletions
diff --git a/src/pluto/certs.c b/src/pluto/certs.c
index 89e289b6c..644f65766 100644
--- a/src/pluto/certs.c
+++ b/src/pluto/certs.c
@@ -18,60 +18,83 @@
#include <stdio.h>
#include <string.h>
#include <unistd.h>
+#include <time.h>
#include <freeswan.h>
-#include "library.h"
-#include "asn1/asn1.h"
-#include "credentials/certificates/certificate.h"
+#include <library.h>
+#include <asn1/asn1.h>
+#include <credentials/certificates/certificate.h>
+#include <credentials/certificates/pgp_certificate.h>
#include "constants.h"
#include "defs.h"
#include "log.h"
#include "certs.h"
#include "whack.h"
+#include "fetch.h"
+#include "keys.h"
#include "builder.h"
/**
- * used for initializatin of certs
+ * Initialization
*/
-const cert_t cert_empty = {CERT_NONE, {NULL}};
+const cert_t cert_empty = {
+ NULL , /* cert */
+ NULL , /* *next */
+ 0 , /* count */
+ FALSE /* smartcard */
+};
/**
- * extracts the certificate to be sent to the peer
+ * Chained lists of X.509 and PGP end entity certificates
*/
-chunk_t cert_get_encoding(cert_t cert)
+static cert_t *certs = NULL;
+
+/**
+ * Free a pluto certificate
+ */
+void cert_free(cert_t *cert)
{
- switch (cert.type)
+ if (cert)
{
- case CERT_PGP:
- return chunk_clone(cert.u.pgp->certificate);
- case CERT_X509_SIGNATURE:
- return cert.u.x509->cert->get_encoding(cert.u.x509->cert);
- default:
- return chunk_empty;
+ certificate_t *certificate = cert->cert;
+
+ if (certificate)
+ {
+ certificate->destroy(certificate);
+ }
+ free(cert);
}
}
-public_key_t* cert_get_public_key(const cert_t cert)
+/**
+ * Add a pluto end entity certificate to the chained list
+ */
+cert_t* cert_add(cert_t *cert)
{
- switch (cert.type)
- {
- case CERT_PGP:
- {
- public_key_t *public_key = cert.u.pgp->public_key;
+ certificate_t *certificate = cert->cert;
+ cert_t *c = certs;
- return public_key->get_ref(public_key);
- }
- case CERT_X509_SIGNATURE:
+ while (c != NULL)
+ {
+ if (certificate->equals(certificate, c->cert)) /* already in chain, free cert */
{
- certificate_t *certificate = cert.u.x509->cert;
-
- return certificate->get_public_key(certificate);
+ cert_free(cert);
+ return c;
}
- default:
- return NULL;
+ c = c->next;
}
+
+ /* insert new cert at the root of the chain */
+ lock_certs_and_keys("cert_add");
+ cert->next = certs;
+ certs = cert;
+ DBG(DBG_CONTROL | DBG_PARSING,
+ DBG_log(" cert inserted")
+ )
+ unlock_certs_and_keys("cert_add");
+ return cert;
}
/**
@@ -161,7 +184,7 @@ private_key_t* load_private_key(char* filename, prompt_pass_t *pass,
/**
* Loads a X.509 or OpenPGP certificate
*/
-bool load_cert(char *filename, const char *label, x509_flag_t flags, cert_t *out)
+cert_t* load_cert(char *filename, const char *label, x509_flag_t flags)
{
cert_t *cert;
@@ -171,83 +194,133 @@ bool load_cert(char *filename, const char *label, x509_flag_t flags, cert_t *out
BUILD_END);
if (cert)
{
- /* the API passes an empty cert_t, we move over and free the built one */
plog(" loaded %s certificate from '%s'", label, filename);
- *out = *cert;
- free(cert);
- return TRUE;
}
- return FALSE;
+ return cert;
}
/**
* Loads a host certificate
*/
-bool load_host_cert(char *filename, cert_t *cert)
+cert_t* load_host_cert(char *filename)
{
char *path = concatenate_paths(HOST_CERT_PATH, filename);
- return load_cert(path, "host", X509_NONE, cert);
+ return load_cert(path, "host", X509_NONE);
}
/**
* Loads a CA certificate
*/
-bool load_ca_cert(char *filename, cert_t *cert)
+cert_t* load_ca_cert(char *filename)
{
char *path = concatenate_paths(CA_CERT_PATH, filename);
- return load_cert(path, "CA", X509_NONE, cert);
+ return load_cert(path, "CA", X509_NONE);
}
/**
- * establish equality of two certificates
+ * for each link pointing to the certificate increase the count by one
*/
-bool same_cert(const cert_t *a, const cert_t *b)
+void cert_share(cert_t *cert)
{
- return a->type == b->type && a->u.x509 == b->u.x509;
+ if (cert != NULL)
+ {
+ cert->count++;
+ }
}
-/**
- * for each link pointing to the certificate increase the count by one
+/* release of a certificate decreases the count by one
+ * the certificate is freed when the counter reaches zero
*/
-void share_cert(cert_t cert)
+void cert_release(cert_t *cert)
{
- switch (cert.type)
+ if (cert && --cert->count == 0)
{
- case CERT_PGP:
- share_pgpcert(cert.u.pgp);
- break;
- case CERT_X509_SIGNATURE:
- share_x509cert(cert.u.x509);
- break;
- default:
- break;
+ cert_t **pp = &certs;
+ while (*pp != cert)
+ {
+ pp = &(*pp)->next;
+ }
+ *pp = cert->next;
+ cert_free(cert);
}
}
-/* release of a certificate decreases the count by one
- * the certificate is freed when the counter reaches zero
+/**
+ * List all PGP end certificates in a chained list
*/
-void release_cert(cert_t cert)
+void list_pgp_end_certs(bool utc)
{
- switch (cert.type)
+ cert_t *cert = certs;
+ time_t now = time(NULL);
+ bool first = TRUE;
+
+
+ while (cert != NULL)
{
- case CERT_PGP:
- release_pgpcert(cert.u.pgp);
- break;
- case CERT_X509_SIGNATURE:
- release_x509cert(cert.u.x509);
- break;
- default:
- break;
+ certificate_t *certificate = cert->cert;
+
+ if (certificate->get_type(certificate) == CERT_GPG)
+ {
+ time_t created, until;
+ public_key_t *key;
+ identification_t *userid = certificate->get_subject(certificate);
+ pgp_certificate_t *pgp_cert = (pgp_certificate_t*)certificate;
+ chunk_t fingerprint = pgp_cert->get_fingerprint(pgp_cert);
+
+ if (first)
+ {
+ whack_log(RC_COMMENT, " ");
+ whack_log(RC_COMMENT, "List of PGP End Entity Certificates:");
+ first = false;
+ }
+ whack_log(RC_COMMENT, " ");
+ whack_log(RC_COMMENT, " userid: '%Y'", userid);
+ whack_log(RC_COMMENT, " digest: %#B", &fingerprint);
+
+ /* list validity */
+ certificate->get_validity(certificate, &now, &created, &until);
+ whack_log(RC_COMMENT, " created: %T", &created, utc);
+ whack_log(RC_COMMENT, " until: %T %s%s", &until, utc,
+ check_expiry(until, CA_CERT_WARNING_INTERVAL, TRUE),
+ (until == TIME_32_BIT_SIGNED_MAX) ? " (expires never)":"");
+
+ key = certificate->get_public_key(certificate);
+ if (key)
+ {
+ chunk_t keyid;
+
+ whack_log(RC_COMMENT, " pubkey: %N %4d bits%s",
+ key_type_names, key->get_type(key),
+ key->get_keysize(key) * BITS_PER_BYTE,
+ has_private_key(cert)? ", has private key" : "");
+ if (key->get_fingerprint(key, KEY_ID_PUBKEY_INFO_SHA1, &keyid))
+ {
+ whack_log(RC_COMMENT, " keyid: %#B", &keyid);
+ }
+ if (key->get_fingerprint(key, KEY_ID_PUBKEY_SHA1, &keyid))
+ {
+ whack_log(RC_COMMENT, " subjkey: %#B", &keyid);
+ }
+ }
+ }
+ cert = cert->next;
}
}
/**
+ * List all X.509 end certificates in a chained list
+ */
+void list_x509_end_certs(bool utc)
+{
+ list_x509cert_chain("End Entity", certs, X509_NONE, utc);
+}
+
+/**
* list all X.509 and OpenPGP end certificates
*/
-void list_certs(bool utc)
+void cert_list(bool utc)
{
list_x509_end_certs(utc);
list_pgp_end_certs(utc);