pluto and scepclient now use the x509 plugin for certificates
authorAndreas Steffen <andreas.steffen@strongswan.org>
Sun, 27 Sep 2009 21:09:30 +0000 (23:09 +0200)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Sun, 27 Sep 2009 21:09:30 +0000 (23:09 +0200)
27 files changed:
src/pluto/ac.c
src/pluto/builder.c
src/pluto/ca.c
src/pluto/ca.h
src/pluto/certs.c
src/pluto/connections.c
src/pluto/crl.c
src/pluto/crl.h
src/pluto/fetch.c
src/pluto/fetch.h
src/pluto/id.c
src/pluto/id.h
src/pluto/ipsec_doi.c
src/pluto/keys.c
src/pluto/ocsp.c
src/pluto/ocsp.h
src/pluto/pkcs7.c
src/pluto/pkcs7.h
src/pluto/smartcard.c
src/pluto/x509.c
src/pluto/x509.h
src/scepclient/Makefile.am
src/scepclient/pkcs10.c
src/scepclient/pkcs10.h
src/scepclient/scep.c
src/scepclient/scep.h
src/scepclient/scepclient.c

index 5594569..96cc9b2 100644 (file)
@@ -669,8 +669,8 @@ x509acert_t* get_x509acert(chunk_t issuer, chunk_t serial)
 
        while (ac != NULL)
        {
-               if (same_dn(issuer, ac->holderIssuer)
-               &&  same_serial(serial, ac->holderSerial))
+               if (same_dn(issuer, ac->holderIssuer) &&
+                       chunk_equals(serial, ac->holderSerial))
                {
                        if (ac!= x509acerts)
                        {
@@ -772,8 +772,7 @@ bool verify_x509acert(x509acert_t *ac, bool strict)
        )
 
        lock_authcert_list("verify_x509acert");
-       aacert = get_authcert(ac->issuerName, ac->authKeySerialNumber
-               , ac->authKeyID, AUTH_AA);
+       aacert = get_authcert(ac->issuerName, ac->authKeyID, AUTH_AA);
        unlock_authcert_list("verify_x509acert");
 
        if (aacert == NULL)
@@ -786,7 +785,7 @@ bool verify_x509acert(x509acert_t *ac, bool strict)
        )
 
        if (!x509_check_signature(ac->certificateInfo, ac->signature, ac->algorithm,
-                                                         aacert))
+                                                         aacert->cert))
        {
                plog("attribute certificate signature is invalid");
                return FALSE;
index fac393e..acaff0d 100644 (file)
@@ -20,6 +20,7 @@
 #include <stdio.h>
 #include <string.h>
 #include <unistd.h>
+#include <time.h>
 
 #include <freeswan.h>
 
@@ -79,13 +80,20 @@ static cert_t *builder_load_cert(certificate_type_t type, va_list args)
                else
                {
                        x509cert_t *x509cert = malloc_thing(x509cert_t);
+
                        *x509cert = empty_x509cert;
-                       if (parse_x509cert(chunk_clone(blob), 0, x509cert))
+                       x509cert->cert = lib->creds->create(lib->creds,
+                                                                               CRED_CERTIFICATE, CERT_X509,
+                                                                               BUILD_BLOB_ASN1_DER, blob,
+                                                                               BUILD_END);
+                       if (x509cert->cert)
                        {
                                cert_t *cert = malloc_thing(cert_t);
+
                                *cert = cert_empty;
                                cert->type = CERT_X509_SIGNATURE;
                                cert->u.x509 = x509cert;
+                               time(&x509cert->installed);
                                return cert;
                        }
                        plog("  error in X.509 certificate");
@@ -158,6 +166,8 @@ static x509crl_t *builder_load_crl(certificate_type_t type, va_list args)
        {
                crl = malloc_thing(x509crl_t);
                *crl = empty_x509crl;
+               crl->distributionPoints = linked_list_create();
+
                if (parse_x509crl(chunk_clone(blob), 0, crl))
                {
                        return crl;
index 77374b6..bc6bfe9 100644 (file)
@@ -20,6 +20,8 @@
 #include <time.h>
 #include <sys/types.h>
 
+#include <utils/identification.h>
+
 #include <freeswan.h>
 
 #include "constants.h"
 
 static x509cert_t *x509authcerts = NULL;
 
-const ca_info_t empty_ca_info = {
-         NULL        ,  /* next */
-         NULL        ,  /* name */
-       UNDEFINED_TIME,
-       { NULL, 0 }   ,  /* authName */
-       { NULL, 0 }   ,  /* authKeyID */
-       { NULL, 0 }   ,  /* authKey SerialNumber */
-         NULL        ,  /* ldaphost */
-         NULL        ,  /* ldapbase */
-         NULL        ,  /* ocspori */
-         NULL        ,  /* crluri */
-         FALSE          /* strictcrlpolicy */
-};
-
 /* chained list of X.509 certification authority information records */
 
 static ca_info_t *ca_infos = NULL;
@@ -57,8 +45,7 @@ static ca_info_t *ca_infos = NULL;
 /*
  * Checks if CA a is trusted by CA b
  */
-bool
-trusted_ca(chunk_t a, chunk_t b, int *pathlen)
+bool trusted_ca(chunk_t a, chunk_t b, int *pathlen)
 {
        bool match = FALSE;
 
@@ -80,28 +67,49 @@ trusted_ca(chunk_t a, chunk_t b, int *pathlen)
 
        /* CA a equals CA b -> we have a match */
        if (same_dn(a, b))
+       {
                return TRUE;
+       }
 
        /* CA a might be a subordinate CA of b */
        lock_authcert_list("trusted_ca");
 
        while ((*pathlen)++ < MAX_CA_PATH_LEN)
        {
-               x509cert_t *cacert = get_authcert(a, chunk_empty, chunk_empty, AUTH_CA);
+               certificate_t *certificate;
+               identification_t *issuer;
+               chunk_t issuer_dn;
+               x509cert_t *cacert;
 
-               /* cacert not found or self-signed root cacert-> exit */
-               if (cacert == NULL || same_dn(cacert->issuer, a))
+               cacert = get_authcert(a, chunk_empty, AUTH_CA);
+               if (cacert == NULL)
+               {
                        break;
+               }
+               certificate = cacert->cert;
+               
+               /* is the certificate self-signed? */
+               {
+                       x509_t *x509 = (x509_t*)certificate;
+
+                       if (x509->get_flags(x509) & X509_SELF_SIGNED)
+                       {
+                               break;
+                       }
+               }
 
                /* does the issuer of CA a match CA b? */
-               match = same_dn(cacert->issuer, b);
+               issuer = certificate->get_issuer(certificate);
+               issuer_dn = issuer->get_encoding(issuer);
+               match = same_dn(issuer_dn, b);
 
                /* we have a match and exit the loop */
                if (match)
+               {
                        break;
-
+               }
                /* go one level up in the CA chain */
-               a = cacert->issuer;
+               a = issuer_dn;
        }
 
        unlock_authcert_list("trusted_ca");
@@ -111,8 +119,8 @@ trusted_ca(chunk_t a, chunk_t b, int *pathlen)
 /*
  * does our CA match one of the requested CAs?
  */
-bool
-match_requested_ca(generalName_t *requested_ca, chunk_t our_ca, int *our_pathlen)
+bool match_requested_ca(generalName_t *requested_ca, chunk_t our_ca,
+                                               int *our_pathlen)
 {
        /* if no ca is requested than any ca will match */
        if (requested_ca == NULL)
@@ -149,8 +157,7 @@ match_requested_ca(generalName_t *requested_ca, chunk_t our_ca, int *our_pathlen
 /*
  *  free the first authority certificate in the chain
  */
-static void
-free_first_authcert(void)
+static void free_first_authcert(void)
 {
        x509cert_t *first = x509authcerts;
        x509authcerts = first->next;
@@ -160,8 +167,7 @@ free_first_authcert(void)
 /*
  *  free  all CA certificates
  */
-void
-free_authcerts(void)
+void free_authcerts(void)
 {
        lock_authcert_list("free_authcerts");
 
@@ -174,30 +180,58 @@ free_authcerts(void)
 /*
  *  get a X.509 authority certificate with a given subject or keyid
  */
-x509cert_t*
-get_authcert(chunk_t subject, chunk_t serial, chunk_t keyid, u_char auth_flags)
+x509cert_t* get_authcert(chunk_t subject, chunk_t keyid, u_char auth_flags)
 {
-       x509cert_t *cert = x509authcerts;
-       x509cert_t *prev_cert = NULL;
+       x509cert_t *cert, *prev_cert = NULL;
+
+       /* the authority certificate list is empty */
+       if (x509authcerts == NULL)
+       {
+               return NULL;
+       }
 
-       while (cert != NULL)
+       for (cert = x509authcerts; cert != NULL; prev_cert = cert, cert = cert->next)
        {
-               if (cert->authority_flags & auth_flags
-               && ((keyid.ptr != NULL) ? same_keyid(keyid, cert->subjectKeyID)
-                       : (same_dn(subject, cert->subject)
-                          && same_serial(serial, cert->serialNumber))))
+               certificate_t *certificate = cert->cert;
+               identification_t *cert_subject;
+               chunk_t cert_subject_dn;
+
+               /* skip non-matching types of authority certificates */
+               if (!(cert->authority_flags & auth_flags))
+               {
+                       continue;
+               }
+
+               /* compare the keyid with the certificate's subjectKeyIdentifier */
+               if (keyid.ptr)
                {
-                       if (cert != x509authcerts)
+                       x509_t *x509 = (x509_t*)certificate;
+                       chunk_t subjectKeyId;
+
+                       subjectKeyId = x509->get_subjectKeyIdentifier(x509);
+                       if (subjectKeyId.ptr && !chunk_equals(keyid, subjectKeyId))
                        {
-                               /* bring the certificate up front */
-                               prev_cert->next = cert->next;
-                               cert->next = x509authcerts;
-                               x509authcerts = cert;
+                               continue;
                        }
-                       return cert;
                }
-               prev_cert = cert;
-               cert = cert->next;
+
+               /* compare the subjectDistinguishedNames */
+               cert_subject = certificate->get_subject(certificate);
+               cert_subject_dn = cert_subject->get_encoding(cert_subject);
+               if (!same_dn(subject, cert_subject_dn))
+               {
+                       continue;
+               }
+
+               /* found the authcert */
+               if (cert != x509authcerts)
+               {
+                       /* bring the certificate up front */
+                       prev_cert->next = cert->next;
+                       cert->next = x509authcerts;
+                       x509authcerts = cert;
+               }
+               return cert;
        }
        return NULL;
 }
@@ -205,9 +239,12 @@ get_authcert(chunk_t subject, chunk_t serial, chunk_t keyid, u_char auth_flags)
 /*
  * add an authority certificate to the chained list
  */
-x509cert_t*
-add_authcert(x509cert_t *cert, u_char auth_flags)
+x509cert_t* add_authcert(x509cert_t *cert, u_char auth_flags)
 {
+       certificate_t *certificate = cert->cert;
+       x509_t *x509 = (x509_t*)certificate;
+       identification_t *cert_subject = certificate->get_subject(certificate);
+       chunk_t cert_subject_dn = cert_subject->get_encoding(cert_subject);
        x509cert_t *old_cert;
 
        /* set authority flags */
@@ -215,12 +252,12 @@ add_authcert(x509cert_t *cert, u_char auth_flags)
 
        lock_authcert_list("add_authcert");
 
-       old_cert = get_authcert(cert->subject, cert->serialNumber
-               , cert->subjectKeyID, auth_flags);
-
+       old_cert = get_authcert(cert_subject_dn, 
+                                                       x509->get_subjectKeyIdentifier(x509),
+                                                       auth_flags);
        if (old_cert != NULL)
        {
-               if (same_x509cert(cert, old_cert))
+               if (certificate->equals(certificate, old_cert->cert))
                {
                        /* cert is already present, just add additional authority flags */
                        old_cert->authority_flags |= cert->authority_flags;
@@ -256,8 +293,7 @@ add_authcert(x509cert_t *cert, u_char auth_flags)
 /*
  *  Loads authority certificates
  */
-void
-load_authcerts(const char *type, const char *path, u_char auth_flags)
+void load_authcerts(const char *type, const char *path, u_char auth_flags)
 {
        struct dirent **filelist;
        u_char buf[BUF_LEN];
@@ -299,8 +335,7 @@ load_authcerts(const char *type, const char *path, u_char auth_flags)
 /*
  *  list all X.509 authcerts with given auth flags in a chained list
  */
-void
-list_authcerts(const char *caption, u_char auth_flags, bool utc)
+void list_authcerts(const char *caption, u_char auth_flags, bool utc)
 {
        lock_authcert_list("list_authcerts");
        list_x509cert_chain(caption, x509authcerts, auth_flags, utc);
@@ -310,19 +345,43 @@ list_authcerts(const char *caption, u_char auth_flags, bool utc)
 /*
  * get a cacert with a given subject or keyid from an alternative list
  */
-static const x509cert_t*
-get_alt_cacert(chunk_t subject, chunk_t serial, chunk_t keyid
-       , const x509cert_t *cert)
+static const x509cert_t* get_alt_cacert(chunk_t subject, chunk_t keyid,
+                                                                               const x509cert_t *cert)
 {
-       while (cert != NULL)
+       if (cert == NULL)
+       {
+               return NULL;
+       }
+
+       for (; cert != NULL; cert = cert->next)
        {
-               if ((keyid.ptr != NULL) ? same_keyid(keyid, cert->subjectKeyID)
-                       : (same_dn(subject, cert->subject)
-                          && same_serial(serial, cert->serialNumber)))
+               certificate_t *certificate = cert->cert;
+               identification_t *cert_subject;
+               chunk_t cert_subject_dn;
+
+               /* compare the keyid with the certificate's subjectKeyIdentifier */
+               if (keyid.ptr)
+               {
+                       x509_t *x509 = (x509_t*)certificate;
+                       chunk_t subjectKeyId;
+
+                       subjectKeyId = x509->get_subjectKeyIdentifier(x509);
+                       if (subjectKeyId.ptr && !chunk_equals(keyid, subjectKeyId))
+                       {
+                               continue;
+                       }
+               }
+
+               /* compare the subjectDistinguishedNames */
+               cert_subject = certificate->get_subject(certificate);
+               cert_subject_dn = cert_subject->get_encoding(cert_subject);
+               if (!same_dn(subject, cert_subject_dn))
                {
-                       return cert;
+                       continue;
                }
-               cert = cert->next;
+
+               /* we found the cacert */
+               return cert;
        }
        return NULL;
 }
@@ -330,8 +389,7 @@ get_alt_cacert(chunk_t subject, chunk_t serial, 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 x509cert_t *cert, const x509cert_t *alt_chain)
 {
        int pathlen;
 
@@ -339,25 +397,25 @@ trust_authcert_candidate(const x509cert_t *cert, const x509cert_t *alt_chain)
 
        for (pathlen = 0; pathlen < MAX_CA_PATH_LEN; pathlen++)
        {
+               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);
+               chunk_t issuer_dn = issuer->get_encoding(issuer);
+               chunk_t authKeyID = x509->get_authKeyIdentifier(x509);
                const x509cert_t *authcert = NULL;
-               u_char buf[BUF_LEN];
 
                DBG(DBG_CONTROL,
-                       dntoa(buf, BUF_LEN, cert->subject);
-                       DBG_log("subject: '%s'",buf);
-                       dntoa(buf, BUF_LEN, cert->issuer);
-                       DBG_log("issuer:  '%s'",buf);
-                       if (cert->authKeyID.ptr != NULL)
+                       DBG_log("subject: '%Y'", subject);
+                       DBG_log("issuer:  '%Y'", issuer);
+                       if (authKeyID.ptr != NULL)
                        {
-                               datatot(cert->authKeyID.ptr, cert->authKeyID.len, ':'
-                                       , buf, BUF_LEN);
-                               DBG_log("authkey:  %s", buf);
+                               DBG_log("authkey:  %#B", &authKeyID);
                        }
                )
 
                /* search in alternative chain first */
-               authcert = get_alt_cacert(cert->issuer, cert->authKeySerialNumber
-                       , cert->authKeyID, alt_chain);
+               authcert = get_alt_cacert(issuer_dn, authKeyID, alt_chain);
 
                if (authcert != NULL)
                {
@@ -368,8 +426,7 @@ trust_authcert_candidate(const x509cert_t *cert, const x509cert_t *alt_chain)
                else
                {
                        /* search in trusted chain */
-                       authcert = get_authcert(cert->issuer, cert->authKeySerialNumber
-                               , cert->authKeyID, AUTH_CA);
+                       authcert = get_authcert(issuer_dn, authKeyID, AUTH_CA);
 
                        if (authcert != NULL)
                        {
@@ -385,8 +442,7 @@ trust_authcert_candidate(const x509cert_t *cert, const x509cert_t *alt_chain)
                        }
                }
 
-               if (!x509_check_signature(cert->tbsCertificate, cert->signature,
-                                                                 cert->algorithm, authcert))
+               if (!certificate->issued_by(certificate, authcert->cert))
                {
                        plog("certificate signature is invalid");
                        unlock_authcert_list("trust_authcert_candidate");
@@ -397,7 +453,7 @@ trust_authcert_candidate(const x509cert_t *cert, const x509cert_t *alt_chain)
                )
 
                /* check if cert is a self-signed root ca */
-               if (pathlen > 0 && same_dn(cert->issuer, cert->subject))
+               if (pathlen > 0 && (x509->get_flags(x509) & X509_SELF_SIGNED))
                {
                        DBG(DBG_CONTROL,
                                DBG_log("reached self-signed root ca")
@@ -417,16 +473,14 @@ trust_authcert_candidate(const x509cert_t *cert, const x509cert_t *alt_chain)
 /*
  *  get a CA info record with a given authName or authKeyID
  */
-ca_info_t*
-get_ca_info(chunk_t authname, chunk_t serial, chunk_t keyid)
+ca_info_t* get_ca_info(chunk_t authname, chunk_t keyid)
 {
        ca_info_t *ca= ca_infos;
 
        while (ca!= NULL)
        {
                if ((keyid.ptr != NULL) ? same_keyid(keyid, ca->authKeyID)
-                       : (same_dn(authname, ca->authName)
-                          && same_serial(serial, ca->authKeySerialNumber)))
+                       : same_dn(authname, ca->authName))
                {
                        return ca;
                }
@@ -443,24 +497,23 @@ static void
 free_ca_info(ca_info_t* ca_info)
 {
        if (ca_info == NULL)
+       {
                return;
-
+       }
+       ca_info->crluris->destroy_function(ca_info->crluris, free);
        free(ca_info->name);
        free(ca_info->ldaphost);
        free(ca_info->ldapbase);
        free(ca_info->ocspuri);
        free(ca_info->authName.ptr);
        free(ca_info->authKeyID.ptr);
-       free(ca_info->authKeySerialNumber.ptr);
-       free_generalNames(ca_info->crluri, TRUE);
        free(ca_info);
 }
 
 /*
  *  free  all CA certificates
  */
-void
-free_ca_infos(void)
+void free_ca_infos(void)
 {
        while (ca_infos != NULL)
        {
@@ -474,8 +527,7 @@ free_ca_infos(void)
 /*
  * find a CA information record by name and optionally delete it
  */
-bool
-find_ca_info_by_name(const char *name, bool delete)
+bool find_ca_info_by_name(const char *name, bool delete)
 {
        ca_info_t **ca_p = &ca_infos;
        ca_info_t *ca = *ca_p;
@@ -501,12 +553,23 @@ find_ca_info_by_name(const char *name, bool delete)
        return FALSE;
 }
 
+/*
+ * Create an empty ca_info_t record
+ */
+ca_info_t* create_ca_info(void)
+{
+       ca_info_t *ca_info = malloc_thing(ca_info_t);
+
+       memset(ca_info, 0, sizeof(ca_info_t));
+       ca_info->crluris = linked_list_create();
+
+       return ca_info;
+}
 
- /*
- * adds a CA description to a chained list
+/**
+ * Adds a CA description to a chained list
  */
-void
-add_ca_info(const whack_message_t *msg)
+void add_ca_info(const whack_message_t *msg)
 {
        smartcard_t *sc = NULL;
        cert_t cert;
@@ -532,13 +595,16 @@ add_ca_info(const whack_message_t *msg)
 
        if (valid_cert)
        {
-               char buf[BUF_LEN];
                x509cert_t *cacert = cert.u.x509;
+               certificate_t *certificate = cacert->cert;
+               x509_t *x509 = (x509_t*)certificate;
+               identification_t *subject = certificate->get_subject(certificate);
+               chunk_t subject_dn = subject->get_encoding(subject);
+               chunk_t subjectKeyID = x509->get_subjectKeyIdentifier(x509);
                ca_info_t *ca = NULL;
 
                /* does the authname already exist? */
-               ca = get_ca_info(cacert->subject, cacert->serialNumber
-                               , cacert->subjectKeyID);
+               ca = get_ca_info(subject_dn, subjectKeyID);
 
                if (ca != NULL)
                {
@@ -552,30 +618,23 @@ add_ca_info(const whack_message_t *msg)
                plog("added ca description \"%s\"", msg->name);
 
                /* create and initialize new ca_info record */
-               ca = malloc_thing(ca_info_t);
-               *ca = empty_ca_info;
+               ca = create_ca_info();
 
                /* name */
                ca->name = clone_str(msg->name);
 
                /* authName */
-               ca->authName = chunk_clone(cacert->subject);
-               dntoa(buf, BUF_LEN, ca->authName);
+               ca->authName = chunk_clone(subject_dn);
                DBG(DBG_CONTROL,
-                       DBG_log("authname: '%s'", buf)
+                       DBG_log("authname: '%Y'", subject)
                )
 
-               /* authSerialNumber */
-               ca->authKeySerialNumber = chunk_clone(cacert->serialNumber);
-
                /* authKeyID */
-               if (cacert->subjectKeyID.ptr != NULL)
+               if (subjectKeyID.ptr)
                {
-                       ca->authKeyID = chunk_clone(cacert->subjectKeyID);
-                       datatot(cacert->subjectKeyID.ptr, cacert->subjectKeyID.len, ':'
-                               , buf, BUF_LEN);
+                       ca->authKeyID = chunk_clone(subjectKeyID);
                        DBG(DBG_CONTROL | DBG_PARSING ,
-                               DBG_log("authkey:  %s", buf)
+                               DBG_log("authkey:  %#B", &subjectKeyID)
                        )
                }
 
@@ -594,23 +653,9 @@ add_ca_info(const whack_message_t *msg)
                                plog("  ignoring ocspuri with unkown protocol");
                }
 
-               /* crluri2*/
-               if (msg->crluri2 != NULL)
-               {
-                       generalName_t gn =
-                               { NULL, GN_URI, {msg->crluri2, strlen(msg->crluri2)} };
-
-                       add_distribution_points(&gn, &ca->crluri);
-               }
-
-               /* crluri */
-               if (msg->crluri != NULL)
-               {
-                       generalName_t gn =
-                               { NULL, GN_URI, {msg->crluri, strlen(msg->crluri)} };
-
-                       add_distribution_points(&gn, &ca->crluri);
-               }
+               /* add crl uris */
+               add_distribution_point(ca->crluris, msg->crluri);
+               add_distribution_point(ca->crluris, msg->crluri2);
 
                /* strictrlpolicy */
                ca->strictcrlpolicy = msg->whack_strict;
@@ -625,11 +670,12 @@ 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, AUTH_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 = add_authcert(cacert, AUTH_CA);
+                       sc->last_cert.u.x509 = cacert;
                        share_cert(sc->last_cert);
                }
                if (sc != NULL)
@@ -640,8 +686,7 @@ add_ca_info(const whack_message_t *msg)
 /*
  * list all ca_info records in the chained list
  */
-void
-list_ca_infos(bool utc)
+void list_ca_infos(bool utc)
 {
        ca_info_t *ca = ca_infos;
 
@@ -672,7 +717,7 @@ list_ca_infos(bool utc)
                if (ca->ocspuri != NULL)
                        whack_log(RC_COMMENT, "       ocspuri:  '%s'", ca->ocspuri);
 
-               list_distribution_points(ca->crluri);
+               list_distribution_points(ca->crluris);
 
                if (ca->authKeyID.ptr != NULL)
                {
@@ -680,12 +725,6 @@ list_ca_infos(bool utc)
                                , buf, BUF_LEN);
                        whack_log(RC_COMMENT, "       authkey:   %s", buf);
                }
-               if (ca->authKeySerialNumber.ptr != NULL)
-               {
-                       datatot(ca->authKeySerialNumber.ptr, ca->authKeySerialNumber.len, ':'
-                               , buf, BUF_LEN);
-                       whack_log(RC_COMMENT, "       aserial:   %s", buf);
-               }
                ca = ca->next;
        }
 }
index 44d079b..eadb96d 100644 (file)
@@ -15,6 +15,8 @@
 #ifndef _CA_H
 #define _CA_H
 
+#include <utils/linked_list.h>
+
 #include "x509.h"
 #include "whack.h"
 
@@ -37,19 +39,18 @@ struct ca_info {
        time_t          installed;
        chunk_t         authName;
        chunk_t         authKeyID;
-       chunk_t         authKeySerialNumber;
        char            *ldaphost;
        char            *ldapbase;
        char            *ocspuri;
-       generalName_t   *crluri;
+       linked_list_t   *crluris;
        bool            strictcrlpolicy;
 };
 
 extern bool trusted_ca(chunk_t a, chunk_t b, int *pathlen);
 extern bool match_requested_ca(generalName_t *requested_ca
        , chunk_t our_ca, int *our_pathlen);
-extern x509cert_t* get_authcert(chunk_t subject, chunk_t serial, chunk_t keyid
-       , u_char auth_flags);
+extern x509cert_t* get_authcert(chunk_t subject, chunk_t keyid,
+                                                               u_char auth_flags);
 extern void load_authcerts(const char *type, const char *path
        , u_char auth_flags);
 extern x509cert_t* add_authcert(x509cert_t *cert, u_char auth_flags);
@@ -57,7 +58,7 @@ extern void free_authcerts(void);
 extern void list_authcerts(const char *caption, u_char auth_flags, bool utc);
 extern bool trust_authcert_candidate(const x509cert_t *cert
        , const x509cert_t *alt_chain);
-extern ca_info_t* get_ca_info(chunk_t name, chunk_t serial, chunk_t keyid);
+extern ca_info_t* get_ca_info(chunk_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);
 extern void delete_ca_info(const char *name);
index 5c6aa56..cdf567e 100644 (file)
@@ -46,9 +46,9 @@ chunk_t cert_get_encoding(cert_t cert)
        switch (cert.type)
        {
        case CERT_PGP:
-               return cert.u.pgp->certificate;
+               return chunk_clone(cert.u.pgp->certificate);
        case CERT_X509_SIGNATURE:
-               return cert.u.x509->certificate;
+               return cert.u.x509->cert->get_encoding(cert.u.x509->cert);
        default:
                return chunk_empty;
        }
@@ -59,11 +59,17 @@ public_key_t* cert_get_public_key(const cert_t cert)
        switch (cert.type)
        {
                case CERT_PGP:
-                       return cert.u.pgp->public_key;
-                       break;
+               {
+                       public_key_t *public_key = cert.u.pgp->public_key;
+
+                       return public_key->get_ref(public_key);
+               }
                case CERT_X509_SIGNATURE:
-                       return cert.u.x509->public_key;
-                       break;
+               {
+                       certificate_t *certificate = cert.u.x509->cert;
+
+                       return certificate->get_public_key(certificate);
+               }
                default:
                        return NULL;
        }
index 1eb2d33..5cd74d7 100644 (file)
@@ -92,17 +92,17 @@ static struct host_pair *host_pairs = NULL;
 static struct connection *unoriented_connections = NULL;
 
 /* check to see that Ids of peers match */
-bool
-same_peer_ids(const struct connection *c, const struct connection *d
-, const struct id *his_id)
+bool same_peer_ids(const struct connection *c, const struct connection *d,
+                                  const struct id *his_id)
 {
        return same_id(&c->spd.this.id, &d->spd.this.id)
                && same_id(his_id == NULL? &c->spd.that.id : his_id, &d->spd.that.id);
 }
 
-static struct host_pair *
-find_host_pair(const ip_address *myaddr, u_int16_t myport
-, const ip_address *hisaddr, u_int16_t hisport)
+static struct host_pair *find_host_pair(const ip_address *myaddr,
+                                                                               u_int16_t myport,
+                                                                               const ip_address *hisaddr,
+                                                                               u_int16_t hisport)
 {
        struct host_pair *p, *prev;
 
@@ -138,9 +138,10 @@ find_host_pair(const ip_address *myaddr, u_int16_t myport
 }
 
 /* find head of list of connections with this pair of hosts */
-static struct connection *
-find_host_pair_connections(const ip_address *myaddr, u_int16_t myport
-, const ip_address *hisaddr, u_int16_t hisport)
+static struct connection *find_host_pair_connections(const ip_address *myaddr,
+                                                                                                        u_int16_t myport,
+                                                                                                        const ip_address *hisaddr,
+                                                                                                               u_int16_t hisport)
 {
        struct host_pair *hp = find_host_pair(myaddr, myport, hisaddr, hisport);
 
@@ -158,8 +159,7 @@ find_host_pair_connections(const ip_address *myaddr, u_int16_t myport
        return hp == NULL? NULL : hp->connections;
 }
 
-static void
-connect_to_host_pair(struct connection *c)
+static void connect_to_host_pair(struct connection *c)
 {
        if (oriented(*c))
        {
@@ -206,8 +206,7 @@ connect_to_host_pair(struct connection *c)
  * Move the winner (if any) to the front.
  * If none is found, and strict, a diagnostic is logged to whack.
  */
-struct connection *
-con_by_name(const char *nm, bool strict)
+struct connection *con_by_name(const char *nm, bool strict)
 {
        struct connection *p, *prev;
 
@@ -235,8 +234,7 @@ con_by_name(const char *nm, bool strict)
        return p;
 }
 
-void
-release_connection(struct connection *c, bool relations)
+void release_connection(struct connection *c, bool relations)
 {
        if (c->kind == CK_INSTANCE)
        {
@@ -264,8 +262,7 @@ release_connection(struct connection *c, bool relations)
        }
 
 
-void
-delete_connection(struct connection *c, bool relations)
+void delete_connection(struct connection *c, bool relations)
 {
        struct connection *old_cur_connection
                = cur_connection == c? NULL : cur_connection;
@@ -361,8 +358,7 @@ delete_connection(struct connection *c, bool relations)
 }
 
 /* Delete connections with the specified name */
-void
-delete_connections_by_name(const char *name, bool strict)
+void delete_connections_by_name(const char *name, bool strict)
 {
        struct connection *c = con_by_name(name, strict);
 
@@ -370,15 +366,13 @@ delete_connections_by_name(const char *name, bool strict)
                delete_connection(c, FALSE);
 }
 
-void
-delete_every_connection(void)
+void delete_every_connection(void)
 {
        while (connections != NULL)
                delete_connection(connections, TRUE);
 }
 
-void
-release_dead_interfaces(void)
+void release_dead_interfaces(void)
 {
        struct host_pair *hp;
 
@@ -427,8 +421,7 @@ release_dead_interfaces(void)
 }
 
 /* adjust orientations of connections to reflect newly added interfaces */
-void
-check_orientations(void)
+void check_orientations(void)
 {
        /* try to orient all the unoriented connections */
        {
@@ -491,8 +484,7 @@ check_orientations(void)
        }
 }
 
-static err_t
-default_end(struct end *e, ip_address *dflt_nexthop)
+static err_t default_end(struct end *e, ip_address *dflt_nexthop)
 {
        err_t ugh = NULL;
        const struct af_info *afi = aftoinfo(addrtypeof(&e->host_addr));
@@ -527,13 +519,8 @@ default_end(struct end *e, ip_address *dflt_nexthop)
  * Note: if that==NULL, skip nexthop
  * Returns strlen of formated result (length excludes NUL at end).
  */
-size_t
-format_end(char *buf
-, size_t buf_len
-, const struct end *this
-, const struct end *that
-, bool is_left
-, lset_t policy)
+size_t format_end(char *buf, size_t buf_len, const struct end *this,
+                                const struct end *that, bool is_left, lset_t policy)
 {
        char client[SUBNETTOT_BUF];
        const char *client_sep = "";
@@ -668,10 +655,9 @@ format_end(char *buf
  */
 #define CONNECTION_BUF  (2 * (END_BUF - 1) + 4)
 
-static size_t
-format_connection(char *buf, size_t buf_len
-                                 , const struct connection *c
-                                 , struct spd_route *sr)
+static size_t format_connection(char *buf, size_t buf_len,
+                                                               const struct connection *c,
+                                                               struct spd_route *sr)
 {
        size_t w = format_end(buf, buf_len, &sr->this, &sr->that, TRUE, LEMPTY);
 
@@ -679,8 +665,7 @@ format_connection(char *buf, size_t buf_len
        return w + format_end(buf + w, buf_len - w, &sr->that, &sr->this, FALSE, c->policy);
 }
 
-static void
-unshare_connection_strings(struct connection *c)
+static void unshare_connection_strings(struct connection *c)
 {
        c->name = clone_str(c->name);
 
@@ -755,8 +740,9 @@ static void load_end_certificate(char *filename, struct end *dst)
                                dst->cert = cert;
                        else
                        {
+                               time_t valid_until = 0;
+
                                /* check validity of cert */
-                               valid_until = cert.u.x509->notAfter;
                                ugh = check_validity(cert.u.x509, &valid_until);
                                if (ugh != NULL)
                                {
@@ -772,9 +758,15 @@ static void load_end_certificate(char *filename, struct end *dst)
                                dst->cert.type = cert.type;
                                dst->cert.u.x509 = add_x509cert(cert.u.x509);
                        }
+
                        /* if no CA is defined, use issuer as default */
                        if (dst->ca.ptr == NULL)
-                               dst->ca = dst->cert.u.x509->issuer;
+                       {
+                               certificate_t *certificate = dst->cert.u.x509->cert;
+                               identification_t *issuer = certificate->get_issuer(certificate);
+
+                               dst->ca = issuer->get_encoding(issuer);
+                       }
                        break;
                default:
                        break;
@@ -796,8 +788,8 @@ static void load_end_certificate(char *filename, struct end *dst)
        }
 }
 
-static bool
-extract_end(struct end *dst, const whack_end_t *src, const char *which)
+static bool extract_end(struct end *dst, const whack_end_t *src,
+                                               const char *which)
 {
        bool same_ca = FALSE;
 
@@ -884,9 +876,9 @@ extract_end(struct end *dst, const whack_end_t *src, const char *which)
        return same_ca;
 }
 
-static bool
-check_connection_end(const whack_end_t *this, const whack_end_t *that
-, const whack_message_t *wm)
+static bool check_connection_end(const whack_end_t *this,
+                                                                const whack_end_t *that,
+                                                                const whack_message_t *wm)
 {
        if (wm->addr_family != addrtypeof(&this->host_addr)
        || wm->addr_family != addrtypeof(&this->host_nexthop)
@@ -921,8 +913,7 @@ check_connection_end(const whack_end_t *this, const whack_end_t *that
        return TRUE;        /* happy */
 }
 
-struct connection *
-find_connection_by_reqid(uint32_t reqid)
+struct connection *find_connection_by_reqid(uint32_t reqid)
 {
        struct connection *c;
 
@@ -936,8 +927,7 @@ find_connection_by_reqid(uint32_t reqid)
        return NULL;
 }
 
-static uint32_t
-gen_reqid(void)
+static uint32_t gen_reqid(void)
 {
        uint32_t start;
        static uint32_t reqid = IPSEC_MANUAL_REQID_MAX & ~3;
@@ -955,8 +945,7 @@ gen_reqid(void)
        return 0; /* never reached ... */
 }
 
-void
-add_connection(const whack_message_t *wm)
+void add_connection(const whack_message_t *wm)
 {
        if (con_by_name(wm->name, FALSE) != NULL)
        {
@@ -1172,8 +1161,7 @@ add_connection(const whack_message_t *wm)
  * Returns name of new connection.  May be NULL.
  * Caller is responsible for freeing.
  */
-char *
-add_group_instance(struct connection *group, const ip_subnet *target)
+char *add_group_instance(struct connection *group, const ip_subnet *target)
 {
        char namebuf[100]
                , targetbuf[SUBNETTOT_BUF];
@@ -1234,9 +1222,8 @@ add_group_instance(struct connection *group, const ip_subnet *target)
 }
 
 /* an old target has disappeared for a group: delete instance */
-void
-remove_group_instance(const struct connection *group USED_BY_DEBUG
-, const char *name)
+void remove_group_instance(const struct connection *group USED_BY_DEBUG,
+                                                  const char *name)
 {
        passert(group->kind == CK_GROUP);
        passert(oriented(*group));
@@ -1254,10 +1241,9 @@ remove_group_instance(const struct connection *group USED_BY_DEBUG
  *
  * Note that instantiate can only deal with a single SPD/eroute.
  */
-static struct connection *
-instantiate(struct connection *c, const ip_address *him
-, u_int16_t his_port
-, const struct id *his_id)
+static struct connection *instantiate(struct connection *c,
+                                                                         const ip_address *him, u_int16_t his_port,
+                                                                         const struct id *his_id)
 {
        struct connection *d;
        int wildcards;
@@ -1318,9 +1304,9 @@ instantiate(struct connection *c, const ip_address *him
        }
 }
 
-struct connection *
-rw_instantiate(struct connection *c, const ip_address *him, u_int16_t his_port
-, const ip_subnet *his_net, const struct id *his_id)
+struct connection *rw_instantiate(struct connection *c, const ip_address *him,
+                                                                 u_int16_t his_port, const ip_subnet *his_net,
+                                                                 const struct id *his_id)
 {
        struct connection *d = instantiate(c, him, his_port, his_id);
 
@@ -1345,13 +1331,10 @@ rw_instantiate(struct connection *c, const ip_address *him, u_int16_t his_port
        return d;
 }
 
-struct connection *
-oppo_instantiate(struct connection *c
-, const ip_address *him
-, const struct id *his_id
-, struct gw_info *gw
-, const ip_address *our_client USED_BY_DEBUG
-, const ip_address *peer_client)
+struct connection *oppo_instantiate(struct connection *c, const ip_address *him,
+                                                                       const struct id *his_id, struct gw_info *gw,
+                                                                       const ip_address *our_client USED_BY_DEBUG,
+                                                                       const ip_address *peer_client)
 {
        struct connection *d = instantiate(c, him, 0, his_id);
 
@@ -1416,8 +1399,7 @@ oppo_instantiate(struct connection *c
 }
 
 /* priority formatting */
-void
-fmt_policy_prio(policy_prio_t pp, char buf[POLICY_PRIO_BUF])
+void fmt_policy_prio(policy_prio_t pp, char buf[POLICY_PRIO_BUF])
 {
        if (pp == BOTTOM_PRIO)
                snprintf(buf, POLICY_PRIO_BUF, "0");
@@ -1431,8 +1413,8 @@ fmt_policy_prio(policy_prio_t pp, char buf[POLICY_PRIO_BUF])
  * Road Warrior: peer's IP address
  * Opportunistic: [" " myclient "==="] " ..." peer ["===" hisclient] '\0'
  */
-static size_t
-fmt_client(const ip_subnet *client, const ip_address *gw, const char *prefix, char buf[ADDRTOT_BUF])
+static size_t fmt_client(const ip_subnet *client, const ip_address *gw,
+                                                const char *prefix, char buf[ADDRTOT_BUF])
 {
        if (subnetisaddr(client, gw))
        {
@@ -1452,8 +1434,7 @@ fmt_client(const ip_subnet *client, const ip_address *gw, const char *prefix, ch
        return strlen(buf);
 }
 
-void
-fmt_conn_instance(const struct connection *c, char buf[CONN_INST_BUF])
+void fmt_conn_instance(const struct connection *c, char buf[CONN_INST_BUF])
 {
        char *p = buf;
 
@@ -1510,11 +1491,10 @@ fmt_conn_instance(const struct connection *c, char buf[CONN_INST_BUF])
  *
  * See also build_outgoing_opportunistic_connection.
  */
-struct connection *
-find_connection_for_clients(struct spd_route **srp,
-                                                       const ip_address *our_client,
-                                                       const ip_address *peer_client,
-                                                       int transport_proto)
+struct connection *find_connection_for_clients(struct spd_route **srp,
+                                                                                          const ip_address *our_client,
+                                                                                          const ip_address *peer_client,
+                                                                                          int transport_proto)
 {
        struct connection *c = connections, *best = NULL;
        policy_prio_t best_prio = BOTTOM_PRIO;
@@ -1654,10 +1634,9 @@ find_connection_for_clients(struct spd_route **srp,
  * find_connection_for_clients.  In this case, we know the gateways
  * that we need to instantiate an opportunistic connection.
  */
-struct connection *
-build_outgoing_opportunistic_connection(struct gw_info *gw
-                                                                               ,const ip_address *our_client
-                                                                               ,const ip_address *peer_client)
+struct connection *build_outgoing_opportunistic_connection(struct gw_info *gw,
+                                                                                       const ip_address *our_client,
+                                                                                       const ip_address *peer_client)
 {
        struct iface *p;
        struct connection *best = NULL;
@@ -1733,8 +1712,7 @@ build_outgoing_opportunistic_connection(struct gw_info *gw
                                                          , our_client, peer_client);
 }
 
-bool
-orient(struct connection *c)
+bool orient(struct connection *c)
 {
        struct spd_route *sr;
 
@@ -1796,8 +1774,7 @@ orient(struct connection *c)
        return oriented(*c);
 }
 
-void
-initiate_connection(const char *name, int whackfd)
+void initiate_connection(const char *name, int whackfd)
 {
        struct connection *c = con_by_name(name, TRUE);
 
@@ -1928,10 +1905,8 @@ struct find_oppo_continuation {
        struct find_oppo_bundle b;
 };
 
-static void
-cannot_oppo(struct connection *c
-                       , struct find_oppo_bundle *b
-                       , err_t ugh)
+static void cannot_oppo(struct connection *c, struct find_oppo_bundle *b,
+                                               err_t ugh)
 {
        char pcb[ADDRTOT_BUF];
        char ocb[ADDRTOT_BUF];
@@ -2048,12 +2023,9 @@ cannot_oppo(struct connection *c
 static void initiate_opportunistic_body(struct find_oppo_bundle *b
        , struct adns_continuation *ac, err_t ac_ugh);      /* forward */
 
-void
-initiate_opportunistic(const ip_address *our_client
-, const ip_address *peer_client
-, int transport_proto
-, bool held
-, int whackfd)
+void initiate_opportunistic(const ip_address *our_client,
+                                                       const ip_address *peer_client, int transport_proto,
+                                                       bool held, int whackfd)
 {
        struct find_oppo_bundle b;
 
@@ -2070,8 +2042,7 @@ initiate_opportunistic(const ip_address *our_client
        initiate_opportunistic_body(&b, NULL, NULL);
 }
 
-static void
-continue_oppo(struct adns_continuation *acr, err_t ugh)
+static void continue_oppo(struct adns_continuation *acr, err_t ugh)
 {
        struct find_oppo_continuation *cr = (void *)acr;    /* inherit, damn you! */
        struct connection *c;
@@ -2145,10 +2116,9 @@ continue_oppo(struct adns_continuation *acr, err_t ugh)
 }
 
 #ifdef USE_KEYRR
-static err_t
-check_key_recs(enum myid_state try_state
-, const struct connection *c
-, struct adns_continuation *ac)
+static err_t check_key_recs(enum myid_state try_state,
+                                                       const struct connection *c,
+                                                       struct adns_continuation *ac)
 {
        /* Check if KEY lookup yielded good results.
         * Looking up based on our ID.  Used if
@@ -2260,10 +2230,9 @@ static err_t check_txt_recs(enum myid_state try_state,
 
 
 /* note: gateways_from_dns must be NULL iff this is the first call */
-static void
-initiate_opportunistic_body(struct find_oppo_bundle *b
-, struct adns_continuation *ac
-, err_t ac_ugh)
+static void initiate_opportunistic_body(struct find_oppo_bundle *b,
+                                                                               struct adns_continuation *ac,
+                                                                               err_t ac_ugh)
 {
        struct connection *c;
        struct spd_route *sr;
@@ -2964,8 +2933,7 @@ initiate_opportunistic_body(struct find_oppo_bundle *b
        close_any(b->whackfd);
 }
 
-void
-terminate_connection(const char *nm)
+void terminate_connection(const char *nm)
 {
        /* Loop because more than one may match (master and instances)
         * But at least one is required (enforced by con_by_name).
@@ -3002,8 +2970,7 @@ terminate_connection(const char *nm)
  */
 bool uniqueIDs = FALSE; /* --uniqueids? */
 
-void
-ISAKMP_SA_established(struct connection *c, so_serial_t serial)
+void ISAKMP_SA_established(struct connection *c, so_serial_t serial)
 {
        c->newest_isakmp_sa = serial;
 
@@ -3047,11 +3014,8 @@ ISAKMP_SA_established(struct connection *c, so_serial_t serial)
  * The return value is used to find other connections sharing a route.
  * *erop is used to find other connections sharing an eroute.
  */
-struct connection *
-route_owner(struct connection *c
-                       , struct spd_route **srp
-                       , struct connection **erop
-                       , struct spd_route **esrp)
+struct connection *route_owner(struct connection *c, struct spd_route **srp,
+                                                          struct connection **erop, struct spd_route **esrp)
 {
        struct connection *d
                , *best_ro = c
@@ -3157,8 +3121,7 @@ route_owner(struct connection *c
  * There ought to be only one.
  * This might get to be a bottleneck -- try hashing if it does.
  */
-struct connection *
-shunt_owner(const ip_subnet *ours, const ip_subnet *his)
+struct connection *shunt_owner(const ip_subnet *ours, const ip_subnet *his)
 {
        struct connection *c;
        struct spd_route *sr;
@@ -3180,9 +3143,9 @@ shunt_owner(const ip_subnet *ours, const ip_subnet *his)
  * We don't know enough to chose amongst those available.
  * ??? no longer usefully different from find_host_pair_connections
  */
-struct connection *
-find_host_connection(const ip_address *me, u_int16_t my_port
-, const ip_address *him, u_int16_t his_port, lset_t policy)
+struct connection *find_host_connection(const ip_address *me, u_int16_t my_port,
+                                                                               const ip_address *him, u_int16_t his_port,
+                                                                               lset_t policy)
 {
        struct connection *c = find_host_pair_connections(me, my_port, him, his_port);
 
@@ -3266,9 +3229,9 @@ find_host_connection(const ip_address *me, u_int16_t my_port
  */
 #define PRIO_NO_MATCH_FOUND     2048
 
-struct connection *
-refine_host_connection(const struct state *st, const struct id *peer_id
-, chunk_t peer_ca)
+struct connection *refine_host_connection(const struct state *st,
+                                                                                 const struct id *peer_id,
+                                                                                 chunk_t peer_ca)
 {
        struct connection *c = st->st_connection;
        struct connection *d;
@@ -3456,8 +3419,8 @@ refine_host_connection(const struct state *st, const struct id *peer_id
  * With virtual addressing, we must not allow someone to use an already
  * used (by another id) addr/net.
  */
-static bool
-is_virtual_net_used(const ip_subnet *peer_net, const struct id *peer_id)
+static bool is_virtual_net_used(const ip_subnet *peer_net,
+                                                               const struct id *peer_id)
 {
        struct connection *d;
 
@@ -3520,18 +3483,17 @@ is_virtual_net_used(const ip_subnet *peer_net, const struct id *peer_id)
 #define PRIO_WEIGHT     (MAX_WILDCARDS+1)*WILD_WEIGHT
 
 /* fc_try: a helper function for find_client_connection */
-static struct connection *
-fc_try(const struct connection *c
-, struct host_pair *hp
-, const struct id *peer_id
-, const ip_subnet *our_net
-, const ip_subnet *peer_net
-, const u_int8_t our_protocol
-, const u_int16_t our_port
-, const u_int8_t peer_protocol
-, const u_int16_t peer_port
-, chunk_t peer_ca
-, const ietfAttrList_t *peer_list)
+static struct connection *fc_try(const struct connection *c,
+                                                                struct host_pair *hp,
+                                                                const struct id *peer_id,
+                                                                const ip_subnet *our_net,
+                                                                const ip_subnet *peer_net,
+                                                                const u_int8_t our_protocol,
+                                                                const u_int16_t our_port,
+                                                                const u_int8_t peer_protocol,
+                                                                const u_int16_t peer_port,
+                                                                chunk_t peer_ca,
+                                                                const ietfAttrList_t *peer_list)
 {
        struct connection *d;
        struct connection *best = NULL;
@@ -3650,17 +3612,16 @@ fc_try(const struct connection *c
        return best;
 }
 
-static struct connection *
-fc_try_oppo(const struct connection *c
-, struct host_pair *hp
-, const ip_subnet *our_net
-, const ip_subnet *peer_net
-, const u_int8_t our_protocol
-, const u_int16_t our_port
-, const u_int8_t peer_protocol
-, const u_int16_t peer_port
-, chunk_t peer_ca
-, const ietfAttrList_t *peer_list)
+static struct connection *fc_try_oppo(const struct connection *c,
+                                                                         struct host_pair *hp,
+                                                                         const ip_subnet *our_net,
+                                                                         const ip_subnet *peer_net,
+                                                                         const u_int8_t our_protocol,
+                                                                         const u_int16_t our_port,
+                                                                         const u_int8_t peer_protocol,
+                                                                         const u_int16_t peer_port,
+                                                                         chunk_t peer_ca,
+                                                                         const ietfAttrList_t *peer_list)
 {
        struct connection *d;
        struct connection *best = NULL;
@@ -3754,8 +3715,8 @@ fc_try_oppo(const struct connection *c
 /*
  * get the peer's CA and group attributes
  */
-chunk_t
-get_peer_ca_and_groups(struct connection *c, const ietfAttrList_t **peer_list)
+chunk_t get_peer_ca_and_groups(struct connection *c,
+                                                          const ietfAttrList_t **peer_list)
 {
        struct state *p1st = find_phase1_state(c, ISAKMP_SA_ESTABLISHED_STATES);
 
@@ -3781,11 +3742,13 @@ get_peer_ca_and_groups(struct connection *c, const ietfAttrList_t **peer_list)
        return chunk_empty;
 }
 
-struct connection *
-find_client_connection(struct connection *c
-, const ip_subnet *our_net, const ip_subnet *peer_net
-, const u_int8_t our_protocol, const u_int16_t our_port
-, const u_int8_t peer_protocol, const u_int16_t peer_port)
+struct connection *find_client_connection(struct connection *c,
+                                                                                 const ip_subnet *our_net,
+                                                                                 const ip_subnet *peer_net,
+                                                                                 const u_int8_t our_protocol,
+                                                                                 const u_int16_t our_port,
+                                                                                 const u_int8_t peer_protocol,
+                                                                                 const u_int16_t peer_port)
 {
        struct connection *d;
        struct spd_route *sr;
@@ -3919,9 +3882,7 @@ find_client_connection(struct connection *c
        return d;
 }
 
-int
-connection_compare(const struct connection *ca
-, const struct connection *cb)
+int connection_compare(const struct connection *ca, const struct connection *cb)
 {
        int ret;
 
@@ -3950,15 +3911,13 @@ connection_compare(const struct connection *ca
        }
 }
 
-static int
-connection_compare_qsort(const void *a, const void *b)
+static int connection_compare_qsort(const void *a, const void *b)
 {
        return connection_compare(*(const struct connection *const *)a
                                                        , *(const struct connection *const *)b);
 }
 
-void
-show_connections_status(bool all, const char *name)
+void show_connections_status(bool all, const char *name)
 {
        struct connection *c;
        int count, i;
@@ -4125,13 +4084,8 @@ struct pending {
 };
 
 /* queue a Quick Mode negotiation pending completion of a suitable Main Mode */
-void
-add_pending(int whack_sock
-, struct state *isakmp_sa
-, struct connection *c
-, lset_t policy
-, unsigned long try
-, so_serial_t replacing)
+void add_pending(int whack_sock, struct state *isakmp_sa, struct connection *c,
+                                lset_t policy, unsigned long try, so_serial_t replacing)
 {
        bool already_queued = FALSE;
        struct pending *p = c->host_pair->pending;
@@ -4169,8 +4123,7 @@ add_pending(int whack_sock
  * This is accomplished by closing all the whack socket file descriptors.
  * We go to a lot of trouble to tell each whack, but to not tell it twice.
  */
-void
-release_pending_whacks(struct state *st, err_t story)
+void release_pending_whacks(struct state *st, err_t story)
 {
        struct pending *p;
        struct stat stst;
@@ -4202,8 +4155,7 @@ release_pending_whacks(struct state *st, err_t story)
        }
 }
 
-static void
-delete_pending(struct pending **pp)
+static void delete_pending(struct pending **pp)
 {
        struct pending *p = *pp;
 
@@ -4214,8 +4166,7 @@ delete_pending(struct pending **pp)
        free(p);
 }
 
-void
-unpend(struct state *st)
+void unpend(struct state *st)
 {
        struct pending **pp
                , *p;
@@ -4241,8 +4192,7 @@ unpend(struct state *st)
 }
 
 /* a Main Mode negotiation has been replaced; update any pending */
-void
-update_pending(struct state *os, struct state *ns)
+void update_pending(struct state *os, struct state *ns)
 {
        struct pending *p;
 
@@ -4259,8 +4209,7 @@ update_pending(struct state *os, struct state *ns)
 }
 
 /* a Main Mode negotiation has failed; discard any pending */
-void
-flush_pending_by_state(struct state *st)
+void flush_pending_by_state(struct state *st)
 {
        struct host_pair *hp = st->st_connection->host_pair;
 
@@ -4280,8 +4229,7 @@ flush_pending_by_state(struct state *st)
 }
 
 /* a connection has been deleted; discard any related pending */
-static void
-flush_pending_by_connection(struct connection *c)
+static void flush_pending_by_connection(struct connection *c)
 {
        if (c->host_pair != NULL)
        {
@@ -4303,8 +4251,7 @@ flush_pending_by_connection(struct connection *c)
        }
 }
 
-void
-show_pending_phase2(const struct host_pair *hp, const struct state *st)
+void show_pending_phase2(const struct host_pair *hp, const struct state *st)
 {
        const struct pending *p;
 
@@ -4329,8 +4276,7 @@ show_pending_phase2(const struct host_pair *hp, const struct state *st)
  * We must be careful to avoid circularity:
  * we don't touch it if it is CK_GOING_AWAY.
  */
-void
-connection_discard(struct connection *c)
+void connection_discard(struct connection *c)
 {
        if (c->kind == CK_INSTANCE)
        {
@@ -4354,8 +4300,7 @@ connection_discard(struct connection *c)
 
 long eclipse_count = 0;
 
-struct connection *
-eclipsed(struct connection *c, struct spd_route **esrp)
+struct connection *eclipsed(struct connection *c, struct spd_route **esrp)
 {
        struct connection *ue;
        struct spd_route *sr1 = &c->spd;
index 52f46e7..291ceb3 100644 (file)
@@ -133,7 +133,7 @@ const x509crl_t empty_x509crl = {
 /**
  *  Get the X.509 CRL with a given issuer
  */
-static x509crl_t* get_x509crl(chunk_t issuer, chunk_t serial, chunk_t keyid)
+static x509crl_t* get_x509crl(chunk_t issuer, chunk_t keyid)
 {
        x509crl_t *crl = x509crls;
        x509crl_t *prev_crl = NULL;
@@ -142,7 +142,7 @@ static x509crl_t* get_x509crl(chunk_t issuer, chunk_t serial, chunk_t keyid)
        {
                if ((keyid.ptr != NULL && crl->authKeyID.ptr != NULL)
                ? same_keyid(keyid, crl->authKeyID)
-               : (same_dn(crl->issuer, issuer) && same_serial(serial, crl->authKeySerialNumber)))
+               : (same_dn(crl->issuer, issuer)))
                {
                        if (crl != x509crls)
                        {
@@ -177,8 +177,8 @@ static void free_revoked_certs(revokedCert_t* revokedCerts)
  */
 void free_crl(x509crl_t *crl)
 {
+       crl->distributionPoints->destroy_function(crl->distributionPoints, free);
        free_revoked_certs(crl->revokedCertificates);
-       free_generalNames(crl->distributionPoints, TRUE);
        free(crl->certificateList.ptr);
        free(crl);
 }
@@ -204,24 +204,19 @@ void free_crls(void)
 /**
  * Insert X.509 CRL into chained list
  */
-bool insert_crl(x509crl_t *crl, chunk_t crl_uri, bool cache_crl)
+bool insert_crl(x509crl_t *crl, char *crl_uri, bool cache_crl)
 {
        x509cert_t *issuer_cert;
        x509crl_t *oldcrl;
        bool valid_sig;
-       generalName_t *gn;
 
        /* add distribution point */
-       gn = malloc_thing(generalName_t);
-       gn->kind = GN_URI;
-       gn->name = crl_uri;
-       gn->next = crl->distributionPoints;
-       crl->distributionPoints = gn;
+       add_distribution_point(crl->distributionPoints, crl_uri);
 
        lock_authcert_list("insert_crl");
+
        /* get the issuer cacert */
-       issuer_cert = get_authcert(crl->issuer, crl->authKeySerialNumber,
-               crl->authKeyID, AUTH_CA);
+       issuer_cert = get_authcert(crl->issuer, crl->authKeyID, AUTH_CA);
        if (issuer_cert == NULL)
        {
                plog("crl issuer cacert not found");
@@ -235,7 +230,7 @@ bool insert_crl(x509crl_t *crl, chunk_t crl_uri, bool cache_crl)
 
        /* check the issuer's signature of the crl */
        valid_sig = x509_check_signature(crl->tbsCertList, crl->signature,
-                                                                        crl->algorithm, issuer_cert);
+                                                                        crl->algorithm, issuer_cert->cert);
        unlock_authcert_list("insert_crl");
 
        if (!valid_sig)
@@ -248,16 +243,15 @@ bool insert_crl(x509crl_t *crl, chunk_t crl_uri, bool cache_crl)
        )
 
        lock_crl_list("insert_crl");
-       oldcrl = get_x509crl(crl->issuer, crl->authKeySerialNumber
-               , crl->authKeyID);
+       oldcrl = get_x509crl(crl->issuer, crl->authKeyID);
 
        if (oldcrl != NULL)
        {
                if (crl->thisUpdate > oldcrl->thisUpdate)
                {
                        /* keep any known CRL distribution points */
-                       add_distribution_points(oldcrl->distributionPoints
-                               , &crl->distributionPoints);
+                       add_distribution_points(crl->distributionPoints,
+                                                                       oldcrl->distributionPoints);
 
                        /* now delete the old CRL */
                        free_first_crl();
@@ -286,23 +280,15 @@ bool insert_crl(x509crl_t *crl, chunk_t crl_uri, bool cache_crl)
         * Only http or ldap URIs are cached but not local file URIs.
         * The issuer's subjectKeyID is used as a unique filename
         */
-       if (cache_crl && strncasecmp(crl_uri.ptr, "file", 4) != 0)
+       if (cache_crl && strncasecmp(crl_uri, "file", 4) != 0)
        {
                char path[BUF_LEN], buf[BUF_LEN];
-               char digest_buf[HASH_SIZE_SHA1];
-               chunk_t subjectKeyID = chunk_create(digest_buf, sizeof(digest_buf));
-               bool has_keyID;
+               certificate_t *certificate = issuer_cert->cert;
+               x509_t *x509 = (x509_t*)certificate;
+               chunk_t subjectKeyID;
 
-               if (issuer_cert->subjectKeyID.ptr == NULL)
-               {
-                       has_keyID = compute_subjectKeyID(issuer_cert, subjectKeyID);
-               }
-               else
-               {
-                       subjectKeyID = issuer_cert->subjectKeyID;
-                       has_keyID = TRUE;
-               }
-               if (has_keyID)
+               subjectKeyID = x509->get_subjectKeyIdentifier(x509);
+               if (subjectKeyID.ptr)
                {
                        datatot(subjectKeyID.ptr, subjectKeyID.len, 16, buf, BUF_LEN);
                        snprintf(path, BUF_LEN, "%s/%s.crl", CRL_PATH, buf);
@@ -348,16 +334,10 @@ void load_crls(void)
                                                CERT_PLUTO_CRL, BUILD_FROM_FILE, filename, BUILD_END);
                                if (crl)
                                {
-                                       chunk_t crl_uri;
+                                       char crl_uri[BUF_LEN];
 
                                        plog("  loaded crl from '%s'", filename);
-                                       crl_uri.len = 7 + sizeof(CRL_PATH) + strlen(filename);
-                                       crl_uri.ptr = malloc(crl_uri.len + 1);
-
-                                       /* build CRL file URI */
-                                       snprintf(crl_uri.ptr, crl_uri.len + 1, "file://%s/%s"
-                                               , CRL_PATH, filename);
-
+                                       snprintf(crl_uri, BUF_LEN, "file://%s/%s", CRL_PATH, filename);
                                        insert_crl(crl, crl_uri, FALSE);
                                }
                                free(filelist[n]);
@@ -543,8 +523,7 @@ check_revocation(const x509crl_t *crl, chunk_t serial
 /*
  * check if any crls are about to expire
  */
-void
-check_crls(void)
+void check_crls(void)
 {
        x509crl_t *crl;
 
@@ -569,9 +548,9 @@ check_crls(void)
                )
                if (time_left < 2*crl_check_interval)
                {
-                       fetch_req_t *req = build_crl_fetch_request(crl->issuer
-                               , crl->authKeySerialNumber
-                               , crl->authKeyID, crl->distributionPoints);
+                       fetch_req_t *req = build_crl_fetch_request(crl->issuer,
+                                                                                                          crl->authKeyID,
+                                                                                                          crl->distributionPoints);
                        add_crl_fetch_request(req);
                }
                crl = crl->next;
@@ -582,51 +561,63 @@ 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
-, crl_reason_t *revocationReason)
+cert_status_t verify_by_crl(const x509cert_t *cert, time_t *until,
+                                                       time_t *revocationDate,
+                                                       crl_reason_t *revocationReason)
 {
+       certificate_t *certificate = cert->cert;
+       x509_t *x509 = (x509_t*)certificate;
+       identification_t *issuer = certificate->get_issuer(certificate);
+       chunk_t issuer_dn = issuer->get_encoding(issuer);
+       chunk_t authKeyID = x509->get_authKeyIdentifier(x509);
        x509crl_t *crl;
+       ca_info_t *ca;
+       enumerator_t *enumerator;
+       char *point;
 
-       ca_info_t *ca = get_ca_info(cert->issuer, cert->authKeySerialNumber
-                                                         , cert->authKeyID);
-
-       generalName_t *crluri = (ca == NULL)? NULL : ca->crluri;
-
+       ca = get_ca_info(issuer_dn, authKeyID);
+       
        *revocationDate = UNDEFINED_TIME;
        *revocationReason = CRL_REASON_UNSPECIFIED;
 
        lock_crl_list("verify_by_crl");
-       crl = get_x509crl(cert->issuer, cert->authKeySerialNumber, cert->authKeyID);
+       crl = get_x509crl(issuer_dn, authKeyID);
 
        if (crl == NULL)
        {
+               linked_list_t *crluris;
+
                unlock_crl_list("verify_by_crl");
                plog("crl not found");
 
-               if (cert->crlDistributionPoints != NULL)
+               crluris = linked_list_create();
+               if (ca)
                {
-                       fetch_req_t *req = build_crl_fetch_request(cert->issuer
-                               , cert->authKeySerialNumber
-                               , cert->authKeyID, cert->crlDistributionPoints);
-                       add_crl_fetch_request(req);
+                       add_distribution_points(crluris, ca->crluris);
                }
 
-               if (crluri != NULL)
+               enumerator = x509->create_crl_uri_enumerator(x509);
+               while (enumerator->enumerate(enumerator, &point))
                {
-                       fetch_req_t *req = build_crl_fetch_request(cert->issuer
-                               , cert->authKeySerialNumber
-                               , cert->authKeyID, crluri);
-                       add_crl_fetch_request(req);
+                       add_distribution_point(crluris, point);
                }
+               enumerator->destroy(enumerator);
 
-               if (cert->crlDistributionPoints != 0 || crluri != NULL)
+               if (crluris->get_count(crluris) > 0)
                {
+                       fetch_req_t *req;
+
+                       req = build_crl_fetch_request(issuer_dn, authKeyID, crluris);
+                       crluris->destroy_function(crluris, free);
+                       add_crl_fetch_request(req);
                        wake_fetch_thread("verify_by_crl");
                        return CERT_UNKNOWN;
                }
                else
+               {
+                       crluris->destroy(crluris);
                        return CERT_UNDEFINED;
+               }
        }
        else
        {
@@ -637,18 +628,23 @@ verify_by_crl(const x509cert_t *cert, time_t *until, time_t *revocationDate
                        DBG_log("crl found")
                )
 
-               add_distribution_points(cert->crlDistributionPoints
-                               , &crl->distributionPoints);
+               if (ca)
+               {
+                       add_distribution_points(crl->distributionPoints, ca->crluris);
+               }
 
-               add_distribution_points(crluri
-                               , &crl->distributionPoints);
+               enumerator = x509->create_crl_uri_enumerator(x509);
+               while (enumerator->enumerate(enumerator, &point))
+               {
+                       add_distribution_point(crl->distributionPoints, point);
+               }
+               enumerator->destroy(enumerator);
 
                lock_authcert_list("verify_by_crl");
 
-               issuer_cert = get_authcert(crl->issuer, crl->authKeySerialNumber
-                               , crl->authKeyID, AUTH_CA);
+               issuer_cert = get_authcert(crl->issuer, crl->authKeyID, AUTH_CA);
                valid = x509_check_signature(crl->tbsCertList, crl->signature,
-                                                                        crl->algorithm, issuer_cert);
+                                                                        crl->algorithm, issuer_cert->cert);
 
                unlock_authcert_list("verify_by_crl");
 
@@ -663,7 +659,7 @@ verify_by_crl(const x509cert_t *cert, time_t *until, time_t *revocationDate
                        *until = crl->nextUpdate;
 
                        /* has the certificate been revoked? */
-                       status = check_revocation(crl, cert->serialNumber, revocationDate
+                       status = check_revocation(crl, x509->get_serial(x509), revocationDate
                                                                , revocationReason);
 
                        if (*until < time(NULL))
@@ -673,9 +669,8 @@ verify_by_crl(const x509cert_t *cert, time_t *until, time_t *revocationDate
                                plog("crl update is overdue since %T", until, TRUE);
 
                                /* try to fetch a crl update */
-                               req = build_crl_fetch_request(crl->issuer
-                                                               , crl->authKeySerialNumber
-                                                               , crl->authKeyID, crl->distributionPoints);
+                               req = build_crl_fetch_request(crl->issuer, crl->authKeyID,
+                                                                                         crl->distributionPoints);
                                unlock_crl_list("verify_by_crl");
 
                                add_crl_fetch_request(req);
@@ -702,8 +697,7 @@ verify_by_crl(const x509cert_t *cert, time_t *until, time_t *revocationDate
 /*
  *  list all X.509 crls in the chained list
  */
-void
-list_crls(bool utc, bool strict)
+void list_crls(bool utc, bool strict)
 {
        x509crl_t *crl;
 
index db3080c..765608f 100644 (file)
@@ -14,6 +14,7 @@
 
 #include "constants.h"
 
+#include <utils/linked_list.h>
 #include <credentials/certificates/crl.h>
 
 /* access structure for a revoked serial number */
@@ -34,7 +35,7 @@ typedef struct x509crl x509crl_t;
 struct x509crl {
   x509crl_t     *next;
   time_t         installed;
-  generalName_t *distributionPoints;
+  linked_list_t *distributionPoints;
   chunk_t        certificateList;
   chunk_t          tbsCertList;
   u_int              version;
@@ -80,7 +81,7 @@ extern const x509crl_t  empty_x509crl;
 extern bool parse_x509crl(chunk_t blob, u_int level0, x509crl_t *crl);
 extern void load_crls(void);
 extern void check_crls(void);
-extern bool insert_crl(x509crl_t *crl, chunk_t crl_uri, bool cache_crl);
+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
        , time_t *revocationDate, crl_reason_t *revocationReason);
 extern void list_crls(bool utc, bool strict);
index b8804fb..4217cd1 100644 (file)
@@ -48,7 +48,6 @@ fetch_req_t empty_fetch_req = {
                  0 , /* trials */
   { NULL, 0}, /* issuer */
   { NULL, 0}, /* authKeyID */
-  { NULL, 0}, /* authKeySerialNumber */
        NULL      /* distributionPoints */
 };
 
@@ -251,10 +250,9 @@ void wake_fetch_thread(const char *who)
  */
 static void free_fetch_request(fetch_req_t *req)
 {
+       req->distributionPoints->destroy_function(req->distributionPoints, free);
        free(req->issuer.ptr);
-       free(req->authKeySerialNumber.ptr);
        free(req->authKeyID.ptr);
-       free_generalNames(req->distributionPoints, TRUE);
        free(req);
 }
 
@@ -286,47 +284,39 @@ x509crl_t* fetch_crl(char *url)
 /**
  * Complete a distributionPoint URI with ca information
  */
-static char* complete_uri(chunk_t distPoint, const char *ldaphost)
+static char* complete_uri(char *distPoint, const char *ldaphost)
 {
-       char *uri;
-       char *ptr  = distPoint.ptr;
-       size_t len = distPoint.len;
+       char *symbol = strchr(distPoint, ':');
 
-       char *symbol = memchr(ptr, ':', len);
-
-       if (symbol != NULL)
+       if (symbol)
        {
-               size_t type_len = symbol - ptr;
+               int type_len = symbol - distPoint;
 
-               if (type_len >= 4 && strncasecmp(ptr, "ldap", 4) == 0)
+               if (type_len >= 4 && strncasecmp(distPoint, "ldap", 4) == 0)
                {
-                       ptr = symbol + 1;
-                       len -= (type_len + 1);
+                       char *ptr  = symbol + 1;
+                       int len = strlen(distPoint) - (type_len + 1);
 
                        if (len > 2 && *ptr++ == '/' && *ptr++ == '/')
                        {
                                len -= 2;
-                               symbol = memchr(ptr, '/', len);
+                               symbol = strchr(ptr, '/');
 
-                               if (symbol != NULL && symbol - ptr == 0 && ldaphost != NULL)
+                               if (symbol && symbol - ptr == 0 && ldaphost)
                                {
-                                       uri = malloc(distPoint.len + strlen(ldaphost) + 1);
+                                       char uri[BUF_LEN];
 
                                        /* insert the ldaphost into the uri */
-                                       sprintf(uri, "%.*s%s%.*s"
-                                               , (int)(distPoint.len - len), distPoint.ptr
-                                               , ldaphost
-                                               , (int)len, symbol);
-                                       return uri;
+                                       snprintf(uri, BUF_LEN, "%.*s%s%.*s", strlen(distPoint)-len,
+                                                        distPoint, ldaphost, len, symbol);
+                                       return strdup(uri);
                                }
                        }
                }
        }
 
        /* default action:  copy distributionPoint without change */
-       uri = malloc(distPoint.len + 1);
-       sprintf(uri, "%.*s", (int)distPoint.len, distPoint.ptr);
-       return uri;
+       return strdup(distPoint);
 }
 
 /**
@@ -343,40 +333,40 @@ static void fetch_crls(bool cache_crls)
 
        while (req != NULL)
        {
+               enumerator_t *enumerator;
+               char *point;
                bool valid_crl = FALSE;
-               generalName_t *gn = req->distributionPoints;
                const char *ldaphost;
                ca_info_t *ca;
 
                lock_ca_info_list("fetch_crls");
 
-               ca = get_ca_info(req->issuer, req->authKeySerialNumber, req->authKeyID);
+               ca = get_ca_info(req->issuer, req->authKeyID);
                ldaphost = (ca == NULL)? NULL : ca->ldaphost;
 
-               while (gn != NULL)
+               enumerator = req->distributionPoints->create_enumerator(req->distributionPoints);
+               while (enumerator->enumerate(enumerator, &point))
                {
-                       char *uri = complete_uri(gn->name, ldaphost);
                        x509crl_t *crl;
+                       char *uri;
 
+                       uri = complete_uri(point, ldaphost);
                        crl = fetch_crl(uri);
+                       free(uri);
+
                        if (crl)
                        {
-                               chunk_t crl_uri = chunk_clone(gn->name);
-
-                               if (insert_crl(crl, crl_uri, cache_crls))
+                               if (insert_crl(crl, point, cache_crls))
                                {
                                        DBG(DBG_CONTROL,
                                                DBG_log("we have a valid crl")
                                        )
                                        valid_crl = TRUE;
-                                       free(uri);
                                        break;
                                }
                        }
-                       free(uri);
-                       gn = gn->next;
                }
-
+               enumerator->destroy(enumerator);
                unlock_ca_info_list("fetch_crls");
 
                if (valid_crl)
@@ -401,19 +391,11 @@ static void fetch_crls(bool cache_crls)
 
 static void fetch_ocsp_status(ocsp_location_t* location)
 {
-       chunk_t request, response;
-       char *uri;
+       chunk_t request = build_ocsp_request(location);
+       chunk_t response = chunk_empty;
 
-       request = build_ocsp_request(location);
-       response = chunk_empty;
-
-       /* we need a null terminated string for curl */
-       uri = malloc(location->uri.len + 1);
-       memcpy(uri, location->uri.ptr, location->uri.len);
-       *(uri + location->uri.len) = '\0';
-
-       DBG1("  requesting ocsp status from '%s' ...", uri);
-       if (lib->fetcher->fetch(lib->fetcher, uri, &response,
+       DBG1("  requesting ocsp status from '%s' ...", location->uri);
+       if (lib->fetcher->fetch(lib->fetcher, location->uri, &response,
                                                        FETCH_REQUEST_DATA, request,
                                                        FETCH_REQUEST_TYPE, "application/ocsp-request",
                                                        FETCH_END) == SUCCESS)
@@ -422,10 +404,9 @@ static void fetch_ocsp_status(ocsp_location_t* location)
        }
        else
        {
-               DBG1("ocsp request to %s failed", uri);
+               DBG1("ocsp request to %s failed", location->uri);
        }
 
-       free(uri);
        free(request.ptr);
        chunk_free(&location->nonce);
 
@@ -554,62 +535,95 @@ void free_ocsp_fetch(void)
 
 
 /**
- * Add additional distribution points
+ * Add an additional distribution point
  */
-void add_distribution_points(const generalName_t *newPoints ,generalName_t **distributionPoints)
+void add_distribution_point(linked_list_t *points, char *new_point)
 {
-       while (newPoints != NULL)
+       char *point;
+       bool add = TRUE;
+       enumerator_t *enumerator;
+
+       if (new_point == NULL || *new_point == '\0')
        {
-               /* skip empty distribution point */
-               if (newPoints->name.len > 0)
+               return;
+       }
+
+       enumerator = points->create_enumerator(points);
+       while (enumerator->enumerate(enumerator, &point))
+       {
+               if (streq(point, new_point))
                {
-                       bool add = TRUE;
-                       generalName_t *gn = *distributionPoints;
+                       add = FALSE;
+                       break;
+               }
+       }
+       enumerator->destroy(enumerator);
 
-                       while (gn != NULL)
-                       {
-                               if (gn->kind == newPoints->kind
-                               && gn->name.len == newPoints->name.len
-                               && memeq(gn->name.ptr, newPoints->name.ptr, gn->name.len))
-                               {
-                                       /* skip if the distribution point is already present */
-                                       add = FALSE;
-                                       break;
-                               }
-                               gn = gn->next;
-                       }
+       if (add)
+       {
+               points->insert_last(points, strdup(new_point));
+       }
+}
 
-                       if (add)
-                       {
-                               /* clone additional distribution point */
-                               gn = clone_thing(*newPoints);
-                               gn->name = chunk_clone(newPoints->name);
+/**
+ * Add additional distribution points
+ */
+void add_distribution_points(linked_list_t *points, linked_list_t *new_points)
+{
+       char *new_point;
+       enumerator_t *enumerator;
 
-                               /* insert additional CRL distribution point */
-                               gn->next = *distributionPoints;
-                               *distributionPoints = gn;
+       enumerator = new_points->create_enumerator(new_points);
+       while (enumerator->enumerate(enumerator, &new_point))
+       {
+               bool add = TRUE;
+               char *point;
+               enumerator_t *enumerator;
+
+               enumerator = points->create_enumerator(points);
+               while (enumerator->enumerate(enumerator, &point))
+               {
+                       if (streq(point, new_point))
+                       {
+                               add = FALSE;
+                               break;
                        }
                }
-               newPoints = newPoints->next;
+               enumerator->destroy(enumerator);
+
+               if (add)
+               {
+                       points->insert_last(points, strdup(new_point));
+               }
        }
+       enumerator->destroy(enumerator);
 }
 
-fetch_req_t* build_crl_fetch_request(chunk_t issuer, chunk_t authKeySerialNumber,
-                                                                        chunk_t authKeyID, const generalName_t *gn)
+fetch_req_t* build_crl_fetch_request(chunk_t issuer, chunk_t authKeyID, 
+                                                                        linked_list_t *distributionPoints)
 {
+       char *point;
+       enumerator_t *enumerator;
        fetch_req_t *req = malloc_thing(fetch_req_t);
-       *req = empty_fetch_req;
+
+       memset(req, 0, sizeof(fetch_req_t));
+       req->distributionPoints = linked_list_create();
 
        /* note current time */
        req->installed = time(NULL);
 
        /* clone fields */
        req->issuer = chunk_clone(issuer);
-       req->authKeySerialNumber =  chunk_clone(authKeySerialNumber);
        req->authKeyID = chunk_clone(authKeyID);
 
        /* copy distribution points */
-       add_distribution_points(gn, &req->distributionPoints);
+       enumerator = distributionPoints->create_enumerator(distributionPoints);
+       while (enumerator->enumerate(enumerator, &point))
+       {
+               req->distributionPoints->insert_last(req->distributionPoints,
+                                                                                        strdup(point));
+       }
+       enumerator->destroy(enumerator);
 
        return req;
 }
@@ -626,9 +640,8 @@ void add_crl_fetch_request(fetch_req_t *req)
 
        while (r != NULL)
        {
-               if ((req->authKeyID.ptr != NULL)? same_keyid(req->authKeyID, r->authKeyID)
-                               : (same_dn(req->issuer, r->issuer)
-                               && same_serial(req->authKeySerialNumber, r->authKeySerialNumber)))
+               if (req->authKeyID.ptr ? same_keyid(req->authKeyID, r->authKeyID) :
+                       same_dn(req->issuer, r->issuer))
                {
                        /* there is already a fetch request */
                        DBG(DBG_CONTROL,
@@ -636,7 +649,8 @@ void add_crl_fetch_request(fetch_req_t *req)
                        )
 
                        /* there might be new distribution points */
-                       add_distribution_points(req->distributionPoints, &r->distributionPoints);
+                       add_distribution_points(r->distributionPoints,
+                                                                       req->distributionPoints);
 
                        unlock_crl_fetch_list("add_crl_fetch_request");
                        free_fetch_request(req);
@@ -672,17 +686,20 @@ void add_ocsp_fetch_request(ocsp_location_t *location, chunk_t serialNumber)
 /**
  * List all distribution points
  */
-void list_distribution_points(const generalName_t *gn)
+void list_distribution_points(linked_list_t *distributionPoints)
 {
-       bool first_gn = TRUE;
+       char *point;
+       bool first_point = TRUE;
+       enumerator_t *enumerator;
 
-       while (gn != NULL)
+       enumerator = distributionPoints->create_enumerator(distributionPoints);
+       while (enumerator->enumerate(enumerator, &point))
        {
-               whack_log(RC_COMMENT, "       %s '%.*s'", (first_gn)? "distPts: "
-                       :"         ", (int)gn->name.len, gn->name.ptr);
-               first_gn = FALSE;
-               gn = gn->next;
+               whack_log(RC_COMMENT, "       %s '%s'",
+                                (first_point)? "distPts: " : "         ", point);
+               first_point = FALSE;
        }
+       enumerator->destroy(enumerator);
 }
 
 /**
@@ -716,12 +733,6 @@ void list_crl_fetch_requests(bool utc)
                                , buf, BUF_LEN);
                        whack_log(RC_COMMENT, "       authkey:   %s", buf);
                }
-               if (req->authKeySerialNumber.ptr != NULL)
-               {
-                       datatot(req->authKeySerialNumber.ptr, req->authKeySerialNumber.len, ':'
-                               , buf, BUF_LEN);
-                       whack_log(RC_COMMENT, "       aserial:   %s", buf);
-               }
                list_distribution_points(req->distributionPoints);
                req = req->next;
        }
index f7b4eb0..a12e86a 100644 (file)
@@ -13,6 +13,8 @@
  * for more details.
  */
 
+#include <utils/linked_list.h>
+
 #include "x509.h"
 
 #define FETCH_CMD_TIMEOUT       10      /* seconds */
@@ -32,8 +34,7 @@ struct fetch_req {
        int           trials;
        chunk_t       issuer;
        chunk_t       authKeyID;
-       chunk_t       authKeySerialNumber;
-       generalName_t *distributionPoints;
+       linked_list_t *distributionPoints;
 };
 
 #ifdef THREADS
@@ -64,13 +65,15 @@ extern void wake_fetch_thread(const char *who);
 extern void init_fetch(void);
 extern void free_crl_fetch(void);
 extern void free_ocsp_fetch(void);
-extern void add_distribution_points(const generalName_t *newPoints
-       , generalName_t **distributionPoints);
-extern fetch_req_t* build_crl_fetch_request(chunk_t issuer, chunk_t authKeySerialNumber
-       , chunk_t authKeyID, const generalName_t *gn);
+extern void add_distribution_point(linked_list_t *points, char* new_point);
+extern void add_distribution_points(linked_list_t *points,
+                                                                       linked_list_t *new_points);
+extern fetch_req_t* build_crl_fetch_request(chunk_t issuer, chunk_t authKeyID,
+                                                                                       linked_list_t *distributionPoints);
 extern void add_crl_fetch_request(fetch_req_t *req);
-extern void add_ocsp_fetch_request(struct ocsp_location *location, chunk_t serialNumber);
-extern void list_distribution_points(const generalName_t *gn);
+extern void add_ocsp_fetch_request(struct ocsp_location *location,
+                                                                  chunk_t serialNumber);
+extern void list_distribution_points(linked_list_t *distributionPoints);
 extern void list_crl_fetch_requests(bool utc);
 extern void list_ocsp_fetch_requests(bool utc);
 extern size_t write_buffer(void *ptr, size_t size, size_t nmemb, void *data);
index f34775e..cd5b350 100644 (file)
@@ -44,8 +44,7 @@ char *myid_str[MYID_SPECIFIED+1];     /* string form of IDs */
 /* initialize id module
  * Fills in myid from environment variable IPSECmyid or defaultrouteaddr
  */
-void
-init_id(void)
+void init_id(void)
 {
        passert(empty_id.kind == ID_ANY);
        myid_state = MYID_UNKNOWN;
@@ -66,8 +65,7 @@ init_id(void)
 /*
  *  free id module
  */
-void
-free_id(void)
+void free_id(void)
 {
        enum myid_state s;
 
@@ -78,8 +76,7 @@ free_id(void)
        }
 }
 
-static void
-calc_myid_str(enum myid_state s)
+static void calc_myid_str(enum myid_state s)
 {
        /* preformat the ID name */
        char buf[BUF_LEN];
@@ -89,8 +86,7 @@ calc_myid_str(enum myid_state s)
 }
 
 
-void
-set_myid(enum myid_state s, char *idstr)
+void set_myid(enum myid_state s, char *idstr)
 {
        if (idstr != NULL)
        {
@@ -114,8 +110,7 @@ set_myid(enum myid_state s, char *idstr)
        }
 }
 
-void
-set_myFQDN(void)
+void set_myFQDN(void)
 {
        char FQDN[HOST_NAME_MAX + 1];
        int r = gethostname(FQDN, sizeof(FQDN));
@@ -151,8 +146,7 @@ set_myFQDN(void)
        }
 }
 
-void
-show_myid_status(void)
+void show_myid_status(void)
 {
        char idstr[BUF_LEN];
 
@@ -163,8 +157,7 @@ show_myid_status(void)
 /* Convert textual form of id into a (temporary) struct id.
  * Note that if the id is to be kept, unshare_id_content will be necessary.
  */
-err_t
-atoid(char *src, struct id *id, bool myid_ok)
+err_t atoid(char *src, struct id *id, bool myid_ok)
 {
        err_t ugh = NULL;
 
@@ -252,15 +245,13 @@ atoid(char *src, struct id *id, bool myid_ok)
 /*
  *  Converts a binary key ID into hexadecimal format
  */
-int
-keyidtoa(char *dst, size_t dstlen, chunk_t keyid)
+int keyidtoa(char *dst, size_t dstlen, chunk_t keyid)
 {
        int n = datatot(keyid.ptr, keyid.len, 'x', dst, dstlen);
        return (((size_t)n < dstlen)? n : dstlen) - 1;
 }
 
-void
-iptoid(const ip_address *ip, struct id *id)
+void iptoid(const ip_address *ip, struct id *id)
 {
        *id = empty_id;
 
@@ -278,8 +269,7 @@ iptoid(const ip_address *ip, struct id *id)
        id->ip_addr = *ip;
 }
 
-int
-idtoa(const struct id *id, char *dst, size_t dstlen)
+int idtoa(const struct id *id, char *dst, size_t dstlen)
 {
        int n;
 
@@ -326,8 +316,7 @@ idtoa(const struct id *id, char *dst, size_t dstlen)
 /* Replace the shell metacharacters ', \, ", `, and $ in a character string
  * by escape sequences consisting of their octal values
  */
-void
-escape_metachar(const char *src, char *dst, size_t dstlen)
+void escape_metachar(const char *src, char *dst, size_t dstlen)
 {
        while (*src != '\0' && dstlen > 4)
        {
@@ -355,8 +344,7 @@ escape_metachar(const char *src, char *dst, size_t dstlen)
 /* Make private copy of string in struct id.
  * This is needed if the result of atoid is to be kept.
  */
-void
-unshare_id_content(struct id *id)
+void unshare_id_content(struct id *id)
 {
        switch (id->kind)
        {
@@ -376,8 +364,7 @@ unshare_id_content(struct id *id)
        }
 }
 
-void
-free_id_content(struct id *id)
+void free_id_content(struct id *id)
 {
        switch (id->kind)
        {
@@ -398,8 +385,7 @@ free_id_content(struct id *id)
 }
 
 /* compare two struct id values */
-bool
-same_id(const struct id *a, const struct id *b)
+bool same_id(const struct id *a, const struct id *b)
 {
        a = resolve_myid(a);
        b = resolve_myid(b);
@@ -446,8 +432,7 @@ same_id(const struct id *a, const struct id *b)
 }
 
 /* compare two struct id values, DNs can contain wildcards */
-bool
-match_id(const struct id *a, const struct id *b, int *wildcards)
+bool match_id(const struct id *a, const struct id *b, int *wildcards)
 {
        if (b->kind == ID_ANY)
        {
@@ -466,8 +451,7 @@ match_id(const struct id *a, const struct id *b, int *wildcards)
 }
 
 /* count the numer of wildcards in an id */
-int
-id_count_wildcards(const struct id *id)
+int id_count_wildcards(const struct id *id)
 {
        switch (id->kind)
        {
@@ -485,8 +469,7 @@ id_count_wildcards(const struct id *id)
  * We assume it will end up being a pointer into a sufficiently
  * stable datastructure.  It only needs to last a short time.
  */
-void
-build_id_payload(struct isakmp_ipsec_id *hd, chunk_t *tl, struct end *end)
+void build_id_payload(struct isakmp_ipsec_id *hd, chunk_t *tl, struct end *end)
 {
        const struct id *id = resolve_myid(&end->id);
 
@@ -515,6 +498,37 @@ build_id_payload(struct isakmp_ipsec_id *hd, chunk_t *tl, struct end *end)
        }
 }
 
+/**
+ *  Converts libstrongswan's identification_t type into pluto's struct id
+ */
+void id_from_identification(struct id *id, identification_t *identification)
+{
+       chunk_t encoding;
+
+       encoding = identification->get_encoding(identification);
+       id->kind = identification->get_type(identification);
+
+       switch (id->kind)
+       {
+               case ID_FQDN:
+               case ID_USER_FQDN:
+               case ID_DER_ASN1_DN:
+               case ID_KEY_ID:
+                       id->name = encoding;
+                       break;
+               case ID_IPV4_ADDR:
+               case ID_IPV6_ADDR:
+                       initaddr(encoding.ptr, encoding.len,
+                                       (id->kind == ID_IPV4_ADDR) ? AF_INET : AF_INET6,
+                                       &id->ip_addr);
+                       break;
+       case ID_ANY:    
+       default:
+               id->kind = ID_ANY;
+               id->name = chunk_empty;
+       }
+}
+
 /*
  * Local Variables:
  * c-basic-offset:4
index dc2dcdf..8fe1a1f 100644 (file)
@@ -15,6 +15,8 @@
 #ifndef _ID_H
 #define _ID_H
 
+#include <utils/identification.h>
+
 #include "defs.h"
 
 struct id {
@@ -26,7 +28,7 @@ struct id {
 
 extern void init_id(void);
 extern void free_id(void);
-extern const struct id empty_id;        /* ID_NONE */
+extern const struct id empty_id;        /* ID_ANY */
 
 enum myid_state {
        MYID_UNKNOWN,       /* not yet figured out */
@@ -59,7 +61,8 @@ extern int id_count_wildcards(const struct id *id);
 #define id_is_ipaddr(id) ((id)->kind == ID_IPV4_ADDR || (id)->kind == ID_IPV6_ADDR)
 
 struct isakmp_ipsec_id; /* forward declaration of tag (defined in packet.h) */
-extern void
-       build_id_payload(struct isakmp_ipsec_id *hd, chunk_t *tl, struct end *end);
+extern void    build_id_payload(struct isakmp_ipsec_id *hd, chunk_t *tl,
+                                                        struct end *end);
+extern void id_from_identification(struct id *id, identification_t *identification);
 
 #endif /* _ID_H */
index 78eaaa0..43c01a8 100644 (file)
@@ -2149,8 +2149,14 @@ static void decode_cert(struct msg_digest *md)
                if (cert->isacert_type == CERT_X509_SIGNATURE)
                {
                        x509cert_t cert = empty_x509cert;
-                       if (parse_x509cert(blob, 0, &cert))
+
+                       cert.cert = lib->creds->create(lib->creds,
+                                                                               CRED_CERTIFICATE, CERT_X509,
+                                                                               BUILD_BLOB_ASN1_DER, blob,
+                                                                               BUILD_END);
+                       if (cert.cert)
                        {
+                               time(&cert.installed);
                                if (verify_x509cert(&cert, strict_crl_policy, &valid_until))
                                {
                                        DBG(DBG_PARSING,
@@ -2162,9 +2168,7 @@ static void decode_cert(struct msg_digest *md)
                                {
                                        plog("X.509 certificate rejected");
                                }
-                               DESTROY_IF(cert.public_key);
-                               free_generalNames(cert.subjectAltName, FALSE);
-                               free_generalNames(cert.crlDistributionPoints, FALSE);
+                               DESTROY_IF(cert.cert);
                        }
                        else
                        {
@@ -3556,6 +3560,8 @@ stf_status main_inR2_outI3(struct msg_digest *md)
        }
        if (send_cert)
        {
+               bool success;
+               chunk_t cert_encoding;  
                pb_stream cert_pbs;
 
                struct isakmp_cert cert_hd;
@@ -3566,7 +3572,10 @@ stf_status main_inR2_outI3(struct msg_digest *md)
                {
                        return STF_INTERNAL_ERROR;
                }
-               if (!out_chunk(cert_get_encoding(mycert), &cert_pbs, "CERT"))
+               cert_encoding = cert_get_encoding(mycert);
+               success = out_chunk(cert_encoding, &cert_pbs, "CERT");
+               free(cert_encoding.ptr);
+               if (!success)   
                {
                        return STF_INTERNAL_ERROR;
                }
@@ -3996,9 +4005,11 @@ main_inI3_outR3_tail(struct msg_digest *md
        }
        if (send_cert)
        {
+               bool success;
+               chunk_t cert_encoding;
                pb_stream cert_pbs;
-
                struct isakmp_cert cert_hd;
+
                cert_hd.isacert_np = ISAKMP_NEXT_SIG;
                cert_hd.isacert_type = mycert.type;
 
@@ -4006,8 +4017,11 @@ main_inI3_outR3_tail(struct msg_digest *md
                {
                        return STF_INTERNAL_ERROR;
                }
-               if (!out_chunk(cert_get_encoding(mycert), &cert_pbs, "CERT"))
-               {
+               cert_encoding = cert_get_encoding(mycert);
+               success = out_chunk(cert_encoding, &cert_pbs, "CERT");
+               free(cert_encoding.ptr);
+               if (!success)
+               {       
                        return STF_INTERNAL_ERROR;
                }
                close_output_pbs(&cert_pbs);
index 4035495..d1ea88f 100644 (file)
@@ -127,6 +127,7 @@ static const secret_t* get_secret(const struct connection *c,
                                break; /* we have found the private key - no sense in searching further */
                        }
                }
+               pub_key->destroy(pub_key);
                return best;
        }
 
@@ -277,6 +278,7 @@ bool has_private_key(cert_t cert)
                        break;
                }
        }
+       pub_key->destroy(pub_key);
        return has_key;
 }
 
@@ -285,17 +287,22 @@ bool has_private_key(cert_t cert)
  */
 private_key_t* get_x509_private_key(const x509cert_t *cert)
 {
+       public_key_t *public_key = cert->cert->get_public_key(cert->cert);
+       private_key_t *private_key = NULL;
        secret_t *s;
 
        for (s = secrets; s != NULL; s = s->next)
        {
+
                if (s->kind == PPK_PUBKEY &&
-                       s->u.private_key->belongs_to(s->u.private_key, cert->public_key))
+                       s->u.private_key->belongs_to(s->u.private_key, public_key))
                {
-                       return s->u.private_key;
+                       private_key = s->u.private_key;
+                       break;
                }
        }
-       return NULL;
+       public_key->destroy(public_key);
+       return private_key;
 }
 
 /* find the appropriate private key (see get_secret).
@@ -1231,7 +1238,7 @@ void delete_public_keys(const struct id *id, key_type_t type,
                if (same_id(id, &pk->id) && pk_type == type
                && (issuer.ptr == NULL || pk->issuer.ptr == NULL
                        || same_dn(issuer, pk->issuer))
-               && same_serial(serial, pk->serial))
+               && (serial.ptr == NULL || chunk_equals(serial, pk->serial)))
                {
                        *pp = free_public_keyentry(p);
                }
@@ -1317,46 +1324,50 @@ bool add_public_key(const struct id *id, enum dns_auth_level dns_auth_level,
 void add_x509_public_key(x509cert_t *cert , time_t until,
                                                 enum dns_auth_level dns_auth_level)
 {
-       generalName_t *gn;
+       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 *id;
+       chunk_t issuer_dn = issuer->get_encoding(issuer);
+       chunk_t serialNumber = x509->get_serial(x509);
        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 = cert->public_key->get_ref(cert->public_key);
+       pk->public_key = cert->cert->get_public_key(cert->cert);
        pk->id.kind = ID_DER_ASN1_DN;
-       pk->id.name = cert->subject;
+       pk->id.name = subject->get_encoding(subject);
        pk->dns_auth_level = dns_auth_level;
        pk->until_time = until;
-       pk->issuer = cert->issuer;
-       pk->serial = cert->serialNumber;
+       pk->issuer = issuer_dn;
+       pk->serial = serialNumber;
        pk_type = pk->public_key->get_type(pk->public_key);
        delete_public_keys(&pk->id, pk_type, pk->issuer, pk->serial);
        install_public_key(pk, &pubkeys);
 
-       gn = cert->subjectAltName;
-
-       while (gn != NULL) /* insert all subjectAltNames */
+       /* insert all subjectAltNames */
+       enumerator = x509->create_subjectAltName_enumerator(x509);
+       while (enumerator->enumerate(enumerator, &id)) 
        {
-               struct id id = empty_id;
-
-               gntoid(&id, gn);
-               if (id.kind != ID_ANY)
+               if (id->get_type(id) != ID_ANY)
                {
                        pk = malloc_thing(pubkey_t);
                        zero(pk);
-                       pk->public_key = cert->public_key->get_ref(cert->public_key);
-                       pk->id = id;
+                       id_from_identification(&pk->id, id);
+                       pk->public_key = cert->cert->get_public_key(cert->cert);
                        pk->dns_auth_level = dns_auth_level;
                        pk->until_time = until;
-                       pk->issuer = cert->issuer;
-                       pk->serial = cert->serialNumber;
+                       pk->issuer = issuer_dn;
+                       pk->serial = serialNumber;
                        delete_public_keys(&pk->id, pk_type, pk->issuer, pk->serial);
                        install_public_key(pk, &pubkeys);
                }
-               gn = gn->next;
        }
+       enumerator->destroy(enumerator);
 }
 
 /* extract id and public key from OpenPGP certificate and
@@ -1385,7 +1396,7 @@ void add_pgp_public_key(pgpcert_t *cert , time_t until,
  */
 void remove_x509_public_key(const x509cert_t *cert)
 {
-       public_key_t *revoked_key = cert->public_key;
+       public_key_t *revoked_key = cert->cert->get_public_key(cert->cert);
        pubkey_list_t *p, **pp;
 
        p  = pubkeys;
@@ -1405,6 +1416,7 @@ void remove_x509_public_key(const x509cert_t *cert)
                }
                p =*pp;
        }
+       revoked_key->destroy(revoked_key);
 }
 
 /*
index da81ce2..510667e 100644 (file)
@@ -283,18 +283,29 @@ static const asn1Object_t singleResponseObjects[] = {
  */
 static bool build_ocsp_location(const x509cert_t *cert, ocsp_location_t *location)
 {
+       certificate_t *certificate = cert->cert;
+       identification_t *issuer = certificate->get_issuer(certificate);
+       x509_t *x509 = (x509_t*)certificate;
+       chunk_t issuer_dn = issuer->get_encoding(issuer);
+       chunk_t authKeyID = x509->get_authKeyIdentifier(x509);
        hasher_t *hasher;
        static u_char digest[HASH_SIZE_SHA1];  /* temporary storage */
 
-       location->uri = cert->accessLocation;
+       enumerator_t *enumerator = x509->create_ocsp_uri_enumerator(x509);
 
-       if (location->uri.ptr == NULL)
+       location->uri = NULL;
+       while (enumerator->enumerate(enumerator, &location->uri))
        {
-               ca_info_t *ca = get_ca_info(cert->issuer, cert->authKeySerialNumber
-                               , cert->authKeyID);
+               break;
+       }
+       enumerator->destroy(enumerator);
+
+       if (location->uri == NULL)
+       {
+               ca_info_t *ca = get_ca_info(issuer_dn, authKeyID);
                if (ca != NULL && ca->ocspuri != NULL)
                {
-                       location->uri = chunk_create(ca->ocspuri, strlen(ca->ocspuri));
+                       location->uri = ca->ocspuri;
                }
                else
                {   /* abort if no ocsp location uri is defined */
@@ -309,23 +320,22 @@ static bool build_ocsp_location(const x509cert_t *cert, ocsp_location_t *locatio
        {
                return FALSE;
        }
-       hasher->get_hash(hasher, cert->issuer, digest);
+       hasher->get_hash(hasher, issuer_dn, digest);
        hasher->destroy(hasher);
 
        location->next = NULL;
-       location->issuer = cert->issuer;
-       location->authKeyID = cert->authKeyID;
-       location->authKeySerialNumber = cert->authKeySerialNumber;
+       location->issuer = issuer_dn;
+       location->authKeyID = authKeyID;
 
-       if (cert->authKeyID.ptr == NULL)
+       if (authKeyID.ptr == NULL)
        {
-               x509cert_t *authcert = get_authcert(cert->issuer
-                               , cert->authKeySerialNumber, cert->authKeyID, AUTH_CA);
+               x509cert_t *authcert = get_authcert(issuer_dn, authKeyID, AUTH_CA);
 
                if (authcert != NULL)
                {
-                       location->authKeyID = authcert->subjectKeyID;
-                       location->authKeySerialNumber = authcert->serialNumber;
+                       x509_t *x509 = (x509_t*)authcert->cert;
+
+                       location->authKeyID = x509->get_subjectKeyIdentifier(x509);
                }
        }
 
@@ -342,9 +352,8 @@ static bool same_ocsp_location(const ocsp_location_t *a, const ocsp_location_t *
 {
        return ((a->authKeyID.ptr != NULL)
                                ? same_keyid(a->authKeyID, b->authKeyID)
-                               : (same_dn(a->issuer, b->issuer)
-                                       && same_serial(a->authKeySerialNumber, b->authKeySerialNumber)))
-                       && chunk_equals(a->uri, b->uri);
+                               : same_dn(a->issuer, b->issuer))
+                       && streq(a->uri, b->uri);
 }
 
 /**
@@ -411,6 +420,8 @@ cert_status_t verify_by_ocsp(const x509cert_t *cert, time_t *until,
                                                         time_t *revocationDate,
                                                         crl_reason_t *revocationReason)
 {
+       x509_t *x509 = (x509_t*)cert->cert;
+       chunk_t serialNumber = x509->get_serial(x509);
        cert_status_t status;
        ocsp_location_t location;
        time_t nextUpdate = 0;
@@ -420,17 +431,19 @@ cert_status_t verify_by_ocsp(const x509cert_t *cert, time_t *until,
 
        /* is an ocsp location defined? */
        if (!build_ocsp_location(cert, &location))
+       {
                return CERT_UNDEFINED;
+       }
 
        lock_ocsp_cache("verify_by_ocsp");
-       status = get_ocsp_status(&location, cert->serialNumber, &nextUpdate
+       status = get_ocsp_status(&location, serialNumber, &nextUpdate
                , revocationDate, revocationReason);
        unlock_ocsp_cache("verify_by_ocsp");
 
        if (status == CERT_UNDEFINED || nextUpdate < time(NULL))
        {
                plog("ocsp status is stale or not in cache");
-               add_ocsp_fetch_request(&location, cert->serialNumber);
+               add_ocsp_fetch_request(&location, serialNumber);
 
                /* inititate fetching of ocsp status */
                wake_fetch_thread("verify_by_ocsp");
@@ -521,8 +534,7 @@ static void free_ocsp_location(ocsp_location_t* location)
        free(location->issuer.ptr);
        free(location->authNameID.ptr);
        free(location->authKeyID.ptr);
-       free(location->authKeySerialNumber.ptr);
-       free(location->uri.ptr);
+       free(location->uri);
        free_certinfos(location->certinfo);
        free(location);
 }
@@ -588,8 +600,7 @@ void list_ocsp_locations(ocsp_location_t *location, bool requests,
                                dntoa(buf, BUF_LEN, location->issuer);
                                whack_log(RC_COMMENT, "       issuer:  '%s'", buf);
                        }
-                       whack_log(RC_COMMENT, "       uri:     '%.*s'", (int)location->uri.len
-                               , location->uri.ptr);
+                       whack_log(RC_COMMENT, "       uri:     '%s'", location->uri);
                        if (location->authNameID.ptr != NULL)
                        {
                                datatot(location->authNameID.ptr, location->authNameID.len, ':'
@@ -602,12 +613,6 @@ void list_ocsp_locations(ocsp_location_t *location, bool requests,
                                        , buf, BUF_LEN);
                                whack_log(RC_COMMENT, "       authkey:  %s", buf);
                        }
-                       if (location->authKeySerialNumber.ptr != NULL)
-                       {
-                               datatot(location->authKeySerialNumber.ptr
-                                       , location->authKeySerialNumber.len, ':', buf, BUF_LEN);
-                               whack_log(RC_COMMENT, "       aserial:  %s", buf);
-                       }
                        while (certinfo != NULL)
                        {
                                char thisUpdate[BUF_LEN];
@@ -662,17 +667,17 @@ static bool get_ocsp_requestor_cert(ocsp_location_t *location)
 
        for (;;)
        {
-               char buf[BUF_LEN];
+               certificate_t *certificate;
 
                /* looking for a certificate from the same issuer */
-               cert = get_x509cert(location->issuer, location->authKeySerialNumber
-                                       ,location->authKeyID, cert);
+               cert = get_x509cert(location->issuer, location->authKeyID, cert);
                if (cert == NULL)
+               {
                        break;
-
+               }
+               certificate = cert->cert;
                DBG(DBG_CONTROL,
-                       dntoa(buf, BUF_LEN, cert->subject);
-                       DBG_log("candidate: '%s'", buf);
+                       DBG_log("candidate: '%Y'", certificate->get_subject(certificate));
                )
 
                if (cert->smartcard)
@@ -774,7 +779,7 @@ static chunk_t sc_build_sha1_signature(chunk_t tbs, smartcard_t *sc)
  */
 static chunk_t build_signature(chunk_t tbsRequest)
 {
-       chunk_t sigdata, certs;
+       chunk_t sigdata, cert, certs;
 
        if (ocsp_requestor_sc != NULL)
        {
@@ -793,11 +798,9 @@ static chunk_t build_signature(chunk_t tbsRequest)
        }
 
        /* include our certificate */
-       certs = asn1_wrap(ASN1_CONTEXT_C_0, "m"
-                               , asn1_simple_object(ASN1_SEQUENCE
-                                       , ocsp_requestor_cert->certificate
-                                 )
-                       );
+       cert = ocsp_requestor_cert->cert->get_encoding(ocsp_requestor_cert->cert);
+       certs = asn1_wrap(ASN1_CONTEXT_C_0, "m",
+                               asn1_wrap(ASN1_SEQUENCE, "m", cert));
 
        /* build signature comprising algorithm, signature and cert */
        return asn1_wrap(ASN1_CONTEXT_C_0, "m"
@@ -872,9 +875,12 @@ static chunk_t build_request_list(ocsp_location_t *location)
  */
 static chunk_t build_requestor_name(void)
 {
+       certificate_t *certificate = ocsp_requestor_cert->cert;
+       identification_t *subject = certificate->get_subject(certificate);
+
        return asn1_wrap(ASN1_CONTEXT_C_1, "m"
                                , asn1_simple_object(ASN1_CONTEXT_C_4
-                                       , ocsp_requestor_cert->subject));
+                                       , subject->get_encoding(subject)));
 }
 
 /**
@@ -976,9 +982,8 @@ static bool valid_ocsp_response(response_t *res)
 
        lock_authcert_list("valid_ocsp_response");
 
-       authcert = get_authcert(res->responder_id_name, chunk_empty
-                                       , res->responder_id_key, AUTH_OCSP | AUTH_CA);
-
+       authcert = get_authcert(res->responder_id_name, res->responder_id_key,
+                                                       AUTH_OCSP | AUTH_CA);
        if (authcert == NULL)
        {
                plog("no matching ocsp signer cert found");
@@ -989,7 +994,8 @@ static bool valid_ocsp_response(response_t *res)
                DBG_log("ocsp signer cert found")
        )
 
-       if (!x509_check_signature(res->tbs, res->signature, res->algorithm, authcert))
+       if (!x509_check_signature(res->tbs, res->signature, res->algorithm,
+                                                         authcert->cert))
        {
                plog("signature of ocsp response is invalid");
                unlock_authcert_list("valid_ocsp_response");
@@ -1002,22 +1008,22 @@ static bool valid_ocsp_response(response_t *res)
 
        for (pathlen = 0; pathlen < MAX_CA_PATH_LEN; pathlen++)
        {
-               u_char buf[BUF_LEN];
                err_t ugh = NULL;
                time_t until;
 
                x509cert_t *cert = authcert;
+               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);
+               chunk_t authKeyID = x509->get_authKeyIdentifier(x509);
 
                DBG(DBG_CONTROL,
-                       dntoa(buf, BUF_LEN, cert->subject);
-                       DBG_log("subject: '%s'",buf);
-                       dntoa(buf, BUF_LEN, cert->issuer);
-                       DBG_log("issuer:  '%s'",buf);
-                       if (cert->authKeyID.ptr != NULL)
+                       DBG_log("subject: '%Y'", subject);
+                       DBG_log("issuer:  '%Y'", issuer);
+                       if (authKeyID.ptr != NULL)
                        {
-                               datatot(cert->authKeyID.ptr, cert->authKeyID.len, ':'
-                                       , buf, BUF_LEN);
-                               DBG_log("authkey:  %s", buf);
+                               DBG_log("authkey:  %#B", &authKeyID);
                        }
                )
 
@@ -1034,9 +1040,7 @@ static bool valid_ocsp_response(response_t *res)
                        DBG_log("certificate is valid")
                )
 
-               authcert = get_authcert(cert->issuer, cert->authKeySerialNumber
-                       , cert->authKeyID, AUTH_CA);
-
+               authcert = get_authcert(issuer->get_encoding(issuer), authKeyID, AUTH_CA);
                if (authcert == NULL)
                {
                        plog("issuer cacert not found");
@@ -1047,8 +1051,7 @@ static bool valid_ocsp_response(response_t *res)
                        DBG_log("issuer cacert found")
                )
 
-               if (!x509_check_signature(cert->tbsCertificate, cert->signature,
-                                                                 cert->algorithm, authcert))
+               if (!certificate->issued_by(certificate, authcert->cert))
                {
                        plog("certificate signature is invalid");
                        unlock_authcert_list("valid_ocsp_response");
@@ -1059,7 +1062,7 @@ static bool valid_ocsp_response(response_t *res)
                )
 
                /* check if cert is self-signed */
-               if (same_dn(cert->issuer, cert->subject))
+               if (x509->get_flags(x509) & X509_SELF_SIGNED)
                {
                        DBG(DBG_CONTROL,
                                DBG_log("reached self-signed root ca")
@@ -1143,14 +1146,27 @@ static bool parse_basic_ocsp_response(chunk_t blob, int level0, response_t *res)
                        break;
                case BASIC_RESPONSE_CERTIFICATE:
                        {
-                               chunk_t blob = chunk_clone(object);
                                x509cert_t *cert = malloc_thing(x509cert_t);
+                               x509_t *x509;
 
                                *cert = empty_x509cert;
-
-                               if (parse_x509cert(blob, parser->get_level(parser)+1, cert)
-                               && cert->isOcspSigner
-                               && trust_authcert_candidate(cert, NULL))
+                               cert->cert = lib->creds->create(lib->creds,
+                                                                                 CRED_CERTIFICATE, CERT_X509,
+                                                                                 BUILD_BLOB_ASN1_DER, object,
+                                                                                 BUILD_END);
+                               if (cert->cert == NULL)
+                               {
+                                       DBG(DBG_CONTROL | DBG_PARSING,
+                                               DBG_log("parsing of embedded ocsp certificate failed")
+                                       )
+                                       free_x509cert(cert);
+                                       break;
+                               }
+                               time(&cert->installed);
+                               x509 = (x509_t*)cert->cert;
+                               
+                               if ((x509->get_flags(x509) & X509_OCSP_SIGNER) &&
+                                       trust_authcert_candidate(cert, NULL))
                                {
                                        add_authcert(cert, AUTH_OCSP);
                                }
@@ -1322,8 +1338,7 @@ ocsp_location_t* add_ocsp_location(const ocsp_location_t *loc,
        location->issuer = chunk_clone(loc->issuer);
        location->authNameID = chunk_clone(loc->authNameID);
        location->authKeyID = chunk_clone(loc->authKeyID);
-       location->authKeySerialNumber = chunk_clone(loc->authKeySerialNumber);
-       location->uri = chunk_clone(loc->uri);
+       location->uri = strdup(loc->uri);
        location->certinfo = NULL;
 
        /* insert new ocsp location in front of chain */
index 4615e6f..dd3854f 100644 (file)
@@ -57,9 +57,8 @@ struct ocsp_location {
        chunk_t          issuer;
        chunk_t          authNameID;
        chunk_t          authKeyID;
-       chunk_t          authKeySerialNumber;
-       chunk_t          uri;
        chunk_t          nonce;
+       char             *uri;
        ocsp_certinfo_t  *certinfo;
 };
 
index 61d3751..dcfc9e8 100644 (file)
@@ -17,6 +17,7 @@
 
 #include <stdlib.h>
 #include <string.h>
+#include <time.h>
 
 #include <freeswan.h>
 
@@ -202,7 +203,7 @@ end:
  * Parse a PKCS#7 signedData object
  */
 bool pkcs7_parse_signedData(chunk_t blob, contentInfo_t *data, x509cert_t **cert,
-                                                       chunk_t *attributes, const x509cert_t *cacert)
+                                                       chunk_t *attributes, certificate_t *cacert)
 {
        u_char buf[BUF_LEN];
        asn1_parser_t *parser;
@@ -252,14 +253,17 @@ bool pkcs7_parse_signedData(chunk_t blob, contentInfo_t *data, x509cert_t **cert
                case PKCS7_SIGNED_CERT:
                        if (cert != NULL)
                        {
-                               chunk_t cert_blob = chunk_clone(object);
                                x509cert_t *newcert = malloc_thing(x509cert_t);
 
-                               *newcert = empty_x509cert;
-
                                DBG2("  parsing pkcs7-wrapped certificate");
-                               if (parse_x509cert(cert_blob, level+1, newcert))
+                               *newcert = empty_x509cert;
+                               newcert->cert = lib->creds->create(lib->creds,
+                                                                                        CRED_CERTIFICATE, CERT_X509,
+                                                                                        BUILD_BLOB_ASN1_DER, object,
+                                                                                        BUILD_END);
+                               if (newcert->cert)
                                {
+                                       time(&newcert->installed);
                                        newcert->next = *cert;
                                        *cert = newcert;
                                }
@@ -308,9 +312,15 @@ bool pkcs7_parse_signedData(chunk_t blob, contentInfo_t *data, x509cert_t **cert
        /* check the signature only if a cacert is available */
        if (cacert != NULL)
        {
-               public_key_t *key = cacert->public_key;
-               signature_scheme_t scheme = SIGN_RSA_EMSA_PKCS1_SHA1;
+               public_key_t *key;
+               signature_scheme_t scheme;
 
+               scheme = signature_scheme_from_oid(digest_alg);
+               if (scheme == SIGN_UNKNOWN)
+               {
+                       DBG1("unsupported signature scheme");
+                       return FALSE;
+               }
                if (signerInfos == 0)
                {
                        DBG1("no signerInfo object found");
@@ -332,11 +342,11 @@ bool pkcs7_parse_signedData(chunk_t blob, contentInfo_t *data, x509cert_t **cert
                        return FALSE;
                }
 
-               /* determine signature scheme */
-               scheme = signature_scheme_from_oid(digest_alg);
-
-               if (scheme == SIGN_UNKNOWN)
+               /* verify the signature */
+               key = cacert->get_public_key(cacert);
+               if (key == NULL)
                {
+                       DBG1("no public key found in CA certificate");
                        return FALSE;
                }
                if (key->verify(key, scheme, *attributes, encrypted_digest))
@@ -346,10 +356,11 @@ bool pkcs7_parse_signedData(chunk_t blob, contentInfo_t *data, x509cert_t **cert
                else
                {
                        DBG1("invalid signature");
-                       return FALSE;
+                       success = FALSE;
                }
+               key->destroy(key);
        }
-       return TRUE;
+       return success;
 }
 
 /**
@@ -629,18 +640,21 @@ static chunk_t pkcs7_build_contentInfo(contentInfo_t *cInfo)
 /**
  * build issuerAndSerialNumber object
  */
-chunk_t pkcs7_build_issuerAndSerialNumber(const x509cert_t *cert)
+chunk_t pkcs7_build_issuerAndSerialNumber(certificate_t *cert)
 {
-       return asn1_wrap(ASN1_SEQUENCE, "cm"
-                               , cert->issuer
-                               , asn1_integer("c", cert->serialNumber));
+       identification_t *issuer = cert->get_issuer(cert);
+       x509_t *x509 = (x509_t*)cert;
+
+       return asn1_wrap(ASN1_SEQUENCE, "cm",
+                                        issuer->get_encoding(issuer),
+                                        asn1_integer("c", x509->get_serial(x509)));
 }
 
 /**
  * create a signed pkcs7 contentInfo object
  */
 chunk_t pkcs7_build_signedData(chunk_t data, chunk_t attributes,
-                                                          const x509cert_t *cert, int digest_alg,
+                                                          certificate_t *cert, int digest_alg,
                                                           private_key_t *key)
 {
        contentInfo_t pkcs7Data, signedData;
@@ -677,7 +691,7 @@ chunk_t pkcs7_build_signedData(chunk_t data, chunk_t attributes,
                                , ASN1_INTEGER_1
                                , asn1_wrap(ASN1_SET, "m", asn1_algorithmIdentifier(digest_alg))
                                , pkcs7_build_contentInfo(&pkcs7Data)
-                               , asn1_simple_object(ASN1_CONTEXT_C_0, cert->certificate)
+                               , asn1_wrap(ASN1_CONTEXT_C_0, "m", cert->get_encoding(cert))
                                , asn1_wrap(ASN1_SET, "m", signerInfo));
 
        cInfo = pkcs7_build_contentInfo(&signedData);
@@ -691,7 +705,7 @@ chunk_t pkcs7_build_signedData(chunk_t data, chunk_t attributes,
 /**
  * create a symmetrically encrypted pkcs7 contentInfo object
  */
-chunk_t pkcs7_build_envelopedData(chunk_t data, const x509cert_t *cert, int enc_alg)
+chunk_t pkcs7_build_envelopedData(chunk_t data, certificate_t *cert, int enc_alg)
 {
        encryption_algorithm_t alg;
        size_t alg_key_size;
@@ -744,9 +758,24 @@ chunk_t pkcs7_build_envelopedData(chunk_t data, const x509cert_t *cert, int enc_
        crypter->set_key(crypter, symmetricKey);
        crypter->encrypt(crypter, in, iv, &out);
        crypter->destroy(crypter);
+       chunk_clear(&in);
     DBG3("encrypted data %B", &out);
 
-       cert->public_key->encrypt(cert->public_key, symmetricKey, &protectedKey);
+       /* protect symmetric key by public key encryption */
+       {
+               public_key_t *key = cert->get_public_key(cert);
+
+               if (key == NULL)
+               {
+                       DBG1("public key not found in encryption certificate");
+                       chunk_clear(&symmetricKey);
+                       chunk_free(&iv);
+                       chunk_free(&out);
+                       return chunk_empty;
+               }
+               key->encrypt(key, symmetricKey, &protectedKey);
+               key->destroy(key);
+       }
 
        /* build pkcs7 enveloped data object */
        {
@@ -781,10 +810,9 @@ chunk_t pkcs7_build_envelopedData(chunk_t data, const x509cert_t *cert, int enc_
                cInfo = pkcs7_build_contentInfo(&envelopedData);
                DBG3("envelopedData %B", &cInfo);
 
-               free(envelopedData.content.ptr);
-               free(symmetricKey.ptr);
-               free(in.ptr);
-               free(iv.ptr);
+               chunk_free(&envelopedData.content);
+               chunk_free(&iv);
+               chunk_clear(&symmetricKey);
                return cInfo;
        }
 }
index 028822d..4122c19 100644 (file)
@@ -20,6 +20,7 @@
 
 #include <crypto/crypters/crypter.h>
 #include <credentials/keys/private_key.h>
+#include <credentials/certificates/certificate.h>
 #include "defs.h"
 #include "x509.h"
 
@@ -35,17 +36,19 @@ struct contentInfo {
 extern const contentInfo_t empty_contentInfo;
 
 extern bool pkcs7_parse_contentInfo(chunk_t blob, u_int level0,
-       contentInfo_t *cInfo);
+                                                                       contentInfo_t *cInfo);
 extern bool pkcs7_parse_signedData(chunk_t blob, contentInfo_t *data,
-       x509cert_t **cert, chunk_t *attributes, const x509cert_t *cacert);
+                                                                  x509cert_t **cert, chunk_t *attributes,
+                                                                  certificate_t *cacert);
 extern bool pkcs7_parse_envelopedData(chunk_t blob, chunk_t *data,
-       chunk_t serialNumber, private_key_t *key);
+                                                                         chunk_t serialNumber, private_key_t *key);
 extern chunk_t pkcs7_contentType_attribute(void);
 extern chunk_t pkcs7_messageDigest_attribute(chunk_t content, int digest_alg);
-extern chunk_t pkcs7_build_issuerAndSerialNumber(const x509cert_t *cert);
+extern chunk_t pkcs7_build_issuerAndSerialNumber(certificate_t *cert);
 extern chunk_t pkcs7_build_signedData(chunk_t data, chunk_t attributes,
-       const x509cert_t *cert, int digest_alg, private_key_t *key);
-extern chunk_t pkcs7_build_envelopedData(chunk_t data, const x509cert_t *cert,
-       int enc_alg);
+                                                                         certificate_t *cert, int digest_alg,
+                                                                         private_key_t *key);
+extern chunk_t pkcs7_build_envelopedData(chunk_t data, certificate_t *cert,
+                                                                                int enc_alg);
 
 #endif /* _PKCS7_H */
index 8b47900..97074f5 100644 (file)
@@ -386,8 +386,7 @@ static enum_names pkcs11_return_names =
  * The calling application is responsible for cleaning up
  * and calling C_Finalize()
  */
-static CK_RV
-scx_unload_pkcs11_module(scx_pkcs11_module_t *mod)
+static CK_RV scx_unload_pkcs11_module(scx_pkcs11_module_t *mod)
 {
        if (!mod || mod->_magic != SCX_MAGIC)
                return CKR_ARGUMENTS_BAD;
@@ -400,8 +399,8 @@ scx_unload_pkcs11_module(scx_pkcs11_module_t *mod)
        return CKR_OK;
 }
 
-static scx_pkcs11_module_t*
-scx_load_pkcs11_module(const char *name, CK_FUNCTION_LIST_PTR_PTR funcs)
+static scx_pkcs11_module_t* scx_load_pkcs11_module(const char *name,
+                                                                CK_FUNCTION_LIST_PTR_PTR funcs)
 {
        CK_RV (*c_get_function_list)(CK_FUNCTION_LIST_PTR_PTR);
        scx_pkcs11_module_t *mod;
@@ -437,9 +436,9 @@ 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 bool scx_find_cert_object(CK_SESSION_HANDLE session,
+                                                                CK_OBJECT_HANDLE object,
+                                                                smartcard_t *sc, cert_t *cert)
 {
        size_t hex_len, label_len;
        u_char *hex_id = NULL;
@@ -518,8 +517,7 @@ scx_find_cert_object(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE object
 /*
  * search a given slot for PKCS#11 certificate objects
  */
-static void
-scx_find_cert_objects(CK_SLOT_ID slot, CK_SESSION_HANDLE session)
+static void scx_find_cert_objects(CK_SLOT_ID slot, CK_SESSION_HANDLE session)
 {
        CK_RV rv;
        CK_OBJECT_CLASS class = CKO_CERTIFICATE;
@@ -616,8 +614,7 @@ scx_find_cert_objects(CK_SLOT_ID slot, CK_SESSION_HANDLE session)
 /*
  * search all slots for PKCS#11 certificate objects
  */
-static void
-scx_find_all_cert_objects(void)
+static void scx_find_all_cert_objects(void)
 {
        CK_RV rv;
        CK_SLOT_ID_PTR slots = NULL_PTR;
@@ -696,8 +693,7 @@ scx_find_all_cert_objects(void)
  * init_args should be unused when we have a PKCS#11 compliant module,
  * but NSS softoken breaks that API.
  */
-void
-scx_init(const char* module, const char *init_args)
+void scx_init(const char* module, const char *init_args)
 {
 #ifdef SMARTCARD
        CK_C_INITIALIZE_ARGS args = { .pReserved = (char *)init_args, };
@@ -752,8 +748,7 @@ scx_init(const char* module, const char *init_args)
 /*
  * finalize and unload PKCS#11 cryptoki module
  */
-void
-scx_finalize(void)
+void scx_finalize(void)
 {
 #ifdef SMARTCARD
        while (smartcards != NULL)
@@ -783,8 +778,7 @@ scx_finalize(void)
 /*
  * does a filename contain the token %smartcard?
  */
-bool
-scx_on_smartcard(const char *filename)
+bool scx_on_smartcard(const char *filename)
 {
        return strneq(filename, SCX_TOKEN, strlen(SCX_TOKEN));
 }
@@ -793,11 +787,9 @@ scx_on_smartcard(const char *filename)
 /*
  * find a specific object on the smartcard
  */
-static bool
-scx_pkcs11_find_object( CK_SESSION_HANDLE session,
-                                               CK_OBJECT_HANDLE_PTR object,
-                                               CK_OBJECT_CLASS class,
-                                               const char* id)
+static bool scx_pkcs11_find_object(CK_SESSION_HANDLE session,
+                                                                  CK_OBJECT_HANDLE_PTR object,
+                                                                  CK_OBJECT_CLASS class, const char* id)
 {
        size_t len;
        char buf[BUF_LEN];
@@ -848,8 +840,7 @@ scx_pkcs11_find_object( CK_SESSION_HANDLE session,
 /*
  * check if a given certificate object id is found in a slot
  */
-static bool
-scx_find_cert_id_in_slot(smartcard_t *sc, CK_SLOT_ID slot)
+static bool scx_find_cert_id_in_slot(smartcard_t *sc, CK_SLOT_ID slot)
 {
        CK_SESSION_HANDLE session;
        CK_OBJECT_HANDLE object;
@@ -905,8 +896,7 @@ scx_find_cert_id_in_slot(smartcard_t *sc, CK_SLOT_ID slot)
 /*
  * Connect to the smart card in the reader and select the correct slot
  */
-bool
-scx_establish_context(smartcard_t *sc)
+bool scx_establish_context(smartcard_t *sc)
 {
 #ifdef SMARTCARD
        bool id_found = FALSE;
@@ -983,8 +973,7 @@ scx_establish_context(smartcard_t *sc)
 /*
  * log in to a session
  */
-bool
-scx_login(smartcard_t *sc)
+bool scx_login(smartcard_t *sc)
 {
 #ifdef SMARTCARD
        CK_RV rv;
@@ -1031,8 +1020,7 @@ scx_login(smartcard_t *sc)
 /*
  * logout from a session
  */
-static void
-scx_logout(smartcard_t *sc)
+static void scx_logout(smartcard_t *sc)
 {
        CK_RV rv;
 
@@ -1052,8 +1040,7 @@ scx_logout(smartcard_t *sc)
 /*
  * Release context and disconnect from card
  */
-void
-scx_release_context(smartcard_t *sc)
+void scx_release_context(smartcard_t *sc)
 {
 #ifdef SMARTCARD
        CK_RV rv;
@@ -1083,9 +1070,8 @@ 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)
+bool scx_load_cert(const char *filename, smartcard_t **scp, cert_t *cert,
+                                  bool *cached)
 {
 #ifdef SMARTCARD        /* compile with smartcard support */
        CK_OBJECT_HANDLE object;
@@ -1158,8 +1144,7 @@ scx_load_cert(const char *filename, smartcard_t **scp, cert_t *cert
  * %smartcard:45   -       -     45
  * %smartcard0:45  -       0     45
  */
-smartcard_t*
-scx_parse_number_slot_id(const char *number_slot_id)
+smartcard_t* scx_parse_number_slot_id(const char *number_slot_id)
 {
        int len = strlen(number_slot_id);
        smartcard_t *sc = malloc_thing(smartcard_t);
@@ -1218,8 +1203,7 @@ scx_parse_number_slot_id(const char *number_slot_id)
 /*
  * Verify pin on card
  */
-bool
-scx_verify_pin(smartcard_t *sc)
+bool scx_verify_pin(smartcard_t *sc)
 {
 #ifdef SMARTCARD
        CK_RV rv;
@@ -1270,9 +1254,8 @@ scx_verify_pin(smartcard_t *sc)
 /*
  * Sign hash on smartcard
  */
-bool
-scx_sign_hash(smartcard_t *sc, const u_char *in, size_t inlen
-, u_char *out, size_t outlen)
+bool scx_sign_hash(smartcard_t *sc, const u_char *in, size_t inlen, u_char *out,
+                                  size_t outlen)
 {
 #ifdef SMARTCARD
        CK_RV rv;
@@ -1380,9 +1363,8 @@ scx_sign_hash(smartcard_t *sc, const u_char *in, size_t inlen
 /*
  * encrypt data block with an RSA public key
  */
-bool
-scx_encrypt(smartcard_t *sc, const u_char *in, size_t inlen
-, u_char *out, size_t *outlen)
+bool scx_encrypt(smartcard_t *sc, const u_char *in, size_t inlen, u_char *out,
+                                size_t *outlen)
 {
 #ifdef SMARTCARD
        CK_RV rv;
@@ -1530,9 +1512,8 @@ scx_encrypt(smartcard_t *sc, const u_char *in, size_t inlen
 /*
  * decrypt a data block with an RSA private key
  */
-bool
-scx_decrypt(smartcard_t *sc, const u_char *in, size_t inlen
-, u_char *out, size_t *outlen)
+bool scx_decrypt(smartcard_t *sc, const u_char *in, size_t inlen, u_char *out,
+                                size_t *outlen)
 {
 #ifdef SMARTCARD
        CK_RV rv;
@@ -1606,9 +1587,8 @@ scx_decrypt(smartcard_t *sc, const u_char *in, size_t inlen
  * decrypt it using a private RSA key and
  * return the decrypted data block via whack
  */
-bool
-scx_op_via_whack(const char* msg, int inbase, int outbase, sc_op_t op
-, const char* keyid, int whackfd)
+bool scx_op_via_whack(const char* msg, int inbase, int outbase, sc_op_t op,
+                                         const char* keyid, int whackfd)
 {
        char inbuf[RSA_MAX_OCTETS];
        char outbuf[2*RSA_MAX_OCTETS + 1];
@@ -1701,8 +1681,7 @@ scx_op_via_whack(const char* msg, int inbase, int outbase, sc_op_t op
  /*
  * get length of RSA key in bytes
  */
-size_t
-scx_get_keylength(smartcard_t *sc)
+size_t scx_get_keylength(smartcard_t *sc)
 {
 #ifdef SMARTCARD
        CK_RV rv;
@@ -1737,8 +1716,7 @@ scx_get_keylength(smartcard_t *sc)
 /*
  * prompt for pin and verify it
  */
-bool
-scx_get_pin(smartcard_t *sc, int whackfd)
+bool scx_get_pin(smartcard_t *sc, int whackfd)
 {
 #ifdef SMARTCARD
        char pin[BUF_LEN];
@@ -1796,8 +1774,7 @@ scx_get_pin(smartcard_t *sc, int whackfd)
 /*
  * free the pin code
  */
-void
-scx_free_pin(chunk_t *pin)
+void scx_free_pin(chunk_t *pin)
 {
        if (pin->ptr != NULL)
        {
@@ -1811,8 +1788,7 @@ scx_free_pin(chunk_t *pin)
 /*
  * frees a smartcard record
  */
-void
-scx_free(smartcard_t *sc)
+void scx_free(smartcard_t *sc)
 {
        if (sc != NULL)
        {
@@ -1827,8 +1803,7 @@ scx_free(smartcard_t *sc)
 /*  release of a smartcard record decreases the count by one
  "  the record is freed when the counter reaches zero
  */
-void
-scx_release(smartcard_t *sc)
+void scx_release(smartcard_t *sc)
 {
        if (sc != NULL && --sc->count == 0)
        {
@@ -1844,8 +1819,7 @@ scx_release(smartcard_t *sc)
 /*
  *  compare two smartcard records by comparing their slots and ids
  */
-static bool
-scx_same(smartcard_t *a, smartcard_t *b)
+static bool scx_same(smartcard_t *a, smartcard_t *b)
 {
        if  (a->number && b->number)
        {
@@ -1863,8 +1837,7 @@ scx_same(smartcard_t *a, smartcard_t *b)
 /*  for each link pointing to the smartcard record
  "  increase the count by one
  */
-void
-scx_share(smartcard_t *sc)
+void scx_share(smartcard_t *sc)
 {
        if (sc != NULL)
                sc->count++;
@@ -1873,8 +1846,7 @@ scx_share(smartcard_t *sc)
 /*
  *  adds a smartcard record to the chained list
  */
-smartcard_t*
-scx_add(smartcard_t *smartcard)
+smartcard_t* scx_add(smartcard_t *smartcard)
 {
        smartcard_t *sc = smartcards;
        smartcard_t **psc = &smartcards;
@@ -1903,8 +1875,7 @@ 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(x509cert_t *cert)
 {
        smartcard_t *sc = smartcards;
 
@@ -1920,8 +1891,7 @@ scx_get(x509cert_t *cert)
 /*
  * prints either the slot number or 'any slot'
  */
-char *
-scx_print_slot(smartcard_t *sc, const char *whitespace)
+char *scx_print_slot(smartcard_t *sc, const char *whitespace)
 {
        char *buf = temporary_cyclic_buffer();
 
@@ -1935,8 +1905,7 @@ scx_print_slot(smartcard_t *sc, const char *whitespace)
 /*
  *  list all smartcard info records in a chained list
  */
-void
-scx_list(bool utc)
+void scx_list(bool utc)
 {
        smartcard_t *sc = smartcards;
 
@@ -1966,10 +1935,10 @@ scx_list(bool utc)
                        whack_log(RC_COMMENT, "       label:   '%s'", sc->label);
                if (sc->last_cert.type == CERT_X509_SIGNATURE)
                {
-                       char buf[BUF_LEN];
+                       certificate_t *certificate = sc->last_cert.u.x509->cert;
 
-                       dntoa(buf, BUF_LEN, sc->last_cert.u.x509->subject);
-                       whack_log(RC_COMMENT, "       subject: '%s'", buf);
+                       whack_log(RC_COMMENT, "       subject: '%Y'",
+                                         certificate->get_subject(certificate));
                }
                sc = sc->next;
        }
index f1d0795..d0a57b3 100644 (file)
 static x509cert_t *x509certs     = NULL;
 
 /**
- * ASN.1 definition of a basicConstraints extension
- */
-static const asn1Object_t basicConstraintsObjects[] = {
-       { 0, "basicConstraints",        ASN1_SEQUENCE, ASN1_NONE          }, /*  0 */
-       { 1,   "CA",                            ASN1_BOOLEAN,  ASN1_DEF|ASN1_BODY }, /*  1 */
-       { 1,   "pathLenConstraint",     ASN1_INTEGER,  ASN1_OPT|ASN1_BODY }, /*  2 */
-       { 1,   "end opt",                       ASN1_EOC,      ASN1_END           }, /*  3 */
-       { 0, "exit",                            ASN1_EOC,      ASN1_EXIT          }
-};
-#define BASIC_CONSTRAINTS_CA   1
-
-/**
  * ASN.1 definition of a authorityKeyIdentifier extension
  */
 static const asn1Object_t authKeyIdentifierObjects[] = {
@@ -78,31 +66,6 @@ static const asn1Object_t authKeyIdentifierObjects[] = {
 #define AUTH_KEY_ID_CERT_SERIAL                5
 
 /**
- * ASN.1 definition of a authorityInfoAccess extension
- */
-static const asn1Object_t authInfoAccessObjects[] = {
-       { 0, "authorityInfoAccess",     ASN1_SEQUENCE,  ASN1_LOOP }, /* 0 */
-       { 1,   "accessDescription",     ASN1_SEQUENCE,  ASN1_NONE }, /* 1 */
-       { 2,     "accessMethod",        ASN1_OID,               ASN1_BODY }, /* 2 */
-       { 2,     "accessLocation",      ASN1_EOC,               ASN1_RAW  }, /* 3 */
-       { 0, "end loop",                        ASN1_EOC,               ASN1_END  }, /* 4 */
-       { 0, "exit",                            ASN1_EOC,               ASN1_EXIT }
-};
-#define AUTH_INFO_ACCESS_METHOD                2
-#define AUTH_INFO_ACCESS_LOCATION      3
-
-/**
- * ASN.1 definition of a extendedKeyUsage extension
- */
-static const asn1Object_t extendedKeyUsageObjects[] = {
-       { 0, "extendedKeyUsage",        ASN1_SEQUENCE,  ASN1_LOOP }, /* 0 */
-       { 1,   "keyPurposeID",          ASN1_OID,               ASN1_BODY }, /* 1 */
-       { 0, "end loop",                        ASN1_EOC,               ASN1_END  }, /* 2 */
-       { 0, "exit",                            ASN1_EOC,               ASN1_EXIT }
-};
-#define EXT_KEY_USAGE_PURPOSE_ID       1
-
-/**
  * ASN.1 definition of generalNames
  */
 static const asn1Object_t generalNamesObjects[] = {
@@ -158,109 +121,13 @@ static const asn1Object_t otherNameObjects[] = {
 #define ON_OBJ_ID_TYPE         0
 #define ON_OBJ_VALUE           1
 
-/**
- * ASN.1 definition of crlDistributionPoints
- */
-static const asn1Object_t crlDistributionPointsObjects[] = {
-       { 0, "crlDistributionPoints",   ASN1_SEQUENCE,          ASN1_LOOP                       }, /*  0 */
-       { 1,   "DistributionPoint",             ASN1_SEQUENCE,          ASN1_NONE                       }, /*  1 */
-       { 2,     "distributionPoint",   ASN1_CONTEXT_C_0,       ASN1_OPT|ASN1_LOOP      }, /*  2 */
-       { 3,       "fullName",                  ASN1_CONTEXT_C_0,       ASN1_OPT|ASN1_OBJ       }, /*  3 */
-       { 3,       "end choice",                ASN1_EOC,                       ASN1_END                        }, /*  4 */
-       { 3,       "nameRelToCRLIssuer",ASN1_CONTEXT_C_1,       ASN1_OPT|ASN1_BODY      }, /*  5 */
-       { 3,       "end choice",                ASN1_EOC,                       ASN1_END                        }, /*  6 */
-       { 2,     "end opt",                             ASN1_EOC,                       ASN1_END                        }, /*  7 */
-       { 2,     "reasons",                             ASN1_CONTEXT_C_1,       ASN1_OPT|ASN1_BODY      }, /*  8 */
-       { 2,     "end opt",                             ASN1_EOC,                       ASN1_END                        }, /*  9 */
-       { 2,     "crlIssuer",                   ASN1_CONTEXT_C_2,       ASN1_OPT|ASN1_BODY      }, /* 10 */
-       { 2,     "end opt",                             ASN1_EOC,                       ASN1_END                        }, /* 11 */
-       { 0, "end loop",                                ASN1_EOC,                       ASN1_END                        }, /* 12 */
-       { 0, "exit",                                    ASN1_EOC,                       ASN1_EXIT                       }
-};
-#define CRL_DIST_POINTS_FULLNAME        3
-
-/**
- * ASN.1 definition of an X.509v3 x509_cert
- */
-static const asn1Object_t certObjects[] = {
-       { 0, "x509",                                    ASN1_SEQUENCE,     ASN1_OBJ           }, /*  0 */
-       { 1,   "tbsCertificate",                ASN1_SEQUENCE,     ASN1_OBJ           }, /*  1 */
-       { 2,     "DEFAULT v1",                  ASN1_CONTEXT_C_0,  ASN1_DEF           }, /*  2 */
-       { 3,       "version",                   ASN1_INTEGER,      ASN1_BODY          }, /*  3 */
-       { 2,     "serialNumber",                ASN1_INTEGER,      ASN1_BODY          }, /*  4 */
-       { 2,     "signature",                   ASN1_EOC,          ASN1_RAW           }, /*  5 */
-       { 2,     "issuer",                              ASN1_SEQUENCE,     ASN1_OBJ           }, /*  6 */
-       { 2,     "validity",                    ASN1_SEQUENCE,     ASN1_NONE          }, /*  7 */
-       { 3,       "notBefore",                 ASN1_EOC,          ASN1_RAW           }, /*  8 */
-       { 3,       "notAfter",                  ASN1_EOC,          ASN1_RAW           }, /*  9 */
-       { 2,     "subject",                             ASN1_SEQUENCE,     ASN1_OBJ           }, /* 10 */
-       { 2,     "subjectPublicKeyInfo",ASN1_SEQUENCE,     ASN1_RAW           }, /* 11 */
-       { 2,     "issuerUniqueID",              ASN1_CONTEXT_C_1,  ASN1_OPT           }, /* 12 */
-       { 2,     "end opt",                             ASN1_EOC,          ASN1_END           }, /* 13 */
-       { 2,     "subjectUniqueID",             ASN1_CONTEXT_C_2,  ASN1_OPT           }, /* 14 */
-       { 2,     "end opt",                             ASN1_EOC,          ASN1_END           }, /* 15 */
-       { 2,     "optional extensions", ASN1_CONTEXT_C_3,  ASN1_OPT           }, /* 16 */
-       { 3,       "extensions",                ASN1_SEQUENCE,     ASN1_LOOP          }, /* 17 */
-       { 4,         "extension",               ASN1_SEQUENCE,     ASN1_NONE          }, /* 18 */
-       { 5,           "extnID",                ASN1_OID,          ASN1_BODY          }, /* 19 */
-       { 5,           "critical",              ASN1_BOOLEAN,      ASN1_DEF|ASN1_BODY }, /* 20 */
-       { 5,           "extnValue",             ASN1_OCTET_STRING, ASN1_BODY          }, /* 21 */
-       { 3,       "end loop",                  ASN1_EOC,          ASN1_END           }, /* 22 */
-       { 2,     "end opt",                             ASN1_EOC,          ASN1_END           }, /* 23 */
-       { 1,   "signatureAlgorithm",    ASN1_EOC,          ASN1_RAW           }, /* 24 */
-       { 1,   "signatureValue",                ASN1_BIT_STRING,   ASN1_BODY          }, /* 25 */
-       { 0, "exit",                                    ASN1_EOC,          ASN1_EXIT          }
-};
-#define X509_OBJ_CERTIFICATE                     0
-#define X509_OBJ_TBS_CERTIFICATE                 1
-#define X509_OBJ_VERSION                         3
-#define X509_OBJ_SERIAL_NUMBER                   4
-#define X509_OBJ_SIG_ALG                         5
-#define X509_OBJ_ISSUER                          6
-#define X509_OBJ_NOT_BEFORE                      8
-#define X509_OBJ_NOT_AFTER                       9
-#define X509_OBJ_SUBJECT                        10
-#define X509_OBJ_SUBJECT_PUBLIC_KEY_INFO        11
-#define X509_OBJ_EXTN_ID                        19
-#define X509_OBJ_CRITICAL                       20
-#define X509_OBJ_EXTN_VALUE                     21
-#define X509_OBJ_ALGORITHM                      24
-#define X509_OBJ_SIGNATURE                      25
-
 const x509cert_t empty_x509cert = {
+         NULL        , /* cert */
          NULL        , /* *next */
        UNDEFINED_TIME, /* installed */
                        0     , /* count */
          FALSE       , /* smartcard */
         AUTH_NONE    , /* authority_flags */
-       { NULL, 0 }   , /* certificate */
-       { NULL, 0 }   , /*   tbsCertificate */
-                       1     , /*     version */
-       { NULL, 0 }   , /*     serialNumber */
-       OID_UNKNOWN   , /*     sigAlg */
-       { NULL, 0 }   , /*     issuer */
-                                       /*     validity */
-                       0     , /*       notBefore */
-                       0     , /*       notAfter */
-       { NULL, 0 }   , /*     subject */
-         NULL        , /*     public_key */
-                                       /*     issuerUniqueID */
-                                       /*     subjectUniqueID */
-                                       /*     extensions */
-                                       /*       extension */
-                                       /*         extnID */
-                                       /*         critical */
-                                       /*         extnValue */
-         FALSE       , /*           isCA */
-         FALSE       , /*           isOcspSigner */
-       { NULL, 0 }   , /*           subjectKeyID */
-       { NULL, 0 }   , /*           authKeyID */
-       { NULL, 0 }   , /*           authKeySerialNumber */
-       { NULL, 0 }   , /*           accessLocation */
-         NULL        , /*           subjectAltName */
-         NULL        , /*           crlDistributionPoints */
-       OID_UNKNOWN   , /*   algorithm */
-       { NULL, 0 }     /*   signature */
 };
 
 /* coding of X.501 distinguished name */
@@ -333,10 +200,6 @@ static const x501rdn_t x501rdns[] = {
 
 #define X501_RDN_ROOF   26
 
-static chunk_t ASN1_subjectAltName_oid = chunk_from_chars(
-       0x06, 0x03, 0x55, 0x1D, 0x11
-);
-
 static void update_chunk(chunk_t *ch, int n)
 {
        n = (n > -1 && n < (int)ch->len)? n : (int)ch->len-1;
@@ -947,14 +810,6 @@ bool match_dn(chunk_t a, chunk_t b, int *wildcards)
 }
 
 /**
- *  Compare two X.509 certificates by comparing their signatures
- */
-bool same_x509cert(const x509cert_t *a, const x509cert_t *b)
-{
-       return chunk_equals(a->signature, b->signature);
-}
-
-/**
  * For each link pointing to the certificate increase the count by one
  */
 void share_x509cert(x509cert_t *cert)
@@ -970,11 +825,12 @@ void share_x509cert(x509cert_t *cert)
  */
 x509cert_t* add_x509cert(x509cert_t *cert)
 {
+       certificate_t *certificate = cert->cert;
        x509cert_t *c = x509certs;
 
        while (c != NULL)
        {
-               if (same_x509cert(c, cert)) /* already in chain, free cert */
+               if (certificate->equals(certificate, c->cert)) /* already in chain, free cert */
                {
                        free_x509cert(cert);
                        return c;
@@ -998,39 +854,47 @@ x509cert_t* add_x509cert(x509cert_t *cert)
  */
 void select_x509cert_id(x509cert_t *cert, struct id *end_id)
 {
+       certificate_t *certificate = cert->cert;
+       x509_t *x509 = (x509_t*)certificate;
+       identification_t *subjectAltName;
+
        bool copy_subject_dn = TRUE;         /* ID is subject DN */
 
        if (end_id->kind != ID_ANY) /* check for matching subjectAltName */
        {
-               generalName_t *gn = cert->subjectAltName;
+               enumerator_t *enumerator;
 
-               while (gn != NULL)
+               enumerator = x509->create_subjectAltName_enumerator(x509);
+               while (enumerator->enumerate(enumerator, &subjectAltName))
                {
                        struct id id = empty_id;
 
-                       gntoid(&id, gn);
+                       id_from_identification(&id, subjectAltName);
                        if (same_id(&id, end_id))
                        {
                                copy_subject_dn = FALSE; /* take subjectAltName instead */
                                break;
                        }
-                       gn = gn->next;
                }
+               enumerator->destroy(enumerator);
        }
 
        if (copy_subject_dn)
        {
+               identification_t *subject = certificate->get_subject(certificate);
+               chunk_t subject_dn = subject->get_encoding(subject);
+
                if (end_id->kind != ID_ANY && end_id->kind != ID_DER_ASN1_DN)
                {
-                        char buf[BUF_LEN];
+                       char buf[BUF_LEN];
 
-                        idtoa(end_id, buf, BUF_LEN);
-                        plog("  no subjectAltName matches ID '%s', replaced by subject DN", buf);
+                       idtoa(end_id, buf, BUF_LEN);
+                       plog("  no subjectAltName matches ID '%s', replaced by subject DN", buf);
                }
                end_id->kind = ID_DER_ASN1_DN;
-               end_id->name.len = cert->subject.len;
+               end_id->name.len = subject_dn.len;
                end_id->name.ptr = temporary_cyclic_buffer();
-               memcpy(end_id->name.ptr, cert->subject.ptr, cert->subject.len);
+               memcpy(end_id->name.ptr, subject_dn.ptr, subject_dn.len);
        }
 }
 
@@ -1047,31 +911,22 @@ bool same_keyid(chunk_t a, chunk_t b)
 }
 
 /**
- * Check for equality between two serial numbers
- */
-bool same_serial(chunk_t a, chunk_t b)
-{
-       /* do not compare serial numbers if one of them is not defined */
-       if (a.ptr == NULL || b.ptr == NULL)
-       {
-               return TRUE;
-       }
-       return chunk_equals(a, b);
-}
-
-/**
  * Get a X.509 certificate with a given issuer found at a certain position
  */
-x509cert_t* get_x509cert(chunk_t issuer, chunk_t serial, chunk_t keyid,
-                                                x509cert_t *chain)
+x509cert_t* get_x509cert(chunk_t issuer, chunk_t keyid, x509cert_t *chain)
 {
        x509cert_t *cert = (chain != NULL)? chain->next : x509certs;
 
        while (cert != NULL)
        {
-               if ((keyid.ptr != NULL) ? same_keyid(keyid, cert->authKeyID)
-                       : (same_dn(issuer, cert->issuer)
-                          && same_serial(serial, cert->authKeySerialNumber)))
+               certificate_t *certificate = cert->cert;
+               x509_t *x509 = (x509_t*)certificate;
+               identification_t *cert_issuer = certificate->get_issuer(certificate);
+               chunk_t cert_issuer_dn = cert_issuer->get_encoding(cert_issuer);
+               chunk_t authKeyID = x509->get_authKeyIdentifier(x509);
+
+               if ((keyid.ptr != NULL) ? same_keyid(keyid, authKeyID)
+                       : same_dn(issuer, cert_issuer_dn))
                {
                        return cert;
                }
@@ -1081,92 +936,6 @@ x509cert_t* get_x509cert(chunk_t issuer, chunk_t serial, chunk_t keyid,
 }
 
 /**
- * Encode a linked list of subjectAltNames
- */
-chunk_t build_subjectAltNames(generalName_t *subjectAltNames)
-{
-       u_char *pos;
-       chunk_t names;
-       size_t len = 0;
-       generalName_t *gn = subjectAltNames;
-
-   /* compute the total size of the ASN.1 attributes object */
-       while (gn != NULL)
-       {
-               len += gn->name.len;
-               gn = gn->next;
-       }
-
-       pos = asn1_build_object(&names, ASN1_SEQUENCE, len);
-
-       gn = subjectAltNames;
-       while (gn != NULL)
-       {
-               chunkcpy(pos, gn->name);
-               gn = gn->next;
-       }
-
-       return asn1_wrap(ASN1_SEQUENCE, "cm"
-                               , ASN1_subjectAltName_oid
-                               , asn1_wrap(ASN1_OCTET_STRING, "m", names));
-}
-
-/**
- * Build a to-be-signed X.509 certificate body
- */
-static chunk_t build_tbs_x509cert(x509cert_t *cert, public_key_t *rsa)
-{
-       /* version is always X.509v3 */
-       chunk_t version = asn1_simple_object(ASN1_CONTEXT_C_0, ASN1_INTEGER_2);
-       chunk_t key = chunk_empty;
-       chunk_t extensions = chunk_empty;
-
-       rsa->get_encoding(rsa, KEY_PUB_ASN1_DER, &key);
-
-       chunk_t keyInfo = asn1_wrap(ASN1_SEQUENCE, "mm",
-                                                       asn1_algorithmIdentifier(OID_RSA_ENCRYPTION),
-                                                       asn1_bitstring("m", key));
-
-       if (cert->subjectAltName != NULL)
-       {
-               extensions = asn1_wrap(ASN1_CONTEXT_C_3, "m"
-                               , asn1_wrap(ASN1_SEQUENCE, "m"
-                               , build_subjectAltNames(cert->subjectAltName)));
-       }
-
-       return asn1_wrap(ASN1_SEQUENCE, "mmmcmcmm"
-                               , version
-                               , asn1_integer("c", cert->serialNumber)
-                               , asn1_algorithmIdentifier(cert->sigAlg)
-                               , cert->issuer
-                               , asn1_wrap(ASN1_SEQUENCE, "mm"
-                                       , asn1_from_time(&cert->notBefore, ASN1_UTCTIME)
-                                       , asn1_from_time(&cert->notAfter,  ASN1_UTCTIME)
-                                 )
-                               , cert->subject
-                               , keyInfo
-                               , extensions
-                  );
-}
-
-/**
- * Build a DER-encoded X.509 certificate
- */
-void build_x509cert(x509cert_t *cert, public_key_t *cert_key,
-                                       private_key_t *signer_key)
-{
-       chunk_t tbs_cert = build_tbs_x509cert(cert, cert_key);
-
-       chunk_t signature = x509_build_signature(tbs_cert, cert->sigAlg
-                                                               , signer_key, TRUE);
-
-       cert->certificate = asn1_wrap(ASN1_SEQUENCE, "mmm"
-                                                               , tbs_cert
-                                                               , asn1_algorithmIdentifier(cert->sigAlg)
-                                                               , signature);
-}
-
-/**
  * Free the dynamic memory used to store generalNames
  */
 void free_generalNames(generalName_t* gn, bool free_name)
@@ -1190,10 +959,12 @@ void free_x509cert(x509cert_t *cert)
 {
        if (cert != NULL)
        {
-               DESTROY_IF(cert->public_key);
-               free_generalNames(cert->subjectAltName, FALSE);
-               free_generalNames(cert->crlDistributionPoints, FALSE);
-               free(cert->certificate.ptr);
+               certificate_t *certificate = cert->cert;
+
+               if (certificate)
+               {
+                       certificate->destroy(certificate);
+               }
                free(cert);
                cert = NULL;
        }
@@ -1230,13 +1001,16 @@ void store_x509certs(x509cert_t **firstcert, bool strict)
        while (*pp != NULL)
        {
                x509cert_t *cert = *pp;
+               certificate_t *certificate = cert->cert;
+               x509_t *x509 = (x509_t*)certificate;
+               x509_flag_t flags = x509->get_flags(x509);
 
-               if (cert->isCA)
+               if (flags & X509_CA)
                {
                        *pp = cert->next;
 
                        /* we don't accept self-signed CA certs */
-                       if (same_dn(cert->issuer, cert->subject))
+                       if (flags & X509_SELF_SIGNED)
                        {
                                plog("self-signed cacert rejected");
                                free_x509cert(cert);
@@ -1302,16 +1076,27 @@ void store_x509certs(x509cert_t **firstcert, bool strict)
  * Check if a signature over binary blob is genuine
  */
 bool x509_check_signature(chunk_t tbs, chunk_t sig, int algorithm,
-                                                 const x509cert_t *issuer_cert)
+                                                 certificate_t *issuer_cert)
 {
-       public_key_t *key = issuer_cert->public_key;
-       signature_scheme_t scheme = signature_scheme_from_oid(algorithm);
+       bool success;
+       public_key_t *key;
+       signature_scheme_t scheme;
 
+       scheme = signature_scheme_from_oid(algorithm);
        if (scheme == SIGN_UNKNOWN)
        {
                return FALSE;
        }
-       return key->verify(key, scheme, tbs, sig);
+
+       key = issuer_cert->get_public_key(issuer_cert);
+       if (key == NULL)
+       {
+               return FALSE;
+       }
+       success = key->verify(key, scheme, tbs, sig);
+       key->destroy(key);
+
+       return success;
 }
 
 /**
@@ -1332,82 +1117,6 @@ chunk_t x509_build_signature(chunk_t tbs, int algorithm, private_key_t *key,
 }
 
 /**
- * Extracts the basicConstraints extension
- */
-static bool parse_basicConstraints(chunk_t blob, int level0)
-{
-       asn1_parser_t *parser;
-       chunk_t object;
-       int objectID;
-       bool isCA = FALSE;
-
-       parser = asn1_parser_create(basicConstraintsObjects, blob);
-       parser->set_top_level(parser, level0);
-
-       while (parser->iterate(parser, &objectID, &object))
-       {
-               if (objectID == BASIC_CONSTRAINTS_CA)
-               {
-                       isCA = object.len && *object.ptr;
-                       DBG(DBG_PARSING,
-                               DBG_log("  %s",(isCA)?"TRUE":"FALSE");
-                       )
-               }
-       }
-       parser->destroy(parser);
-
-       return isCA;
-}
-
-/**
- *  Converts a X.500 generalName into an ID
- */
-void gntoid(struct id *id, const generalName_t *gn)
-{
-       switch(gn->kind)
-       {
-       case GN_DNS_NAME:           /* ID type: ID_FQDN */
-               id->kind = ID_FQDN;
-               id->name = gn->name;
-               break;
-       case GN_IP_ADDRESS:         /* ID type: ID_IPV4_ADDR */
-               {
-                       const struct af_info *afi = &af_inet4_info;
-                       err_t ugh = NULL;
-
-                       id->kind = afi->id_addr;
-                       ugh = initaddr(gn->name.ptr, gn->name.len, afi->af, &id->ip_addr);
-               }
-               break;
-       case GN_RFC822_NAME:        /* ID type: ID_USER_FQDN */
-               id->kind = ID_USER_FQDN;
-               id->name = gn->name;
-               break;
-       default:
-               id->kind = ID_ANY;
-               id->name = chunk_empty;
-       }
-}
-
-/**
- * Compute the subjectKeyIdentifier according to section 4.2.1.2 of RFC 3280
- * as the 160 bit SHA-1 hash of the public key
- */
-bool compute_subjectKeyID(x509cert_t *cert, chunk_t subjectKeyID)
-{
-       chunk_t fingerprint;
-
-       if (!cert->public_key->get_fingerprint(cert->public_key, KEY_ID_PUBKEY_SHA1,
-                                                                                  &fingerprint))
-       {
-               plog("  unable to compute subjectKeyID");
-               return FALSE;
-       }
-       memcpy(subjectKeyID.ptr, fingerprint.ptr, subjectKeyID.len);
-       return TRUE;
-}
-
-/**
  * Extracts an otherName
  */
 static bool parse_otherName(chunk_t blob, int level0)
@@ -1608,294 +1317,31 @@ void parse_authorityKeyIdentifier(chunk_t blob, int level0,
 }
 
 /**
- * Extracts an authorityInfoAcess location
- */
-static void parse_authorityInfoAccess(chunk_t blob, int level0,
-                                                                         chunk_t *accessLocation)
-{
-       asn1_parser_t *parser;
-       chunk_t object;
-       int objectID;
-       int accessMethod = OID_UNKNOWN;
-
-       parser = asn1_parser_create(authInfoAccessObjects, blob);
-       parser->set_top_level(parser, level0);
-
-       while (parser->iterate(parser, &objectID, &object))
-       {
-               switch (objectID)
-               {
-               case AUTH_INFO_ACCESS_METHOD:
-                       accessMethod = asn1_known_oid(object);
-                       break;
-               case AUTH_INFO_ACCESS_LOCATION:
-                       {
-                               switch (accessMethod)
-                               {
-                               case OID_OCSP:
-                                       if (*object.ptr == ASN1_CONTEXT_S_6)
-                                       {
-                                               if (asn1_length(&object) == ASN1_INVALID_LENGTH)
-                                               {
-                                                       goto end;
-                                               }
-                                               DBG(DBG_PARSING,
-                                                       DBG_log("  '%.*s'",(int)object.len, object.ptr)
-                                               )
-
-                                               /* only HTTP(S) URIs accepted */
-                                               if (strncasecmp(object.ptr, "http", 4) == 0)
-                                               {
-                                                       *accessLocation = object;
-                                                       goto end;
-                                               }
-                                       }
-                                       plog("warning: ignoring OCSP InfoAccessLocation with unkown protocol");
-                                       break;
-                               default:
-                                       /* unkown accessMethod, ignoring */
-                                       break;
-                               }
-                       }
-                       break;
-               default:
-                       break;
-               }
-       }
-
-end:
-       parser->destroy(parser);
-}
-
-/**
- * Extracts extendedKeyUsage OIDs
- */
-static bool parse_extendedKeyUsage(chunk_t blob, int level0)
-{
-       asn1_parser_t *parser;
-       chunk_t object;
-       int objectID;
-       bool ocsp_signing = FALSE;
-
-       parser = asn1_parser_create(extendedKeyUsageObjects, blob);
-       parser->set_top_level(parser, level0);
-
-       while (parser->iterate(parser, &objectID, &object))
-       {
-               if (objectID == EXT_KEY_USAGE_PURPOSE_ID
-               && asn1_known_oid(object) == OID_OCSP_SIGNING)
-               {
-                       ocsp_signing = TRUE;
-               }
-       }
-       parser->destroy(parser);
-
-       return ocsp_signing;
-}
-
-/**
- * Extracts one or several crlDistributionPoints
- * and puts them into a chained list
- */
-static generalName_t* parse_crlDistributionPoints(chunk_t blob, int level0)
-{
-       asn1_parser_t *parser;
-       chunk_t object;
-       int objectID;
-
-       generalName_t *top_gn = NULL;      /* top of the chained list */
-       generalName_t **tail_gn = &top_gn; /* tail of the chained list */
-
-       parser = asn1_parser_create(crlDistributionPointsObjects, blob);
-       parser->set_top_level(parser, level0);
-
-       while (parser->iterate(parser, &objectID, &object))
-       {
-               if (objectID == CRL_DIST_POINTS_FULLNAME)
-               {
-                       generalName_t *gn;
-
-                       gn = parse_generalNames(object, parser->get_level(parser)+1, TRUE);
-                       /* append extracted generalNames to existing chained list */
-                       *tail_gn = gn;
-                       /* find new tail of the chained list */
-                       while (gn != NULL)
-                       {
-                               tail_gn = &gn->next;  gn = gn->next;
-                       }
-               }
-       }
-       parser->destroy(parser);
-
-       return top_gn;
-}
-
-/**
- *  Parses an X.509v3 certificate
- */
-bool parse_x509cert(chunk_t blob, u_int level0, x509cert_t *cert)
-{
-       u_char  buf[BUF_LEN];
-       asn1_parser_t *parser;
-       chunk_t object;
-       int objectID;
-       int extn_oid = OID_UNKNOWN;
-       bool critical;
-       bool success = FALSE;
-
-       parser = asn1_parser_create(certObjects, blob);
-       parser->set_top_level(parser, level0);
-
-       while (parser->iterate(parser, &objectID, &object))
-       {
-               u_int level = parser->get_level(parser) + 1;
-
-               switch (objectID) {
-               case X509_OBJ_CERTIFICATE:
-                       cert->certificate = object;
-                       break;
-               case X509_OBJ_TBS_CERTIFICATE:
-                       cert->tbsCertificate = object;
-                       break;
-               case X509_OBJ_VERSION:
-                       cert->version = (object.len) ? (1+(u_int)*object.ptr) : 1;
-                       DBG(DBG_PARSING,
-                               DBG_log("  v%d", cert->version);
-                       )
-                       break;
-               case X509_OBJ_SERIAL_NUMBER:
-                       cert->serialNumber = object;
-                       break;
-               case X509_OBJ_SIG_ALG:
-                       cert->sigAlg = asn1_parse_algorithmIdentifier(object, level, NULL);
-                       break;
-               case X509_OBJ_ISSUER:
-                       cert->issuer = object;
-                       DBG(DBG_PARSING,
-                               dntoa(buf, BUF_LEN, object);
-                               DBG_log("  '%s'",buf)
-                       )
-                       break;
-               case X509_OBJ_NOT_BEFORE:
-                       cert->notBefore = asn1_parse_time(object, level);
-                       break;
-               case X509_OBJ_NOT_AFTER:
-                       cert->notAfter = asn1_parse_time(object, level);
-                       break;
-               case X509_OBJ_SUBJECT:
-                       cert->subject = object;
-                       DBG(DBG_PARSING,
-                               dntoa(buf, BUF_LEN, object);
-                               DBG_log("  '%s'",buf)
-                       )
-                       break;
-               case X509_OBJ_SUBJECT_PUBLIC_KEY_INFO:
-                       cert->public_key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY,
-                                               KEY_ANY, BUILD_BLOB_ASN1_DER, object, BUILD_END);
-                       if (cert->public_key == NULL)
-                       {
-                               goto end;
-                       }
-                       break;
-               case X509_OBJ_EXTN_ID:
-                       extn_oid = asn1_known_oid(object);
-                       break;
-               case X509_OBJ_CRITICAL:
-                       critical = object.len && *object.ptr;
-                       DBG(DBG_PARSING,
-                               DBG_log("  %s",(critical)?"TRUE":"FALSE");
-                       )
-                       break;
-               case X509_OBJ_EXTN_VALUE:
-                       {
-                               switch (extn_oid) {
-                               case OID_SUBJECT_KEY_ID:
-                                       if (!asn1_parse_simple_object(&object, ASN1_OCTET_STRING,
-                                                                                                 level, "keyIdentifier"))
-                                       {
-                                               goto end;
-                                       }
-                                       cert->subjectKeyID = object;
-                                       break;
-                               case OID_SUBJECT_ALT_NAME:
-                                       cert->subjectAltName =
-                                               parse_generalNames(object, level, FALSE);
-                                       break;
-                               case OID_BASIC_CONSTRAINTS:
-                                       cert->isCA =
-                                               parse_basicConstraints(object, level);
-                                       break;
-                               case OID_CRL_DISTRIBUTION_POINTS:
-                                       cert->crlDistributionPoints =
-                                               parse_crlDistributionPoints(object, level);
-                                       break;
-                                case OID_AUTHORITY_KEY_ID:
-                                       parse_authorityKeyIdentifier(object, level
-                                               , &cert->authKeyID, &cert->authKeySerialNumber);
-                                       break;
-                               case OID_AUTHORITY_INFO_ACCESS:
-                                       parse_authorityInfoAccess(object, level, &cert->accessLocation);
-                                       break;
-                               case OID_EXTENDED_KEY_USAGE:
-                                       cert->isOcspSigner = parse_extendedKeyUsage(object, level);
-                                       break;
-                               case OID_NS_REVOCATION_URL:
-                               case OID_NS_CA_REVOCATION_URL:
-                               case OID_NS_CA_POLICY_URL:
-                               case OID_NS_COMMENT:
-                                       if (!asn1_parse_simple_object(&object, ASN1_IA5STRING
-                                       , level, oid_names[extn_oid].name))
-                                       {
-                                               goto end;
-                                       }
-                                       break;
-                               default:
-                                       break;
-                               }
-                       }
-                       break;
-               case X509_OBJ_ALGORITHM:
-                       cert->algorithm = asn1_parse_algorithmIdentifier(object, level, NULL);
-                       break;
-               case X509_OBJ_SIGNATURE:
-                       cert->signature = object;
-                       break;
-               default:
-                       break;
-               }
-       }
-       success = parser->success(parser);
-       time(&cert->installed);
-
-end:
-       parser->destroy(parser);
-       return success;
-}
-
-/**
  * Verify the validity of a certificate by
  * checking the notBefore and notAfter dates
  */
 err_t check_validity(const x509cert_t *cert, time_t *until)
 {
-       time_t current_time;
-
+       time_t current_time, notBefore, notAfter;
+       certificate_t *certificate = cert->cert;
+       
        time(&current_time);
+       certificate->get_validity(certificate, &current_time, &notBefore, &notAfter);
        DBG(DBG_CONTROL | DBG_PARSING ,
-               DBG_log("  not before  : %T", &cert->notBefore, TRUE);
+               DBG_log("  not before  : %T", &notBefore, TRUE);
                DBG_log("  current time: %T", &current_time, TRUE);
-               DBG_log("  not after   : %T", &cert->notAfter, TRUE);
+               DBG_log("  not after   : %T", &notAfter, TRUE);
        )
 
-       if (cert->notAfter < *until)
+       if (*until == 0 || notAfter < *until)
        {
-               *until = cert->notAfter;
+               *until = notAfter;
        }
-       if (current_time < cert->notBefore)
+       if (current_time < notBefore)
        {
                return "certificate is not valid yet";
        }
-       if (current_time > cert->notAfter)
+       if (current_time > notAfter)
        {
                return "certificate has expired";
        }
@@ -1912,24 +1358,24 @@ bool verify_x509cert(const x509cert_t *cert, bool strict, time_t *until)
 {
        int pathlen;
 
-       *until = cert->notAfter;
+       *until = 0;
 
        for (pathlen = 0; pathlen < MAX_CA_PATH_LEN; pathlen++)
        {
+               certificate_t *certificate = cert->cert;
+               identification_t *subject = certificate->get_subject(certificate);
+               identification_t *issuer  = certificate->get_issuer(certificate);
+               x509_t *x509 = (x509_t*)certificate;
+               chunk_t authKeyID = x509->get_authKeyIdentifier(x509);
                x509cert_t *issuer_cert;
-               u_char buf[BUF_LEN];
                err_t ugh = NULL;
 
                DBG(DBG_CONTROL,
-                       dntoa(buf, BUF_LEN, cert->subject);
-                       DBG_log("subject: '%s'",buf);
-                       dntoa(buf, BUF_LEN, cert->issuer);
-                       DBG_log("issuer:  '%s'",buf);
-                       if (cert->authKeyID.ptr != NULL)
+                       DBG_log("subject: '%Y'", subject);
+                       DBG_log("issuer:  '%Y'", issuer);
+                       if (authKeyID.ptr != NULL)
                        {
-                               datatot(cert->authKeyID.ptr, cert->authKeyID.len, ':'
-                                       , buf, BUF_LEN);
-                               DBG_log("authkey:  %s", buf);
+                               DBG_log("authkey:  %#B", &authKeyID);
                        }
                )
 
@@ -1946,9 +1392,8 @@ bool verify_x509cert(const x509cert_t *cert, bool strict, time_t *until)
                )
 
                lock_authcert_list("verify_x509cert");
-               issuer_cert = get_authcert(cert->issuer, cert->authKeySerialNumber
-                       , cert->authKeyID, AUTH_CA);
-
+               issuer_cert = get_authcert(issuer->get_encoding(issuer),
+                                                                  authKeyID, AUTH_CA);
                if (issuer_cert == NULL)
                {
                        plog("issuer cacert not found");
@@ -1959,8 +1404,7 @@ bool verify_x509cert(const x509cert_t *cert, bool strict, time_t *until)
                        DBG_log("issuer cacert found")
                )
 
-               if (!x509_check_signature(cert->tbsCertificate, cert->signature,
-                                                                 cert->algorithm, issuer_cert))
+               if (!certificate->issued_by(certificate, issuer_cert->cert))
                {
                        plog("certificate signature is invalid");
                        unlock_authcert_list("verify_x509cert");
@@ -1972,7 +1416,7 @@ bool verify_x509cert(const x509cert_t *cert, bool strict, time_t *until)
                unlock_authcert_list("verify_x509cert");
 
                /* check if cert is a self-signed root ca */
-               if (pathlen > 0 && same_dn(cert->issuer, cert->subject))
+               if (pathlen > 0 && (x509->get_flags(x509) & X509_SELF_SIGNED))
                {
                        DBG(DBG_CONTROL,
                                DBG_log("reached self-signed root ca")
@@ -2063,11 +1507,13 @@ void list_x509cert_chain(const char *caption, x509cert_t* cert,
        {
                if (auth_flags == AUTH_NONE || (auth_flags & cert->authority_flags))
                {
-                       u_char buf[BUF_LEN];
-                       public_key_t *key = cert->public_key;
-                       chunk_t keyid;
+                       time_t notBefore, notAfter;
+                       public_key_t *key;
+                       chunk_t serial, keyid, subjkey, authkey;
                        cert_t c;
-
+                       certificate_t *certificate = cert->cert;
+                       x509_t *x509 = (x509_t*)certificate;
+                       
                        c.type = CERT_X509_SIGNATURE;
                        c.u.x509 = cert;
 
@@ -2081,45 +1527,47 @@ void list_x509cert_chain(const char *caption, x509cert_t* cert,
 
                        whack_log(RC_COMMENT, "%T, count: %d", &cert->installed, utc,
                                cert->count);
-                       dntoa(buf, BUF_LEN, cert->subject);
-                       whack_log(RC_COMMENT, "       subject:  '%s'", buf);
-                       dntoa(buf, BUF_LEN, cert->issuer);
-                       whack_log(RC_COMMENT, "       issuer:   '%s'", buf);
-                       datatot(cert->serialNumber.ptr, cert->serialNumber.len, ':',
-                                buf, BUF_LEN);
-                       whack_log(RC_COMMENT, "       serial:    %s", buf);
+                       whack_log(RC_COMMENT, "       subject:  '%Y'",
+                               certificate->get_subject(certificate));
+                       whack_log(RC_COMMENT, "       issuer:   '%Y'",
+                               certificate->get_issuer(certificate));
+                               serial = x509->get_serial(x509);
+                       whack_log(RC_COMMENT, "       serial:    %#B", &serial);
+
+                       /* list validity */
+                       certificate->get_validity(certificate, &now, &notBefore, &notAfter);
                        whack_log(RC_COMMENT, "       validity:  not before %T %s",
-                               &cert->notBefore, utc,
-                               (cert->notBefore < now)?"ok":"fatal (not valid yet)");
+                               &notBefore, utc,
+                               (notBefore < now)?"ok":"fatal (not valid yet)");
                        whack_log(RC_COMMENT, "                  not after  %T %s",
-                               &cert->notAfter, utc,
-                               check_expiry(cert->notAfter, 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,
-                               cert->smartcard ? ", on smartcard" :
-                               (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);
-                       }
-                       if (cert->subjectKeyID.ptr != NULL)
-                       {
-                               datatot(cert->subjectKeyID.ptr, cert->subjectKeyID.len, ':',
-                                               buf, BUF_LEN);
-                               whack_log(RC_COMMENT, "       subjkey:   %s", buf);
-                       }
-                       if (cert->authKeyID.ptr != NULL)
+                               &notAfter, utc,
+                               check_expiry(notAfter, CA_CERT_WARNING_INTERVAL, TRUE));
+
+                       key = certificate->get_public_key(certificate);
+                       if (key);
                        {
-                               datatot(cert->authKeyID.ptr, cert->authKeyID.len, ':',
-                                               buf, BUF_LEN);
-                               whack_log(RC_COMMENT, "       authkey:   %s", buf);
+                               whack_log(RC_COMMENT, "       pubkey:    %N %4d bits%s",
+                                       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" : ""));
+
+                               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, &subjkey))
+                               {
+                                       whack_log(RC_COMMENT, "       subjkey:   %#B", &subjkey);
+                               }
+                               key->destroy(key);
                        }
-                       if (cert->authKeySerialNumber.ptr != NULL)
+
+                       /* list optional authorityKeyIdentifier */
+                       authkey = x509->get_authKeyIdentifier(x509);
+                       if (authkey.ptr)
                        {
-                               datatot(cert->authKeySerialNumber.ptr,
-                                               cert->authKeySerialNumber.len, ':', buf, BUF_LEN);
-                               whack_log(RC_COMMENT, "       aserial:   %s", buf);
+                               whack_log(RC_COMMENT, "       authkey:   %#B", &authkey);
                        }
                }
                cert = cert->next;
index 6c1b4a6..490ffc3 100644 (file)
@@ -20,7 +20,7 @@
 
 #include <credentials/keys/public_key.h>
 #include <credentials/keys/private_key.h>
-
+#include <credentials/certificates/x509.h>
 #include "constants.h"
 #include "id.h"
 
@@ -53,80 +53,39 @@ struct generalName {
 typedef struct x509cert x509cert_t;
 
 struct x509cert {
+       certificate_t  *cert;
        x509cert_t     *next;
-       time_t         installed;
-       int            count;
-       bool           smartcard;
-       u_char         authority_flags;
-       chunk_t        certificate;
-       chunk_t          tbsCertificate;
-       u_int              version;
-       chunk_t            serialNumber;
-                                 /*   signature */
-       int                  sigAlg;
-       chunk_t            issuer;
-                                 /*   validity */
-       time_t               notBefore;
-       time_t               notAfter;
-       chunk_t            subject;
-       public_key_t       *public_key;
-                                 /*   issuerUniqueID */
-                                 /*   subjectUniqueID */
-                                 /*   v3 extensions */
-                                 /*   extension */
-                                 /*     extension */
-                                 /*       extnID */
-                                 /*       critical */
-                                 /*       extnValue */
-       bool                     isCA;
-       bool                     isOcspSigner; /* ocsp */
-       chunk_t                  subjectKeyID;
-       chunk_t                  authKeyID;
-       chunk_t                  authKeySerialNumber;
-       chunk_t                  accessLocation; /* ocsp */
-       generalName_t            *subjectAltName;
-       generalName_t            *crlDistributionPoints;
-                                 /* signatureAlgorithm */
-       int                algorithm;
-       chunk_t          signature;
+       time_t          installed;
+       int             count;
+       bool            smartcard;
+       u_char          authority_flags;
 };
 
 /* used for initialization */
 extern const x509cert_t empty_x509cert;
 
-extern bool same_serial(chunk_t a, chunk_t b);
 extern bool same_keyid(chunk_t a, chunk_t b);
 extern bool same_dn(chunk_t a, chunk_t b);
 extern bool match_dn(chunk_t a, chunk_t b, int *wildcards);
-extern bool same_x509cert(const x509cert_t *a, const x509cert_t *b);
 extern void hex_str(chunk_t bin, chunk_t *str);
 extern int dn_count_wildcards(chunk_t dn);
 extern int dntoa(char *dst, size_t dstlen, chunk_t dn);
 extern int dntoa_or_null(char *dst, size_t dstlen, chunk_t dn,
                                                 const char* null_dn);
 extern err_t atodn(char *src, chunk_t *dn);
-extern void gntoid(struct id *id, const generalName_t *gn);
-extern bool compute_subjectKeyID(x509cert_t *cert, chunk_t subjectKeyID);
 extern void select_x509cert_id(x509cert_t *cert, struct id *end_id);
-extern bool parse_x509cert(chunk_t blob, u_int level0, x509cert_t *cert);
-extern time_t parse_time(chunk_t blob, int level0);
-extern void parse_authorityKeyIdentifier(chunk_t blob, int level0
-       , chunk_t *authKeyID, chunk_t *authKeySerialNumber);
+extern void parse_authorityKeyIdentifier(chunk_t blob, int level0,
+                                                                                chunk_t *authKeyID,
+                                                                                chunk_t *authKeySerialNumber);
 extern chunk_t get_directoryName(chunk_t blob, int level, bool implicit);
 extern err_t check_validity(const x509cert_t *cert, time_t *until);
-
 extern bool x509_check_signature(chunk_t tbs, chunk_t sig, int algorithm,
-                                                                const x509cert_t *issuer_cert);
+                                                                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(chunk_t issuer, chunk_t serial, chunk_t keyid,
-                                                               x509cert_t* chain);
-extern void build_x509cert(x509cert_t *cert, public_key_t *cert_key,
-                                                  private_key_t *signer_key);
-extern chunk_t build_subjectAltNames(generalName_t *subjectAltNames);
+extern x509cert_t* get_x509cert(chunk_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);
index 88481fa..36a38a6 100644 (file)
@@ -1,5 +1,5 @@
 ipsec_PROGRAMS = scepclient
-scepclient_SOURCES = scepclient.c pkcs10.c pkcs10.h scep.c scep.h loglite.c
+scepclient_SOURCES = scepclient.c scep.c scep.h loglite.c
 
 PLUTODIR=$(top_srcdir)/src/pluto
 OPENACDIR=$(top_srcdir)/src/openac
index 95fd768..0419677 100644 (file)
@@ -45,15 +45,14 @@ static const chunk_t ASN1_extensionRequest_oid = chunk_from_chars(
 );
 
 /**
- * @brief Adds a subjectAltName in DER-coded form to a linked list
+ * Adds a subjectAltName in DER-coded form to a linked list
  *
- * @param[in,out]       subjectAltNames head of the linked list of subjectAltNames
- * @param[in]           kind            type of the subjectAltName (which is a generalName)
- * @param[in]           value           value of the subjectAltName as an ASCII string
+ * @param[in]       subjectAltNames linked list of subjectAltNames
+ * @param[in]       kind            type of the subjectAltName (which is a generalName)
+ * @param[in]       value           value of the subjectAltName as an ASCII string
  */
-void
-pkcs10_add_subjectAltName(generalName_t **subjectAltNames, generalNames_t kind
-, char *value)
+void pkcs10_add_subjectAltName(linked_list_t *subjectAltNames,
+                                                          generalNames_t kind, char *value)
 {
        generalName_t *gn;
        asn1_t asn1_type = ASN1_EOC;
@@ -96,16 +95,15 @@ pkcs10_add_subjectAltName(generalName_t **subjectAltNames, generalNames_t kind
 }
 
 /**
- * @brief Builds the requestInfoAttributes of the certificationRequestInfo-field
+ * Builds the requestInfoAttributes of the certificationRequestInfo-field
  *
  * challenge password ans subjectAltNames are only included,
  * when avaiable in given #pkcs10_t structure
  *
  * @param[in]   pkcs10          Pointer to a #pkcs10_t structure
- * @return                                      1 if succeeded, 0 otherwise
+ * @return                      1 if succeeded, 0 otherwise
  */
-static chunk_t
-build_req_info_attributes(pkcs10_t* pkcs10)
+static chunk_t build_req_info_attributes(pkcs10_t* pkcs10)
 {
 
        chunk_t subjectAltNames   = chunk_empty;
@@ -143,13 +141,12 @@ build_req_info_attributes(pkcs10_t* pkcs10)
 }
 
 /**
- * @brief Builds a DER-code pkcs#10 certificate request
+ * Builds a DER-code pkcs#10 certificate request
  *
  * @param[in]   pkcs10          pointer to a pkcs10_t struct
  * @return                      DER-code pkcs10 request
  */
-static chunk_t
-pkcs10_build_request(pkcs10_t *pkcs10, int signature_alg)
+static chunk_t pkcs10_build_request(pkcs10_t *pkcs10, int signature_alg)
 {
        chunk_t key = chunk_empty;
 
@@ -175,7 +172,7 @@ pkcs10_build_request(pkcs10_t *pkcs10, int signature_alg)
 }
 
 /**
- * @brief Creates a pkcs#10 certificate request object
+ * Creates a pkcs#10 certificate request object
  *
  * To create a certificate request, the RSA key and the
  * names to be included as subject in the certificate request
@@ -190,7 +187,7 @@ pkcs10_build_request(pkcs10_t *pkcs10, int signature_alg)
  */
 pkcs10_t* pkcs10_build(private_key_t *private, public_key_t *public,
                                           chunk_t subject, chunk_t challengePassword,
-                                          generalName_t *subjectAltNames, int signature_alg)
+                                          linked_list_t *subjectAltNames, int signature_alg)
 {
        pkcs10_t *pkcs10 = malloc_thing(pkcs10_t);
 
@@ -205,12 +202,11 @@ pkcs10_t* pkcs10_build(private_key_t *private, public_key_t *public,
 }
 
 /**
- * @brief Frees the resources used by an #pkcs10_t object
+ * Frees the resources used by an #pkcs10_t object
  *
  * @param[in]   pkcs10          #pkcs10_t to free
  */
-void
-pkcs10_free(pkcs10_t *pkcs10)
+void pkcs10_free(pkcs10_t *pkcs10)
 {
        if (pkcs10 != NULL)
        {
index e10a3ef..a4d8925 100644 (file)
@@ -23,6 +23,7 @@
 #ifndef _PKCS10_H
 #define _PKCS10_H
 
+#include <utils/linked_list.h>
 #include <credentials/keys/private_key.h>
 #include <credentials/keys/public_key.h>
 
@@ -45,16 +46,16 @@ struct pkcs10_struct {
        chunk_t         request;
        chunk_t         subject;
        chunk_t         challengePassword;
-       generalName_t  *subjectAltNames;
+       linked_list_t  *subjectAltNames;
 };
 
 extern const pkcs10_t empty_pkcs10;
 
-extern void pkcs10_add_subjectAltName(generalName_t **subjectAltNames,
+extern void pkcs10_add_subjectAltName(linked_list_t *subjectAltNames,
                                                                          generalNames_t kind, char *value);
 extern pkcs10_t* pkcs10_build(private_key_t *private, public_key_t *public,
                                                          chunk_t subject, chunk_t challengePassword,
-                                                         generalName_t *subjectAltNames, int signature_alg);
+                                                         linked_list_t *subjectAltNames, int signature_alg);
 extern void pkcs10_free(pkcs10_t *pkcs10);
 
 #endif /* _PKCS10_H */
index 86fd565..5987056 100644 (file)
@@ -370,8 +370,8 @@ chunk_t scep_senderNonce_attribute(void)
  * Builds a pkcs7 enveloped and signed scep request
  */
 chunk_t scep_build_request(chunk_t data, chunk_t transID, scep_msg_t msg,
-                                                  const x509cert_t *enc_cert, int enc_alg,
-                                                  const x509cert_t *signer_cert, int digest_alg,
+                                                  certificate_t *enc_cert, int enc_alg,
+                                                  certificate_t *signer_cert, int digest_alg,
                                                   private_key_t *private_key)
 {
        chunk_t envelopedData, attributes, request;
@@ -525,7 +525,7 @@ bool scep_http_request(const char *url, chunk_t pkcs7, scep_op_t op,
 }
 
 err_t scep_parse_response(chunk_t response, chunk_t transID, contentInfo_t *data,
-                                                 scep_attributes_t *attrs, x509cert_t *signer_cert)
+                                                 scep_attributes_t *attrs, certificate_t *signer_cert)
 {
        chunk_t attributes;
 
index e044f0b..f64c6b1 100644 (file)
@@ -23,6 +23,8 @@
 #ifndef _SCEP_H
 #define _SCEP_H
 
+#include <credentials/certificates/certificate.h>
+
 #include "../pluto/defs.h"
 #include "../pluto/pkcs7.h"
 
@@ -81,13 +83,13 @@ extern chunk_t scep_transId_attribute(chunk_t transaction_id);
 extern chunk_t scep_messageType_attribute(scep_msg_t m);
 extern chunk_t scep_senderNonce_attribute(void);
 extern chunk_t scep_build_request(chunk_t data, chunk_t transID, scep_msg_t msg,
-                                                                 const x509cert_t *enc_cert, int enc_alg,
-                                                                 const x509cert_t *signer_cert, int digest_alg,
+                                                                 certificate_t *enc_cert, int enc_alg,
+                                                                 certificate_t *signer_cert, int digest_alg,
                                                                  private_key_t *private_key);
 extern bool scep_http_request(const char *url, chunk_t pkcs7, scep_op_t op,
                                                          bool http_get_request, chunk_t *response);
 extern err_t scep_parse_response(chunk_t response, chunk_t transID,
                                                                 contentInfo_t *data, scep_attributes_t *attrs,
-                                                                x509cert_t *signer_cert);
+                                                                certificate_t *signer_cert);
 
 #endif /* _SCEP_H */
index 34b9854..91f89cc 100644 (file)
 #include <asn1/oid.h>
 #include <utils/optionsfrom.h>
 #include <utils/enumerator.h>
+#include <utils/linked_list.h>
+#include <crypto/hashers/hasher.h>
 #include <crypto/crypters/crypter.h>
 #include <crypto/proposal/proposal_keywords.h>
 #include <credentials/keys/private_key.h>
 #include <credentials/keys/public_key.h>
+#include <credentials/certificates/certificate.h>
+#include <credentials/certificates/x509.h>
+#include <credentials/certificates/pkcs10.h>
 
 #include "../pluto/constants.h"
 #include "../pluto/defs.h"
@@ -52,7 +57,6 @@
 #include "../pluto/pkcs7.h"
 #include "../pluto/certs.h"
 
-#include "pkcs10.h"
 #include "scep.h"
 
 /*
@@ -121,26 +125,27 @@ options_t *options;
  * Global variables
  */
 
-private_key_t *private_key = NULL;
-public_key_t *public_key = NULL;
-
 chunk_t pkcs1;
 chunk_t pkcs7;
-chunk_t subject;
 chunk_t challengePassword;
 chunk_t serialNumber;
 chunk_t transID;
 chunk_t fingerprint;
+chunk_t encoding;
+chunk_t pkcs10_encoding;
 chunk_t issuerAndSubject;
 chunk_t getCertInitial;
 chunk_t scep_response;
-cert_t cert;
 
-x509cert_t *x509_signer        = NULL;
-x509cert_t *x509_ca_enc        = NULL;
-x509cert_t *x509_ca_sig        = NULL;
-generalName_t *subjectAltNames = NULL;
-pkcs10_t *pkcs10               = NULL;
+linked_list_t *subjectAltNames;
+
+identification_t *subject      = NULL;
+private_key_t *private_key     = NULL;
+public_key_t *public_key       = NULL;
+certificate_t *x509_signer     = NULL;
+certificate_t *x509_ca_enc     = NULL;
+certificate_t *x509_ca_sig     = NULL;
+certificate_t *pkcs10_req      = NULL;
 
 /**
  * @brief exit scepclient
@@ -152,27 +157,25 @@ exit_scepclient(err_t message, ...)
 {
        int status = 0;
 
+       DESTROY_IF(subject);
        DESTROY_IF(private_key);
        DESTROY_IF(public_key);
+       DESTROY_IF(x509_signer);
+       DESTROY_IF(x509_ca_enc);
+       DESTROY_IF(x509_ca_sig);
+       DESTROY_IF(pkcs10_req);
+       subjectAltNames->destroy_offset(subjectAltNames,
+                                                                  offsetof(identification_t, destroy));
        free(pkcs1.ptr);
        free(pkcs7.ptr);
-       free(subject.ptr);
        free(serialNumber.ptr);
        free(transID.ptr);
        free(fingerprint.ptr);
+       free(encoding.ptr);
+       free(pkcs10_encoding.ptr);
        free(issuerAndSubject.ptr);
        free(getCertInitial.ptr);
        free(scep_response.ptr);
-
-       free_generalNames(subjectAltNames, TRUE);
-       if (x509_signer != NULL)
-       {
-               x509_signer->subjectAltName = NULL;
-       }
-       free_x509cert(x509_signer);
-       free_x509cert(x509_ca_enc);
-       free_x509cert(x509_ca_sig);
-       pkcs10_free(pkcs10);
        options->destroy(options);
 
        /* print any error message to stderr */
@@ -357,8 +360,8 @@ int main(int argc, char **argv)
        /* digest algorithm used by pkcs7, default is SHA-1 */
        int pkcs7_digest_alg = OID_SHA1;
 
-       /* signature algorithm used by pkcs10, default is SHA-1 with RSA encryption */
-       int pkcs10_signature_alg = OID_SHA1;
+       /* signature algorithm used by pkcs10, default is SHA-1 */
+       hash_algorithm_t pkcs10_signature_alg = HASH_SHA1;
 
        /* URL of the SCEP-Server */
        char *scep_url = NULL;
@@ -374,18 +377,6 @@ int main(int argc, char **argv)
 
        err_t ugh = NULL;
 
-       /* initialize global variables */
-       pkcs1             = chunk_empty;
-       pkcs7             = chunk_empty;
-       serialNumber      = chunk_empty;
-       transID           = chunk_empty;
-       fingerprint       = chunk_empty;
-       issuerAndSubject  = chunk_empty;
-       challengePassword = chunk_empty;
-       getCertInitial    = chunk_empty;
-       scep_response     = chunk_empty;
-       log_to_stderr     = TRUE;
-
        /* initialize library */
        if (!library_init(NULL))
        {
@@ -400,8 +391,21 @@ int main(int argc, char **argv)
                exit(SS_RC_DAEMON_INTEGRITY);
        }
 
-       /* initialize optionsfrom */
-       options = options_create();
+       /* initialize global variables */
+       pkcs1             = chunk_empty;
+       pkcs7             = chunk_empty;
+       serialNumber      = chunk_empty;
+       transID           = chunk_empty;
+       fingerprint       = chunk_empty;
+       encoding          = chunk_empty;
+       pkcs10_encoding   = chunk_empty; 
+       issuerAndSubject  = chunk_empty;
+       challengePassword = chunk_empty;
+       getCertInitial    = chunk_empty;
+       scep_response     = chunk_empty;
+       subjectAltNames   = linked_list_create();
+       options           = options_create();
+       log_to_stderr     = TRUE;
 
        for (;;)
        {
@@ -614,7 +618,6 @@ int main(int argc, char **argv)
 
                case 's':       /* --subjectAltName */
                        {
-                               generalNames_t kind;
                                char *value = strstr(optarg, "=");
 
                                if (value)
@@ -625,25 +628,19 @@ int main(int argc, char **argv)
                                        value++;
                                }
 
-                               if (strcaseeq("email", optarg))
-                               {
-                                       kind = GN_RFC822_NAME;
-                               }
-                               else if (strcaseeq("dns", optarg))
-                               {
-                                       kind = GN_DNS_NAME;
-                               }
-                               else if (strcaseeq("ip", optarg))
+                               if (strcaseeq("email", optarg) ||
+                                       strcaseeq("dns", optarg)   ||
+                                       strcaseeq("ip", optarg))
                                {
-                                       kind = GN_IP_ADDRESS;
+                                       subjectAltNames->insert_last(subjectAltNames,
+                                                                identification_create_from_string(value));
+                                       continue;
                                }
                                else
                                {
                                        usage("invalid --subjectAltName type");
                                        continue;
                                }
-                               pkcs10_add_subjectAltName(&subjectAltNames, kind, value);
-                               continue;
                        }
 
                case 'p':       /* --password */
@@ -831,11 +828,6 @@ int main(int argc, char **argv)
        }
        else
        {
-               char buf[IDTOA_BUF];
-               chunk_t dn = chunk_empty;
-
-               dn.ptr = buf;
-
                if (distinguishedName == NULL)
                {
                        char buf[BUF_LEN];
@@ -853,21 +845,29 @@ int main(int argc, char **argv)
                DBG(DBG_CONTROL,
                        DBG_log("dn: '%s'", distinguishedName);
                )
-               ugh = atodn(distinguishedName, &dn);
-               if (ugh != NULL)
+               subject = identification_create_from_string(distinguishedName);
+               if (subject->get_type(subject) != ID_DER_ASN1_DN)
                {
-                       exit_scepclient(ugh);
+                       exit_scepclient("parsing of distinguished name failed");
                }
 
-               subject = chunk_clone(dn);
-
                DBG(DBG_CONTROL,
                        DBG_log("building pkcs10 object:")
                )
-               pkcs10 = pkcs10_build(private_key, public_key, subject,
-                                                         challengePassword, subjectAltNames,
-                                                         pkcs10_signature_alg);
-               fingerprint = scep_generate_pkcs10_fingerprint(pkcs10->request);
+               pkcs10_req = lib->creds->create(lib->creds, CRED_CERTIFICATE,
+                                               CERT_PKCS10_REQUEST,
+                                               BUILD_SIGNING_KEY, private_key,
+                                               BUILD_SUBJECT, subject,
+                                               BUILD_SUBJECT_ALTNAMES, subjectAltNames,
+                                               BUILD_PASSPHRASE, challengePassword,
+                                               BUILD_DIGEST_ALG, pkcs10_signature_alg,
+                                               BUILD_END);
+               if (!pkcs10_req)
+               {
+                       exit_scepclient("generating pkcs10 request failed");
+               }
+               pkcs10_encoding = pkcs10_req->get_encoding(pkcs10_req);
+               fingerprint = scep_generate_pkcs10_fingerprint(pkcs10_encoding);
                plog("  fingerprint:    %s", fingerprint.ptr);
        }
 
@@ -878,9 +878,10 @@ int main(int argc, char **argv)
        {
                char *path = concatenate_paths(REQ_PATH, file_out_pkcs10);
 
-               if (!chunk_write(pkcs10->request, path, "pkcs10",  0022, force))
+               if (!chunk_write(pkcs10_encoding, path, "pkcs10",  0022, force))
+               {
                        exit_scepclient("could not write pkcs10 file '%s'", path);
-
+               }
                filetype_out &= ~PKCS10;   /* delete PKCS10 flag */
        }
 
@@ -901,8 +902,9 @@ int main(int argc, char **argv)
                )
                if (!private_key->get_encoding(private_key, KEY_PRIV_ASN1_DER, &pkcs1) ||
                        !chunk_write(pkcs1, path, "pkcs1", 0066, force))
+               {
                        exit_scepclient("could not write pkcs1 file '%s'", path);
-
+               }
                filetype_out &= ~PKCS1;   /* delete PKCS1 flag */
        }
 
@@ -914,19 +916,23 @@ int main(int argc, char **argv)
        scep_generate_transaction_id(public_key, &transID, &serialNumber);
        plog("  transaction ID: %.*s", (int)transID.len, transID.ptr);
 
+       notBefore = notBefore ? notBefore : time(NULL);
+       notAfter  = notAfter  ? notAfter  : (notBefore + validity);
+
        /* generate a self-signed X.509 certificate */
-       x509_signer = malloc_thing(x509cert_t);
-       *x509_signer = empty_x509cert;
-       x509_signer->serialNumber = serialNumber;
-       x509_signer->sigAlg = OID_SHA1_WITH_RSA;
-       x509_signer->issuer = subject;
-       x509_signer->notBefore = (notBefore)? notBefore
-                                                                               : time(NULL);
-       x509_signer->notAfter = (notAfter)? notAfter
-                                                                         : x509_signer->notBefore + validity;
-       x509_signer->subject = subject;
-       x509_signer->subjectAltName = subjectAltNames;
-       build_x509cert(x509_signer, public_key, private_key);
+       x509_signer = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
+                                               BUILD_SIGNING_KEY, private_key,
+                                               BUILD_PUBLIC_KEY, public_key,
+                                               BUILD_SUBJECT, subject,
+                                               BUILD_NOT_BEFORE_TIME, notBefore,
+                                               BUILD_NOT_AFTER_TIME, notAfter,
+                                               BUILD_SERIAL, serialNumber,
+                                               BUILD_SUBJECT_ALTNAMES, subjectAltNames,
+                                               BUILD_END);
+       if (!x509_signer)
+       {
+               exit_scepclient("generating certificate failed");
+       }
 
        /*
         * output of self-signed X.509 certificate file
@@ -935,9 +941,16 @@ int main(int argc, char **argv)
        {
                char *path = concatenate_paths(HOST_CERT_PATH, file_out_cert_self);
 
-               if (!chunk_write(x509_signer->certificate, path, "self-signed cert", 0022, force))
+               encoding = x509_signer->get_encoding(x509_signer);
+               if (!encoding.ptr)
+               {
+                       exit_scepclient("encoding certificate failed");
+               }
+               if (!chunk_write(encoding, path, "self-signed cert", 0022, force))
+               {
                        exit_scepclient("could not write self-signed cert file '%s'", path);
-;
+               }
+               chunk_free(&encoding);
                filetype_out &= ~CERT_SELF;   /* delete CERT_SELF flag */
        }
 
@@ -951,13 +964,13 @@ int main(int argc, char **argv)
         */
        {
                char *path = concatenate_paths(CA_CERT_PATH, file_in_cacert_enc);
-               cert_t cert;
-
-               if (!load_cert(path, "encryption cacert", &cert))
+       
+               x509_ca_enc = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
+                                                                                BUILD_FROM_FILE, path, BUILD_END);
+               if (!x509_ca_enc)
                {
                        exit_scepclient("could not load encryption cacert file '%s'", path);
                }
-               x509_ca_enc = cert.u.x509;
        }
 
        /*
@@ -978,10 +991,10 @@ int main(int argc, char **argv)
                DBG(DBG_CONTROL,
                        DBG_log("building pkcs7 request")
                )
-               pkcs7 = scep_build_request(pkcs10->request
-                                       , transID, SCEP_PKCSReq_MSG
-                                       , x509_ca_enc, pkcs7_symmetric_cipher
-                                       , x509_signer, pkcs7_digest_alg, private_key);
+               pkcs7 = scep_build_request(pkcs10_encoding,
+                                               transID, SCEP_PKCSReq_MSG,
+                                               x509_ca_enc, pkcs7_symmetric_cipher,
+                                               x509_signer, pkcs7_digest_alg, private_key);
        }
 
        /*
@@ -1008,7 +1021,6 @@ int main(int argc, char **argv)
        if (filetype_out & CERT)
        {
                char *path = concatenate_paths(CA_CERT_PATH, file_in_cacert_sig);
-               cert_t cert;
                time_t poll_start = 0;
 
                x509cert_t       *certs         = NULL;
@@ -1017,9 +1029,12 @@ int main(int argc, char **argv)
                contentInfo_t     data          = empty_contentInfo;
                scep_attributes_t attrs         = empty_scep_attributes;
 
-               if (!load_cert(path, "signature cacert", &cert))
+               x509_ca_sig = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
+                                                                                BUILD_FROM_FILE, path, BUILD_END);
+               if (!x509_ca_sig)
+               {
                        exit_scepclient("could not load signature cacert file '%s'", path);
-               x509_ca_sig = cert.u.x509;
+               }
 
                if (!scep_http_request(scep_url, pkcs7, SCEP_PKI_OPERATION,
                        http_get_request, &scep_response))
@@ -1036,12 +1051,14 @@ int main(int argc, char **argv)
                /* in case of manual mode, we are going into a polling loop */
                if (attrs.pkiStatus == SCEP_PENDING)
                {
+                       identification_t *issuer = x509_ca_sig->get_subject(x509_ca_sig);
+
                        plog("  scep request pending, polling every %d seconds"
                                , poll_interval);
                        poll_start = time_monotonic(NULL);
-                       issuerAndSubject = asn1_wrap(ASN1_SEQUENCE, "cc"
-                                                                  , x509_ca_sig->subject
-                                                                  , subject);
+                       issuerAndSubject = asn1_wrap(ASN1_SEQUENCE, "cc",
+                                                                       issuer->get_encoding(issuer),
+                                                                       subject);
                }
                while (attrs.pkiStatus == SCEP_PENDING)
                {
@@ -1110,13 +1127,20 @@ int main(int argc, char **argv)
                {
                        bool stored = FALSE;
                        x509cert_t *cert = certs;
+                       x509_t *x509 = (x509_t*)cert->cert;
 
-                       if (!cert->isCA)
+                       if (!(x509->get_flags(x509) & X509_CA))
                        {
                                if (stored)
+                               {
                                        exit_scepclient("multiple certs received, only first stored");
-                               if (!chunk_write(cert->certificate, path, "requested cert", 0022, force))
+                               }
+                               encoding = cert->cert->get_encoding(cert->cert);
+                               if (!chunk_write(encoding, path, "requested cert", 0022, force))
+                               {
                                        exit_scepclient("could not write cert file '%s'", path);
+                               }
+                               chunk_free(&encoding);
                                stored = TRUE;
                        }
                        certs = certs->next;