* 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;
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);
}
}
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)
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)
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))
}
}
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);
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);
}
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)
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))
}
}
enumerator->destroy(enumerator);
-
+
/* if no valid trustchain was found, fall back to the first usable cert */
if (!private)
{
/**
* 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);
}
/**
enumerator = message->create_payload_enumerator(message);
while (enumerator->enumerate(enumerator, &payload))
{
- switch(payload->get_type(payload))
+ switch (payload->get_type(payload))
{
case CERTIFICATE_REQUEST:
{
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)
/* 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);
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))
{
*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: