Respect policy mappings in certificatePolicy validation
This commit is contained in:
@@ -254,53 +254,93 @@ static bool check_name_constraints(certificate_t *subject, x509_t *issuer)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if an issuer certificate has a given policy OID
|
||||||
|
*/
|
||||||
|
static bool has_policy(x509_t *issuer, chunk_t oid)
|
||||||
|
{
|
||||||
|
chunk_t any_policy = chunk_from_chars(0x55,0x1d,0x20,0x00);
|
||||||
|
x509_policy_mapping_t *mapping;
|
||||||
|
x509_cert_policy_t *policy;
|
||||||
|
enumerator_t *enumerator;
|
||||||
|
|
||||||
|
enumerator = issuer->create_cert_policy_enumerator(issuer);
|
||||||
|
while (enumerator->enumerate(enumerator, &policy))
|
||||||
|
{
|
||||||
|
if (chunk_equals(oid, policy->oid) ||
|
||||||
|
chunk_equals(any_policy, policy->oid))
|
||||||
|
{
|
||||||
|
enumerator->destroy(enumerator);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
enumerator->destroy(enumerator);
|
||||||
|
|
||||||
|
/* fall back to a mapped policy */
|
||||||
|
enumerator = issuer->create_policy_mapping_enumerator(issuer);
|
||||||
|
while (enumerator->enumerate(enumerator, &mapping))
|
||||||
|
{
|
||||||
|
if (chunk_equals(mapping->subject, oid))
|
||||||
|
{
|
||||||
|
enumerator->destroy(enumerator);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
enumerator->destroy(enumerator);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check certificatePolicies
|
* Check certificatePolicies
|
||||||
*/
|
*/
|
||||||
static bool check_policy(x509_t *subject, x509_t *issuer, auth_cfg_t *auth)
|
static bool check_policy(x509_t *subject, x509_t *issuer, auth_cfg_t *auth)
|
||||||
{
|
{
|
||||||
chunk_t any_policy = chunk_from_chars(0x55,0x1d,0x20,0x00);
|
certificate_t *cert = (certificate_t*)subject;
|
||||||
certificate_t *cert = (certificate_t*)issuer;
|
x509_policy_mapping_t *mapping;
|
||||||
enumerator_t *spols, *ipols;
|
x509_cert_policy_t *policy;
|
||||||
x509_cert_policy_t *spol, *ipol;
|
enumerator_t *enumerator;
|
||||||
bool found = TRUE;
|
|
||||||
char *oid;
|
char *oid;
|
||||||
|
|
||||||
spols = subject->create_cert_policy_enumerator(subject);
|
/* verify if policyMappings in subject are valid */
|
||||||
while (spols->enumerate(spols, &spol))
|
enumerator = subject->create_policy_mapping_enumerator(subject);
|
||||||
|
while (enumerator->enumerate(enumerator, &mapping))
|
||||||
{
|
{
|
||||||
found = FALSE;
|
if (!has_policy(issuer, mapping->issuer))
|
||||||
ipols = issuer->create_cert_policy_enumerator(issuer);
|
|
||||||
while (ipols->enumerate(ipols, &ipol))
|
|
||||||
{
|
{
|
||||||
if (chunk_equals(spol->oid, ipol->oid) ||
|
oid = asn1_oid_to_string(mapping->issuer);
|
||||||
chunk_equals(ipol->oid, any_policy))
|
DBG1(DBG_CFG, "certificate '%Y' maps policy from %s, but issuer "
|
||||||
{
|
"misses it", cert->get_subject(cert), oid);
|
||||||
found = TRUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ipols->destroy(ipols);
|
|
||||||
if (!found)
|
|
||||||
{
|
|
||||||
oid = asn1_oid_to_string(spol->oid);
|
|
||||||
DBG1(DBG_CFG, "policy %s missing in issuing certificate '%Y'",
|
|
||||||
oid, cert->get_subject(cert));
|
|
||||||
free(oid);
|
free(oid);
|
||||||
break;
|
enumerator->destroy(enumerator);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
enumerator->destroy(enumerator);
|
||||||
|
|
||||||
|
enumerator = subject->create_cert_policy_enumerator(subject);
|
||||||
|
while (enumerator->enumerate(enumerator, &policy))
|
||||||
|
{
|
||||||
|
if (!has_policy(issuer, policy->oid))
|
||||||
|
{
|
||||||
|
oid = asn1_oid_to_string(policy->oid);
|
||||||
|
DBG1(DBG_CFG, "policy %s missing in issuing certificate '%Y'",
|
||||||
|
oid, cert->get_issuer(cert));
|
||||||
|
free(oid);
|
||||||
|
enumerator->destroy(enumerator);
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (auth)
|
if (auth)
|
||||||
{
|
{
|
||||||
oid = asn1_oid_to_string(spol->oid);
|
oid = asn1_oid_to_string(policy->oid);
|
||||||
if (oid)
|
if (oid)
|
||||||
{
|
{
|
||||||
auth->add(auth, AUTH_RULE_CERT_POLICY, oid);
|
auth->add(auth, AUTH_RULE_CERT_POLICY, oid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
spols->destroy(spols);
|
enumerator->destroy(enumerator);
|
||||||
|
|
||||||
return found;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(cert_validator_t, validate, bool,
|
METHOD(cert_validator_t, validate, bool,
|
||||||
|
|||||||
Reference in New Issue
Block a user