Use certificate CRLIssuer information to look up cacched CRLs or CDPs
This commit is contained in:
parent
630d58724a
commit
7d7beaa1fa
|
@ -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;
|
||||
|
@ -410,6 +410,62 @@ static certificate_t *get_better_crl(certificate_t *cand, certificate_t *best,
|
|||
return best;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find or fetch a certificate for a given crlIssuer
|
||||
*/
|
||||
static cert_validation_t find_crl(x509_t *subject, identification_t *issuer,
|
||||
certificate_t **best, bool *uri_found)
|
||||
{
|
||||
cert_validation_t valid = VALIDATION_SKIPPED;
|
||||
enumerator_t *enumerator;
|
||||
certificate_t *current;
|
||||
char *uri;
|
||||
|
||||
/* find a cached crl */
|
||||
enumerator = lib->credmgr->create_cert_enumerator(lib->credmgr,
|
||||
CERT_X509_CRL, KEY_ANY, issuer, FALSE);
|
||||
while (enumerator->enumerate(enumerator, ¤t))
|
||||
{
|
||||
current->get_ref(current);
|
||||
*best = get_better_crl(current, *best, subject, &valid, FALSE);
|
||||
if (*best && valid != VALIDATION_STALE)
|
||||
{
|
||||
DBG1(DBG_CFG, " using cached crl");
|
||||
break;
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
/* 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))
|
||||
{
|
||||
*uri_found = TRUE;
|
||||
current = fetch_crl(uri);
|
||||
if (!current->has_issuer(current, issuer))
|
||||
{
|
||||
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)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
}
|
||||
return valid;
|
||||
}
|
||||
|
||||
/**
|
||||
* validate a x509 certificate using CRL
|
||||
*/
|
||||
|
@ -417,72 +473,54 @@ static cert_validation_t check_crl(x509_t *subject, x509_t *issuer,
|
|||
auth_cfg_t *auth)
|
||||
{
|
||||
cert_validation_t valid = VALIDATION_SKIPPED;
|
||||
identification_t *keyid = NULL;
|
||||
identification_t *id;
|
||||
certificate_t *best = NULL;
|
||||
bool uri_found = FALSE;
|
||||
certificate_t *current;
|
||||
public_key_t *public;
|
||||
enumerator_t *enumerator;
|
||||
chunk_t chunk;
|
||||
char *uri = NULL;
|
||||
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))
|
||||
/* use issuers subjectKeyIdentifier to find a cached CRL / fetch from CDP */
|
||||
chunk = issuer->get_subjectKeyIdentifier(issuer);
|
||||
if (chunk.len)
|
||||
{
|
||||
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, issuer,
|
||||
&valid, FALSE);
|
||||
if (best && valid != VALIDATION_STALE)
|
||||
{
|
||||
DBG1(DBG_CFG, " using cached crl");
|
||||
break;
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
/* 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, keyid);
|
||||
while (enumerator->enumerate(enumerator, &uri))
|
||||
{
|
||||
current = fetch_crl(uri);
|
||||
if (current)
|
||||
{
|
||||
best = get_better_crl(current, best, subject, issuer,
|
||||
&valid, TRUE);
|
||||
if (best && valid != VALIDATION_STALE)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
}
|
||||
keyid->destroy(keyid);
|
||||
id = identification_create_from_encoding(ID_KEY_ID, chunk);
|
||||
valid = find_crl(subject, id, &best, &uri_found);
|
||||
id->destroy(id);
|
||||
}
|
||||
DESTROY_IF(public);
|
||||
|
||||
/* fallback to fetching crls from cdps from subject's certificate */
|
||||
/* 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 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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue