aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/libstrongswan/credentials/builder.c1
-rw-r--r--src/libstrongswan/credentials/builder.h2
-rw-r--r--src/libstrongswan/credentials/certificates/x509.h18
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_x509.c1
-rw-r--r--src/libstrongswan/plugins/x509/x509_cert.c133
5 files changed, 152 insertions, 3 deletions
diff --git a/src/libstrongswan/credentials/builder.c b/src/libstrongswan/credentials/builder.c
index c780588c2..cdf5c702d 100644
--- a/src/libstrongswan/credentials/builder.c
+++ b/src/libstrongswan/credentials/builder.c
@@ -47,6 +47,7 @@ ENUM(builder_part_names, BUILD_FROM_FILE, BUILD_END,
"BUILD_PERMITTED_NAME_CONSTRAINTS",
"BUILD_EXCLUDED_NAME_CONSTRAINTS",
"BUILD_CERTIFICATE_POLICIES",
+ "BUILD_POLICY_MAPPINGS",
"BUILD_X509_FLAG",
"BUILD_REVOKED_ENUMERATOR",
"BUILD_CHALLENGE_PWD",
diff --git a/src/libstrongswan/credentials/builder.h b/src/libstrongswan/credentials/builder.h
index a2a3a4873..f2b3f44f6 100644
--- a/src/libstrongswan/credentials/builder.h
+++ b/src/libstrongswan/credentials/builder.h
@@ -101,6 +101,8 @@ enum builder_part_t {
BUILD_EXCLUDED_NAME_CONSTRAINTS,
/** certificatePolicy OIDs, linked_list_t* of x509_cert_policy_t* */
BUILD_CERTIFICATE_POLICIES,
+ /** policyMapping OIDs, linked_list_t* of x509_policy_mapping_t* */
+ BUILD_POLICY_MAPPINGS,
/** 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 6f054f82a..b0f361edb 100644
--- a/src/libstrongswan/credentials/certificates/x509.h
+++ b/src/libstrongswan/credentials/certificates/x509.h
@@ -28,6 +28,7 @@
typedef struct x509_t x509_t;
typedef struct x509_cert_policy_t x509_cert_policy_t;
+typedef struct x509_policy_mapping_t x509_policy_mapping_t;
typedef enum x509_flag_t x509_flag_t;
/**
@@ -67,6 +68,16 @@ struct x509_cert_policy_t {
};
/**
+ * X.509 policyMapping extension
+ */
+struct x509_policy_mapping_t {
+ /** OID of issuerDomainPolicy */
+ chunk_t issuer;
+ /** OID of subjectDomainPolicy */
+ chunk_t subject;
+};
+
+/**
* X.509 certificate interface.
*
* This interface adds additional methods to the certificate_t type to
@@ -156,6 +167,13 @@ struct x509_t {
* @return enumerator over x509_cert_policy_t
*/
enumerator_t* (*create_cert_policy_enumerator)(x509_t *this);
+
+ /**
+ * Create an enumerator over policy mappings.
+ *
+ * @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 3326ffd35..6ffe08f6e 100644
--- a/src/libstrongswan/plugins/openssl/openssl_x509.c
+++ b/src/libstrongswan/plugins/openssl/openssl_x509.c
@@ -574,6 +574,7 @@ static private_openssl_x509_t *create_empty()
.create_ipAddrBlock_enumerator = (void*)enumerator_create_empty,
.create_name_constraint_enumerator = (void*)enumerator_create_empty,
.create_cert_policy_enumerator = (void*)enumerator_create_empty,
+ .create_policy_mapping_enumerator = (void*)enumerator_create_empty,
},
},
.subjectAltNames = linked_list_create(),
diff --git a/src/libstrongswan/plugins/x509/x509_cert.c b/src/libstrongswan/plugins/x509/x509_cert.c
index 160e7b5c4..f79418382 100644
--- a/src/libstrongswan/plugins/x509/x509_cert.c
+++ b/src/libstrongswan/plugins/x509/x509_cert.c
@@ -147,6 +147,11 @@ struct private_x509_cert_t {
linked_list_t *cert_policies;
/**
+ * List of policyMappings, as x509_policy_mapping_t
+ */
+ linked_list_t *policy_mappings;
+
+ /**
* certificate's embedded public key
*/
public_key_t *public_key;
@@ -245,6 +250,16 @@ static void cert_policy_destroy(x509_cert_policy_t *this)
}
/**
+ * Free policy mapping
+ */
+static void policy_mapping_destroy(x509_policy_mapping_t *mapping)
+{
+ free(mapping->issuer.ptr);
+ free(mapping->subject.ptr);
+ free(mapping);
+}
+
+/**
* ASN.1 definition of a basicConstraints extension
*/
static const asn1Object_t basicConstraintsObjects[] = {
@@ -960,6 +975,62 @@ static void parse_certificatePolicies(chunk_t blob, int level0,
}
/**
+ * ASN.1 definition of a policyMappings extension
+ */
+static const asn1Object_t policyMappingsObjects[] = {
+ { 0, "policyMappings", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
+ { 1, "policyMapping", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */
+ { 2, "issuerPolicy", ASN1_OID, ASN1_BODY }, /* 2 */
+ { 2, "subjectPolicy", ASN1_OID, ASN1_BODY }, /* 3 */
+ { 0, "end loop", ASN1_EOC, ASN1_END }, /* 4 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
+};
+#define POLICY_MAPPING 1
+#define POLICY_MAPPING_ISSUER 2
+#define POLICY_MAPPING_SUBJECT 3
+
+/**
+ * Parse policyMappings
+ */
+static void parse_policyMappings(chunk_t blob, int level0,
+ private_x509_cert_t *this)
+{
+ x509_policy_mapping_t *map = NULL;
+ asn1_parser_t *parser;
+ chunk_t object;
+ int objectID;
+
+ parser = asn1_parser_create(policyMappingsObjects, blob);
+ parser->set_top_level(parser, level0);
+
+ while (parser->iterate(parser, &objectID, &object))
+ {
+ switch (objectID)
+ {
+ case POLICY_MAPPING:
+ INIT(map);
+ this->policy_mappings->insert_last(this->policy_mappings, map);
+ break;
+ case POLICY_MAPPING_ISSUER:
+ if (map && !map->issuer.len)
+ {
+ map->issuer = chunk_clone(object);
+ }
+ break;
+ case POLICY_MAPPING_SUBJECT:
+ if (map && !map->subject.len)
+ {
+ map->subject = chunk_clone(object);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ parser->destroy(parser);
+}
+
+/**
* ASN.1 definition of ipAddrBlocks according to RFC 3779
*/
static const asn1Object_t ipAddrBlocksObjects[] = {
@@ -1274,6 +1345,9 @@ static bool parse_certificate(private_x509_cert_t *this)
case OID_CERTIFICATE_POLICIES:
parse_certificatePolicies(object, level, this);
break;
+ case OID_POLICY_MAPPINGS:
+ parse_policyMappings(object, level, this);
+ break;
case OID_NS_REVOCATION_URL:
case OID_NS_CA_REVOCATION_URL:
case OID_NS_CA_POLICY_URL:
@@ -1638,6 +1712,12 @@ METHOD(x509_t, create_cert_policy_enumerator, enumerator_t*,
return this->cert_policies->create_enumerator(this->cert_policies);
}
+METHOD(x509_t, create_policy_mapping_enumerator, enumerator_t*,
+ private_x509_cert_t *this)
+{
+ return this->policy_mappings->create_enumerator(this->policy_mappings);
+}
+
METHOD(certificate_t, destroy, void,
private_x509_cert_t *this)
{
@@ -1655,6 +1735,8 @@ METHOD(certificate_t, destroy, void,
offsetof(identification_t, destroy));
this->cert_policies->destroy_function(this->cert_policies,
(void*)cert_policy_destroy);
+ this->policy_mappings->destroy_function(this->policy_mappings,
+ (void*)policy_mapping_destroy);
DESTROY_IF(this->issuer);
DESTROY_IF(this->subject);
DESTROY_IF(this->public_key);
@@ -1706,6 +1788,7 @@ static private_x509_cert_t* create_empty(void)
.create_ipAddrBlock_enumerator = _create_ipAddrBlock_enumerator,
.create_name_constraint_enumerator = _create_name_constraint_enumerator,
.create_cert_policy_enumerator = _create_cert_policy_enumerator,
+ .create_policy_mapping_enumerator = _create_policy_mapping_enumerator,
},
},
.version = 1,
@@ -1716,6 +1799,7 @@ static private_x509_cert_t* create_empty(void)
.permitted_names = linked_list_create(),
.excluded_names = linked_list_create(),
.cert_policies = linked_list_create(),
+ .policy_mappings = linked_list_create(),
.pathLenConstraint = X509_NO_PATH_LEN_CONSTRAINT,
.ref = 1,
);
@@ -1793,7 +1877,7 @@ static bool generate(private_x509_cert_t *cert, certificate_t *sign_cert,
chunk_t ocspSigning = chunk_empty, certPolicies = chunk_empty;
chunk_t basicConstraints = chunk_empty, nameConstraints = chunk_empty;
chunk_t keyUsage = chunk_empty, keyUsageBits = chunk_empty;
- chunk_t subjectAltNames = chunk_empty;
+ chunk_t subjectAltNames = chunk_empty, policyMappings = chunk_empty;
chunk_t subjectKeyIdentifier = chunk_empty, authKeyIdentifier = chunk_empty;
chunk_t crlDistributionPoints = chunk_empty, authorityInfoAccess = chunk_empty;
identification_t *issuer, *subject;
@@ -2078,15 +2162,38 @@ static bool generate(private_x509_cert_t *cert, certificate_t *sign_cert,
asn1_wrap(ASN1_SEQUENCE, "m", certPolicies)));
}
+ if (cert->policy_mappings->get_count(cert->policy_mappings))
+ {
+ x509_policy_mapping_t *mapping;
+
+ enumerator = create_policy_mapping_enumerator(cert);
+ while (enumerator->enumerate(enumerator, &mapping))
+ {
+ chunk_t chunk;
+
+ chunk = asn1_wrap(ASN1_SEQUENCE, "mm",
+ asn1_wrap(ASN1_OID, "c", mapping->issuer),
+ asn1_wrap(ASN1_OID, "c", mapping->subject));
+ policyMappings = chunk_cat("mm", policyMappings, chunk);
+ }
+ enumerator->destroy(enumerator);
+
+ policyMappings = asn1_wrap(ASN1_SEQUENCE, "mm",
+ asn1_build_known_oid(OID_POLICY_MAPPINGS),
+ asn1_wrap(ASN1_OCTET_STRING, "m",
+ asn1_wrap(ASN1_SEQUENCE, "m", policyMappings)));
+ }
+
if (basicConstraints.ptr || subjectAltNames.ptr || authKeyIdentifier.ptr ||
crlDistributionPoints.ptr || nameConstraints.ptr)
{
extensions = asn1_wrap(ASN1_CONTEXT_C_3, "m",
- asn1_wrap(ASN1_SEQUENCE, "mmmmmmmmmm",
+ asn1_wrap(ASN1_SEQUENCE, "mmmmmmmmmmm",
basicConstraints, keyUsage, subjectKeyIdentifier,
authKeyIdentifier, subjectAltNames,
extendedKeyUsage, crlDistributionPoints,
- authorityInfoAccess, nameConstraints, certPolicies));
+ authorityInfoAccess, nameConstraints, certPolicies,
+ policyMappings));
}
cert->tbsCertificate = asn1_wrap(ASN1_SEQUENCE, "mmmcmcmm",
@@ -2309,6 +2416,26 @@ x509_cert_t *x509_cert_gen(certificate_type_t type, va_list args)
enumerator->destroy(enumerator);
continue;
}
+ case BUILD_POLICY_MAPPINGS:
+ {
+ enumerator_t *enumerator;
+ linked_list_t *list;
+ x509_policy_mapping_t* mapping, *in;
+
+ list = va_arg(args, linked_list_t*);
+ enumerator = list->create_enumerator(list);
+ while (enumerator->enumerate(enumerator, &in))
+ {
+ INIT(mapping,
+ .issuer = chunk_clone(in->issuer),
+ .subject = chunk_clone(in->subject),
+ );
+ cert->policy_mappings->insert_last(cert->policy_mappings,
+ mapping);
+ }
+ enumerator->destroy(enumerator);
+ continue;
+ }
case BUILD_NOT_BEFORE_TIME:
cert->notBefore = va_arg(args, time_t);
continue;