updated charon to new fingerprinting API

This commit is contained in:
Martin Willi 2009-08-24 14:20:29 +02:00
parent b4b68b64b8
commit 64fdbce4da
3 changed files with 85 additions and 91 deletions

View File

@ -630,6 +630,7 @@ static cert_validation_t check_ocsp(private_credential_manager_t *this,
certificate_t *best = NULL, *current; certificate_t *best = NULL, *current;
identification_t *keyid = NULL; identification_t *keyid = NULL;
public_key_t *public; public_key_t *public;
chunk_t chunk;
char *uri = NULL; char *uri = NULL;
/** lookup cache for valid OCSP responses */ /** lookup cache for valid OCSP responses */
@ -651,9 +652,9 @@ static cert_validation_t check_ocsp(private_credential_manager_t *this,
/* derive the authorityKeyIdentifier from the issuer's public key */ /* derive the authorityKeyIdentifier from the issuer's public key */
current = &issuer->interface; current = &issuer->interface;
public = current->get_public_key(current); 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 */ /** fetch from configured OCSP responder URLs */
if (keyid && valid != VALIDATION_GOOD && valid != VALIDATION_REVOKED) 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); enumerator->destroy(enumerator);
} }
DESTROY_IF(public); DESTROY_IF(public);
DESTROY_IF(keyid);
/* fallback to URL fetching from subject certificate's URIs */ /* fallback to URL fetching from subject certificate's URIs */
if (valid != VALIDATION_GOOD && valid != VALIDATION_REVOKED) 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; certificate_t *current;
public_key_t *public; public_key_t *public;
enumerator_t *enumerator; enumerator_t *enumerator;
chunk_t chunk;
char *uri = NULL; char *uri = NULL;
/* derive the authorityKeyIdentifier from the issuer's public key */ /* derive the authorityKeyIdentifier from the issuer's public key */
current = &issuer->interface; current = &issuer->interface;
public = current->get_public_key(current); 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);
}
/* find a cached crl by authorityKeyIdentifier */ /* find a cached crl by authorityKeyIdentifier */
if (keyid)
{
enumerator = create_cert_enumerator(this, CERT_X509_CRL, KEY_ANY, enumerator = create_cert_enumerator(this, CERT_X509_CRL, KEY_ANY,
keyid, FALSE); keyid, FALSE);
while (enumerator->enumerate(enumerator, &current)) while (enumerator->enumerate(enumerator, &current))
@ -871,10 +871,9 @@ static cert_validation_t check_crl(private_credential_manager_t *this,
} }
} }
enumerator->destroy(enumerator); enumerator->destroy(enumerator);
}
/* fallback to fetching crls from credential sets cdps */ /* fallback to fetching crls from credential sets cdps */
if (keyid && valid != VALIDATION_GOOD && valid != VALIDATION_REVOKED) if (valid != VALIDATION_GOOD && valid != VALIDATION_REVOKED)
{ {
enumerator = create_cdp_enumerator(this, CERT_X509_CRL, keyid); enumerator = create_cdp_enumerator(this, CERT_X509_CRL, keyid);
@ -893,6 +892,8 @@ static cert_validation_t check_crl(private_credential_manager_t *this,
} }
enumerator->destroy(enumerator); enumerator->destroy(enumerator);
} }
keyid->destroy(keyid);
}
DESTROY_IF(public); DESTROY_IF(public);
/* fallback to fetching crls from cdps from subject's certificate */ /* fallback to fetching crls from cdps from subject's certificate */
@ -1425,15 +1426,17 @@ static private_key_t *get_private_by_cert(private_credential_manager_t *this,
{ {
private_key_t *private = NULL; private_key_t *private = NULL;
identification_t *keyid; identification_t *keyid;
chunk_t chunk;
public_key_t *public; public_key_t *public;
public = cert->get_public_key(cert); public = cert->get_public_key(cert);
if (public) if (public)
{ {
keyid = public->get_id(public, ID_PUBKEY_INFO_SHA1); if (public->get_fingerprint(public, KEY_ID_PUBKEY_INFO_SHA1, &chunk))
if (keyid)
{ {
keyid = identification_create_from_encoding(ID_KEY_ID, chunk);
private = get_private_by_keyid(this, type, keyid); private = get_private_by_keyid(this, type, keyid);
keyid->destroy(keyid);
} }
public->destroy(public); public->destroy(public);
} }
@ -1453,17 +1456,9 @@ static private_key_t *get_private(private_credential_manager_t *this,
auth_cfg_t *trustchain; auth_cfg_t *trustchain;
/* check if this is a lookup by key ID, and do it if so */ /* 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); return get_private_by_keyid(this, type, id);
default:
break;
}
} }
/* if a specific certificate is preferred, check for a matching key */ /* if a specific certificate is preferred, check for a matching key */

View File

@ -50,28 +50,36 @@ struct private_ike_cert_post_t {
/** /**
* Generates the cert payload, if possible with "Hash and URL" * 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;
if (this->ike_sa->supports_extension(this->ike_sa, EXT_HASH_AND_URL)) chunk_t hash, encoded ;
{
/* 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; enumerator_t *enumerator;
char *url; char *url;
hasher->allocate_hash(hasher, encoded, &hash); if (!this->ike_sa->supports_extension(this->ike_sa, EXT_HASH_AND_URL))
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 */ return cert_payload_create_from_cert(cert);
payload = cert_payload_create_from_hash_and_url(hash, url); }
hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
if (!hasher)
{
DBG1(DBG_IKE, "unable to use hash-and-url: sha1 not supported");
return cert_payload_create_from_cert(cert);
}
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); enumerator->destroy(enumerator);
@ -79,21 +87,11 @@ static cert_payload_t *build_cert_payload(private_ike_cert_post_t *this, certifi
chunk_free(&hash); chunk_free(&hash);
chunk_free(&encoded); chunk_free(&encoded);
hasher->destroy(hasher); hasher->destroy(hasher);
} if (url)
else
{ {
DBG1(DBG_IKE, "unable to use hash-and-url: sha1 not supported"); return cert_payload_create_from_hash_and_url(hash, url);
} }
} return cert_payload_create_from_cert(cert);
if (!payload)
{
/* 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);
}
return payload;
} }
/** /**

View File

@ -92,8 +92,7 @@ static void process_certreqs(private_ike_cert_pre_t *this, message_t *message)
identification_t *id; identification_t *id;
certificate_t *cert; certificate_t *cert;
id = identification_create_from_encoding( id = identification_create_from_encoding(ID_KEY_ID, keyid);
ID_PUBKEY_INFO_SHA1, keyid);
cert = charon->credentials->get_cert(charon->credentials, cert = charon->credentials->get_cert(charon->credentials,
CERT_X509, KEY_ANY, id, TRUE); CERT_X509, KEY_ANY, id, TRUE);
if (cert) if (cert)
@ -156,7 +155,7 @@ static certificate_t *try_get_cert(cert_payload_t *cert_payload)
/* invalid "Hash and URL" data (logged elsewhere) */ /* invalid "Hash and URL" data (logged elsewhere) */
break; 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 = charon->credentials->get_cert(charon->credentials,
CERT_X509, KEY_ANY, id, FALSE); CERT_X509, KEY_ANY, id, FALSE);
id->destroy(id); id->destroy(id);
@ -284,7 +283,7 @@ static void add_certreq(certreq_payload_t **req, certificate_t *cert)
case CERT_X509: case CERT_X509:
{ {
public_key_t *public; public_key_t *public;
identification_t *keyid; chunk_t keyid;
x509_t *x509 = (x509_t*)cert; x509_t *x509 = (x509_t*)cert;
if (!(x509->get_flags(x509) & X509_CA)) 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); *req = certreq_payload_create_type(CERT_X509);
} }
keyid = public->get_id(public, ID_PUBKEY_INFO_SHA1); if (public->get_fingerprint(public, KEY_ID_PUBKEY_INFO_SHA1, &keyid))
(*req)->add_keyid(*req, keyid->get_encoding(keyid)); {
public->destroy(public); (*req)->add_keyid(*req, keyid);
DBG1(DBG_IKE, "sending cert request for \"%Y\"", DBG1(DBG_IKE, "sending cert request for \"%Y\"",
cert->get_subject(cert)); cert->get_subject(cert));
}
public->destroy(public);
break; break;
} }
default: default: