merged pluto's PGP certificate parsing with charon's
authorAndreas Steffen <andreas.steffen@strongswan.org>
Tue, 10 Nov 2009 22:54:04 +0000 (23:54 +0100)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Tue, 10 Nov 2009 22:54:04 +0000 (23:54 +0100)
25 files changed:
src/pluto/Makefile.am
src/pluto/ac.c
src/pluto/builder.c
src/pluto/ca.c
src/pluto/ca.h
src/pluto/certs.c
src/pluto/certs.h
src/pluto/connections.c
src/pluto/connections.h
src/pluto/crl.c
src/pluto/crl.h
src/pluto/ike_alg.c
src/pluto/ipsec_doi.c
src/pluto/keys.c
src/pluto/keys.h
src/pluto/ocsp.c
src/pluto/ocsp.h
src/pluto/pgpcert.c
src/pluto/pgpcert.h
src/pluto/rcv_whack.c
src/pluto/smartcard.c
src/pluto/smartcard.h
src/pluto/x509.c
src/pluto/x509.h
src/whack/whack.h

index e966299..14a13a5 100644 (file)
@@ -36,7 +36,6 @@ modecfg.c modecfg.h \
 nat_traversal.c nat_traversal.h \
 ocsp.c ocsp.h \
 packet.c packet.h \
-pgpcert.c pgpcert.h \
 pkcs7.c pkcs7.h \
 plutomain.c \
 rcv_whack.c rcv_whack.h \
index f2d81a5..d8b1611 100644 (file)
@@ -85,7 +85,7 @@ bool ac_verify_cert(certificate_t *cert, bool strict)
        identification_t *subject = cert->get_subject(cert);
        identification_t *issuer  = cert->get_issuer(cert);
        chunk_t authKeyID = ac->get_authKeyIdentifier(ac);
-       x509cert_t *aacert;
+       cert_t *aacert;
        time_t notBefore, valid_until;
 
        DBG1("holder: '%Y'", subject);
index 6c7cde5..0cba32b 100644 (file)
@@ -64,43 +64,31 @@ static cert_t *builder_load_cert(certificate_type_t type, va_list args)
        }
        if (blob.ptr)
        {
+               cert_t *cert = malloc_thing(cert_t);
+
+               *cert = cert_empty;
+
                if (pgp)
                {
-                       pgpcert_t *pgpcert = malloc_thing(pgpcert_t);
-                       *pgpcert = pgpcert_empty;
-                       if (parse_pgp(chunk_clone(blob), pgpcert))
-                       {
-                               cert_t *cert = malloc_thing(cert_t);
-                               *cert = cert_empty;
-                               cert->type = CERT_PGP;
-                               cert->u.pgp = pgpcert;
-                               return cert;
-                       }
-                       plog("  error in OpenPGP certificate");
-                       free_pgpcert(pgpcert);
+                       cert->cert = lib->creds->create(lib->creds,
+                                                                                  CRED_CERTIFICATE, CERT_GPG,
+                                                                                  BUILD_BLOB_PGP, blob,
+                                                                                  BUILD_END);
                }
                else
                {
-                       x509cert_t *x509cert = malloc_thing(x509cert_t);
-
-                       *x509cert = empty_x509cert;
-                       x509cert->cert = lib->creds->create(lib->creds,
-                                                                               CRED_CERTIFICATE, CERT_X509,
-                                                                               BUILD_BLOB_ASN1_DER, blob,
-                                                                               BUILD_X509_FLAG, flags,
-                                                                               BUILD_END);
-                       if (x509cert->cert)
-                       {
-                               cert_t *cert = malloc_thing(cert_t);
-
-                               *cert = cert_empty;
-                               cert->type = CERT_X509_SIGNATURE;
-                               cert->u.x509 = x509cert;
-                               return cert;
-                       }
-                       plog("  error in X.509 certificate");
-                       free_x509cert(x509cert);
+                       cert->cert = lib->creds->create(lib->creds,
+                                                                                  CRED_CERTIFICATE, CERT_X509,
+                                                                                  BUILD_BLOB_ASN1_DER, blob,
+                                                                                  BUILD_X509_FLAG, flags,
+                                                                                  BUILD_END);
+               }
+               if (cert->cert)
+               {
+                       return cert;
                }
+               plog("  error in X.509 certificate");
+               cert_free(cert);
        }
        return NULL;
 }
index 583ef8b..e25e7f6 100644 (file)
@@ -37,7 +37,7 @@
 
 /* chained list of X.509 authority certificates (ca, aa, and ocsp) */
 
-static x509cert_t *x509authcerts = NULL;
+static cert_t *x509authcerts = NULL;
 
 /* chained list of X.509 certification authority information records */
 
@@ -79,7 +79,7 @@ bool trusted_ca(identification_t *a, identification_t *b, int *pathlen)
        {
                certificate_t *certificate;
                identification_t *issuer;
-               x509cert_t *cacert;
+               cert_t *cacert;
 
                cacert = get_authcert(a, chunk_empty, X509_CA);
                if (cacert == NULL)
@@ -161,9 +161,10 @@ bool match_requested_ca(linked_list_t *requested_ca, identification_t *our_ca,
  */
 static void free_first_authcert(void)
 {
-       x509cert_t *first = x509authcerts;
+       cert_t *first = x509authcerts;
+
        x509authcerts = first->next;
-       free_x509cert(first);
+       cert_free(first);
 }
 
 /*
@@ -174,18 +175,19 @@ void free_authcerts(void)
        lock_authcert_list("free_authcerts");
 
        while (x509authcerts != NULL)
+       {
                free_first_authcert();
-
+       }
        unlock_authcert_list("free_authcerts");
 }
 
 /*
  *  get a X.509 authority certificate with a given subject or keyid
  */
-x509cert_t* get_authcert(identification_t *subject, chunk_t keyid,
+cert_t* get_authcert(identification_t *subject, chunk_t keyid,
                                                 x509_flag_t auth_flags)
 {
-       x509cert_t *cert, *prev_cert = NULL;
+       cert_t *cert, *prev_cert = NULL;
 
        /* the authority certificate list is empty */
        if (x509authcerts == NULL)
@@ -238,11 +240,11 @@ x509cert_t* get_authcert(identification_t *subject, chunk_t keyid,
 /*
  * add an authority certificate to the chained list
  */
-x509cert_t* add_authcert(x509cert_t *cert, x509_flag_t auth_flags)
+cert_t* add_authcert(cert_t *cert, x509_flag_t auth_flags)
 {
        certificate_t *certificate = cert->cert;
        x509_t *x509 = (x509_t*)certificate;
-       x509cert_t *old_cert;
+       cert_t *old_cert;
 
        lock_authcert_list("add_authcert");
 
@@ -258,7 +260,7 @@ x509cert_t* add_authcert(x509cert_t *cert, x509_flag_t auth_flags)
                        )
                        unlock_authcert_list("add_authcert");
 
-                       free_x509cert(cert);
+                       cert_free(cert);
                        return old_cert;
                }
                else
@@ -274,7 +276,7 @@ x509cert_t* add_authcert(x509cert_t *cert, x509_flag_t auth_flags)
        /* add new authcert to chained list */
        cert->next = x509authcerts;
        x509authcerts = cert;
-       share_x509cert(cert);  /* set count to one */
+       cert_share(cert);  /* set count to one */
        DBG(DBG_CONTROL | DBG_PARSING,
                DBG_log("  authcert inserted")
        )
@@ -302,16 +304,17 @@ void load_authcerts(char *type, char *path, x509_flag_t auth_flags)
 
        while (enumerator->enumerate(enumerator, NULL, &file, &st))
        {
-               cert_t cert;
+               cert_t *cert;
 
                if (!S_ISREG(st.st_mode))
                {
                        /* skip special file */
                        continue;
                }
-               if (load_cert(file, type, auth_flags, &cert))
+               cert = load_cert(file, type, auth_flags);
+               if (cert)
                {
-                       add_authcert(cert.u.x509, auth_flags);
+                       add_authcert(cert, auth_flags);
                }
        }
        enumerator->destroy(enumerator);
@@ -330,8 +333,8 @@ void list_authcerts(const char *caption, x509_flag_t auth_flags, bool utc)
 /*
  * get a cacert with a given subject or keyid from an alternative list
  */
-static const x509cert_t* get_alt_cacert(identification_t *subject, chunk_t keyid,
-                                                                               const x509cert_t *cert)
+static const cert_t* get_alt_cacert(identification_t *subject, chunk_t keyid,
+                                                                               const cert_t *cert)
 {
        if (cert == NULL)
        {
@@ -369,7 +372,7 @@ static const x509cert_t* get_alt_cacert(identification_t *subject, chunk_t keyid
 /* establish trust into a candidate authcert by going up the trust chain.
  * validity and revocation status are not checked.
  */
-bool trust_authcert_candidate(const x509cert_t *cert, const x509cert_t *alt_chain)
+bool trust_authcert_candidate(const cert_t *cert, const cert_t *alt_chain)
 {
        int pathlen;
 
@@ -382,7 +385,7 @@ bool trust_authcert_candidate(const x509cert_t *cert, const x509cert_t *alt_chai
                identification_t *subject = certificate->get_subject(certificate);
                identification_t *issuer = certificate->get_issuer(certificate);
                chunk_t authKeyID = x509->get_authKeyIdentifier(x509);
-               const x509cert_t *authcert = NULL;
+               const cert_t *authcert = NULL;
 
                DBG(DBG_CONTROL,
                        DBG_log("subject: '%Y'", subject);
@@ -551,8 +554,7 @@ ca_info_t* create_ca_info(void)
 void add_ca_info(const whack_message_t *msg)
 {
        smartcard_t *sc = NULL;
-       cert_t cert;
-       bool valid_cert = FALSE;
+       cert_t *cert = NULL;
        bool cached_cert = FALSE;
 
        if (find_ca_info_by_name(msg->name, FALSE))
@@ -564,18 +566,17 @@ void add_ca_info(const whack_message_t *msg)
        if (scx_on_smartcard(msg->cacert))
        {
                /* load CA cert from smartcard */
-               valid_cert = scx_load_cert(msg->cacert, &sc, &cert, &cached_cert);
+               cert = scx_load_cert(msg->cacert, &sc, &cached_cert);
        }
        else
        {
                /* load CA cert from file */
-               valid_cert = load_ca_cert(msg->cacert, &cert);
+               cert = load_ca_cert(msg->cacert);
        }
 
-       if (valid_cert)
+       if (cert)
        {
-               x509cert_t *cacert = cert.u.x509;
-               certificate_t *certificate = cacert->cert;
+               certificate_t *certificate = cert->cert;
                x509_t *x509 = (x509_t*)certificate;
                identification_t *subject = certificate->get_subject(certificate);
                chunk_t subjectKeyID = x509->get_subjectKeyIdentifier(x509);
@@ -589,7 +590,7 @@ void add_ca_info(const whack_message_t *msg)
                        /* ca_info is already present */
                        loglog(RC_DUPNAME, "  duplicate ca information in record \"%s\" found,"
                                                           "ignoring \"%s\"", ca->name, msg->name);
-                       free_x509cert(cacert);
+                       cert_free(cert);
                        return;
                }
 
@@ -647,13 +648,15 @@ void add_ca_info(const whack_message_t *msg)
                unlock_ca_info_list("add_ca_info");
 
                /* add cacert to list of authcerts */
-               cacert = add_authcert(cacert, X509_CA);
+               cert = add_authcert(cert, X509_CA);
                if (!cached_cert && sc != NULL)
                {
-                       if (sc->last_cert.type == CERT_X509_SIGNATURE)
-                               sc->last_cert.u.x509->count--;
-                       sc->last_cert.u.x509 = cacert;
-                       share_cert(sc->last_cert);
+                       if (sc->last_cert != NULL)
+                       {
+                               sc->last_cert->count--;
+                       }
+                       sc->last_cert = cert;
+                       cert_share(sc->last_cert);
                }
                if (sc != NULL)
                        time(&sc->last_load);
index 7b016f9..d964a69 100644 (file)
@@ -18,7 +18,7 @@
 #include <utils/linked_list.h>
 #include <utils/identification.h>
 
-#include "x509.h"
+#include "certs.h"
 #include "whack.h"
 
 /* CA info structures */
@@ -40,14 +40,13 @@ struct ca_info {
 extern bool trusted_ca(identification_t *a, identification_t *b, int *pathlen);
 extern bool match_requested_ca(linked_list_t *requested_ca,
                                                           identification_t *our_ca, int *our_pathlen);
-extern x509cert_t* get_authcert(identification_t *subject, chunk_t keyid,
+extern cert_t* get_authcert(identification_t *subject, chunk_t keyid,
                                                                x509_flag_t auth_flags);
 extern void load_authcerts(char *type, char *path, x509_flag_t auth_flags);
-extern x509cert_t* add_authcert(x509cert_t *cert, x509_flag_t auth_flags);
+extern cert_t* add_authcert(cert_t *cert, x509_flag_t auth_flags);
 extern void free_authcerts(void);
 extern void list_authcerts(const char *caption, x509_flag_t auth_flags, bool utc);
-extern bool trust_authcert_candidate(const x509cert_t *cert,
-                                                                        const x509cert_t *alt_chain);
+extern bool trust_authcert_candidate(const cert_t *cert, const cert_t *alt_chain);
 extern ca_info_t* get_ca_info(identification_t *name, chunk_t keyid);
 extern bool find_ca_info_by_name(const char *name, bool delete);
 extern void add_ca_info(const whack_message_t *msg);
index 89e289b..644f657 100644 (file)
 #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);
index faf820d..b2b11eb 100644 (file)
 #define _CERTS_H
 
 #include <credentials/keys/private_key.h>
+#include <credentials/certificates/certificate.h>
+#include <credentials/certificates/x509.h>
 
-#include "x509.h"
-#include "pgpcert.h"
+#include <freeswan.h>
+
+#include "defs.h"
 
 /* path definitions for private keys, end certs,
  * cacerts, attribute certs and crls
 #define CRL_WARNING_INTERVAL             7 /* days */
 #define ACERT_WARNING_INTERVAL           1 /* day */
 
-/* certificate access structure
- * currently X.509 and OpenPGP certificates are supported
- */
-typedef struct {
-       u_char type;
-       union {
-               x509cert_t *x509;
-               pgpcert_t  *pgp;
-       } u;
-} cert_t;
+/* access structure for a pluto certificate */
+
+typedef struct cert_t cert_t;
+
+struct cert_t {
+       certificate_t  *cert;
+       cert_t         *next;
+       int             count;
+       bool            smartcard;
+};
 
 /* used for initialization */
 extern const cert_t cert_empty;
@@ -62,18 +65,16 @@ extern const cert_t cert_empty;
  */
 extern bool no_cr_send;
 
-extern public_key_t* cert_get_public_key(const cert_t cert);
-extern chunk_t cert_get_encoding(cert_t cert);
 extern private_key_t* load_private_key(char* filename, prompt_pass_t *pass,
                                                                           key_type_t type);
-extern bool load_cert(char *filename, const char *label, x509_flag_t flags,
-                                         cert_t *cert);
-extern bool load_host_cert(char *filename, cert_t *cert);
-extern bool load_ca_cert(char *filename, cert_t *cert);
-extern bool same_cert(const cert_t *a, const cert_t *b);
-extern void share_cert(cert_t cert);
-extern void release_cert(cert_t cert);
-extern void list_certs(bool utc);
+extern cert_t* load_cert(char *filename, const char *label, x509_flag_t flags);
+extern cert_t* load_host_cert(char *filename);
+extern cert_t* load_ca_cert(char *filename);
+extern cert_t* cert_add(cert_t *cert);
+extern void cert_free(cert_t *cert);
+extern void cert_share(cert_t *cert);
+extern void cert_release(cert_t *cert);
+extern void cert_list(bool utc);
 
 #endif /* _CERTS_H */
 
index 45d88a3..e571f6a 100644 (file)
@@ -39,7 +39,6 @@
 #include "x509.h"
 #include "ca.h"
 #include "crl.h"
-#include "pgpcert.h"
 #include "certs.h"
 #include "ac.h"
 #include "smartcard.h"
@@ -398,9 +397,9 @@ void delete_connection(connection_t *c, bool relations)
        gw_delref(&c->gw_info);
 
        lock_certs_and_keys("delete_connection");
-       release_cert(c->spd.this.cert);
+       cert_release(c->spd.this.cert);
        scx_release(c->spd.this.sc);
-       release_cert(c->spd.that.cert);
+       cert_release(c->spd.that.cert);
        scx_release(c->spd.that.sc);
        unlock_certs_and_keys("delete_connection");
 
@@ -736,7 +735,7 @@ static void unshare_connection_strings(connection_t *c)
        c->spd.this.pool = clone_str(c->spd.this.pool);
        c->spd.this.updown = clone_str(c->spd.this.updown);
        scx_share(c->spd.this.sc);
-       share_cert(c->spd.this.cert);
+       cert_share(c->spd.this.cert);
        if (c->spd.this.ca)
        {
                c->spd.this.ca = c->spd.this.ca->clone(c->spd.this.ca);
@@ -749,7 +748,7 @@ static void unshare_connection_strings(connection_t *c)
        c->spd.that.pool = clone_str(c->spd.that.pool);
        c->spd.that.updown = clone_str(c->spd.that.updown);
        scx_share(c->spd.that.sc);
-       share_cert(c->spd.that.cert);
+       cert_share(c->spd.that.cert);
        if (c->spd.that.ca)
        {
                c->spd.that.ca = c->spd.that.ca->clone(c->spd.that.ca);
@@ -767,13 +766,12 @@ static void unshare_connection_strings(connection_t *c)
 static void load_end_certificate(char *filename, struct end *dst)
 {
        time_t valid_until;
-       cert_t cert;
-       bool valid_cert = FALSE;
+       cert_t *cert = NULL;
+       certificate_t *certificate;
        bool cached_cert = FALSE;
-
+       
        /* initialize end certificate */
-       dst->cert.type = CERT_NONE;
-       dst->cert.u.x509 = NULL;
+       dst->cert = NULL;
 
        /* initialize smartcard info record */
        dst->sc = NULL;
@@ -783,87 +781,73 @@ static void load_end_certificate(char *filename, struct end *dst)
                if (scx_on_smartcard(filename))
                {
                        /* load cert from smartcard */
-                       valid_cert = scx_load_cert(filename, &dst->sc, &cert, &cached_cert);
+                       cert = scx_load_cert(filename, &dst->sc, &cached_cert);
                }
                else
                {
                        /* load cert from file */
-                       valid_cert = load_host_cert(filename, &cert);
+                       cert = load_host_cert(filename);
                }
        }
 
-       if (valid_cert)
+       if (cert)
        {
-               switch (cert.type)
-               {
-               case CERT_PGP:
-                       dst->id = select_pgpcert_id(cert.u.pgp, dst->id);
+               certificate = cert->cert;
 
-                       if (cached_cert)
-                       {
-                               dst->cert = cert;
-                       }
-                       else
-                       {
-                               valid_until = cert.u.pgp->until;
-                               add_pgp_public_key(cert.u.pgp, cert.u.pgp->until, DAL_LOCAL);
-                               dst->cert.type = cert.type;
-                               dst->cert.u.pgp = add_pgpcert(cert.u.pgp);
-                       }
-                       break;
-               case CERT_X509_SIGNATURE:
-                       dst->id = select_x509cert_id(cert.u.x509, dst->id);
+               if (dst->id->get_type(dst->id) == ID_ANY ||
+                       !certificate->has_subject(certificate, dst->id))
+               {
+                       plog( "  id '%Y' not confirmed by certificate, defaulting to '%Y'",
+                                dst->id, certificate->get_subject(certificate));
+                       dst->id->destroy(dst->id);
+                       dst->id = certificate->get_subject(certificate);
+                       dst->id = dst->id->clone(dst->id);
+               }
 
-                       if (cached_cert)
-                       {
-                               dst->cert = cert;
-                       }
-                       else
+               if (cached_cert)
+               {
+                       dst->cert = cert;
+               }
+               else
+               {
+                       if (!certificate->get_validity(certificate, NULL, NULL, &valid_until))
                        {
-                               certificate_t *certificate = cert.u.x509->cert;
-                               
-                               if (!certificate->get_validity(certificate, NULL, NULL, &valid_until))
-                               {
-                                       free_x509cert(cert.u.x509);
-                                       break;
-                               }
-                               DBG(DBG_CONTROL,
-                                       DBG_log("certificate is valid")
-                               )
-                               add_x509_public_key(cert.u.x509, valid_until, DAL_LOCAL);
-                               dst->cert.type = cert.type;
-                               dst->cert.u.x509 = add_x509cert(cert.u.x509);
+                               cert_free(cert);
+                               return;
                        }
+                       DBG(DBG_CONTROL,
+                               DBG_log("certificate is valid")
+                       )
+                       add_public_key_from_cert(cert, valid_until, DAL_LOCAL);
+                       dst->cert = cert_add(cert);
+               }
+               certificate = dst->cert->cert;
 
-                       /* if no CA is defined, use issuer as default */
-                       if (dst->ca == NULL)
-                       {
-                               certificate_t *certificate = dst->cert.u.x509->cert;
-                               identification_t *issuer = certificate->get_issuer(certificate);
+               /* if no CA is defined, use issuer as default */
+               if (dst->ca == NULL && certificate->get_type(certificate) == CERT_X509)
+               {
+                       identification_t *issuer;
 
-                               dst->ca = issuer->clone(issuer);
-                       }
-                       break;
-               default:
-                       break;
+                       issuer = certificate->get_issuer(certificate);
+                       dst->ca = issuer->clone(issuer);
                }
 
                /* cache the certificate that was last retrieved from the smartcard */
                if (dst->sc)
                {
-                       if (!same_cert(&dst->sc->last_cert, &dst->cert))
+                       if (!certificate->equals(certificate, dst->sc->last_cert->cert))
                        {
                                lock_certs_and_keys("load_end_certificates");
-                               release_cert(dst->sc->last_cert);
+                               cert_release(dst->sc->last_cert);
                                dst->sc->last_cert = dst->cert;
-                               share_cert(dst->cert);
+                               cert_share(dst->cert);
                                unlock_certs_and_keys("load_end_certificates");
                        }
                        time(&dst->sc->last_load);
                }
        }
        scx_share(dst->sc);
-       share_cert(dst->cert);
+       cert_share(dst->cert);
 }
 
 static bool extract_end(struct end *dst, const whack_end_t *src,
index 5a12812..ee2e00d 100644 (file)
@@ -147,7 +147,7 @@ struct end {
        u_int16_t host_port;        /* host order */
        u_int16_t port;             /* host order */
        u_int8_t protocol;
-       cert_t cert;                /* end certificate */
+       cert_t *cert;               /* end certificate */
        identification_t *ca;       /* CA distinguished name */
        ietf_attributes_t *groups;  /* access control groups */
        smartcard_t *sc;            /* smartcard reader and key info */
index f80c795..84fe775 100644 (file)
@@ -113,7 +113,7 @@ bool insert_crl(x509crl_t *x509crl, char *crl_uri, bool cache_crl)
        crl_t *crl = (crl_t*)cert_crl;
        identification_t *issuer = cert_crl->get_issuer(cert_crl);
        chunk_t authKeyID = crl->get_authKeyIdentifier(crl);
-       x509cert_t *issuer_cert;
+       cert_t *issuer_cert;
        x509crl_t *oldcrl;
        time_t now, nextUpdate;
        bool valid_sig;
@@ -340,8 +340,7 @@ void check_crls(void)
 /*
  * verify if a cert hasn't been revoked by a crl
  */
-cert_status_t verify_by_crl(const x509cert_t *cert, time_t *until,
-                                                       time_t *revocationDate,
+cert_status_t verify_by_crl(cert_t *cert, time_t *until, time_t *revocationDate,
                                                        crl_reason_t *revocationReason)
 {
        certificate_t *certificate = cert->cert;
@@ -402,7 +401,7 @@ cert_status_t verify_by_crl(const x509cert_t *cert, time_t *until,
                certificate_t *cert_crl = x509crl->crl;
                crl_t *crl = (crl_t*)cert_crl;
                chunk_t authKeyID = crl->get_authKeyIdentifier(crl);
-               x509cert_t *issuer_cert;
+               cert_t *issuer_cert;
                bool trusted, valid;
 
                DBG(DBG_CONTROL,
index bac0717..43bafe1 100644 (file)
@@ -26,7 +26,6 @@ struct x509crl {
        certificate_t *crl;
        x509crl_t     *next;
        linked_list_t *distributionPoints;
-       chunk_t        signature;
 };
 
 /* apply a strict CRL policy
@@ -46,7 +45,7 @@ extern long crl_check_interval;
 extern void load_crls(void);
 extern void check_crls(void);
 extern bool insert_crl(x509crl_t *crl, char *crl_uri, bool cache_crl);
-extern cert_status_t verify_by_crl(const x509cert_t *cert, time_t *until,
+extern cert_status_t verify_by_crl(cert_t *cert, time_t *until,
                                                                   time_t *revocationDate,
                                                                   crl_reason_t *revocationReason);
 extern void list_crls(bool utc, bool strict);
index 3528a62..7521dd3 100644 (file)
@@ -199,9 +199,10 @@ struct db_context *ike_alg_db_new(connection_t *c, lset_t policy)
                        key_type_t key_type = KEY_ANY;
 
 
-                       if (c->spd.this.cert.type != CERT_NONE)
+                       if (c->spd.this.cert)
                        {
-                               public_key_t *key = cert_get_public_key(c->spd.this.cert);
+                               certificate_t *certificate = c->spd.this.cert->cert;
+                               public_key_t *key = certificate->get_public_key(certificate);
 
                                if (key == NULL)
                                {                               
index b7f5fce..1f8917d 100644 (file)
@@ -905,7 +905,6 @@ main_outI1(int whack_sock, connection_t *c, struct state *predecessor
        struct state *st = new_state();
        pb_stream reply;    /* not actually a reply, but you know what I mean */
        pb_stream rbody;
-
        int vids_to_send = 0;
 
        /* set up new state */
@@ -925,7 +924,8 @@ main_outI1(int whack_sock, connection_t *c, struct state *predecessor
        {
                vids_to_send++;
        }
-       if (c->spd.this.cert.type == CERT_PGP)
+       if (c->spd.this.cert &&
+               c->spd.this.cert->cert->get_type(c->spd.this.cert->cert) == CERT_GPG)
        {
                vids_to_send++;
        }
@@ -1022,7 +1022,8 @@ main_outI1(int whack_sock, connection_t *c, struct state *predecessor
        /* if we  have an OpenPGP certificate we assume an
         * OpenPGP peer and have to send the Vendor ID
         */
-       if (c->spd.this.cert.type == CERT_PGP)
+       if (c->spd.this.cert &&
+               c->spd.this.cert->cert->get_type(c->spd.this.cert->cert) == CERT_GPG)
        {
                if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
                , &rbody, VID_OPENPGP))
@@ -2166,12 +2167,12 @@ static void decode_cert(struct msg_digest *md)
                blob.len = pbs_left(&p->pbs);
                if (cert->isacert_type == CERT_X509_SIGNATURE)
                {
-                       x509cert_t x509cert = empty_x509cert;
+                       cert_t x509cert = cert_empty;
 
                        x509cert.cert = lib->creds->create(lib->creds,
-                                                                               CRED_CERTIFICATE, CERT_X509,
-                                                                               BUILD_BLOB_ASN1_DER, blob,
-                                                                               BUILD_END);
+                                                                                          CRED_CERTIFICATE, CERT_X509,
+                                                                                          BUILD_BLOB_ASN1_DER, blob,
+                                                                                          BUILD_END);
                        if (x509cert.cert)
                        {
                                if (verify_x509cert(&x509cert, strict_crl_policy, &valid_until))
@@ -2179,7 +2180,7 @@ static void decode_cert(struct msg_digest *md)
                                        DBG(DBG_PARSING,
                                                DBG_log("Public key validated")
                                        )
-                                       add_x509_public_key(&x509cert, valid_until, DAL_SIGNED);
+                                       add_public_key_from_cert(&x509cert, valid_until, DAL_SIGNED);
                                }
                                else
                                {
@@ -3518,7 +3519,7 @@ stf_status main_inR2_outI3(struct msg_digest *md)
        
        connection_t *c = st->st_connection;
        certpolicy_t cert_policy = c->spd.this.sendcert;
-       cert_t mycert = c->spd.this.cert;
+       cert_t *mycert = c->spd.this.cert;
        bool requested, send_cert, send_cr;
        bool pubkey_auth = uses_pubkey_auth(st->st_oakley.auth);
 
@@ -3548,8 +3549,9 @@ stf_status main_inR2_outI3(struct msg_digest *md)
         * or are requested to send it
         */
        requested = cert_policy == CERT_SEND_IF_ASKED && c->got_certrequest;
-       send_cert = pubkey_auth && mycert.type != CERT_NONE
-                               && (cert_policy == CERT_ALWAYS_SEND || requested);
+       send_cert = pubkey_auth && mycert &&
+                               mycert->cert->get_type(mycert->cert) == CERT_X509 &&
+                               (cert_policy == CERT_ALWAYS_SEND || requested);
 
        /* send certificate request if we don't have a preloaded RSA public key */
        send_cr = !no_cr_send && send_cert && !has_preloaded_public_key(st);
@@ -3599,7 +3601,7 @@ stf_status main_inR2_outI3(struct msg_digest *md)
                DBG(DBG_CONTROL,
                        DBG_log("our certificate policy is %N", cert_policy_names, cert_policy)
                )
-               if (mycert.type != CERT_NONE)
+               if (mycert && mycert->cert->get_type(mycert->cert) == CERT_X509)
                {
                        const char *request_text = "";
 
@@ -3623,13 +3625,13 @@ stf_status main_inR2_outI3(struct msg_digest *md)
 
                struct isakmp_cert cert_hd;
                cert_hd.isacert_np = (send_cr)? ISAKMP_NEXT_CR : ISAKMP_NEXT_SIG;
-               cert_hd.isacert_type = mycert.type;
+               cert_hd.isacert_type = CERT_X509_SIGNATURE;
 
                if (!out_struct(&cert_hd, &isakmp_ipsec_certificate_desc, &md->rbody, &cert_pbs))
                {
                        return STF_INTERNAL_ERROR;
                }
-               cert_encoding = cert_get_encoding(mycert);
+               cert_encoding = mycert->cert->get_encoding(mycert->cert);
                success = out_chunk(cert_encoding, &cert_pbs, "CERT");
                free(cert_encoding.ptr);
                if (!success)   
@@ -3645,7 +3647,7 @@ stf_status main_inR2_outI3(struct msg_digest *md)
                identification_t *ca = st->st_connection->spd.that.ca;
                chunk_t cr = (ca) ? ca->get_encoding(ca) : chunk_empty;
 
-               if (!build_and_ship_CR(mycert.type, cr, &md->rbody, ISAKMP_NEXT_SIG))
+               if (!build_and_ship_CR(CERT_X509_SIGNATURE, cr, &md->rbody, ISAKMP_NEXT_SIG))
                {
                        return STF_INTERNAL_ERROR;
                }
@@ -3971,7 +3973,7 @@ main_inI3_outR3_tail(struct msg_digest *md
        u_int8_t auth_payload;
        pb_stream r_id_pbs; /* ID Payload; also used for hash calculation */
        certpolicy_t cert_policy;
-       cert_t mycert;
+       cert_t *mycert;
        bool pubkey_auth, send_cert, requested;
 
        /* ID and HASH_I or SIG_I in
@@ -3996,7 +3998,8 @@ main_inI3_outR3_tail(struct msg_digest *md
        requested = cert_policy == CERT_SEND_IF_ASKED
                                && st->st_connection->got_certrequest;
        pubkey_auth = uses_pubkey_auth(st->st_oakley.auth);
-       send_cert = pubkey_auth && mycert.type != CERT_NONE &&
+       send_cert = pubkey_auth && mycert &&
+                               mycert->cert->get_type(mycert->cert) == CERT_X509 &&
                                (cert_policy == CERT_ALWAYS_SEND || requested);
 
        /*************** build output packet HDR*;IDir;HASH/SIG_R ***************/
@@ -4039,7 +4042,7 @@ main_inI3_outR3_tail(struct msg_digest *md
                DBG(DBG_CONTROL,
                        DBG_log("our certificate policy is %N", cert_policy_names, cert_policy)
                )
-               if (mycert.type != CERT_NONE)
+               if (mycert && mycert->cert->get_type(mycert->cert) == CERT_X509)
                {
                        const char *request_text = "";
 
@@ -4063,13 +4066,13 @@ main_inI3_outR3_tail(struct msg_digest *md
                struct isakmp_cert cert_hd;
 
                cert_hd.isacert_np = ISAKMP_NEXT_SIG;
-               cert_hd.isacert_type = mycert.type;
+               cert_hd.isacert_type = CERT_X509_SIGNATURE;
 
                if (!out_struct(&cert_hd, &isakmp_ipsec_certificate_desc, &md->rbody, &cert_pbs))
                {
                        return STF_INTERNAL_ERROR;
                }
-               cert_encoding = cert_get_encoding(mycert);
+               cert_encoding = mycert->cert->get_encoding(mycert->cert);
                success = out_chunk(cert_encoding, &cert_pbs, "CERT");
                free(cert_encoding.ptr);
                if (!success)
index f054a6b..8cf28ac 100644 (file)
 
 #include <library.h>
 #include <asn1/asn1.h>
+#include <credentials/certificates/pgp_certificate.h>
 
 #include "constants.h"
 #include "defs.h"
 #include "x509.h"
-#include "pgpcert.h"
 #include "certs.h"
 #include "smartcard.h"
 #include "connections.h"
@@ -111,9 +111,11 @@ static const secret_t* get_secret(const connection_t *c,
        identification_t *my_id, *his_id;
 
        /* is there a certificate assigned to this connection? */
-       if (kind == PPK_PUBKEY && c->spd.this.cert.type != CERT_NONE)
+       if (kind == PPK_PUBKEY && c->spd.this.cert)
        {
-               public_key_t *pub_key = cert_get_public_key(c->spd.this.cert);
+               certificate_t *certificate = c->spd.this.cert->cert;
+
+               public_key_t *pub_key = certificate->get_public_key(certificate);
 
                for (s = secrets; s != NULL; s = s->next)
                {
@@ -262,11 +264,11 @@ const chunk_t* get_preshared_secret(const connection_t *c)
 /* check the existence of a private key matching a public key contained
  * in an X.509 or OpenPGP certificate
  */
-bool has_private_key(cert_t cert)
+bool has_private_key(cert_t *cert)
 {
        secret_t *s;
        bool has_key = FALSE;
-       public_key_t *pub_key = cert_get_public_key(cert);
+       public_key_t *pub_key = cert->cert->get_public_key(cert->cert);
 
        for (s = secrets; s != NULL; s = s->next)
        {
@@ -284,7 +286,7 @@ bool has_private_key(cert_t cert)
 /*
  * get the matching private key belonging to a given X.509 certificate
  */
-private_key_t* get_x509_private_key(const x509cert_t *cert)
+private_key_t* get_x509_private_key(const cert_t *cert)
 {
        public_key_t *public_key = cert->cert->get_public_key(cert->cert);
        private_key_t *private_key = NULL;
@@ -1272,80 +1274,86 @@ bool add_public_key(identification_t *id, enum dns_auth_level dns_auth_level,
        return TRUE;
 }
 
-/* extract id and public key from x.509 certificate and
- * insert it into a pubkeyrec
+/**
+ * Extract id and public key a certificate and insert it into a pubkeyrec
  */
-void add_x509_public_key(x509cert_t *cert , time_t until,
-                                                enum dns_auth_level dns_auth_level)
+void add_public_key_from_cert(cert_t *cert , time_t until,
+                                                         enum dns_auth_level dns_auth_level)
 {
        certificate_t *certificate = cert->cert;
-       x509_t *x509 = (x509_t*)certificate;
        identification_t *subject = certificate->get_subject(certificate);
-       identification_t *issuer = certificate->get_issuer(certificate);
+       identification_t *issuer = NULL;
        identification_t *id;
-       chunk_t serialNumber = x509->get_serial(x509);
+       chunk_t serialNumber = chunk_empty;
        pubkey_t *pk;
        key_type_t pk_type;
-       enumerator_t *enumerator;
 
        /* ID type: ID_DER_ASN1_DN  (X.509 subject field) */
        pk = malloc_thing(pubkey_t);
        zero(pk);
        pk->public_key = certificate->get_public_key(certificate);
+       pk_type = pk->public_key->get_type(pk->public_key);
        pk->id = subject->clone(subject);
        pk->dns_auth_level = dns_auth_level;
        pk->until_time = until;
-       pk->issuer = issuer->clone(issuer);
-       pk->serial = chunk_clone(serialNumber);
-       pk_type = pk->public_key->get_type(pk->public_key);
+       if (certificate->get_type(certificate) == CERT_X509)
+       {
+               x509_t *x509 = (x509_t*)certificate;
+
+               issuer = certificate->get_issuer(certificate);
+               serialNumber = x509->get_serial(x509);
+               pk->issuer = issuer->clone(issuer);
+               pk->serial = chunk_clone(serialNumber);
+       }
        delete_public_keys(pk->id, pk_type, pk->issuer, pk->serial);
        install_public_key(pk, &pubkeys);
 
-       /* insert all subjectAltNames */
-       enumerator = x509->create_subjectAltName_enumerator(x509);
-       while (enumerator->enumerate(enumerator, &id)) 
+       if (certificate->get_type(certificate) == CERT_X509)
        {
-               if (id->get_type(id) != ID_ANY)
+               x509_t *x509 = (x509_t*)certificate;
+               enumerator_t *enumerator;
+
+               /* insert all subjectAltNames from X.509 certificates */
+               enumerator = x509->create_subjectAltName_enumerator(x509);
+               while (enumerator->enumerate(enumerator, &id)) 
                {
-                       pk = malloc_thing(pubkey_t);
-                       zero(pk);
-                       pk->id = id->clone(id);
-                       pk->public_key = certificate->get_public_key(certificate);
-                       pk->dns_auth_level = dns_auth_level;
-                       pk->until_time = until;
-                       pk->issuer = issuer->clone(issuer);
-                       pk->serial = chunk_clone(serialNumber);
-                       delete_public_keys(pk->id, pk_type, pk->issuer, pk->serial);
-                       install_public_key(pk, &pubkeys);
+                       if (id->get_type(id) != ID_ANY)
+                       {
+                               pk = malloc_thing(pubkey_t);
+                               zero(pk);
+                               pk->id = id->clone(id);
+                               pk->public_key = certificate->get_public_key(certificate);
+                               pk->dns_auth_level = dns_auth_level;
+                               pk->until_time = until;
+                               pk->issuer = issuer->clone(issuer);
+                               pk->serial = chunk_clone(serialNumber);
+                               delete_public_keys(pk->id, pk_type, pk->issuer, pk->serial);
+                               install_public_key(pk, &pubkeys);
+                       }
                }
+               enumerator->destroy(enumerator);
+       }
+       else
+       {
+               pgp_certificate_t *pgp_cert = (pgp_certificate_t*)certificate;
+               chunk_t fingerprint = pgp_cert->get_fingerprint(pgp_cert);
+
+               /* add v3 or v4 PGP fingerprint */
+               pk = malloc_thing(pubkey_t);
+               zero(pk);
+               pk->id = identification_create_from_encoding(ID_KEY_ID, fingerprint);
+               pk->public_key = certificate->get_public_key(certificate);
+               pk->dns_auth_level = dns_auth_level;
+               pk->until_time = until;
+               delete_public_keys(pk->id, pk_type, pk->issuer, pk->serial);
+               install_public_key(pk, &pubkeys);
        }
-       enumerator->destroy(enumerator);
-}
-
-/* extract id and public key from OpenPGP certificate and
- * insert it into a pubkeyrec
- */
-void add_pgp_public_key(pgpcert_t *cert , time_t until,
-                                               enum dns_auth_level dns_auth_level)
-{
-       pubkey_t *pk;
-       key_type_t pk_type;
-
-       pk = malloc_thing(pubkey_t);
-       zero(pk);
-       pk->public_key = cert->public_key->get_ref(cert->public_key);
-       pk->id = cert->fingerprint->clone(cert->fingerprint);
-       pk->dns_auth_level = dns_auth_level;
-       pk->until_time = until;
-       pk_type = pk->public_key->get_type(pk->public_key);
-       delete_public_keys(pk->id, pk_type, NULL, chunk_empty);
-       install_public_key(pk, &pubkeys);
 }
 
 /*  when a X.509 certificate gets revoked, all instances of
  *  the corresponding public key must be removed
  */
-void remove_x509_public_key(const x509cert_t *cert)
+void remove_x509_public_key(const cert_t *cert)
 {
        public_key_t *revoked_key = cert->cert->get_public_key(cert->cert);
        pubkey_list_t *p, **pp;
index 558a44f..d856c00 100644 (file)
@@ -45,7 +45,7 @@ struct connection;
 
 extern const chunk_t *get_preshared_secret(const struct connection *c);
 extern private_key_t *get_private_key(const struct connection *c);
-extern private_key_t *get_x509_private_key(const x509cert_t *cert);
+extern private_key_t *get_x509_private_key(const cert_t *cert);
 
 /* public key machinery  */
 
@@ -84,12 +84,10 @@ extern bool add_public_key(identification_t *id,
                                                   enum pubkey_alg alg,
                                                   chunk_t rfc3110_key,
                                                   pubkey_list_t **head);
-extern bool has_private_key(cert_t cert);
-extern void add_x509_public_key(x509cert_t *cert, time_t until
-       , enum dns_auth_level dns_auth_level);
-extern void add_pgp_public_key(pgpcert_t *cert, time_t until
-       , enum dns_auth_level dns_auth_level);
-extern void remove_x509_public_key(const x509cert_t *cert);
+extern bool has_private_key(cert_t *cert);
+extern void add_public_key_from_cert(cert_t *cert, time_t until,
+                                                                        enum dns_auth_level dns_auth_level);
+extern void remove_x509_public_key(const cert_t *cert);
 extern void list_public_keys(bool utc);
 
 struct gw_info; /* forward declaration of tag (defined in dnskey.h) */
index 2674aa2..d1533cc 100644 (file)
@@ -145,7 +145,7 @@ static chunk_t ocsp_default_uri;
 static ocsp_location_t *ocsp_cache = NULL;
 
 /* static temporary storage for ocsp requestor information */
-static x509cert_t *ocsp_requestor_cert = NULL;
+static cert_t *ocsp_requestor_cert = NULL;
 
 static smartcard_t *ocsp_requestor_sc = NULL;
 
@@ -281,7 +281,7 @@ static const asn1Object_t singleResponseObjects[] = {
  * Build an ocsp location from certificate information
  * without unsharing its contents
  */
-static bool build_ocsp_location(const x509cert_t *cert, ocsp_location_t *location)
+static bool build_ocsp_location(const cert_t *cert, ocsp_location_t *location)
 {
        certificate_t *certificate = cert->cert;
        identification_t *issuer = certificate->get_issuer(certificate);
@@ -329,7 +329,7 @@ static bool build_ocsp_location(const x509cert_t *cert, ocsp_location_t *locatio
 
        if (authKeyID.ptr == NULL)
        {
-               x509cert_t *authcert = get_authcert(issuer, authKeyID, X509_CA);
+               cert_t *authcert = get_authcert(issuer, authKeyID, X509_CA);
 
                if (authcert)
                {
@@ -416,7 +416,7 @@ static cert_status_t get_ocsp_status(const ocsp_location_t *loc,
 /**
  * Verify the ocsp status of a certificate
  */
-cert_status_t verify_by_ocsp(const x509cert_t *cert, time_t *until,
+cert_status_t verify_by_ocsp(const cert_t *cert, time_t *until,
                                                         time_t *revocationDate,
                                                         crl_reason_t *revocationReason)
 {
@@ -646,7 +646,7 @@ void list_ocsp_cache(bool utc, bool strict)
 
 static bool get_ocsp_requestor_cert(ocsp_location_t *location)
 {
-       x509cert_t *cert = NULL;
+       cert_t *cert = NULL;
 
        /* initialize temporary static storage */
        ocsp_requestor_cert = NULL;
@@ -962,7 +962,7 @@ chunk_t build_ocsp_request(ocsp_location_t *location)
 static bool valid_ocsp_response(response_t *res)
 {
        int pathlen, pathlen_constraint;
-       x509cert_t *authcert;
+       cert_t *authcert;
 
        lock_authcert_list("valid_ocsp_response");
 
@@ -992,7 +992,7 @@ static bool valid_ocsp_response(response_t *res)
 
        for (pathlen = -1; pathlen <= X509_MAX_PATH_LEN; pathlen++)
        {
-               x509cert_t *cert = authcert;
+               cert_t *cert = authcert;
                certificate_t *certificate = cert->cert;
                x509_t *x509 = (x509_t*)certificate;
                identification_t *subject = certificate->get_subject(certificate);
@@ -1133,10 +1133,10 @@ static bool parse_basic_ocsp_response(chunk_t blob, int level0, response_t *res)
                        break;
                case BASIC_RESPONSE_CERTIFICATE:
                        {
-                               x509cert_t *cert = malloc_thing(x509cert_t);
+                               cert_t *cert = malloc_thing(cert_t);
                                x509_t *x509;
 
-                               *cert = empty_x509cert;
+                               *cert = cert_empty;
                                cert->cert = lib->creds->create(lib->creds,
                                                                                  CRED_CERTIFICATE, CERT_X509,
                                                                                  BUILD_BLOB_ASN1_DER, object,
@@ -1146,7 +1146,7 @@ static bool parse_basic_ocsp_response(chunk_t blob, int level0, response_t *res)
                                        DBG(DBG_CONTROL | DBG_PARSING,
                                                DBG_log("parsing of embedded ocsp certificate failed")
                                        )
-                                       free_x509cert(cert);
+                                       cert_free(cert);
                                        break;
                                }
                                x509 = (x509_t*)cert->cert;
@@ -1161,7 +1161,7 @@ static bool parse_basic_ocsp_response(chunk_t blob, int level0, response_t *res)
                                        DBG(DBG_CONTROL | DBG_PARSING,
                                                DBG_log("embedded ocsp certificate rejected")
                                        )
-                                       free_x509cert(cert);
+                                       cert_free(cert);
                                }
                        }
                        break;
index a3ba6c0..977cca3 100644 (file)
@@ -69,11 +69,11 @@ extern ocsp_location_t* add_ocsp_location(const ocsp_location_t *loc
 extern void add_certinfo(ocsp_location_t *loc, ocsp_certinfo_t *info
        , ocsp_location_t **chain, bool request);
 extern void check_ocsp(void);
-extern cert_status_t verify_by_ocsp(const x509cert_t *cert, time_t *until
+extern cert_status_t verify_by_ocsp(const cert_t *cert, time_t *until
        , time_t *revocationTime, crl_reason_t *revocationReason);
 extern bool ocsp_set_request_cert(char* path);
 extern void ocsp_set_default_uri(char* uri);
-extern void ocsp_cache_add_cert(const x509cert_t* cert);
+extern void ocsp_cache_add_cert(const cert_t* cert);
 extern chunk_t build_ocsp_request(ocsp_location_t* location);
 extern void parse_ocsp(ocsp_location_t* location, chunk_t blob);
 extern void list_ocsp_locations(ocsp_location_t *location, bool requests
index 3e9831e..380186c 100644 (file)
 #include "whack.h"
 #include "keys.h"
 
-typedef enum pgp_packet_tag_t pgp_packet_tag_t;
-
-/**
- * OpenPGP packet tags as defined in section 4.3 of RFC 4880
- */
-enum pgp_packet_tag_t {
-       PGP_PKT_RESERVED               =  0,
-       PGP_PKT_PUBKEY_ENC_SESSION_KEY =  1,
-       PGP_PKT_SIGNATURE              =  2,
-       PGP_PKT_SYMKEY_ENC_SESSION_KEY =  3,
-       PGP_PKT_ONE_PASS_SIGNATURE_PKT =  4,
-       PGP_PKT_SECRET_KEY             =  5,
-       PGP_PKT_PUBLIC_KEY             =  6,
-       PGP_PKT_SECRET_SUBKEY          =  7,
-       PGP_PKT_COMPRESSED_DATA        =  8,
-       PGP_PKT_SYMKEY_ENC_DATA        =  9,
-       PGP_PKT_MARKER                 = 10,
-       PGP_PKT_LITERAL_DATA           = 11,
-       PGP_PKT_TRUST                  = 12,
-       PGP_PKT_USER_ID                = 13,
-       PGP_PKT_PUBLIC_SUBKEY          = 14,
-       PGP_PKT_USER_ATTRIBUTE         = 17,
-       PGP_PKT_SYM_ENC_INT_PROT_DATA  = 18,
-       PGP_PKT_MOD_DETECT_CODE        = 19
-};
-
-ENUM_BEGIN(pgp_packet_tag_names, PGP_PKT_RESERVED, PGP_PKT_PUBLIC_SUBKEY,
-       "Reserved",
-       "Public-Key Encrypted Session Key Packet",
-       "Signature Packet",
-       "Symmetric-Key Encrypted Session Key Packet",
-       "One-Pass Signature Packet",
-       "Secret Key Packet",
-       "Public Key Packet",
-       "Secret Subkey Packet",
-       "Compressed Data Packet",
-       "Symmetrically Encrypted Data Packet",
-       "Marker Packet",
-       "Literal Data Packet",
-       "Trust Packet",
-       "User ID Packet",
-       "Public Subkey Packet"
-);
-ENUM_NEXT(pgp_packet_tag_names, PGP_PKT_USER_ATTRIBUTE, PGP_PKT_MOD_DETECT_CODE, PGP_PKT_PUBLIC_SUBKEY,
-       "User Attribute Packet",
-       "Sym. Encrypted and Integrity Protected Data Packet",
-       "Modification Detection Code Packet"
-);
-ENUM_END(pgp_packet_tag_names, PGP_PKT_MOD_DETECT_CODE);
-
-/**
- * Chained list of OpenPGP end certificates
- */
-static pgpcert_t *pgpcerts   = NULL;
-
-/**
- * Size of PGP Key ID
- */
-#define PGP_KEYID_SIZE          8
-
-const pgpcert_t pgpcert_empty = {
-         NULL     , /* next */
-            0  , /* version */
-                       0  , /* count */
-       { NULL, 0 }, /* certificate */
-                       0  , /* created */
-                       0  , /* until */
-         NULL     , /* public key */
-         NULL       /* fingerprint */
-};
-
-#define PGP_INVALID_LENGTH     0xffffffff
-
-/**
- * Returns the length of an OpenPGP (RFC 4880) packet
- * The blob pointer is advanced past the length field.
- */
-static size_t pgp_length(chunk_t *blob, size_t len)
-{
-       size_t size = 0;
-
-       if (len > blob->len)
-       {
-               return PGP_INVALID_LENGTH;
-       }
-       blob->len -= len;
-
-       while (len-- > 0)
-       {
-               size = 256*size + *blob->ptr++;
-       }
-       return size;
-}
-
-/**
- * Extracts the length of a PGP packet
- */
-static size_t pgp_old_packet_length(chunk_t *blob)
-{
-       /* bits 0 and 1 define the packet length type */
-       int len_type = 0x03 & *blob->ptr++;
-
-       blob->len--;
-
-       /* len_type: 0 -> 1 byte, 1 -> 2 bytes, 2 -> 4 bytes */
-       return pgp_length(blob, (len_type == 0)? 1: len_type << 1);
-}
-
-/**
- * Extracts PGP packet version (V3 or V4)
- */
-static u_char pgp_version(chunk_t *blob)
-{
-       u_char version = *blob->ptr++;
-       blob->len--;
-       DBG(DBG_PARSING,
-               DBG_log("L3 - version:");
-               DBG_log("  V%d", version)
-       )
-       return version;
-}
-
-/**
- * Parse OpenPGP signature packet defined in section 5.2.2 of RFC 4880
- */
-static bool parse_pgp_signature_packet(chunk_t *packet, pgpcert_t *cert)
-{
-       time_t created;
-       chunk_t keyid;
-       u_char  sig_type;
-       u_char version = pgp_version(packet);
-
-       /* we parse only V3 signature packets */
-       if (version != 3)
-       {
-               return TRUE;
-       }
-
-       /* size byte must have the value 5 */
-       if (pgp_length(packet, 1) != 5)
-       {
-               plog("  size must be 5");
-               return FALSE;
-       }
-
-       /* signature type - 1 byte */
-       sig_type = (u_char)pgp_length(packet, 1);
-       DBG(DBG_PARSING,
-               DBG_log("L3 - signature type:  0x%2x", sig_type)
-       )
-
-       /* creation date - 4 bytes */
-       created = (time_t)pgp_length(packet, 4);
-       DBG(DBG_PARSING,
-               DBG_log("L3 - created:");
-               DBG_log("  %T", &cert->created, TRUE)
-       )
-
-       /* key ID of signer - 8 bytes */
-       keyid.ptr = packet->ptr;
-       keyid.len = PGP_KEYID_SIZE;
-       DBG_cond_dump_chunk(DBG_PARSING, "L3 - key ID of signer", keyid);
-
-   return TRUE;
-}
-
-/**
- * Parses the version and validity of an OpenPGP public key packet
- */
-static bool parse_pgp_pubkey_version_validity(chunk_t *packet, pgpcert_t *cert)
-{
-       cert->version = pgp_version(packet);
-
-       if (cert->version < 3 || cert->version > 4)
-       {
-               plog("OpenPGP packet version V%d not supported", cert->version);
-               return FALSE;
-       }
-
-       /* creation date - 4 bytes */
-       cert->created = (time_t)pgp_length(packet, 4);
-       DBG(DBG_PARSING,
-               DBG_log("L3 - created:");
-               DBG_log("  %T", &cert->created, TRUE)
-       )
-
-       if (cert->version == 3)
-       {
-               /* validity in days - 2 bytes */
-               cert->until   = (time_t)pgp_length(packet, 2);
-
-               /* validity of 0 days means that the key never expires */
-               if (cert->until > 0)
-               {
-                       cert->until = cert->created + 24*3600*cert->until;
-               }
-               DBG(DBG_PARSING,
-                       DBG_log("L3 - until:");
-                       DBG_log("  %T", &cert->until, TRUE);
-               )
-       }
-       return TRUE;
-}
-
-/**
- * Parse OpenPGP public key packet defined in section 5.5.2 of RFC 4880
- */
-static bool parse_pgp_pubkey_packet(chunk_t *packet, pgpcert_t *cert)
-{
-       chunk_t pubkey_packet = *packet;
-
-       if (!parse_pgp_pubkey_version_validity(packet, cert))
-       {
-               return FALSE;
-       }
-
-       cert->public_key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_ANY,
-                                                                                 BUILD_BLOB_PGP, *packet, BUILD_END);
-       if (cert->public_key == NULL)
-       {
-               return FALSE;
-       }
-
-       /* compute V4 or V3 fingerprint according to section 12.2 of RFC 4880 */
-       if (cert->version == 4)
-       {
-               chunk_t pubkey_packet_header = chunk_from_chars(
-                               0x99, pubkey_packet.len / 256, pubkey_packet.len % 256
-               );
-               chunk_t hash;
-               hasher_t *hasher;
-
-               hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
-               if (hasher == NULL)
-               {
-                       plog("no SHA-1 hasher available");
-                       return FALSE;
-               }
-               hasher->allocate_hash(hasher, pubkey_packet_header, NULL);
-               hasher->allocate_hash(hasher, pubkey_packet, &hash);
-               hasher->destroy(hasher);
-               cert->fingerprint = identification_create_from_encoding(ID_KEY_ID, hash);
-               free(hash.ptr);
-       }
-       else
-       {
-               chunk_t fp;
-
-               /* V3 fingerprint is computed by public_key_t class */
-               if (!cert->public_key->get_fingerprint(cert->public_key, KEY_ID_PGPV3,
-                                                                                          &fp))
-               {
-                       return FALSE;
-               }
-               cert->fingerprint = identification_create_from_encoding(ID_KEY_ID, fp);
-       }
-       return TRUE;
-}
-
-bool parse_pgp(chunk_t blob, pgpcert_t *cert)
-{
-       DBG(DBG_PARSING,
-               DBG_log("L0 - PGP file:")
-       )
-       DBG_cond_dump_chunk(DBG_RAW, "", blob);
-
-       if (cert == NULL)
-       {
-               /* should not occur, nothing to parse */
-               return FALSE;
-       }
-
-       /* parse a PGP certificate file */
-       cert->certificate = blob;
-
-       while (blob.len > 0)
-       {
-               chunk_t packet = chunk_empty;
-               u_char packet_tag = *blob.ptr;
-
-               DBG(DBG_PARSING,
-                       DBG_log("L1 - PGP packet:  tag= 0x%2x", packet_tag)
-               )
-
-               /* bit 7 must be set */
-               if (!(packet_tag & 0x80))
-               {
-                       plog("  incorrect Packet Tag");
-                       return FALSE;
-               }
-
-               /* bit 6 set defines new packet format */
-               if (packet_tag & 0x40)
-               {
-                       plog("  new PGP packet format not supported");
-                       return FALSE;
-               }
-               else
-               {
-                       int packet_type = (packet_tag & 0x3C) >> 2;
-
-                       packet.len = pgp_old_packet_length(&blob);
-                       packet.ptr = blob.ptr;
-                       blob.ptr += packet.len;
-                       blob.len -= packet.len;
-                       DBG(DBG_PARSING,
-                               DBG_log("  %N (%d), old format, %u bytes",
-                                               pgp_packet_tag_names, packet_type,
-                                               packet_type, packet.len);
-                               DBG_log("L2 - body:")
-                       )
-                       DBG_cond_dump_chunk(DBG_RAW, "", packet);
-
-                       /* parse a PGP certificate */
-                       switch (packet_type)
-                       {
-                               case PGP_PKT_PUBLIC_KEY:
-                                       if (!parse_pgp_pubkey_packet(&packet, cert))
-                                       {
-                                               return FALSE;
-                                       }
-                                       break;
-                               case PGP_PKT_SIGNATURE:
-                                       if (!parse_pgp_signature_packet(&packet, cert))
-                                       {
-                                               return FALSE;
-                                       }
-                                       break;
-                               case PGP_PKT_USER_ID:
-                                       DBG(DBG_PARSING,
-                                               DBG_log("L3 - user ID:");
-                                               DBG_log("  '%.*s'", (int)packet.len, packet.ptr)
-                                       )
-                                       break;
-                               default:
-                                       break;
-                       }
-               }
-       }
-       return TRUE;
-}
-
-/**
- *  Compare two OpenPGP certificates
- */
-static bool same_pgpcert(pgpcert_t *a, pgpcert_t *b)
-{
-       return a->certificate.len == b->certificate.len &&
-               memeq(a->certificate.ptr, b->certificate.ptr, b->certificate.len);
-}
-
-/**
- * For each link pointing to the certificate increase the count by one
- */
-void share_pgpcert(pgpcert_t *cert)
-{
-       if (cert != NULL)
-       {
-               cert->count++;
-       }
-}
-
-/**
- * Select the OpenPGP keyid as ID
- */
-identification_t* select_pgpcert_id(pgpcert_t *cert, identification_t *id)
-{
-       id->destroy(id);
-
-       return cert->fingerprint->clone(cert->fingerprint);
-}
-
-/**
- *  Add an OpenPGP user/host certificate to the chained list
- */
-pgpcert_t* add_pgpcert(pgpcert_t *cert)
-{
-       pgpcert_t *c = pgpcerts;
-
-       while (c != NULL)
-       {
-               if (same_pgpcert(c, cert)) /* already in chain, free cert */
-               {
-                       free_pgpcert(cert);
-                       return c;
-               }
-               c = c->next;
-       }
-
-       /* insert new cert at the root of the chain */
-       cert->next = pgpcerts;
-       pgpcerts = cert;
-       DBG(DBG_CONTROL | DBG_PARSING,
-               DBG_log("  pgp cert inserted")
-       )
-       return cert;
-}
-
-/**
- *  Release of a certificate decreases the count by one.
- *  The certificate is freed when the counter reaches zero
- */
-void release_pgpcert(pgpcert_t *cert)
-{
-       if (cert != NULL && --cert->count == 0)
-       {
-               pgpcert_t **pp = &pgpcerts;
-               while (*pp != cert)
-               {
-                       pp = &(*pp)->next;
-               }
-               *pp = cert->next;
-               free_pgpcert(cert);
-       }
-}
-
-/**
- *  Free a PGP certificate
- */
-void free_pgpcert(pgpcert_t *cert)
-{
-       if (cert != NULL)
-       {
-               DESTROY_IF(cert->public_key);
-               DESTROY_IF(cert->fingerprint);
-               free(cert->certificate.ptr);
-               free(cert);
-       }
-}
-
-/**
- *  List all PGP end certificates in a chained list
- */
-void list_pgp_end_certs(bool utc)
-{
-   pgpcert_t *cert = pgpcerts;
-   time_t now;
-
-       /* determine the current time */
-       time(&now);
-
-       if (cert != NULL)
-       {
-               whack_log(RC_COMMENT, " ");
-               whack_log(RC_COMMENT, "List of PGP End Entity Certificates:");
-       }
-
-       while (cert != NULL)
-       {
-               public_key_t *key = cert->public_key;
-               chunk_t keyid;
-               cert_t c;
-
-               c.type = CERT_PGP;
-               c.u.pgp = cert;
-
-               whack_log(RC_COMMENT, " ");
-               whack_log(RC_COMMENT, "  digest:    %Y", cert->fingerprint);
-               whack_log(RC_COMMENT, "  created:   %T", &cert->created, utc);
-               whack_log(RC_COMMENT, "  until:     %T %s", &cert->until, utc,
-                               check_expiry(cert->until, CA_CERT_WARNING_INTERVAL, TRUE));
-               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(c)? ", has private key" : "");
-               if (key->get_fingerprint(key, KEY_ID_PUBKEY_INFO_SHA1, &keyid))
-               {
-                       whack_log(RC_COMMENT, "  keyid:     %#B", &keyid);
-               }
-               cert = cert->next;
-       }
-}
 
index 27c1605..fa58982 100644 (file)
 #ifndef _PGPCERT_H
 #define _PGPCERT_H
 
-#include <utils/identification.h>
-#include <crypto/hashers/hasher.h>
-#include <credentials/keys/private_key.h>
-#include <credentials/keys/public_key.h>
-
-/*
- * Length of PGP V3 fingerprint
- */
-#define PGP_FINGERPRINT_SIZE    HASH_SIZE_MD5
-
-typedef char fingerprint_t[PGP_FINGERPRINT_SIZE];
-
-/* access structure for an OpenPGP certificate */
-
-typedef struct pgpcert pgpcert_t;
-
-struct pgpcert {
-       pgpcert_t        *next;
-       int              version;
-       int              count;
-       chunk_t          certificate;
-       time_t           created;
-       time_t           until;
-       public_key_t     *public_key;
-       identification_t *fingerprint;
-};
-
-extern const pgpcert_t pgpcert_empty;
-extern bool parse_pgp(chunk_t blob, pgpcert_t *cert);
-extern void share_pgpcert(pgpcert_t *cert);
-extern identification_t* select_pgpcert_id(pgpcert_t *cert, identification_t *id);
-extern pgpcert_t* add_pgpcert(pgpcert_t *cert);
 extern void list_pgp_end_certs(bool utc);
-extern void release_pgpcert(pgpcert_t *cert);
-extern void free_pgpcert(pgpcert_t *cert);
 
 #endif /* _PGPCERT_H */
index 79e63d2..826a1aa 100644 (file)
@@ -476,7 +476,7 @@ void whack_handle(int whackctlfd)
 
        if (msg.whack_list & LIST_CERTS)
        {
-               list_certs(msg.whack_utc);
+               cert_list(msg.whack_utc);
        }
 
        if (msg.whack_list & LIST_CACERTS)
index 1c96615..f1a3932 100644 (file)
@@ -59,21 +59,21 @@ static smartcard_t *smartcards   = NULL;
 static int sc_number = 0;
 
 const smartcard_t empty_sc = {
-         NULL               , /* next */
-                       0            , /* last_load */
-       { CERT_NONE, {NULL} }, /* last_cert */
-                       0            , /* count */
-                       0            , /* number */
-          999999            , /* slot */
-         NULL               , /* id */
-         NULL               , /* label */
-       { NULL, 0 }          , /* pin */
-         FALSE              , /* pinpad */
-         FALSE              , /* valid */
-         FALSE              , /* session_opened */
-         FALSE              , /* logged_in */
-         TRUE               , /* any_slot */
-                       0L           , /* session */
+         NULL         , /* next */
+                       0      , /* last_load */
+         NULL         , /* last_cert */
+                       0      , /* count */
+                       0      , /* number */
+         999999       , /* slot */
+         NULL         , /* id */
+         NULL         , /* label */
+       { NULL, 0 }    , /* pin */
+         FALSE        , /* pinpad */
+         FALSE        , /* valid */
+         FALSE        , /* session_opened */
+         FALSE        , /* logged_in */
+         TRUE         , /* any_slot */
+                       0L     , /* session */
 };
 
 #ifdef SMARTCARD        /* compile with smartcard support */
@@ -437,14 +437,13 @@ failed: scx_unload_pkcs11_module(mod);
 /*
  * retrieve a certificate object
  */
-static bool scx_find_cert_object(CK_SESSION_HANDLE session,
-                                                                CK_OBJECT_HANDLE object,
-                                                                smartcard_t *sc, cert_t *cert)
+static cert_t* scx_find_cert_object(CK_SESSION_HANDLE session,
+                                                                       CK_OBJECT_HANDLE object, smartcard_t *sc)
 {
        size_t hex_len, label_len;
        u_char *hex_id = NULL;
+       cert_t *cert;
        chunk_t blob;
-       x509cert_t *x509cert;
 
        CK_ATTRIBUTE attr[] = {
                { CKA_ID,    NULL_PTR, 0L },
@@ -452,16 +451,13 @@ static bool scx_find_cert_object(CK_SESSION_HANDLE session,
                { CKA_VALUE, NULL_PTR, 0L }
        };
 
-       /* initialize the return argument */
-       *cert = cert_empty;
-
        /* get the length of the attributes first */
        CK_RV rv = pkcs11_functions->C_GetAttributeValue(session, object, attr, 3);
        if (rv != CKR_OK)
        {
                plog("couldn't read the attribute sizes: %s"
                        , enum_show(&pkcs11_return_names, rv));
-               return FALSE;
+               return NULL;
        }
 
        free(sc->label);
@@ -486,7 +482,7 @@ static bool scx_find_cert_object(CK_SESSION_HANDLE session,
                free(hex_id);
                free(sc->label);
                free(blob.ptr);
-               return FALSE;
+               return NULL;
        }
 
        free(sc->id);
@@ -500,22 +496,23 @@ static bool scx_find_cert_object(CK_SESSION_HANDLE session,
        sc->label[label_len] = '\0';
 
        /* parse the retrieved cert */
-       x509cert = malloc_thing(x509cert_t);
-       *x509cert = empty_x509cert;
-       x509cert->smartcard = TRUE;
-       x509cert->cert = lib->creds->create(lib->creds,
-                                                                               CRED_CERTIFICATE, CERT_X509,
-                                                                               BUILD_BLOB_ASN1_DER, blob,
-                                                                               BUILD_END);
-       if (x509cert->cert)
-       {
-               cert->type = CERT_X509_SIGNATURE;
-               cert->u.x509 = x509cert;
-               return TRUE;
+
+       /* initialize the return argument */
+       cert = malloc_thing(cert_t);
+       *cert = cert_empty;
+       cert->smartcard = TRUE;
+       cert->cert = lib->creds->create(lib->creds,
+                                                                       CRED_CERTIFICATE, CERT_X509,
+                                                                       BUILD_BLOB_ASN1_DER, blob,
+                                                                       BUILD_END);
+       if (cert->cert)
+       {
+               return cert;
        }
+
        plog("failed to load cert from smartcard, error in X.509 certificate");
-       free_x509cert(x509cert);
-       return FALSE;
+       cert_free(cert);
+       return NULL;
 }
 
 
@@ -542,7 +539,7 @@ static void scx_find_cert_objects(CK_SLOT_ID slot, CK_SESSION_HANDLE session)
                CK_ULONG obj_count = 0;
                time_t valid_until;
                smartcard_t *sc;
-               x509cert_t *cert;
+               certificate_t *certificate;
                x509_t *x509;
 
                rv = pkcs11_functions->C_FindObjects(session, &object, 1, &obj_count);
@@ -562,8 +559,8 @@ static void scx_find_cert_objects(CK_SLOT_ID slot, CK_SESSION_HANDLE session)
                *sc = empty_sc;
                sc->any_slot = FALSE;
                sc->slot  = slot;
-
-               if (!scx_find_cert_object(session, object, sc, &sc->last_cert))
+               sc->last_cert = scx_find_cert_object(session, object, sc);
+               if (sc->last_cert == NULL)
                {
                        scx_free(sc);
                        continue;
@@ -574,10 +571,9 @@ static void scx_find_cert_objects(CK_SLOT_ID slot, CK_SESSION_HANDLE session)
                )
 
                /* check validity of certificate */
-               cert = sc->last_cert.u.x509;
-               if (!cert->cert->get_validity(cert->cert, NULL, NULL, &valid_until))
+               certificate = sc->last_cert->cert;
+               if (!certificate->get_validity(certificate, NULL, NULL, &valid_until))
                {
-                       free_x509cert(cert);
                        scx_free(sc);
                        continue;
                }
@@ -586,20 +582,20 @@ static void scx_find_cert_objects(CK_SLOT_ID slot, CK_SESSION_HANDLE session)
                )
 
                sc = scx_add(sc);
-               x509 = (x509_t*)cert->cert;
+               x509 = (x509_t*)certificate;
 
                /* put end entity and ca certificates into different chains */
                if (x509->get_flags(x509) & X509_CA)
                {
-                       sc->last_cert.u.x509 = add_authcert(cert, X509_CA);
+                       sc->last_cert = add_authcert(sc->last_cert, X509_CA);
                }
                else
                {
-                       add_x509_public_key(cert, valid_until, DAL_LOCAL);
-                       sc->last_cert.u.x509 = add_x509cert(cert);
+                       add_public_key_from_cert(sc->last_cert, valid_until, DAL_LOCAL);
+                       sc->last_cert = cert_add(sc->last_cert);
                }
 
-               share_cert(sc->last_cert);
+               cert_share(sc->last_cert);
                time(&sc->last_load);
        }
 
@@ -1070,67 +1066,66 @@ void scx_release_context(smartcard_t *sc)
 /*
  * Load host certificate from smartcard
  */
-bool scx_load_cert(const char *filename, smartcard_t **scp, cert_t *cert,
-                                  bool *cached)
+cert_t* scx_load_cert(const char *filename, smartcard_t **scp, bool *cached)
 {
 #ifdef SMARTCARD        /* compile with smartcard support */
-       CK_OBJECT_HANDLE object;
-
        const char *number_slot_id = filename + strlen(SCX_TOKEN);
-
-       smartcard_t *sc = scx_add(scx_parse_number_slot_id(number_slot_id));
+       CK_OBJECT_HANDLE object;
+       smartcard_t *sc;
+       cert_t *cert = NULL;
 
        /* return the smartcard object */
-       *scp = sc;
+       *scp = sc = scx_add(scx_parse_number_slot_id(number_slot_id));
 
        /* is there a cached smartcard certificate? */
-       *cached = sc->last_cert.type != CERT_NONE
-                         && (time(NULL) - sc->last_load) < SCX_CERT_CACHE_INTERVAL;
+       *cached = sc->last_cert && 
+                         (time(NULL) - sc->last_load) < SCX_CERT_CACHE_INTERVAL;
 
        if (*cached)
        {
-               *cert = sc->last_cert;
                plog("  using cached cert from smartcard #%d (%s, id: %s, label: '%s')"
                                , sc->number
                                , scx_print_slot(sc, "")
                                , sc->id
                                , sc->label);
-               return TRUE;
+               return sc->last_cert;
        }
 
        if (!scx_establish_context(sc))
        {
                scx_release_context(sc);
-               return FALSE;
+               return NULL;
        }
 
        /* find the certificate object */
        if (!scx_pkcs11_find_object(sc->session, &object, CKO_CERTIFICATE, sc->id))
        {
                scx_release_context(sc);
-               return FALSE;
+               return NULL;
        }
 
        /* retrieve the certificate object */
-       if (!scx_find_cert_object(sc->session, object, sc, cert))
+       cert = scx_find_cert_object(sc->session, object, sc);
+       if (cert == NULL)
        {
                scx_release_context(sc);
-               return FALSE;
+               return NULL;
        }
 
        if (!pkcs11_keep_state)
+       {
                scx_release_context(sc);
-
+       }
        plog("  loaded cert from smartcard #%d (%s, id: %s, label: '%s')"
                , sc->number
                , scx_print_slot(sc, "")
                , sc->id
                , sc->label);
 
-       return TRUE;
+       return cert;
 #else
        plog("  warning: SMARTCARD support is deactivated in pluto/Makefile!");
-       return FALSE;
+       return NULL;
 #endif
 }
 
@@ -1793,6 +1788,7 @@ void scx_free(smartcard_t *sc)
        if (sc != NULL)
        {
                scx_release_context(sc);
+               cert_release(sc->last_cert);
                free(sc->id);
                free(sc->label);
                scx_free_pin(&sc->pin);
@@ -1811,7 +1807,6 @@ void scx_release(smartcard_t *sc)
                while (*pp != sc)
                        pp = &(*pp)->next;
                *pp = sc->next;
-               release_cert(sc->last_cert);
                scx_free(sc);
        }
 }
@@ -1875,14 +1870,16 @@ smartcard_t* scx_add(smartcard_t *smartcard)
 /*
  * get the smartcard that belongs to an X.509 certificate
  */
-smartcard_t* scx_get(x509cert_t *cert)
+smartcard_t* scx_get(cert_t *cert)
 {
        smartcard_t *sc = smartcards;
 
        while (sc != NULL)
        {
-               if (sc->last_cert.u.x509 == cert)
+               if (sc->last_cert == cert)
+               {
                        return sc;
+               }
                sc = sc->next;
        }
        return NULL;
@@ -1929,9 +1926,9 @@ void scx_list(bool utc)
                        whack_log(RC_COMMENT, "  id:       %s", sc->id);
                if (sc->label != NULL)
                        whack_log(RC_COMMENT, "  label:   '%s'", sc->label);
-               if (sc->last_cert.type == CERT_X509_SIGNATURE)
+               if (sc->last_cert)
                {
-                       certificate_t *certificate = sc->last_cert.u.x509->cert;
+                       certificate_t *certificate = sc->last_cert->cert;
 
                        whack_log(RC_COMMENT, "  subject: '%Y'",
                                          certificate->get_subject(certificate));
index 60a0fcc..7a22297 100644 (file)
@@ -42,7 +42,7 @@ typedef struct smartcard smartcard_t;
 struct smartcard {
        smartcard_t  *next;
        time_t        last_load;
-       cert_t        last_cert;
+       cert_t        *last_cert;
        int           count;
        int           number;
        unsigned long slot;
@@ -75,8 +75,7 @@ extern void scx_finalize(void);
 extern bool scx_establish_context(smartcard_t *sc);
 extern bool scx_login(smartcard_t *sc);
 extern bool scx_on_smartcard(const char *filename);
-extern bool scx_load_cert(const char *filename, smartcard_t **scp
-       , cert_t *cert, bool *cached);
+extern cert_t* scx_load_cert(const char *filename, smartcard_t **scp, bool *cached);
 extern bool scx_verify_pin(smartcard_t *sc);
 extern void scx_share(smartcard_t *sc);
 extern bool scx_sign_hash(smartcard_t *sc, const u_char *in, size_t inlen
@@ -90,7 +89,7 @@ extern bool scx_op_via_whack(const char* msg, int inbase, int outbase
 extern bool scx_get_pin(smartcard_t *sc, int whackfd);
 extern size_t scx_get_keylength(smartcard_t *sc);
 extern smartcard_t* scx_add(smartcard_t *sc);
-extern smartcard_t* scx_get(x509cert_t *cert);
+extern smartcard_t* scx_get(cert_t *cert);
 extern void scx_release(smartcard_t *sc);
 extern void scx_release_context(smartcard_t *sc);
 extern void scx_free_pin(chunk_t *pin);
index a612a70..705ff2c 100644 (file)
 #include "ocsp.h"
 
 /**
- * Chained lists of X.509 end certificates
- */
-static x509cert_t *x509certs     = NULL;
-
-const x509cert_t empty_x509cert = {
-         NULL        , /* cert */
-         NULL        , /* *next */
-                       0     , /* count */
-         FALSE         /* smartcard */
-};
-
-/* coding of X.501 distinguished name */
-
-/**
- * For each link pointing to the certificate increase the count by one
- */
-void share_x509cert(x509cert_t *cert)
-{
-       if (cert != NULL)
-       {
-               cert->count++;
-       }
-}
-
-/**
- *  Add a X.509 user/host certificate to the chained list
- */
-x509cert_t* add_x509cert(x509cert_t *cert)
-{
-       certificate_t *certificate = cert->cert;
-       x509cert_t *c = x509certs;
-
-       while (c != NULL)
-       {
-               if (certificate->equals(certificate, c->cert)) /* already in chain, free cert */
-               {
-                       free_x509cert(cert);
-                       return c;
-               }
-               c = c->next;
-       }
-
-       /* insert new cert at the root of the chain */
-       lock_certs_and_keys("add_x509cert");
-       cert->next = x509certs;
-       x509certs = cert;
-       DBG(DBG_CONTROL | DBG_PARSING,
-               DBG_log("  x509 cert inserted")
-       )
-       unlock_certs_and_keys("add_x509cert");
-       return cert;
-}
-
-/**
- * Choose either subject DN or a subjectAltName as connection end ID
- */
-identification_t* select_x509cert_id(x509cert_t *cert, identification_t *id)
-{
-       certificate_t *certificate = cert->cert;
-       x509_t *x509 = (x509_t*)certificate;
-       identification_t *subject, *subjectAltName;
-
-       bool copy_subject_dn = TRUE;    /* ID is subject DN */
-
-       if (id->get_type(id) != ID_ANY) /* check for a matching subjectAltName */
-       {
-               enumerator_t *enumerator;
-
-               enumerator = x509->create_subjectAltName_enumerator(x509);
-               while (enumerator->enumerate(enumerator, &subjectAltName))
-               {
-                       if (id->equals(id, subjectAltName))
-                       {
-                               copy_subject_dn = FALSE; /* take subjectAltName instead */
-                               break;
-                       }
-               }
-               enumerator->destroy(enumerator);
-       }
-       if (copy_subject_dn)
-       {
-               id->destroy(id);
-               subject = certificate->get_subject(certificate);
-               plog("  no subjectAltName matches ID '%Y', replaced by subject DN", id);
-
-               return subject->clone(subject);
-       }
-       else
-       {
-               return id;
-       }
-}
-
-/**
  * Check for equality between two key identifiers
  */
 bool same_keyid(chunk_t a, chunk_t b)
@@ -151,9 +57,9 @@ bool same_keyid(chunk_t a, chunk_t b)
 /**
  * Get a X.509 certificate with a given issuer found at a certain position
  */
-x509cert_t* get_x509cert(identification_t *issuer, chunk_t keyid, x509cert_t *chain)
+cert_t* get_x509cert(identification_t *issuer, chunk_t keyid, cert_t *chain)
 {
-       x509cert_t *cert = chain ? chain->next : x509certs;
+       cert_t *cert = chain->next;
 
        while (cert)
        {
@@ -172,47 +78,11 @@ x509cert_t* get_x509cert(identification_t *issuer, chunk_t keyid, x509cert_t *ch
 }
 
 /**
- *  Free a X.509 certificate
- */
-void free_x509cert(x509cert_t *cert)
-{
-       if (cert)
-       {
-               certificate_t *certificate = cert->cert;
-
-               if (certificate)
-               {
-                       certificate->destroy(certificate);
-               }
-               free(cert);
-               cert = NULL;
-       }
-}
-
-/**
- * Release of a certificate decreases the count by one
- * the certificate is freed when the counter reaches zero
- */
-void release_x509cert(x509cert_t *cert)
-{
-       if (cert && --cert->count == 0)
-       {
-               x509cert_t **pp = &x509certs;
-               while (*pp != cert)
-               {
-                       pp = &(*pp)->next;
-               }
-               *pp = cert->next;
-               free_x509cert(cert);
-       }
-}
-
-/**
  * Stores a chained list of end certs and CA certs
  */
 void store_x509certs(linked_list_t *certs, bool strict)
 {
-       x509cert_t *x509cert, *cacerts = NULL;
+       cert_t *x509cert, *cacerts = NULL;
        certificate_t *cert;
        enumerator_t *enumerator;
 
@@ -235,8 +105,8 @@ void store_x509certs(linked_list_t *certs, bool strict)
                        else
                        {
                                /* insertion into temporary chain of candidate CA certs */
-                               x509cert = malloc_thing(x509cert_t);
-                               *x509cert = empty_x509cert;
+                               x509cert = malloc_thing(cert_t);
+                               *x509cert = cert_empty;
                                x509cert->cert = cert->get_ref(cert);
                                x509cert->next = cacerts;
                                cacerts = x509cert;
@@ -249,7 +119,7 @@ void store_x509certs(linked_list_t *certs, bool strict)
 
        while (cacerts)
        {
-               x509cert_t *cert = cacerts;
+               cert_t *cert = cacerts;
 
                cacerts = cacerts->next;
 
@@ -260,7 +130,7 @@ void store_x509certs(linked_list_t *certs, bool strict)
                else
                {
                        plog("intermediate cacert rejected");
-                       free_x509cert(cert);
+                       cert_free(cert);
                }
        }
 
@@ -274,8 +144,8 @@ void store_x509certs(linked_list_t *certs, bool strict)
 
                if (!(x509->get_flags(x509) & X509_CA))
                {
-                       x509cert = malloc_thing(x509cert_t);
-                       *x509cert = empty_x509cert;
+                       x509cert = malloc_thing(cert_t);
+                       *x509cert = cert_empty;
                        x509cert->cert = cert->get_ref(cert);
 
                        if (verify_x509cert(x509cert, strict, &valid_until))
@@ -283,12 +153,12 @@ void store_x509certs(linked_list_t *certs, bool strict)
                                DBG(DBG_CONTROL | DBG_PARSING,
                                        DBG_log("public key validated")
                                )
-                               add_x509_public_key(x509cert, valid_until, DAL_SIGNED);
+                               add_public_key_from_cert(x509cert, valid_until, DAL_SIGNED);
                        }
                        else
                        {
                                plog("X.509 certificate rejected");
-                               free_x509cert(x509cert);
+                               cert_free(x509cert);
                        }
                }
        }
@@ -342,7 +212,7 @@ chunk_t x509_build_signature(chunk_t tbs, int algorithm, private_key_t *key,
 /**
  * Verifies a X.509 certificate
  */
-bool verify_x509cert(const x509cert_t *cert, bool strict, time_t *until)
+bool verify_x509cert(cert_t *cert, bool strict, time_t *until)
 {
        int pathlen, pathlen_constraint;
 
@@ -355,7 +225,7 @@ bool verify_x509cert(const x509cert_t *cert, bool strict, time_t *until)
                identification_t *issuer  = certificate->get_issuer(certificate);
                x509_t *x509 = (x509_t*)certificate;
                chunk_t authKeyID = x509->get_authKeyIdentifier(x509);
-               x509cert_t *issuer_cert;
+               cert_t *issuer_cert;
                time_t notBefore, notAfter;
                bool valid;
 
@@ -497,7 +367,7 @@ bool verify_x509cert(const x509cert_t *cert, bool strict, time_t *until)
 /**
  * List all X.509 certs in a chained list
  */
-void list_x509cert_chain(const char *caption, x509cert_t* cert,
+void list_x509cert_chain(const char *caption, cert_t* cert,
                                                 x509_flag_t flags, bool utc)
 {
        bool first = TRUE;
@@ -511,7 +381,8 @@ void list_x509cert_chain(const char *caption, x509cert_t* cert,
                certificate_t *certificate = cert->cert;
                x509_t *x509 = (x509_t*)certificate;
 
-               if (flags == X509_NONE || (flags & x509->get_flags(x509)))
+               if (certificate->get_type(certificate) == CERT_X509 &&
+                  (flags == X509_NONE || (flags & x509->get_flags(x509))))
                {
                        enumerator_t *enumerator;
                        char buf[BUF_LEN];
@@ -522,10 +393,6 @@ void list_x509cert_chain(const char *caption, x509cert_t* cert,
                        time_t notBefore, notAfter;
                        public_key_t *key;
                        chunk_t serial, keyid, subjkey, authkey;
-                       cert_t c;
-
-                       c.type = CERT_X509_SIGNATURE;
-                       c.u.x509 = cert;
 
                        if (first)
                        {
@@ -581,7 +448,7 @@ void list_x509cert_chain(const char *caption, x509cert_t* cert,
                                        key_type_names, key->get_type(key),
                                        key->get_keysize(key) * BITS_PER_BYTE,                          
                                        cert->smartcard ? ", on smartcard" :
-                                       (has_private_key(c)? ", has private key" : ""));
+                                       (has_private_key(cert)? ", has private key" : ""));
 
                                if (key->get_fingerprint(key, KEY_ID_PUBKEY_INFO_SHA1, &keyid))
                                {
@@ -613,10 +480,3 @@ void list_x509cert_chain(const char *caption, x509cert_t* cert,
        }
 }
 
-/**
- * List all X.509 end certificates in a chained list
- */
-void list_x509_end_certs(bool utc)
-{
-       list_x509cert_chain("End Entity", x509certs, X509_NONE, utc);
-}
index 40e7e7e..615b2ab 100644 (file)
 
 #include <utils/identification.h>
 #include <utils/linked_list.h>
-#include <credentials/keys/public_key.h>
 #include <credentials/keys/private_key.h>
 #include <credentials/certificates/x509.h>
 
 #include "constants.h"
-
-/* access structure for an X.509v3 certificate */
-
-typedef struct x509cert x509cert_t;
-
-struct x509cert {
-       certificate_t  *cert;
-       x509cert_t     *next;
-       int             count;
-       bool            smartcard;
-};
-
-/* used for initialization */
-extern const x509cert_t empty_x509cert;
+#include "certs.h"
 
 extern bool same_keyid(chunk_t a, chunk_t b);
-extern identification_t* select_x509cert_id(x509cert_t *cert, identification_t *id);
-extern void parse_authorityKeyIdentifier(chunk_t blob, int level0,
-                                                                                chunk_t *authKeyID,
-                                                                                chunk_t *authKeySerialNumber);
 extern bool x509_check_signature(chunk_t tbs, chunk_t sig, int algorithm,
                                                                 certificate_t *issuer_cert);
 extern chunk_t x509_build_signature(chunk_t tbs, int algorithm,
                                                                        private_key_t *key, bool bit_string);
-extern bool verify_x509cert(const x509cert_t *cert, bool strict, time_t *until);
-extern x509cert_t* add_x509cert(x509cert_t *cert);
-extern x509cert_t* get_x509cert(identification_t *issuer, chunk_t keyid, x509cert_t* chain);
-extern void share_x509cert(x509cert_t *cert);
-extern void release_x509cert(x509cert_t *cert);
-extern void free_x509cert(x509cert_t *cert);
+extern bool verify_x509cert(cert_t *cert, bool strict, time_t *until);
+extern cert_t* get_x509cert(identification_t *issuer, chunk_t keyid, cert_t* chain);
 extern void store_x509certs(linked_list_t *certs, bool strict);
-extern void list_x509cert_chain(const char *caption, x509cert_t* cert,
+extern void list_x509cert_chain(const char *caption, cert_t* cert,
                                                                x509_flag_t flags, bool utc);
 extern void list_x509_end_certs(bool utc);
 
index 6d5f0fb..3f66a7b 100644 (file)
@@ -18,6 +18,7 @@
 #include <freeswan.h>
 
 #include <defs.h>
+#include <constants.h>
 
 /* copy of smartcard operations, defined in smartcard.h */
 #ifndef SC_OP_T