diff options
author | Martin Willi <martin@revosec.ch> | 2010-12-02 15:38:44 +0100 |
---|---|---|
committer | Martin Willi <martin@revosec.ch> | 2011-01-05 16:45:56 +0100 |
commit | 7d7beaa1fabf8d4bc4a44b9c0ab8cb431202e3d3 (patch) | |
tree | d1d5aa491840737d5e9395c3b164b8d2663d3287 /src | |
parent | 630d58724ab085305d8429da5219d351307572a6 (diff) | |
download | strongswan-7d7beaa1fabf8d4bc4a44b9c0ab8cb431202e3d3.tar.bz2 strongswan-7d7beaa1fabf8d4bc4a44b9c0ab8cb431202e3d3.tar.xz |
Use certificate CRLIssuer information to look up cacched CRLs or CDPs
Diffstat (limited to 'src')
-rw-r--r-- | src/libstrongswan/plugins/revocation/revocation_validator.c | 138 |
1 files changed, 88 insertions, 50 deletions
diff --git a/src/libstrongswan/plugins/revocation/revocation_validator.c b/src/libstrongswan/plugins/revocation/revocation_validator.c index 511a04a3e..a20f40a26 100644 --- a/src/libstrongswan/plugins/revocation/revocation_validator.c +++ b/src/libstrongswan/plugins/revocation/revocation_validator.c @@ -350,7 +350,7 @@ static bool verify_crl(certificate_t *crl) * Get the better of two CRLs, and check for usable CRL info */ static certificate_t *get_better_crl(certificate_t *cand, certificate_t *best, - x509_t *subject, x509_t *issuer, cert_validation_t *valid, bool cache) + x509_t *subject, cert_validation_t *valid, bool cache) { enumerator_t *enumerator; time_t revocation, valid_until; @@ -411,78 +411,116 @@ static certificate_t *get_better_crl(certificate_t *cand, certificate_t *best, } /** - * validate a x509 certificate using CRL + * Find or fetch a certificate for a given crlIssuer */ -static cert_validation_t check_crl(x509_t *subject, x509_t *issuer, - auth_cfg_t *auth) +static cert_validation_t find_crl(x509_t *subject, identification_t *issuer, + certificate_t **best, bool *uri_found) { cert_validation_t valid = VALIDATION_SKIPPED; - identification_t *keyid = NULL; - certificate_t *best = NULL; - certificate_t *current; - public_key_t *public; enumerator_t *enumerator; - chunk_t chunk; - char *uri = NULL; + certificate_t *current; + char *uri; - /* derive the authorityKeyIdentifier from the issuer's public key */ - current = &issuer->interface; - public = current->get_public_key(current); - if (public && public->get_fingerprint(public, KEYID_PUBKEY_SHA1, &chunk)) + /* find a cached crl */ + enumerator = lib->credmgr->create_cert_enumerator(lib->credmgr, + CERT_X509_CRL, KEY_ANY, issuer, FALSE); + while (enumerator->enumerate(enumerator, ¤t)) { - keyid = identification_create_from_encoding(ID_KEY_ID, chunk); - - /* find a cached crl by authorityKeyIdentifier */ - enumerator = lib->credmgr->create_cert_enumerator(lib->credmgr, - CERT_X509_CRL, KEY_ANY, keyid, FALSE); - while (enumerator->enumerate(enumerator, ¤t)) + current->get_ref(current); + *best = get_better_crl(current, *best, subject, &valid, FALSE); + if (*best && valid != VALIDATION_STALE) { - current->get_ref(current); - best = get_better_crl(current, best, subject, issuer, - &valid, FALSE); - if (best && valid != VALIDATION_STALE) - { - DBG1(DBG_CFG, " using cached crl"); - break; - } + DBG1(DBG_CFG, " using cached crl"); + break; } - enumerator->destroy(enumerator); + } + enumerator->destroy(enumerator); - /* fallback to fetching crls from credential sets cdps */ - if (valid != VALIDATION_GOOD && valid != VALIDATION_REVOKED) + /* fallback to fetching crls from credential sets cdps */ + if (valid != VALIDATION_GOOD && valid != VALIDATION_REVOKED) + { + enumerator = lib->credmgr->create_cdp_enumerator(lib->credmgr, + CERT_X509_CRL, issuer); + while (enumerator->enumerate(enumerator, &uri)) { - enumerator = lib->credmgr->create_cdp_enumerator(lib->credmgr, - CERT_X509_CRL, keyid); - while (enumerator->enumerate(enumerator, &uri)) + *uri_found = TRUE; + current = fetch_crl(uri); + if (!current->has_issuer(current, issuer)) { - current = fetch_crl(uri); - if (current) + DBG1(DBG_CFG, "issuer of fetched CRL '%Y' does not match CRL " + "issuer '%Y'", current->get_issuer(current), issuer); + current->destroy(current); + continue; + } + if (current) + { + *best = get_better_crl(current, *best, subject, &valid, TRUE); + if (*best && valid != VALIDATION_STALE) { - best = get_better_crl(current, best, subject, issuer, - &valid, TRUE); - if (best && valid != VALIDATION_STALE) - { - break; - } + break; } } - enumerator->destroy(enumerator); } - keyid->destroy(keyid); + enumerator->destroy(enumerator); } - DESTROY_IF(public); + return valid; +} + +/** + * validate a x509 certificate using CRL + */ +static cert_validation_t check_crl(x509_t *subject, x509_t *issuer, + auth_cfg_t *auth) +{ + cert_validation_t valid = VALIDATION_SKIPPED; + identification_t *id; + certificate_t *best = NULL; + bool uri_found = FALSE; + certificate_t *current; + enumerator_t *enumerator; + chunk_t chunk; + char *uri; + + /* use issuers subjectKeyIdentifier to find a cached CRL / fetch from CDP */ + chunk = issuer->get_subjectKeyIdentifier(issuer); + if (chunk.len) + { + id = identification_create_from_encoding(ID_KEY_ID, chunk); + valid = find_crl(subject, id, &best, &uri_found); + id->destroy(id); + } + + /* find a cached CRL or fetch via configured CDP via CRLIssuer */ + enumerator = subject->create_crl_uri_enumerator(subject); + while (valid != VALIDATION_GOOD && valid != VALIDATION_REVOKED && + enumerator->enumerate(enumerator, &uri, &id)) + { + if (id) + { + valid = find_crl(subject, id, &best, &uri_found); + } + } + enumerator->destroy(enumerator); - /* fallback to fetching crls from cdps from subject's certificate */ + /* fallback to fetching CRLs from CDPs found in subjects certificate */ if (valid != VALIDATION_GOOD && valid != VALIDATION_REVOKED) { enumerator = subject->create_crl_uri_enumerator(subject); - while (enumerator->enumerate(enumerator, &uri, NULL)) + while (enumerator->enumerate(enumerator, &uri, &id)) { + uri_found = TRUE; current = fetch_crl(uri); if (current) { - best = get_better_crl(current, best, subject, issuer, - &valid, TRUE); + if (id && !current->has_issuer(current, id)) + { + DBG1(DBG_CFG, "issuer of fetched CRL '%Y' does not match " + "certificates CRL issuer '%Y'", + current->get_issuer(current), id); + current->destroy(current); + continue; + } + best = get_better_crl(current, best, subject, &valid, TRUE); if (best && valid != VALIDATION_STALE) { break; @@ -493,7 +531,7 @@ static cert_validation_t check_crl(x509_t *subject, x509_t *issuer, } /* an uri was found, but no result. switch validation state to failed */ - if (valid == VALIDATION_SKIPPED && uri) + if (valid == VALIDATION_SKIPPED && uri_found) { valid = VALIDATION_FAILED; } |