From: Martin Willi Date: Tue, 19 Feb 2013 10:26:21 +0000 (+0100) Subject: Add a cert_validator hook allowing plugins to provide custom lifetime checking X-Git-Tag: 5.0.3dr3~38^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=de399f550d1bf7a84e57da52af10c8c2532403b9;p=thirdparty%2Fstrongswan.git Add a cert_validator hook allowing plugins to provide custom lifetime checking --- diff --git a/src/libstrongswan/credentials/cert_validator.h b/src/libstrongswan/credentials/cert_validator.h index effc6b0d65..325fa0af3b 100644 --- a/src/libstrongswan/credentials/cert_validator.h +++ b/src/libstrongswan/credentials/cert_validator.h @@ -34,6 +34,22 @@ typedef struct cert_validator_t cert_validator_t; */ struct cert_validator_t { + /** + * Check the lifetime of a certificate. + * + * If this function returns SUCCESS or FAILED, the certificate lifetime is + * considered definitely (in-)valid, without asking other validators. + * If all registered validaters return NEED_MORE, the default + * lifetime check is performed. + * + * @param cert certificate to check lifetime + * @param pathlen the current length of the path bottom-up + * @param anchor is certificate trusted root anchor? + * @param auth container for resulting authentication info + * @return SUCCESS, FAILED or NEED_MORE to ask next validator + */ + status_t (*check_lifetime)(cert_validator_t *this, certificate_t *cert, + int pathlen, bool anchor, auth_cfg_t *auth); /** * Validate a subject certificate in relation to its issuer. * diff --git a/src/libstrongswan/credentials/credential_manager.c b/src/libstrongswan/credentials/credential_manager.c index a427b57fb7..44eaec62c2 100644 --- a/src/libstrongswan/credentials/credential_manager.c +++ b/src/libstrongswan/credentials/credential_manager.c @@ -514,6 +514,52 @@ static void cache_queue(private_credential_manager_t *this) this->queue_mutex->unlock(this->queue_mutex); } +/** + * Use validators to check the lifetime of certificates + */ +static bool check_lifetime(private_credential_manager_t *this, + certificate_t *cert, char *label, + int pathlen, bool trusted, auth_cfg_t *auth) +{ + time_t not_before, not_after; + cert_validator_t *validator; + enumerator_t *enumerator; + status_t status = NEED_MORE; + + enumerator = this->validators->create_enumerator(this->validators); + while (enumerator->enumerate(enumerator, &validator)) + { + if (!validator->check_lifetime) + { + continue; + } + status = validator->check_lifetime(validator, cert, + pathlen, trusted, auth); + if (status != NEED_MORE) + { + break; + } + } + enumerator->destroy(enumerator); + + switch (status) + { + case NEED_MORE: + if (!cert->get_validity(cert, NULL, ¬_before, ¬_after)) + { + DBG1(DBG_CFG, "%s certificate invalid (valid from %T to %T)", + label, ¬_before, FALSE, ¬_after, FALSE); + return FALSE; + } + return TRUE; + case SUCCESS: + return TRUE; + case FAILED: + default: + return FALSE; + } +} + /** * check a certificate for its lifetime */ @@ -521,20 +567,12 @@ static bool check_certificate(private_credential_manager_t *this, certificate_t *subject, certificate_t *issuer, bool online, int pathlen, bool trusted, auth_cfg_t *auth) { - time_t not_before, not_after; cert_validator_t *validator; enumerator_t *enumerator; - if (!subject->get_validity(subject, NULL, ¬_before, ¬_after)) - { - DBG1(DBG_CFG, "subject certificate invalid (valid from %T to %T)", - ¬_before, FALSE, ¬_after, FALSE); - return FALSE; - } - if (!issuer->get_validity(issuer, NULL, ¬_before, ¬_after)) + if (!check_lifetime(this, subject, "subject", pathlen, FALSE, auth) || + !check_lifetime(this, issuer, "issuer", pathlen + 1, trusted, auth)) { - DBG1(DBG_CFG, "issuer certificate invalid (valid from %T to %T)", - ¬_before, FALSE, ¬_after, FALSE); return FALSE; }