updated charon to new fingerprinting API
authorMartin Willi <martin@strongswan.org>
Mon, 24 Aug 2009 12:20:29 +0000 (14:20 +0200)
committerMartin Willi <martin@strongswan.org>
Wed, 26 Aug 2009 09:23:53 +0000 (11:23 +0200)
src/charon/credentials/credential_manager.c
src/charon/sa/tasks/ike_cert_post.c
src/charon/sa/tasks/ike_cert_pre.c

index 0967cbc..405424c 100644 (file)
@@ -294,7 +294,7 @@ static enumerator_t* create_private_enumerator(
  * Implementation of credential_manager_t.get_private_by_keyid.
  */   
 static private_key_t *get_private_by_keyid(private_credential_manager_t *this,
-                                                                                  key_type_t key, identification_t *keyid)
+                                                                               key_type_t key, identification_t *keyid)
 {
        private_key_t *found = NULL;
        enumerator_t *enumerator;
@@ -630,8 +630,9 @@ static cert_validation_t check_ocsp(private_credential_manager_t *this,
        certificate_t *best = NULL, *current;
        identification_t *keyid = NULL;
        public_key_t *public;
+       chunk_t chunk;
        char *uri = NULL;
-
+       
        /** lookup cache for valid OCSP responses */
        enumerator = create_cert_enumerator(this, CERT_X509_OCSP_RESPONSE,
                                                                                KEY_ANY, NULL, FALSE);
@@ -647,13 +648,13 @@ static cert_validation_t check_ocsp(private_credential_manager_t *this,
                }
        }
        enumerator->destroy(enumerator);
-
+       
        /* derive the authorityKeyIdentifier from the issuer's public key */
        current = &issuer->interface;
        public = current->get_public_key(current);
-       if (public)
+       if (public && public->get_fingerprint(public, KEY_ID_PUBKEY_SHA1, &chunk))
        {
-               keyid = public->get_id(public, ID_PUBKEY_SHA1);
+               keyid = identification_create_from_encoding(ID_KEY_ID, chunk);
        }
        /** fetch from configured OCSP responder URLs */
        if (keyid && valid != VALIDATION_GOOD && valid != VALIDATION_REVOKED)
@@ -676,6 +677,7 @@ static cert_validation_t check_ocsp(private_credential_manager_t *this,
                enumerator->destroy(enumerator);
        }
        DESTROY_IF(public);
+       DESTROY_IF(keyid);
 
        /* fallback to URL fetching from subject certificate's URIs */
        if (valid != VALIDATION_GOOD && valid != VALIDATION_REVOKED)
@@ -844,19 +846,17 @@ static cert_validation_t check_crl(private_credential_manager_t *this,
        certificate_t *current;
        public_key_t *public;
        enumerator_t *enumerator;
+       chunk_t chunk;
        char *uri = NULL;
        
        /* derive the authorityKeyIdentifier from the issuer's public key */
        current = &issuer->interface;
        public = current->get_public_key(current);
-       if (public)
-       {
-               keyid = public->get_id(public, ID_PUBKEY_SHA1);
-       }
-       
-       /* find a cached crl by authorityKeyIdentifier */
-       if (keyid)
+       if (public && public->get_fingerprint(public, KEY_ID_PUBKEY_SHA1, &chunk))
        {
+               keyid = identification_create_from_encoding(ID_KEY_ID, chunk);
+               
+               /* find a cached crl by authorityKeyIdentifier */
                enumerator = create_cert_enumerator(this, CERT_X509_CRL, KEY_ANY, 
                                                                                        keyid, FALSE);
                while (enumerator->enumerate(enumerator, &current))
@@ -871,35 +871,36 @@ static cert_validation_t check_crl(private_credential_manager_t *this,
                        }
                }
                enumerator->destroy(enumerator);
-       }
-
-       /* fallback to fetching crls from credential sets cdps */
-       if (keyid && valid != VALIDATION_GOOD && valid != VALIDATION_REVOKED)
-       {
-               enumerator = create_cdp_enumerator(this, CERT_X509_CRL, keyid);
-
-               while (enumerator->enumerate(enumerator, &uri))
+               
+               /* fallback to fetching crls from credential sets cdps */
+               if (valid != VALIDATION_GOOD && valid != VALIDATION_REVOKED)
                {
-                       current = fetch_crl(this, uri);
-                       if (current)
+                       enumerator = create_cdp_enumerator(this, CERT_X509_CRL, keyid);
+                       
+                       while (enumerator->enumerate(enumerator, &uri))
                        {
-                               best = get_better_crl(this, current, best, subject, issuer,
-                                                                         &valid, TRUE);
-                               if (best && valid != VALIDATION_STALE)
+                               current = fetch_crl(this, uri);
+                               if (current)
                                {
-                                       break;
+                                       best = get_better_crl(this, current, best, subject, issuer,
+                                                                                 &valid, TRUE);
+                                       if (best && valid != VALIDATION_STALE)
+                                       {
+                                               break;
+                                       }
                                }
                        }
+                       enumerator->destroy(enumerator);
                }
-               enumerator->destroy(enumerator);
+               keyid->destroy(keyid);
        }
        DESTROY_IF(public);
-
+       
        /* fallback to fetching crls from cdps from subject's certificate */
        if (valid != VALIDATION_GOOD && valid != VALIDATION_REVOKED)
        {
                enumerator = subject->create_crl_uri_enumerator(subject);
-
+               
                while (enumerator->enumerate(enumerator, &uri))
                {
                        current = fetch_crl(this, uri);
@@ -1424,16 +1425,18 @@ static private_key_t *get_private_by_cert(private_credential_manager_t *this,
                                                                                  certificate_t *cert, key_type_t type)
 {
        private_key_t *private = NULL;
-       identification_t* keyid;
+       identification_t *keyid;
+       chunk_t chunk;
        public_key_t *public;
-
+       
        public = cert->get_public_key(cert);
        if (public)
        {
-               keyid = public->get_id(public, ID_PUBKEY_INFO_SHA1);
-               if (keyid)
+               if (public->get_fingerprint(public, KEY_ID_PUBKEY_INFO_SHA1, &chunk))
                {
+                       keyid = identification_create_from_encoding(ID_KEY_ID, chunk);
                        private = get_private_by_keyid(this, type, keyid);
+                       keyid->destroy(keyid);
                }
                public->destroy(public);
        }
@@ -1453,19 +1456,11 @@ static private_key_t *get_private(private_credential_manager_t *this,
        auth_cfg_t *trustchain;
        
        /* check if this is a lookup by key ID, and do it if so */
-       if (id)
+       if (id && id->get_type(id) == ID_KEY_ID)
        {
-               switch (id->get_type(id))
-               {
-                       case ID_PUBKEY_SHA1:
-                       case ID_PUBKEY_INFO_SHA1:
-                       case ID_KEY_ID:
-                               return get_private_by_keyid(this, type, id);
-                       default:
-                               break;
-               }
+               return get_private_by_keyid(this, type, id);
        }
-
+       
        /* if a specific certificate is preferred, check for a matching key */
        cert = auth->get(auth, AUTH_RULE_SUBJECT_CERT);
        if (cert)
@@ -1482,7 +1477,7 @@ static private_key_t *get_private(private_credential_manager_t *this,
                        return private;
                }
        }
-                       
+       
        /* try to build a trust chain for each certificate found */
        enumerator = create_cert_enumerator(this, CERT_ANY, type, id, FALSE);
        while (enumerator->enumerate(enumerator, &cert))
@@ -1502,7 +1497,7 @@ static private_key_t *get_private(private_credential_manager_t *this,
                }
        }
        enumerator->destroy(enumerator);
-
+       
        /* if no valid trustchain was found, fall back to the first usable cert */
        if (!private)
        {
index 70e87c2..9967a96 100644 (file)
@@ -50,50 +50,48 @@ struct private_ike_cert_post_t {
 /**
  * Generates the cert payload, if possible with "Hash and URL"
  */
-static cert_payload_t *build_cert_payload(private_ike_cert_post_t *this, certificate_t *cert)
+static cert_payload_t *build_cert_payload(private_ike_cert_post_t *this,
+                                                                                certificate_t *cert)
 {
-       cert_payload_t *payload = NULL;
+       hasher_t *hasher;
+       identification_t *id;
+       chunk_t hash, encoded ;
+       enumerator_t *enumerator;
+       char *url;
        
-       if (this->ike_sa->supports_extension(this->ike_sa, EXT_HASH_AND_URL))
+       if (!this->ike_sa->supports_extension(this->ike_sa, EXT_HASH_AND_URL))
        {
-               /* ok, our peer sent us a HTTP_CERT_LOOKUP_SUPPORTED Notify */
-               hasher_t *hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
-               if (hasher != NULL)
-               {       
-                       chunk_t hash, encoded = cert->get_encoding(cert);
-                       enumerator_t *enumerator;
-                       char *url;
-                       
-                       hasher->allocate_hash(hasher, encoded, &hash);
-                       identification_t *id = identification_create_from_encoding(ID_CERT_DER_SHA1, hash);
-                       
-                       enumerator = charon->credentials->create_cdp_enumerator(charon->credentials, CERT_X509, id);
-                       if (enumerator->enumerate(enumerator, &url))
-                       {
-                               /* if we have an URL available we send that to our peer */
-                               payload = cert_payload_create_from_hash_and_url(hash, url);
-                       }
-                       enumerator->destroy(enumerator);
-                       
-                       id->destroy(id);
-                       chunk_free(&hash);
-                       chunk_free(&encoded);
-                       hasher->destroy(hasher);
-               }
-               else
-               {
-                       DBG1(DBG_IKE, "unable to use hash-and-url: sha1 not supported");
-               }
+               return cert_payload_create_from_cert(cert);
        }
        
-       if (!payload)
+       hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
+       if (!hasher)
        {
-               /* our peer does not support "Hash and URL" or we do not have an URL
-                * to send to our peer, just create a normal cert payload */
-               payload = cert_payload_create_from_cert(cert);
+               DBG1(DBG_IKE, "unable to use hash-and-url: sha1 not supported");
+               return cert_payload_create_from_cert(cert);
        }
        
-       return payload;
+       encoded = cert->get_encoding(cert);
+       hasher->allocate_hash(hasher, encoded, &hash);
+       id = identification_create_from_encoding(ID_KEY_ID, hash);
+       
+       enumerator = charon->credentials->create_cdp_enumerator(
+                                                                               charon->credentials, CERT_X509, id);
+       if (!enumerator->enumerate(enumerator, &url))
+       {
+               url = NULL;
+       }
+       enumerator->destroy(enumerator);
+       
+       id->destroy(id);
+       chunk_free(&hash);
+       chunk_free(&encoded);
+       hasher->destroy(hasher);
+       if (url)
+       {
+               return cert_payload_create_from_hash_and_url(hash, url);
+       }
+       return cert_payload_create_from_cert(cert);
 }
 
 /**
index 1c72f28..8706b58 100644 (file)
@@ -70,7 +70,7 @@ static void process_certreqs(private_ike_cert_pre_t *this, message_t *message)
        enumerator = message->create_payload_enumerator(message);
        while (enumerator->enumerate(enumerator, &payload))
        {
-               switch(payload->get_type(payload))
+               switch (payload->get_type(payload))
                {
                        case CERTIFICATE_REQUEST:
                        {
@@ -92,8 +92,7 @@ static void process_certreqs(private_ike_cert_pre_t *this, message_t *message)
                                        identification_t *id;
                                        certificate_t *cert;
                                        
-                                       id = identification_create_from_encoding(
-                                                                                       ID_PUBKEY_INFO_SHA1, keyid);
+                                       id = identification_create_from_encoding(ID_KEY_ID, keyid);
                                        cert = charon->credentials->get_cert(charon->credentials, 
                                                                                        CERT_X509, KEY_ANY, id, TRUE);
                                        if (cert)
@@ -156,7 +155,7 @@ static certificate_t *try_get_cert(cert_payload_t *cert_payload)
                                /* invalid "Hash and URL" data (logged elsewhere) */
                                break;
                        }
-                       id = identification_create_from_encoding(ID_CERT_DER_SHA1, hash);
+                       id = identification_create_from_encoding(ID_KEY_ID, hash);
                        cert = charon->credentials->get_cert(charon->credentials, 
                                                                                                 CERT_X509, KEY_ANY, id, FALSE);
                        id->destroy(id);
@@ -284,7 +283,7 @@ static void add_certreq(certreq_payload_t **req, certificate_t *cert)
                case CERT_X509:
                {
                        public_key_t *public;
-                       identification_t *keyid;
+                       chunk_t keyid;
                        x509_t *x509 = (x509_t*)cert;
                        
                        if (!(x509->get_flags(x509) & X509_CA))
@@ -300,11 +299,13 @@ static void add_certreq(certreq_payload_t **req, certificate_t *cert)
                        {
                                *req = certreq_payload_create_type(CERT_X509);
                        }
-                       keyid = public->get_id(public, ID_PUBKEY_INFO_SHA1);
-                       (*req)->add_keyid(*req, keyid->get_encoding(keyid));
+                       if (public->get_fingerprint(public, KEY_ID_PUBKEY_INFO_SHA1, &keyid))
+                       {
+                               (*req)->add_keyid(*req, keyid);
+                               DBG1(DBG_IKE, "sending cert request for \"%Y\"",
+                                        cert->get_subject(cert));
+                       }
                        public->destroy(public);
-                       DBG1(DBG_IKE, "sending cert request for \"%Y\"",
-                                cert->get_subject(cert));
                        break;
                }
                default: