aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/libstrongswan/asn1/oid.txt2
-rw-r--r--src/libstrongswan/credentials/builder.c2
-rw-r--r--src/libstrongswan/credentials/builder.h4
-rw-r--r--src/libstrongswan/credentials/certificates/x509.h12
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_x509.c7
-rw-r--r--src/libstrongswan/plugins/x509/x509_cert.c128
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;