diff options
author | Martin Willi <martin@revosec.ch> | 2010-12-15 17:45:32 +0100 |
---|---|---|
committer | Martin Willi <martin@revosec.ch> | 2011-01-05 16:46:02 +0100 |
commit | a742d97fb8e2ecf54750a6c50e2827b93c1d650c (patch) | |
tree | 85e0e3106c94bdf87144710f049b366794a263f6 /src/libstrongswan | |
parent | 5dba5852fcaa965cfc0adb0c2a756814af2c1885 (diff) | |
download | strongswan-a742d97fb8e2ecf54750a6c50e2827b93c1d650c.tar.bz2 strongswan-a742d97fb8e2ecf54750a6c50e2827b93c1d650c.tar.xz |
Added support for policyConstraints to x509 plugin
Diffstat (limited to 'src/libstrongswan')
-rw-r--r-- | src/libstrongswan/asn1/oid.txt | 2 | ||||
-rw-r--r-- | src/libstrongswan/credentials/builder.c | 2 | ||||
-rw-r--r-- | src/libstrongswan/credentials/builder.h | 4 | ||||
-rw-r--r-- | src/libstrongswan/credentials/certificates/x509.h | 12 | ||||
-rw-r--r-- | src/libstrongswan/plugins/openssl/openssl_x509.c | 7 | ||||
-rw-r--r-- | src/libstrongswan/plugins/x509/x509_cert.c | 128 |
6 files changed, 147 insertions, 8 deletions
diff --git a/src/libstrongswan/asn1/oid.txt b/src/libstrongswan/asn1/oid.txt index 7b7455288..3c8ea118c 100644 --- a/src/libstrongswan/asn1/oid.txt +++ b/src/libstrongswan/asn1/oid.txt @@ -55,7 +55,7 @@ 0x00 "anyPolicy" OID_ANY_POLICY 0x21 "policyMappings" OID_POLICY_MAPPINGS 0x23 "authorityKeyIdentifier" OID_AUTHORITY_KEY_ID - 0x24 "policyConstraints" + 0x24 "policyConstraints" OID_POLICY_CONSTRAINTS 0x25 "extendedKeyUsage" OID_EXTENDED_KEY_USAGE 0x00 "anyExtendedKeyUsage" 0x2E "freshestCRL" OID_FRESHEST_CRL diff --git a/src/libstrongswan/credentials/builder.c b/src/libstrongswan/credentials/builder.c index cdf5c702d..122001924 100644 --- a/src/libstrongswan/credentials/builder.c +++ b/src/libstrongswan/credentials/builder.c @@ -48,6 +48,8 @@ ENUM(builder_part_names, BUILD_FROM_FILE, BUILD_END, "BUILD_EXCLUDED_NAME_CONSTRAINTS", "BUILD_CERTIFICATE_POLICIES", "BUILD_POLICY_MAPPINGS", + "BUILD_POLICY_CONSTRAINT_EXPLICIT", + "BUILD_POLICY_CONSTRAINT_INHIBIT", "BUILD_X509_FLAG", "BUILD_REVOKED_ENUMERATOR", "BUILD_CHALLENGE_PWD", diff --git a/src/libstrongswan/credentials/builder.h b/src/libstrongswan/credentials/builder.h index f2b3f44f6..56eee3cf0 100644 --- a/src/libstrongswan/credentials/builder.h +++ b/src/libstrongswan/credentials/builder.h @@ -103,6 +103,10 @@ enum builder_part_t { BUILD_CERTIFICATE_POLICIES, /** policyMapping OIDs, linked_list_t* of x509_policy_mapping_t* */ BUILD_POLICY_MAPPINGS, + /** requireExplicitPolicy constraint, int */ + BUILD_POLICY_CONSTRAINT_EXPLICIT, + /** inhibitPolicyMapping constraint, int */ + BUILD_POLICY_CONSTRAINT_INHIBIT, /** enforce an additional X509 flag, x509_flag_t */ BUILD_X509_FLAG, /** enumerator_t over (chunk_t serial, time_t date, crl_reason_t reason) */ diff --git a/src/libstrongswan/credentials/certificates/x509.h b/src/libstrongswan/credentials/certificates/x509.h index d620bbde8..f4ec73029 100644 --- a/src/libstrongswan/credentials/certificates/x509.h +++ b/src/libstrongswan/credentials/certificates/x509.h @@ -121,11 +121,19 @@ struct x509_t { /** * Get an optional path length constraint. * - * @return pathLenConstraint, -1 if no constraint exists + * @return pathLenConstraint, X509_NO_CONSTRAINT if none found */ int (*get_pathLenConstraint)(x509_t *this); /** + * Get a policyConstraint, inhibitPolicyMapping or requireExplicitPolicy. + * + * @param inhibit TRUE to get inhibitPolicyMapping + * @return constraint, X509_NO_CONSTRAINT if none found + */ + int (*get_policyConstraint)(x509_t *this, bool inhibit); + + /** * Create an enumerator over all subjectAltNames. * * @return enumerator over subjectAltNames as identification_t* @@ -174,6 +182,8 @@ struct x509_t { * @return enumerator over x509_policy_mapping */ enumerator_t* (*create_policy_mapping_enumerator)(x509_t *this); + + }; #endif /** X509_H_ @}*/ diff --git a/src/libstrongswan/plugins/openssl/openssl_x509.c b/src/libstrongswan/plugins/openssl/openssl_x509.c index 7b6ac121f..58b58b6df 100644 --- a/src/libstrongswan/plugins/openssl/openssl_x509.c +++ b/src/libstrongswan/plugins/openssl/openssl_x509.c @@ -277,6 +277,12 @@ METHOD(x509_t, get_pathLenConstraint, int, return this->pathlen; } +METHOD(x509_t, get_policyConstraint, int, + private_openssl_x509_t *this, bool inhibit) +{ + return X509_NO_CONSTRAINT; +} + METHOD(x509_t, create_subjectAltName_enumerator, enumerator_t*, private_openssl_x509_t *this) { @@ -568,6 +574,7 @@ static private_openssl_x509_t *create_empty() .get_subjectKeyIdentifier = _get_subjectKeyIdentifier, .get_authKeyIdentifier = _get_authKeyIdentifier, .get_pathLenConstraint = _get_pathLenConstraint, + .get_policyConstraint = _get_policyConstraint, .create_subjectAltName_enumerator = _create_subjectAltName_enumerator, .create_crl_uri_enumerator = _create_crl_uri_enumerator, .create_ocsp_uri_enumerator = _create_ocsp_uri_enumerator, diff --git a/src/libstrongswan/plugins/x509/x509_cert.c b/src/libstrongswan/plugins/x509/x509_cert.c index 4f6cdaa4b..4d34de470 100644 --- a/src/libstrongswan/plugins/x509/x509_cert.c +++ b/src/libstrongswan/plugins/x509/x509_cert.c @@ -174,7 +174,17 @@ struct private_x509_cert_t { /** * Path Length Constraint */ - int pathLenConstraint; + char pathLenConstraint; + + /** + * requireExplicitPolicy Constraint + */ + char explicit_policy_constraint; + + /** + * inhibitPolicyMapping Constraint + */ + char inhibit_policy_constraint; /** * x509 constraints and other flags @@ -1031,6 +1041,66 @@ static void parse_policyMappings(chunk_t blob, int level0, } /** + * ASN.1 definition of a policyConstraints extension + */ +static const asn1Object_t policyConstraintsObjects[] = { + { 0, "policyConstraints", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */ + { 1, "requireExplicitPolicy", ASN1_CONTEXT_C_0, ASN1_OPT|ASN1_NONE }, /* 1 */ + { 2, "SkipCerts", ASN1_INTEGER, ASN1_BODY }, /* 2 */ + { 1, "end opt", ASN1_EOC, ASN1_END }, /* 3 */ + { 1, "inhibitPolicyMapping", ASN1_CONTEXT_C_1, ASN1_OPT|ASN1_NONE }, /* 4 */ + { 2, "SkipCerts", ASN1_INTEGER, ASN1_BODY }, /* 5 */ + { 1, "end opt", ASN1_EOC, ASN1_END }, /* 6 */ + { 0, "exit", ASN1_EOC, ASN1_EXIT } +}; +#define POLICY_CONSTRAINT_EXPLICIT 2 +#define POLICY_CONSTRAINT_INHIBIT 5 + +/** + * Parse policyConstraints + */ +static void parse_policyConstraints(chunk_t blob, int level0, + private_x509_cert_t *this) +{ + asn1_parser_t *parser; + chunk_t object; + int objectID; + + parser = asn1_parser_create(policyConstraintsObjects, blob); + parser->set_top_level(parser, level0); + + while (parser->iterate(parser, &objectID, &object)) + { + switch (objectID) + { + case POLICY_CONSTRAINT_EXPLICIT: + if (object.len == 0) + { + this->explicit_policy_constraint = 0; + } + else if (object.len == 1) + { + this->explicit_policy_constraint = *object.ptr; + } + break; + case POLICY_CONSTRAINT_INHIBIT: + if (object.len == 0) + { + this->inhibit_policy_constraint = 0; + } + else if (object.len == 1) + { + this->inhibit_policy_constraint = *object.ptr; + } + break; + default: + break; + } + } + parser->destroy(parser); +} + +/** * ASN.1 definition of ipAddrBlocks according to RFC 3779 */ static const asn1Object_t ipAddrBlocksObjects[] = { @@ -1348,6 +1418,9 @@ static bool parse_certificate(private_x509_cert_t *this) case OID_POLICY_MAPPINGS: parse_policyMappings(object, level, this); break; + case OID_POLICY_CONSTRAINTS: + parse_policyConstraints(object, level, this); + break; case OID_NS_REVOCATION_URL: case OID_NS_CA_REVOCATION_URL: case OID_NS_CA_POLICY_URL: @@ -1646,6 +1719,16 @@ METHOD(x509_t, get_pathLenConstraint, int, return this->pathLenConstraint; } +METHOD(x509_t, get_policyConstraint, int, + private_x509_cert_t *this, bool inhibit) +{ + if (inhibit) + { + return this->inhibit_policy_constraint; + } + return this->explicit_policy_constraint; +} + METHOD(x509_t, create_subjectAltName_enumerator, enumerator_t*, private_x509_cert_t *this) { @@ -1782,6 +1865,7 @@ static private_x509_cert_t* create_empty(void) .get_subjectKeyIdentifier = _get_subjectKeyIdentifier, .get_authKeyIdentifier = _get_authKeyIdentifier, .get_pathLenConstraint = _get_pathLenConstraint, + .get_policyConstraint = _get_policyConstraint, .create_subjectAltName_enumerator = _create_subjectAltName_enumerator, .create_crl_uri_enumerator = _create_crl_uri_enumerator, .create_ocsp_uri_enumerator = _create_ocsp_uri_enumerator, @@ -1801,6 +1885,8 @@ static private_x509_cert_t* create_empty(void) .cert_policies = linked_list_create(), .policy_mappings = linked_list_create(), .pathLenConstraint = X509_NO_CONSTRAINT, + .explicit_policy_constraint = X509_NO_CONSTRAINT, + .inhibit_policy_constraint = X509_NO_CONSTRAINT, .ref = 1, ); return this; @@ -1880,6 +1966,7 @@ static bool generate(private_x509_cert_t *cert, certificate_t *sign_cert, chunk_t subjectAltNames = chunk_empty, policyMappings = chunk_empty; chunk_t subjectKeyIdentifier = chunk_empty, authKeyIdentifier = chunk_empty; chunk_t crlDistributionPoints = chunk_empty, authorityInfoAccess = chunk_empty; + chunk_t policyConstraints = chunk_empty; identification_t *issuer, *subject; crl_uri_t *entry; chunk_t key_info; @@ -1999,9 +2086,8 @@ static bool generate(private_x509_cert_t *cert, certificate_t *sign_cert, if (cert->pathLenConstraint != X509_NO_CONSTRAINT) { - char pathlen = (char)cert->pathLenConstraint; - - pathLenConstraint = asn1_integer("c", chunk_from_thing(pathlen)); + pathLenConstraint = asn1_integer("c", + chunk_from_thing(cert->pathLenConstraint)); } basicConstraints = asn1_wrap(ASN1_SEQUENCE, "mmm", asn1_build_known_oid(OID_BASIC_CONSTRAINTS), @@ -2184,16 +2270,40 @@ static bool generate(private_x509_cert_t *cert, certificate_t *sign_cert, asn1_wrap(ASN1_SEQUENCE, "m", policyMappings))); } + if (cert->inhibit_policy_constraint != X509_NO_CONSTRAINT || + cert->explicit_policy_constraint != X509_NO_CONSTRAINT) + { + chunk_t inhibit = chunk_empty, explicit = chunk_empty; + + if (cert->explicit_policy_constraint != X509_NO_CONSTRAINT) + { + explicit = asn1_wrap(ASN1_CONTEXT_C_0, "m", + asn1_integer("c", + chunk_from_thing(cert->explicit_policy_constraint))); + } + if (cert->inhibit_policy_constraint != X509_NO_CONSTRAINT) + { + inhibit = asn1_wrap(ASN1_CONTEXT_C_1, "m", + asn1_integer("c", + chunk_from_thing(cert->inhibit_policy_constraint))); + } + policyConstraints = asn1_wrap(ASN1_SEQUENCE, "mm", + asn1_build_known_oid(OID_POLICY_CONSTRAINTS), + asn1_wrap(ASN1_OCTET_STRING, "m", + asn1_wrap(ASN1_SEQUENCE, "mm", + explicit, inhibit))); + } + if (basicConstraints.ptr || subjectAltNames.ptr || authKeyIdentifier.ptr || crlDistributionPoints.ptr || nameConstraints.ptr) { extensions = asn1_wrap(ASN1_CONTEXT_C_3, "m", - asn1_wrap(ASN1_SEQUENCE, "mmmmmmmmmmm", + asn1_wrap(ASN1_SEQUENCE, "mmmmmmmmmmmm", basicConstraints, keyUsage, subjectKeyIdentifier, authKeyIdentifier, subjectAltNames, extendedKeyUsage, crlDistributionPoints, authorityInfoAccess, nameConstraints, certPolicies, - policyMappings)); + policyMappings, policyConstraints)); } cert->tbsCertificate = asn1_wrap(ASN1_SEQUENCE, "mmmcmcmm", @@ -2436,6 +2546,12 @@ x509_cert_t *x509_cert_gen(certificate_type_t type, va_list args) enumerator->destroy(enumerator); continue; } + case BUILD_POLICY_CONSTRAINT_EXPLICIT: + cert->explicit_policy_constraint = va_arg(args, int); + continue; + case BUILD_POLICY_CONSTRAINT_INHIBIT: + cert->inhibit_policy_constraint = va_arg(args, int); + continue; case BUILD_NOT_BEFORE_TIME: cert->notBefore = va_arg(args, time_t); continue; |