diff options
-rw-r--r-- | src/charon/credentials/credential_manager.c | 87 | ||||
-rw-r--r-- | src/charon/sa/tasks/ike_cert_post.c | 70 | ||||
-rw-r--r-- | src/charon/sa/tasks/ike_cert_pre.c | 19 |
3 files changed, 85 insertions, 91 deletions
diff --git a/src/charon/credentials/credential_manager.c b/src/charon/credentials/credential_manager.c index 0967cbc81..405424c16 100644 --- a/src/charon/credentials/credential_manager.c +++ b/src/charon/credentials/credential_manager.c @@ -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, ¤t)) @@ -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) { diff --git a/src/charon/sa/tasks/ike_cert_post.c b/src/charon/sa/tasks/ike_cert_post.c index 70e87c2e7..9967a969f 100644 --- a/src/charon/sa/tasks/ike_cert_post.c +++ b/src/charon/sa/tasks/ike_cert_post.c @@ -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); } /** diff --git a/src/charon/sa/tasks/ike_cert_pre.c b/src/charon/sa/tasks/ike_cert_pre.c index 1c72f289f..8706b58d8 100644 --- a/src/charon/sa/tasks/ike_cert_pre.c +++ b/src/charon/sa/tasks/ike_cert_pre.c @@ -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: |