aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMartin Willi <martin@revosec.ch>2010-12-16 16:44:33 +0100
committerMartin Willi <martin@revosec.ch>2011-01-05 16:46:03 +0100
commit6c547631c024ec565af43b20c253714bce7fa12d (patch)
treea2b112af54e75bb2f6d2e472cd66818f3e4a746c /src
parent58be32e88e605ef5374244dceb249689a3547ea6 (diff)
downloadstrongswan-6c547631c024ec565af43b20c253714bce7fa12d.tar.bz2
strongswan-6c547631c024ec565af43b20c253714bce7fa12d.tar.xz
Respect policy mappings in certificatePolicy validation
Diffstat (limited to 'src')
-rw-r--r--src/libstrongswan/plugins/constraints/constraints_validator.c88
1 files changed, 64 insertions, 24 deletions
diff --git a/src/libstrongswan/plugins/constraints/constraints_validator.c b/src/libstrongswan/plugins/constraints/constraints_validator.c
index 6c5bae0fe..5c8ea7de2 100644
--- a/src/libstrongswan/plugins/constraints/constraints_validator.c
+++ b/src/libstrongswan/plugins/constraints/constraints_validator.c
@@ -255,52 +255,92 @@ static bool check_name_constraints(certificate_t *subject, x509_t *issuer)
}
/**
+ * 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
*/
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*)issuer;
- enumerator_t *spols, *ipols;
- x509_cert_policy_t *spol, *ipol;
- bool found = TRUE;
+ certificate_t *cert = (certificate_t*)subject;
+ x509_policy_mapping_t *mapping;
+ x509_cert_policy_t *policy;
+ enumerator_t *enumerator;
char *oid;
- spols = subject->create_cert_policy_enumerator(subject);
- while (spols->enumerate(spols, &spol))
+ /* verify if policyMappings in subject are valid */
+ enumerator = subject->create_policy_mapping_enumerator(subject);
+ while (enumerator->enumerate(enumerator, &mapping))
{
- found = FALSE;
- ipols = issuer->create_cert_policy_enumerator(issuer);
- while (ipols->enumerate(ipols, &ipol))
+ if (!has_policy(issuer, mapping->issuer))
{
- if (chunk_equals(spol->oid, ipol->oid) ||
- chunk_equals(ipol->oid, any_policy))
- {
- found = TRUE;
- break;
- }
+ oid = asn1_oid_to_string(mapping->issuer);
+ DBG1(DBG_CFG, "certificate '%Y' maps policy from %s, but issuer "
+ "misses it", cert->get_subject(cert), oid);
+ free(oid);
+ enumerator->destroy(enumerator);
+ return FALSE;
}
- ipols->destroy(ipols);
- if (!found)
+ }
+ 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(spol->oid);
+ oid = asn1_oid_to_string(policy->oid);
DBG1(DBG_CFG, "policy %s missing in issuing certificate '%Y'",
- oid, cert->get_subject(cert));
+ oid, cert->get_issuer(cert));
free(oid);
- break;
+ enumerator->destroy(enumerator);
+ return FALSE;
}
if (auth)
{
- oid = asn1_oid_to_string(spol->oid);
+ oid = asn1_oid_to_string(policy->oid);
if (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,