diff options
author | Martin Willi <martin@revosec.ch> | 2012-06-11 14:52:37 +0200 |
---|---|---|
committer | Martin Willi <martin@revosec.ch> | 2012-06-12 14:24:49 +0200 |
commit | fd4ff118586ca4cad4dc1cfe15a42857897fa5e0 (patch) | |
tree | 9294d3270f3ecb6015d9d5488575a493f55f7205 /src | |
parent | a37f2d2006e74bce8614ebf13b45c7a7e9851f83 (diff) | |
download | strongswan-fd4ff118586ca4cad4dc1cfe15a42857897fa5e0.tar.bz2 strongswan-fd4ff118586ca4cad4dc1cfe15a42857897fa5e0.tar.xz |
Add signature schemes to auth_cfg during trustchain validation
Diffstat (limited to 'src')
5 files changed, 45 insertions, 19 deletions
diff --git a/src/libstrongswan/credentials/credential_manager.c b/src/libstrongswan/credentials/credential_manager.c index d54359ebf..8704cd2bb 100644 --- a/src/libstrongswan/credentials/credential_manager.c +++ b/src/libstrongswan/credentials/credential_manager.c @@ -569,7 +569,8 @@ static certificate_t *get_pretrusted_cert(private_credential_manager_t *this, * Get the issuing certificate of a subject certificate */ static certificate_t *get_issuer_cert(private_credential_manager_t *this, - certificate_t *subject, bool trusted) + certificate_t *subject, bool trusted, + signature_scheme_t *scheme) { enumerator_t *enumerator; certificate_t *issuer = NULL, *candidate; @@ -578,7 +579,7 @@ static certificate_t *get_issuer_cert(private_credential_manager_t *this, subject->get_issuer(subject), trusted); while (enumerator->enumerate(enumerator, &candidate)) { - if (this->cache->issued_by(this->cache, subject, candidate)) + if (this->cache->issued_by(this->cache, subject, candidate, scheme)) { issuer = candidate->get_ref(candidate); break; @@ -628,6 +629,7 @@ static bool verify_trust_chain(private_credential_manager_t *this, { certificate_t *current, *issuer; auth_cfg_t *auth; + signature_scheme_t scheme; int pathlen; auth = auth_cfg_create(); @@ -637,11 +639,11 @@ static bool verify_trust_chain(private_credential_manager_t *this, for (pathlen = 0; pathlen <= MAX_TRUST_PATH_LEN; pathlen++) { - issuer = get_issuer_cert(this, current, TRUE); + issuer = get_issuer_cert(this, current, TRUE, &scheme); if (issuer) { /* accept only self-signed CAs as trust anchor */ - if (this->cache->issued_by(this->cache, issuer, issuer)) + if (this->cache->issued_by(this->cache, issuer, issuer, NULL)) { auth->add(auth, AUTH_RULE_CA_CERT, issuer->get_ref(issuer)); DBG1(DBG_CFG, " using trusted ca certificate \"%Y\"", @@ -654,10 +656,11 @@ static bool verify_trust_chain(private_credential_manager_t *this, DBG1(DBG_CFG, " using trusted intermediate ca certificate " "\"%Y\"", issuer->get_subject(issuer)); } + auth->add(auth, AUTH_RULE_SIGNATURE_SCHEME, scheme); } else { - issuer = get_issuer_cert(this, current, FALSE); + issuer = get_issuer_cert(this, current, FALSE, &scheme); if (issuer) { if (current->equals(current, issuer)) @@ -670,6 +673,7 @@ static bool verify_trust_chain(private_credential_manager_t *this, auth->add(auth, AUTH_RULE_IM_CERT, issuer->get_ref(issuer)); DBG1(DBG_CFG, " using untrusted intermediate certificate " "\"%Y\"", issuer->get_subject(issuer)); + auth->add(auth, AUTH_RULE_SIGNATURE_SCHEME, scheme); } else { @@ -764,7 +768,7 @@ METHOD(enumerator_t, trusted_enumerate, bool, * However, in order to fulfill authorization rules, we try to build * the trust chain if it is not self signed */ if (this->this->cache->issued_by(this->this->cache, - this->pretrusted, this->pretrusted) || + this->pretrusted, this->pretrusted, NULL) || verify_trust_chain(this->this, this->pretrusted, this->auth, TRUE, this->online)) { @@ -972,7 +976,7 @@ static auth_cfg_t *build_trustchain(private_credential_manager_t *this, else { if (!has_anchor && - this->cache->issued_by(this->cache, current, current)) + this->cache->issued_by(this->cache, current, current, NULL)) { /* If no trust anchor specified, accept any CA */ trustchain->add(trustchain, AUTH_RULE_CA_CERT, current); return trustchain; @@ -983,7 +987,7 @@ static auth_cfg_t *build_trustchain(private_credential_manager_t *this, { break; } - issuer = get_issuer_cert(this, current, FALSE); + issuer = get_issuer_cert(this, current, FALSE, NULL); if (!issuer) { if (!has_anchor) @@ -1116,9 +1120,9 @@ METHOD(credential_manager_t, flush_cache, void, METHOD(credential_manager_t, issued_by, bool, private_credential_manager_t *this, certificate_t *subject, - certificate_t *issuer) + certificate_t *issuer, signature_scheme_t *scheme) { - return this->cache->issued_by(this->cache, subject, issuer); + return this->cache->issued_by(this->cache, subject, issuer, scheme); } METHOD(credential_manager_t, add_set, void, diff --git a/src/libstrongswan/credentials/credential_manager.h b/src/libstrongswan/credentials/credential_manager.h index ad789c718..d9a47b7d7 100644 --- a/src/libstrongswan/credentials/credential_manager.h +++ b/src/libstrongswan/credentials/credential_manager.h @@ -204,10 +204,12 @@ struct credential_manager_t { * * @param subject subject certificate to check * @param issuer issuer certificate that potentially has signed subject + * @param scheme receives used signature scheme, if given * @return TRUE if issuer signed subject */ bool (*issued_by)(credential_manager_t *this, - certificate_t *subject, certificate_t *issuer); + certificate_t *subject, certificate_t *issuer, + signature_scheme_t *scheme); /** * Register a credential set to the manager. diff --git a/src/libstrongswan/credentials/sets/cert_cache.c b/src/libstrongswan/credentials/sets/cert_cache.c index 24007baa1..a7d0ed8f9 100644 --- a/src/libstrongswan/credentials/sets/cert_cache.c +++ b/src/libstrongswan/credentials/sets/cert_cache.c @@ -47,6 +47,11 @@ struct relation_t { certificate_t *issuer; /** + * Signature scheme used to sign this relation + */ + signature_scheme_t scheme; + + /** * Cache hits */ u_int hits; @@ -77,7 +82,8 @@ struct private_cert_cache_t { * Cache relation in a free slot/replace an other */ static void cache(private_cert_cache_t *this, - certificate_t *subject, certificate_t *issuer) + certificate_t *subject, certificate_t *issuer, + signature_scheme_t scheme) { relation_t *rel; int i, offset, try; @@ -95,6 +101,7 @@ static void cache(private_cert_cache_t *this, { rel->subject = subject->get_ref(subject); rel->issuer = issuer->get_ref(issuer); + rel->scheme = scheme; return rel->lock->unlock(rel->lock); } rel->lock->unlock(rel->lock); @@ -123,6 +130,7 @@ static void cache(private_cert_cache_t *this, } rel->subject = subject->get_ref(subject); rel->issuer = issuer->get_ref(issuer); + rel->scheme = scheme; rel->hits = 0; return rel->lock->unlock(rel->lock); } @@ -133,9 +141,11 @@ static void cache(private_cert_cache_t *this, } METHOD(cert_cache_t, issued_by, bool, - private_cert_cache_t *this, certificate_t *subject, certificate_t *issuer) + private_cert_cache_t *this, certificate_t *subject, certificate_t *issuer, + signature_scheme_t *schemep) { relation_t *found = NULL, *current; + signature_scheme_t scheme; int i; for (i = 0; i < CACHE_SIZE; i++) @@ -154,7 +164,11 @@ METHOD(cert_cache_t, issued_by, bool, { /* write hit counter is not locked, but not critical */ current->hits++; - found = current; + found = current;; + if (schemep) + { + *schemep = current->scheme; + } } } } @@ -165,9 +179,13 @@ METHOD(cert_cache_t, issued_by, bool, } } /* no cache hit, check and cache signature */ - if (subject->issued_by(subject, issuer, NULL)) + if (subject->issued_by(subject, issuer, &scheme)) { - cache(this, subject, issuer); + cache(this, subject, issuer, scheme); + if (schemep) + { + *schemep = scheme; + } return TRUE; } return FALSE; diff --git a/src/libstrongswan/credentials/sets/cert_cache.h b/src/libstrongswan/credentials/sets/cert_cache.h index d2721866e..2bcdbe464 100644 --- a/src/libstrongswan/credentials/sets/cert_cache.h +++ b/src/libstrongswan/credentials/sets/cert_cache.h @@ -45,10 +45,12 @@ struct cert_cache_t { * * @param subject certificate to verify * @param issuer issuing certificate to verify subject + * @param scheme receives used signature scheme, if given * @return TRUE if subject issued by issuer */ bool (*issued_by)(cert_cache_t *this, - certificate_t *subject, certificate_t *issuer); + certificate_t *subject, certificate_t *issuer, + signature_scheme_t *scheme); /** * Flush the certificate cache. diff --git a/src/libstrongswan/plugins/revocation/revocation_validator.c b/src/libstrongswan/plugins/revocation/revocation_validator.c index ff3ef14d8..dc8e454e7 100644 --- a/src/libstrongswan/plugins/revocation/revocation_validator.c +++ b/src/libstrongswan/plugins/revocation/revocation_validator.c @@ -111,7 +111,7 @@ static bool verify_ocsp(ocsp_response_t *response, auth_cfg_t *auth) KEY_ANY, responder, FALSE); while (enumerator->enumerate(enumerator, &issuer, ¤t)) { - if (lib->credmgr->issued_by(lib->credmgr, subject, issuer)) + if (lib->credmgr->issued_by(lib->credmgr, subject, issuer, NULL)) { DBG1(DBG_CFG, " ocsp response correctly signed by \"%Y\"", issuer->get_subject(issuer)); @@ -341,7 +341,7 @@ static bool verify_crl(certificate_t *crl, auth_cfg_t *auth) KEY_ANY, crl->get_issuer(crl), FALSE); while (enumerator->enumerate(enumerator, &issuer, ¤t)) { - if (lib->credmgr->issued_by(lib->credmgr, crl, issuer)) + if (lib->credmgr->issued_by(lib->credmgr, crl, issuer, NULL)) { DBG1(DBG_CFG, " crl correctly signed by \"%Y\"", issuer->get_subject(issuer)); |