Add signature schemes to auth_cfg during trustchain validation
This commit is contained in:
@@ -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, ¤t))
|
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\"",
|
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, ¤t))
|
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\"",
|
DBG1(DBG_CFG, " crl correctly signed by \"%Y\"",
|
||||||
issuer->get_subject(issuer));
|
issuer->get_subject(issuer));
|
||||||
|
|||||||
Reference in New Issue
Block a user