Add signature schemes to auth_cfg during trustchain validation

This commit is contained in:
Martin Willi
2012-06-12 14:24:49 +02:00
parent a37f2d2006
commit fd4ff11858
5 changed files with 45 additions and 19 deletions
@@ -569,7 +569,8 @@ static certificate_t *get_pretrusted_cert(private_credential_manager_t *this,
* Get the issuing certificate of a subject certificate * Get the issuing certificate of a subject certificate
*/ */
static certificate_t *get_issuer_cert(private_credential_manager_t *this, 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; enumerator_t *enumerator;
certificate_t *issuer = NULL, *candidate; 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); subject->get_issuer(subject), trusted);
while (enumerator->enumerate(enumerator, &candidate)) 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); issuer = candidate->get_ref(candidate);
break; break;
@@ -628,6 +629,7 @@ static bool verify_trust_chain(private_credential_manager_t *this,
{ {
certificate_t *current, *issuer; certificate_t *current, *issuer;
auth_cfg_t *auth; auth_cfg_t *auth;
signature_scheme_t scheme;
int pathlen; int pathlen;
auth = auth_cfg_create(); 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++) 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) if (issuer)
{ {
/* accept only self-signed CAs as trust anchor */ /* 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)); auth->add(auth, AUTH_RULE_CA_CERT, issuer->get_ref(issuer));
DBG1(DBG_CFG, " using trusted ca certificate \"%Y\"", 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 " DBG1(DBG_CFG, " using trusted intermediate ca certificate "
"\"%Y\"", issuer->get_subject(issuer)); "\"%Y\"", issuer->get_subject(issuer));
} }
auth->add(auth, AUTH_RULE_SIGNATURE_SCHEME, scheme);
} }
else else
{ {
issuer = get_issuer_cert(this, current, FALSE); issuer = get_issuer_cert(this, current, FALSE, &scheme);
if (issuer) if (issuer)
{ {
if (current->equals(current, 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)); auth->add(auth, AUTH_RULE_IM_CERT, issuer->get_ref(issuer));
DBG1(DBG_CFG, " using untrusted intermediate certificate " DBG1(DBG_CFG, " using untrusted intermediate certificate "
"\"%Y\"", issuer->get_subject(issuer)); "\"%Y\"", issuer->get_subject(issuer));
auth->add(auth, AUTH_RULE_SIGNATURE_SCHEME, scheme);
} }
else else
{ {
@@ -764,7 +768,7 @@ METHOD(enumerator_t, trusted_enumerate, bool,
* However, in order to fulfill authorization rules, we try to build * However, in order to fulfill authorization rules, we try to build
* the trust chain if it is not self signed */ * the trust chain if it is not self signed */
if (this->this->cache->issued_by(this->this->cache, 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, verify_trust_chain(this->this, this->pretrusted, this->auth,
TRUE, this->online)) TRUE, this->online))
{ {
@@ -972,7 +976,7 @@ static auth_cfg_t *build_trustchain(private_credential_manager_t *this,
else else
{ {
if (!has_anchor && 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 */ { /* If no trust anchor specified, accept any CA */
trustchain->add(trustchain, AUTH_RULE_CA_CERT, current); trustchain->add(trustchain, AUTH_RULE_CA_CERT, current);
return trustchain; return trustchain;
@@ -983,7 +987,7 @@ static auth_cfg_t *build_trustchain(private_credential_manager_t *this,
{ {
break; break;
} }
issuer = get_issuer_cert(this, current, FALSE); issuer = get_issuer_cert(this, current, FALSE, NULL);
if (!issuer) if (!issuer)
{ {
if (!has_anchor) if (!has_anchor)
@@ -1116,9 +1120,9 @@ METHOD(credential_manager_t, flush_cache, void,
METHOD(credential_manager_t, issued_by, bool, METHOD(credential_manager_t, issued_by, bool,
private_credential_manager_t *this, certificate_t *subject, 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, METHOD(credential_manager_t, add_set, void,
@@ -204,10 +204,12 @@ struct credential_manager_t {
* *
* @param subject subject certificate to check * @param subject subject certificate to check
* @param issuer issuer certificate that potentially has signed subject * @param issuer issuer certificate that potentially has signed subject
* @param scheme receives used signature scheme, if given
* @return TRUE if issuer signed subject * @return TRUE if issuer signed subject
*/ */
bool (*issued_by)(credential_manager_t *this, 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. * Register a credential set to the manager.
@@ -46,6 +46,11 @@ struct relation_t {
*/ */
certificate_t *issuer; certificate_t *issuer;
/**
* Signature scheme used to sign this relation
*/
signature_scheme_t scheme;
/** /**
* Cache hits * Cache hits
*/ */
@@ -77,7 +82,8 @@ struct private_cert_cache_t {
* Cache relation in a free slot/replace an other * Cache relation in a free slot/replace an other
*/ */
static void cache(private_cert_cache_t *this, 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; relation_t *rel;
int i, offset, try; int i, offset, try;
@@ -95,6 +101,7 @@ static void cache(private_cert_cache_t *this,
{ {
rel->subject = subject->get_ref(subject); rel->subject = subject->get_ref(subject);
rel->issuer = issuer->get_ref(issuer); rel->issuer = issuer->get_ref(issuer);
rel->scheme = scheme;
return rel->lock->unlock(rel->lock); return rel->lock->unlock(rel->lock);
} }
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->subject = subject->get_ref(subject);
rel->issuer = issuer->get_ref(issuer); rel->issuer = issuer->get_ref(issuer);
rel->scheme = scheme;
rel->hits = 0; rel->hits = 0;
return rel->lock->unlock(rel->lock); 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, 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; relation_t *found = NULL, *current;
signature_scheme_t scheme;
int i; int i;
for (i = 0; i < CACHE_SIZE; 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 */ /* write hit counter is not locked, but not critical */
current->hits++; 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 */ /* 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 TRUE;
} }
return FALSE; return FALSE;
@@ -45,10 +45,12 @@ struct cert_cache_t {
* *
* @param subject certificate to verify * @param subject certificate to verify
* @param issuer issuing certificate to verify subject * @param issuer issuing certificate to verify subject
* @param scheme receives used signature scheme, if given
* @return TRUE if subject issued by issuer * @return TRUE if subject issued by issuer
*/ */
bool (*issued_by)(cert_cache_t *this, 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. * Flush the certificate cache.
@@ -111,7 +111,7 @@ static bool verify_ocsp(ocsp_response_t *response, auth_cfg_t *auth)
KEY_ANY, responder, FALSE); KEY_ANY, responder, FALSE);
while (enumerator->enumerate(enumerator, &issuer, &current)) while (enumerator->enumerate(enumerator, &issuer, &current))
{ {
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\"", DBG1(DBG_CFG, " ocsp response correctly signed by \"%Y\"",
issuer->get_subject(issuer)); 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); KEY_ANY, crl->get_issuer(crl), FALSE);
while (enumerator->enumerate(enumerator, &issuer, &current)) while (enumerator->enumerate(enumerator, &issuer, &current))
{ {
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\"", DBG1(DBG_CFG, " crl correctly signed by \"%Y\"",
issuer->get_subject(issuer)); issuer->get_subject(issuer));