summaryrefslogtreecommitdiff
path: root/src/libstrongswan/plugins/x509/x509_cert.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstrongswan/plugins/x509/x509_cert.c')
-rw-r--r--src/libstrongswan/plugins/x509/x509_cert.c1132
1 files changed, 1132 insertions, 0 deletions
diff --git a/src/libstrongswan/plugins/x509/x509_cert.c b/src/libstrongswan/plugins/x509/x509_cert.c
index 559090aa0..0eabc8010 100644
--- a/src/libstrongswan/plugins/x509/x509_cert.c
+++ b/src/libstrongswan/plugins/x509/x509_cert.c
@@ -117,7 +117,11 @@ struct private_x509_cert_t {
linked_list_t *subjectAltNames;
/**
+<<<<<<< HEAD
* List of crlDistributionPoints as allocated char*
+=======
+ * List of crlDistributionPoints as x509_cdp_t*
+>>>>>>> upstream/4.5.1
*/
linked_list_t *crl_uris;
@@ -132,6 +136,29 @@ struct private_x509_cert_t {
linked_list_t *ipAddrBlocks;
/**
+<<<<<<< HEAD
+=======
+ * List of permitted name constraints
+ */
+ linked_list_t *permitted_names;
+
+ /**
+ * List of exluced name constraints
+ */
+ linked_list_t *excluded_names;
+
+ /**
+ * List of certificatePolicies, as x509_cert_policy_t
+ */
+ linked_list_t *cert_policies;
+
+ /**
+ * List of policyMappings, as x509_policy_mapping_t
+ */
+ linked_list_t *policy_mappings;
+
+ /**
+>>>>>>> upstream/4.5.1
* certificate's embedded public key
*/
public_key_t *public_key;
@@ -154,7 +181,26 @@ struct private_x509_cert_t {
/**
* Path Length Constraint
*/
+<<<<<<< HEAD
int pathLenConstraint;
+=======
+ u_char pathLenConstraint;
+
+ /**
+ * requireExplicitPolicy Constraint
+ */
+ u_char require_explicit;
+
+ /**
+ * inhibitPolicyMapping Constraint
+ */
+ u_char inhibit_mapping;
+
+ /**
+ * inhibitAnyPolicy Constraint
+ */
+ u_char inhibit_any;
+>>>>>>> upstream/4.5.1
/**
* x509 constraints and other flags
@@ -187,6 +233,56 @@ static const chunk_t ASN1_subjectAltName_oid = chunk_from_chars(
);
/**
+<<<<<<< HEAD
+=======
+ * Destroy a CertificateDistributionPoint
+ */
+static void crl_uri_destroy(x509_cdp_t *this)
+{
+ free(this->uri);
+ DESTROY_IF(this->issuer);
+ free(this);
+}
+
+/**
+ * Destroy a CertificatePolicy
+ */
+static void cert_policy_destroy(x509_cert_policy_t *this)
+{
+ free(this->oid.ptr);
+ free(this->cps_uri);
+ free(this->unotice_text);
+ free(this);
+}
+
+/**
+ * Free policy mapping
+ */
+static void policy_mapping_destroy(x509_policy_mapping_t *mapping)
+{
+ free(mapping->issuer.ptr);
+ free(mapping->subject.ptr);
+ free(mapping);
+}
+
+/**
+ * Parse a length constraint from an unwrapped integer
+ */
+static u_int parse_constraint(chunk_t object)
+{
+ switch (object.len)
+ {
+ case 0:
+ return 0;
+ case 1:
+ return (object.ptr[0] & 0x80) ? X509_NO_CONSTRAINT : object.ptr[0];
+ default:
+ return X509_NO_CONSTRAINT;
+ }
+}
+
+/**
+>>>>>>> upstream/4.5.1
* ASN.1 definition of a basicConstraints extension
*/
static const asn1Object_t basicConstraintsObjects[] = {
@@ -228,6 +324,7 @@ static void parse_basicConstraints(chunk_t blob, int level0,
case BASIC_CONSTRAINTS_PATH_LEN:
if (isCA)
{
+<<<<<<< HEAD
if (object.len == 0)
{
this->pathLenConstraint = 0;
@@ -237,6 +334,9 @@ static void parse_basicConstraints(chunk_t blob, int level0,
this->pathLenConstraint = *object.ptr;
}
/* we ignore path length constraints > 127 */
+=======
+ this->pathLenConstraint = parse_constraint(object);
+>>>>>>> upstream/4.5.1
}
break;
default:
@@ -574,7 +674,11 @@ static void parse_authorityInfoAccess(chunk_t blob, int level0,
}
break;
default:
+<<<<<<< HEAD
/* unkown accessMethod, ignoring */
+=======
+ /* unknown accessMethod, ignoring */
+>>>>>>> upstream/4.5.1
break;
}
break;
@@ -589,6 +693,63 @@ end:
}
/**
+<<<<<<< HEAD
+=======
+ * Extract KeyUsage flags
+ */
+static void parse_keyUsage(chunk_t blob, private_x509_cert_t *this)
+{
+ enum {
+ KU_DIGITAL_SIGNATURE = 0,
+ KU_NON_REPUDIATION = 1,
+ KU_KEY_ENCIPHERMENT = 2,
+ KU_DATA_ENCIPHERMENT = 3,
+ KU_KEY_AGREEMENT = 4,
+ KU_KEY_CERT_SIGN = 5,
+ KU_CRL_SIGN = 6,
+ KU_ENCIPHER_ONLY = 7,
+ KU_DECIPHER_ONLY = 8,
+ };
+
+ if (asn1_unwrap(&blob, &blob) == ASN1_BIT_STRING && blob.len)
+ {
+ int bit, byte, unused = blob.ptr[0];
+
+ blob = chunk_skip(blob, 1);
+ for (byte = 0; byte < blob.len; byte++)
+ {
+ for (bit = 0; bit < 8; bit++)
+ {
+ if (byte == blob.len - 1 && bit > (7 - unused))
+ {
+ break;
+ }
+ if (blob.ptr[byte] & 1 << (7 - bit))
+ {
+ switch (byte * 8 + bit)
+ {
+ case KU_CRL_SIGN:
+ this->flags |= X509_CRL_SIGN;
+ break;
+ case KU_KEY_CERT_SIGN:
+ /* we use the caBasicConstraint, MUST be set */
+ case KU_DIGITAL_SIGNATURE:
+ case KU_NON_REPUDIATION:
+ case KU_KEY_ENCIPHERMENT:
+ case KU_DATA_ENCIPHERMENT:
+ case KU_KEY_AGREEMENT:
+ case KU_ENCIPHER_ONLY:
+ case KU_DECIPHER_ONLY:
+ break;
+ }
+ }
+ }
+ }
+ }
+}
+
+/**
+>>>>>>> upstream/4.5.1
* ASN.1 definition of a extendedKeyUsage extension
*/
static const asn1Object_t extendedKeyUsageObjects[] = {
@@ -600,7 +761,11 @@ static const asn1Object_t extendedKeyUsageObjects[] = {
#define EXT_KEY_USAGE_PURPOSE_ID 1
/**
+<<<<<<< HEAD
* Extracts extendedKeyUsage OIDs - currently only OCSP_SIGING is returned
+=======
+ * Extracts extendedKeyUsage OIDs
+>>>>>>> upstream/4.5.1
*/
static void parse_extendedKeyUsage(chunk_t blob, int level0,
private_x509_cert_t *this)
@@ -649,16 +814,72 @@ static const asn1Object_t crlDistributionPointsObjects[] = {
{ 2, "end opt", ASN1_EOC, ASN1_END }, /* 7 */
{ 2, "reasons", ASN1_CONTEXT_C_1, ASN1_OPT|ASN1_BODY }, /* 8 */
{ 2, "end opt", ASN1_EOC, ASN1_END }, /* 9 */
+<<<<<<< HEAD
{ 2, "crlIssuer", ASN1_CONTEXT_C_2, ASN1_OPT|ASN1_BODY }, /* 10 */
+=======
+ { 2, "crlIssuer", ASN1_CONTEXT_C_2, ASN1_OPT|ASN1_OBJ }, /* 10 */
+>>>>>>> upstream/4.5.1
{ 2, "end opt", ASN1_EOC, ASN1_END }, /* 11 */
{ 0, "end loop", ASN1_EOC, ASN1_END }, /* 12 */
{ 0, "exit", ASN1_EOC, ASN1_EXIT }
};
+<<<<<<< HEAD
+#define CRL_DIST_POINTS_FULLNAME 3
+=======
+#define CRL_DIST_POINTS 1
#define CRL_DIST_POINTS_FULLNAME 3
+#define CRL_DIST_POINTS_ISSUER 10
+
+/**
+ * Add entry to the list of each pairing of URI and Issuer
+ */
+static void add_cdps(linked_list_t *list, linked_list_t *uris,
+ linked_list_t *issuers)
+{
+ identification_t *issuer, *id;
+ enumerator_t *enumerator;
+ x509_cdp_t *cdp;
+ char *uri;
+
+ while (uris->remove_last(uris, (void**)&id) == SUCCESS)
+ {
+ if (asprintf(&uri, "%Y", id) > 0)
+ {
+ if (issuers->get_count(issuers))
+ {
+ enumerator = issuers->create_enumerator(issuers);
+ while (enumerator->enumerate(enumerator, &issuer))
+ {
+ INIT(cdp,
+ .uri = strdup(uri),
+ .issuer = issuer->clone(issuer),
+ );
+ list->insert_last(list, cdp);
+ }
+ enumerator->destroy(enumerator);
+ free(uri);
+ }
+ else
+ {
+ INIT(cdp,
+ .uri = uri,
+ );
+ list->insert_last(list, cdp);
+ }
+ }
+ id->destroy(id);
+ }
+ while (issuers->remove_last(issuers, (void**)&id) == SUCCESS)
+ {
+ id->destroy(id);
+ }
+}
+>>>>>>> upstream/4.5.1
/**
* Extracts one or several crlDistributionPoints into a list
*/
+<<<<<<< HEAD
static void parse_crlDistributionPoints(chunk_t blob, int level0,
private_x509_cert_t *this)
{
@@ -667,11 +888,24 @@ static void parse_crlDistributionPoints(chunk_t blob, int level0,
int objectID;
linked_list_t *list = linked_list_create();
+=======
+void x509_parse_crlDistributionPoints(chunk_t blob, int level0,
+ linked_list_t *list)
+{
+ linked_list_t *uris, *issuers;
+ asn1_parser_t *parser;
+ chunk_t object;
+ int objectID;
+
+ uris = linked_list_create();
+ issuers = linked_list_create();
+>>>>>>> upstream/4.5.1
parser = asn1_parser_create(crlDistributionPointsObjects, blob);
parser->set_top_level(parser, level0);
while (parser->iterate(parser, &objectID, &object))
{
+<<<<<<< HEAD
if (objectID == CRL_DIST_POINTS_FULLNAME)
{
identification_t *id;
@@ -694,6 +928,258 @@ static void parse_crlDistributionPoints(chunk_t blob, int level0,
}
parser->destroy(parser);
list->destroy(list);
+=======
+ switch (objectID)
+ {
+ case CRL_DIST_POINTS:
+ add_cdps(list, uris, issuers);
+ break;
+ case CRL_DIST_POINTS_FULLNAME:
+ x509_parse_generalNames(object, parser->get_level(parser) + 1,
+ TRUE, uris);
+ break;
+ case CRL_DIST_POINTS_ISSUER:
+ x509_parse_generalNames(object, parser->get_level(parser) + 1,
+ TRUE, issuers);
+ break;
+ default:
+ break;
+ }
+ }
+ parser->destroy(parser);
+
+ add_cdps(list, uris, issuers);
+
+ uris->destroy(uris);
+ issuers->destroy(issuers);
+}
+
+/**
+ * ASN.1 definition of nameConstraints
+ */
+static const asn1Object_t nameConstraintsObjects[] = {
+ { 0, "nameConstraints", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
+ { 1, "permittedSubtrees", ASN1_CONTEXT_C_0, ASN1_OPT|ASN1_LOOP }, /* 1 */
+ { 2, "generalSubtree", ASN1_SEQUENCE, ASN1_BODY }, /* 2 */
+ { 1, "end loop", ASN1_EOC, ASN1_END }, /* 3 */
+ { 1, "excludedSubtrees", ASN1_CONTEXT_C_1, ASN1_OPT|ASN1_LOOP }, /* 4 */
+ { 2, "generalSubtree", ASN1_SEQUENCE, ASN1_BODY }, /* 5 */
+ { 1, "end loop", ASN1_EOC, ASN1_END }, /* 6 */
+ { 0, "end loop", ASN1_EOC, ASN1_END }, /* 7 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
+};
+#define NAME_CONSTRAINT_PERMITTED 2
+#define NAME_CONSTRAINT_EXCLUDED 5
+
+/**
+ * Parse permitted/excluded nameConstraints
+ */
+static void parse_nameConstraints(chunk_t blob, int level0,
+ private_x509_cert_t *this)
+{
+ asn1_parser_t *parser;
+ identification_t *id;
+ chunk_t object;
+ int objectID;
+
+ parser = asn1_parser_create(nameConstraintsObjects, blob);
+ parser->set_top_level(parser, level0);
+
+ while (parser->iterate(parser, &objectID, &object))
+ {
+ switch (objectID)
+ {
+ case NAME_CONSTRAINT_PERMITTED:
+ id = parse_generalName(object, parser->get_level(parser) + 1);
+ if (id)
+ {
+ this->permitted_names->insert_last(this->permitted_names, id);
+ }
+ break;
+ case NAME_CONSTRAINT_EXCLUDED:
+ id = parse_generalName(object, parser->get_level(parser) + 1);
+ if (id)
+ {
+ this->excluded_names->insert_last(this->excluded_names, id);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ parser->destroy(parser);
+}
+
+/**
+ * ASN.1 definition of a certificatePolicies extension
+ */
+static const asn1Object_t certificatePoliciesObject[] = {
+ { 0, "certificatePolicies", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
+ { 1, "policyInformation", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */
+ { 2, "policyId", ASN1_OID, ASN1_BODY }, /* 2 */
+ { 2, "qualifier", ASN1_SEQUENCE, ASN1_OPT|ASN1_BODY }, /* 3 */
+ { 3, "qualifierInfo", ASN1_SEQUENCE, ASN1_NONE }, /* 4 */
+ { 4, "qualifierId", ASN1_OID, ASN1_BODY }, /* 5 */
+ { 4, "cPSuri", ASN1_IA5STRING, ASN1_OPT|ASN1_BODY }, /* 6 */
+ { 4, "end choice", ASN1_EOC, ASN1_END }, /* 7 */
+ { 4, "userNotice", ASN1_SEQUENCE, ASN1_OPT|ASN1_NONE }, /* 8 */
+ { 5, "explicitText", ASN1_EOC, ASN1_RAW }, /* 9 */
+ { 4, "end choice", ASN1_EOC, ASN1_END }, /* 10 */
+ { 2, "end opt", ASN1_EOC, ASN1_END }, /* 12 */
+ { 0, "end loop", ASN1_EOC, ASN1_END }, /* 13 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
+};
+#define CERT_POLICY_ID 2
+#define CERT_POLICY_QUALIFIER_ID 5
+#define CERT_POLICY_CPS_URI 6
+#define CERT_POLICY_EXPLICIT_TEXT 9
+
+/**
+ * Parse certificatePolicies
+ */
+static void parse_certificatePolicies(chunk_t blob, int level0,
+ private_x509_cert_t *this)
+{
+ x509_cert_policy_t *policy = NULL;
+ asn1_parser_t *parser;
+ chunk_t object;
+ int objectID, qualifier = OID_UNKNOWN;
+
+ parser = asn1_parser_create(certificatePoliciesObject, blob);
+ parser->set_top_level(parser, level0);
+
+ while (parser->iterate(parser, &objectID, &object))
+ {
+ switch (objectID)
+ {
+ case CERT_POLICY_ID:
+ INIT(policy,
+ .oid = chunk_clone(object),
+ );
+ this->cert_policies->insert_last(this->cert_policies, policy);
+ break;
+ case CERT_POLICY_QUALIFIER_ID:
+ qualifier = asn1_known_oid(object);
+ break;
+ case CERT_POLICY_CPS_URI:
+ if (policy && !policy->cps_uri && object.len &&
+ qualifier == OID_POLICY_QUALIFIER_CPS &&
+ chunk_printable(object, NULL, 0))
+ {
+ policy->cps_uri = strndup(object.ptr, object.len);
+ }
+ break;
+ case CERT_POLICY_EXPLICIT_TEXT:
+ /* TODO */
+ break;
+ default:
+ break;
+ }
+ }
+ parser->destroy(parser);
+}
+
+/**
+ * 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 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:
+ this->require_explicit = parse_constraint(object);
+ break;
+ case POLICY_CONSTRAINT_INHIBIT:
+ this->inhibit_mapping = parse_constraint(object);
+ break;
+ default:
+ break;
+ }
+ }
+ parser->destroy(parser);
+>>>>>>> upstream/4.5.1
}
/**
@@ -888,11 +1374,14 @@ static const asn1Object_t certObjects[] = {
#define X509_OBJ_SIGNATURE 25
/**
+<<<<<<< HEAD
* forward declaration
*/
static bool issued_by(private_x509_cert_t *this, certificate_t *issuer);
/**
+=======
+>>>>>>> upstream/4.5.1
* Parses an X.509v3 certificate
*/
static bool parse_certificate(private_x509_cert_t *this)
@@ -992,7 +1481,12 @@ static bool parse_certificate(private_x509_cert_t *this)
parse_basicConstraints(object, level, this);
break;
case OID_CRL_DISTRIBUTION_POINTS:
+<<<<<<< HEAD
parse_crlDistributionPoints(object, level, this);
+=======
+ x509_parse_crlDistributionPoints(object, level,
+ this->crl_uris);
+>>>>>>> upstream/4.5.1
break;
case OID_AUTHORITY_KEY_ID:
this->authKeyIdentifier = x509_parse_authorityKeyIdentifier(object,
@@ -1002,7 +1496,11 @@ static bool parse_certificate(private_x509_cert_t *this)
parse_authorityInfoAccess(object, level, this);
break;
case OID_KEY_USAGE:
+<<<<<<< HEAD
/* TODO parse the flags */
+=======
+ parse_keyUsage(object, this);
+>>>>>>> upstream/4.5.1
break;
case OID_EXTENDED_KEY_USAGE:
parse_extendedKeyUsage(object, level, this);
@@ -1010,6 +1508,29 @@ static bool parse_certificate(private_x509_cert_t *this)
case OID_IP_ADDR_BLOCKS:
parse_ipAddrBlocks(object, level, this);
break;
+<<<<<<< HEAD
+=======
+ case OID_NAME_CONSTRAINTS:
+ parse_nameConstraints(object, level, this);
+ break;
+ case OID_CERTIFICATE_POLICIES:
+ parse_certificatePolicies(object, level, this);
+ break;
+ case OID_POLICY_MAPPINGS:
+ parse_policyMappings(object, level, this);
+ break;
+ case OID_POLICY_CONSTRAINTS:
+ parse_policyConstraints(object, level, this);
+ break;
+ case OID_INHIBIT_ANY_POLICY:
+ if (!asn1_parse_simple_object(&object, ASN1_INTEGER,
+ level, "inhibitAnyPolicy"))
+ {
+ goto end;
+ }
+ this->inhibit_any = parse_constraint(object);
+ break;
+>>>>>>> upstream/4.5.1
case OID_NS_REVOCATION_URL:
case OID_NS_CA_REVOCATION_URL:
case OID_NS_CA_POLICY_URL:
@@ -1022,9 +1543,15 @@ static bool parse_certificate(private_x509_cert_t *this)
break;
default:
if (critical && lib->settings->get_bool(lib->settings,
+<<<<<<< HEAD
"libstrongswan.plugins.x509.enforce_critical", FALSE))
{
DBG1(DBG_LIB, "critical %s extension not supported",
+=======
+ "libstrongswan.x509.enforce_critical", TRUE))
+ {
+ DBG1(DBG_LIB, "critical '%s' extension not supported",
+>>>>>>> upstream/4.5.1
(extn_oid == OID_UNKNOWN) ? "unknown" :
(char*)oid_names[extn_oid].name);
goto end;
@@ -1057,7 +1584,13 @@ end:
hasher_t *hasher;
/* check if the certificate is self-signed */
+<<<<<<< HEAD
if (issued_by(this, &this->public.interface.interface))
+=======
+ if (this->public.interface.interface.issued_by(
+ &this->public.interface.interface,
+ &this->public.interface.interface))
+>>>>>>> upstream/4.5.1
{
this->flags |= X509_SELF_SIGNED;
}
@@ -1074,34 +1607,54 @@ end:
return success;
}
+<<<<<<< HEAD
/**
* Implementation of certificate_t.get_type
*/
static certificate_type_t get_type(private_x509_cert_t *this)
+=======
+METHOD(certificate_t, get_type, certificate_type_t,
+ private_x509_cert_t *this)
+>>>>>>> upstream/4.5.1
{
return CERT_X509;
}
+<<<<<<< HEAD
/**
* Implementation of certificate_t.get_subject
*/
static identification_t* get_subject(private_x509_cert_t *this)
+=======
+METHOD(certificate_t, get_subject, identification_t*,
+ private_x509_cert_t *this)
+>>>>>>> upstream/4.5.1
{
return this->subject;
}
+<<<<<<< HEAD
/**
* Implementation of certificate_t.get_issuer
*/
static identification_t* get_issuer(private_x509_cert_t *this)
+=======
+METHOD(certificate_t, get_issuer, identification_t*,
+ private_x509_cert_t *this)
+>>>>>>> upstream/4.5.1
{
return this->issuer;
}
+<<<<<<< HEAD
/**
* Implementation of certificate_t.has_subject.
*/
static id_match_t has_subject(private_x509_cert_t *this, identification_t *subject)
+=======
+METHOD(certificate_t, has_subject, id_match_t,
+ private_x509_cert_t *this, identification_t *subject)
+>>>>>>> upstream/4.5.1
{
identification_t *current;
enumerator_t *enumerator;
@@ -1142,19 +1695,29 @@ static id_match_t has_subject(private_x509_cert_t *this, identification_t *subje
return best;
}
+<<<<<<< HEAD
/**
* Implementation of certificate_t.has_issuer.
*/
static id_match_t has_issuer(private_x509_cert_t *this, identification_t *issuer)
+=======
+METHOD(certificate_t, has_issuer, id_match_t,
+ private_x509_cert_t *this, identification_t *issuer)
+>>>>>>> upstream/4.5.1
{
/* issuerAltNames currently not supported */
return this->issuer->matches(this->issuer, issuer);
}
+<<<<<<< HEAD
/**
* Implementation of certificate_t.issued_by.
*/
static bool issued_by(private_x509_cert_t *this, certificate_t *issuer)
+=======
+METHOD(certificate_t, issued_by, bool,
+ private_x509_cert_t *this, certificate_t *issuer)
+>>>>>>> upstream/4.5.1
{
public_key_t *key;
signature_scheme_t scheme;
@@ -1201,15 +1764,21 @@ static bool issued_by(private_x509_cert_t *this, certificate_t *issuer)
return valid;
}
+<<<<<<< HEAD
/**
* Implementation of certificate_t.get_public_key
*/
static public_key_t* get_public_key(private_x509_cert_t *this)
+=======
+METHOD(certificate_t, get_public_key, public_key_t*,
+ private_x509_cert_t *this)
+>>>>>>> upstream/4.5.1
{
this->public_key->get_ref(this->public_key);
return this->public_key;
}
+<<<<<<< HEAD
/**
* Implementation of certificate_t.get_ref
*/
@@ -1232,6 +1801,18 @@ static x509_flag_t get_flags(private_x509_cert_t *this)
*/
static bool get_validity(private_x509_cert_t *this, time_t *when,
time_t *not_before, time_t *not_after)
+=======
+METHOD(certificate_t, get_ref, certificate_t*,
+ private_x509_cert_t *this)
+{
+ ref_get(&this->ref);
+ return &this->public.interface.interface;
+}
+
+METHOD(certificate_t, get_validity, bool,
+ private_x509_cert_t *this, time_t *when, time_t *not_before,
+ time_t *not_after)
+>>>>>>> upstream/4.5.1
{
time_t t = when ? *when : time(NULL);
@@ -1246,11 +1827,16 @@ static bool get_validity(private_x509_cert_t *this, time_t *when,
return (t >= this->notBefore && t <= this->notAfter);
}
+<<<<<<< HEAD
/**
* Implementation of certificate_t.get_encoding.
*/
static bool get_encoding(private_x509_cert_t *this, cred_encoding_type_t type,
chunk_t *encoding)
+=======
+METHOD(certificate_t, get_encoding, bool,
+ private_x509_cert_t *this, cred_encoding_type_t type, chunk_t *encoding)
+>>>>>>> upstream/4.5.1
{
if (type == CERT_ASN1_DER)
{
@@ -1261,10 +1847,15 @@ static bool get_encoding(private_x509_cert_t *this, cred_encoding_type_t type,
CRED_PART_X509_ASN1_DER, this->encoding, CRED_PART_END);
}
+<<<<<<< HEAD
/**
* Implementation of certificate_t.equals.
*/
static bool equals(private_x509_cert_t *this, certificate_t *other)
+=======
+METHOD(certificate_t, equals, bool,
+ private_x509_cert_t *this, certificate_t *other)
+>>>>>>> upstream/4.5.1
{
chunk_t encoding;
bool equal;
@@ -1290,18 +1881,34 @@ static bool equals(private_x509_cert_t *this, certificate_t *other)
return equal;
}
+<<<<<<< HEAD
/**
* Implementation of x509_t.get_serial.
*/
static chunk_t get_serial(private_x509_cert_t *this)
+=======
+METHOD(x509_t, get_flags, x509_flag_t,
+ private_x509_cert_t *this)
+{
+ return this->flags;
+}
+
+METHOD(x509_t, get_serial, chunk_t,
+ private_x509_cert_t *this)
+>>>>>>> upstream/4.5.1
{
return this->serialNumber;
}
+<<<<<<< HEAD
/**
* Implementation of x509_t.get_subjectKeyIdentifier.
*/
static chunk_t get_subjectKeyIdentifier(private_x509_cert_t *this)
+=======
+METHOD(x509_t, get_subjectKeyIdentifier, chunk_t,
+ private_x509_cert_t *this)
+>>>>>>> upstream/4.5.1
{
if (this->subjectKeyIdentifier.ptr)
{
@@ -1323,14 +1930,20 @@ static chunk_t get_subjectKeyIdentifier(private_x509_cert_t *this)
}
}
+<<<<<<< HEAD
/**
* Implementation of x509_t.get_authKeyIdentifier.
*/
static chunk_t get_authKeyIdentifier(private_x509_cert_t *this)
+=======
+METHOD(x509_t, get_authKeyIdentifier, chunk_t,
+ private_x509_cert_t *this)
+>>>>>>> upstream/4.5.1
{
return this->authKeyIdentifier;
}
+<<<<<<< HEAD
/**
* Implementation of x509_t.get_pathLenConstraint.
*/
@@ -1343,46 +1956,125 @@ static int get_pathLenConstraint(private_x509_cert_t *this)
* Implementation of x509_cert_t.create_subjectAltName_enumerator.
*/
static enumerator_t* create_subjectAltName_enumerator(private_x509_cert_t *this)
+=======
+METHOD(x509_t, get_constraint, u_int,
+ private_x509_cert_t *this, x509_constraint_t type)
+{
+ switch (type)
+ {
+ case X509_PATH_LEN:
+ return this->pathLenConstraint;
+ case X509_REQUIRE_EXPLICIT_POLICY:
+ return this->require_explicit;
+ case X509_INHIBIT_POLICY_MAPPING:
+ return this->inhibit_mapping;
+ case X509_INHIBIT_ANY_POLICY:
+ return this->inhibit_any;
+ default:
+ return X509_NO_CONSTRAINT;
+ }
+}
+
+METHOD(x509_t, create_subjectAltName_enumerator, enumerator_t*,
+ private_x509_cert_t *this)
+>>>>>>> upstream/4.5.1
{
return this->subjectAltNames->create_enumerator(this->subjectAltNames);
}
+<<<<<<< HEAD
/**
* Implementation of x509_cert_t.create_ocsp_uri_enumerator.
*/
static enumerator_t* create_ocsp_uri_enumerator(private_x509_cert_t *this)
+=======
+METHOD(x509_t, create_ocsp_uri_enumerator, enumerator_t*,
+ private_x509_cert_t *this)
+>>>>>>> upstream/4.5.1
{
return this->ocsp_uris->create_enumerator(this->ocsp_uris);
}
+<<<<<<< HEAD
/**
* Implementation of x509_cert_t.create_crl_uri_enumerator.
*/
static enumerator_t* create_crl_uri_enumerator(private_x509_cert_t *this)
+=======
+METHOD(x509_t, create_crl_uri_enumerator, enumerator_t*,
+ private_x509_cert_t *this)
+>>>>>>> upstream/4.5.1
{
return this->crl_uris->create_enumerator(this->crl_uris);
}
+<<<<<<< HEAD
/**
* Implementation of x509_cert_t.create_ipAddrBlock_enumerator.
*/
static enumerator_t* create_ipAddrBlock_enumerator(private_x509_cert_t *this)
+=======
+METHOD(x509_t, create_ipAddrBlock_enumerator, enumerator_t*,
+ private_x509_cert_t *this)
+>>>>>>> upstream/4.5.1
{
return this->ipAddrBlocks->create_enumerator(this->ipAddrBlocks);
}
+<<<<<<< HEAD
/**
* Implementation of certificate_t.destroy.
*/
static void destroy(private_x509_cert_t *this)
+=======
+METHOD(x509_t, create_name_constraint_enumerator, enumerator_t*,
+ private_x509_cert_t *this, bool perm)
+{
+ if (perm)
+ {
+ return this->permitted_names->create_enumerator(this->permitted_names);
+ }
+ return this->excluded_names->create_enumerator(this->excluded_names);
+}
+
+METHOD(x509_t, create_cert_policy_enumerator, enumerator_t*,
+ private_x509_cert_t *this)
+{
+ 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)
+>>>>>>> upstream/4.5.1
{
if (ref_put(&this->ref))
{
this->subjectAltNames->destroy_offset(this->subjectAltNames,
offsetof(identification_t, destroy));
+<<<<<<< HEAD
this->crl_uris->destroy_function(this->crl_uris, free);
this->ocsp_uris->destroy_function(this->ocsp_uris, free);
this->ipAddrBlocks->destroy_offset(this->ipAddrBlocks, offsetof(traffic_selector_t, destroy));
+=======
+ this->crl_uris->destroy_function(this->crl_uris, (void*)crl_uri_destroy);
+ this->ocsp_uris->destroy_function(this->ocsp_uris, free);
+ this->ipAddrBlocks->destroy_offset(this->ipAddrBlocks,
+ offsetof(traffic_selector_t, destroy));
+ this->permitted_names->destroy_offset(this->permitted_names,
+ offsetof(identification_t, destroy));
+ this->excluded_names->destroy_offset(this->excluded_names,
+ 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);
+>>>>>>> upstream/4.5.1
DESTROY_IF(this->issuer);
DESTROY_IF(this->subject);
DESTROY_IF(this->public_key);
@@ -1404,6 +2096,7 @@ static void destroy(private_x509_cert_t *this)
*/
static private_x509_cert_t* create_empty(void)
{
+<<<<<<< HEAD
private_x509_cert_t *this = malloc_thing(private_x509_cert_t);
this->public.interface.interface.get_type = (certificate_type_t (*) (certificate_t*))get_type;
@@ -1452,15 +2145,102 @@ static private_x509_cert_t* create_empty(void)
this->ref = 1;
this->parsed = FALSE;
+=======
+ private_x509_cert_t *this;
+
+ INIT(this,
+ .public = {
+ .interface = {
+ .interface = {
+ .get_type = _get_type,
+ .get_subject = _get_subject,
+ .get_issuer = _get_issuer,
+ .has_subject = _has_subject,
+ .has_issuer = _has_issuer,
+ .issued_by = _issued_by,
+ .get_public_key = _get_public_key,
+ .get_validity = _get_validity,
+ .get_encoding = _get_encoding,
+ .equals = _equals,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ .get_flags = _get_flags,
+ .get_serial = _get_serial,
+ .get_subjectKeyIdentifier = _get_subjectKeyIdentifier,
+ .get_authKeyIdentifier = _get_authKeyIdentifier,
+ .get_constraint = _get_constraint,
+ .create_subjectAltName_enumerator = _create_subjectAltName_enumerator,
+ .create_crl_uri_enumerator = _create_crl_uri_enumerator,
+ .create_ocsp_uri_enumerator = _create_ocsp_uri_enumerator,
+ .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,
+ .subjectAltNames = linked_list_create(),
+ .crl_uris = linked_list_create(),
+ .ocsp_uris = linked_list_create(),
+ .ipAddrBlocks = linked_list_create(),
+ .permitted_names = linked_list_create(),
+ .excluded_names = linked_list_create(),
+ .cert_policies = linked_list_create(),
+ .policy_mappings = linked_list_create(),
+ .pathLenConstraint = X509_NO_CONSTRAINT,
+ .require_explicit = X509_NO_CONSTRAINT,
+ .inhibit_mapping = X509_NO_CONSTRAINT,
+ .inhibit_any = X509_NO_CONSTRAINT,
+ .ref = 1,
+ );
+>>>>>>> upstream/4.5.1
return this;
}
/**
+<<<<<<< HEAD
+=======
+ * Build a generalName from an id
+ */
+chunk_t build_generalName(identification_t *id)
+{
+ int context;
+
+ switch (id->get_type(id))
+ {
+ case ID_RFC822_ADDR:
+ context = ASN1_CONTEXT_S_1;
+ break;
+ case ID_FQDN:
+ context = ASN1_CONTEXT_S_2;
+ break;
+ case ID_DER_ASN1_DN:
+ context = ASN1_CONTEXT_C_4;
+ break;
+ case ID_IPV4_ADDR:
+ case ID_IPV6_ADDR:
+ context = ASN1_CONTEXT_S_7;
+ break;
+ default:
+ DBG1(DBG_LIB, "encoding %N as generalName not supported",
+ id_type_names, id->get_type(id));
+ return chunk_empty;
+ }
+ return asn1_wrap(context, "c", id->get_encoding(id));
+}
+
+/**
+>>>>>>> upstream/4.5.1
* Encode a linked list of subjectAltNames
*/
chunk_t x509_build_subjectAltNames(linked_list_t *list)
{
+<<<<<<< HEAD
chunk_t subjectAltNames = chunk_empty;
+=======
+ chunk_t subjectAltNames = chunk_empty, name;
+>>>>>>> upstream/4.5.1
enumerator_t *enumerator;
identification_t *id;
@@ -1472,6 +2252,7 @@ chunk_t x509_build_subjectAltNames(linked_list_t *list)
enumerator = list->create_enumerator(list);
while (enumerator->enumerate(enumerator, &id))
{
+<<<<<<< HEAD
int context;
chunk_t name;
@@ -1495,6 +2276,9 @@ chunk_t x509_build_subjectAltNames(linked_list_t *list)
return chunk_empty;
}
name = asn1_wrap(context, "c", id->get_encoding(id));
+=======
+ name = build_generalName(id);
+>>>>>>> upstream/4.5.1
subjectAltNames = chunk_cat("mm", subjectAltNames, name);
}
enumerator->destroy(enumerator);
@@ -1508,6 +2292,50 @@ chunk_t x509_build_subjectAltNames(linked_list_t *list)
}
/**
+<<<<<<< HEAD
+=======
+ * Encode CRL distribution points extension from a x509_cdp_t list
+ */
+chunk_t x509_build_crlDistributionPoints(linked_list_t *list, int extn)
+{
+ chunk_t crlDistributionPoints = chunk_empty;
+ enumerator_t *enumerator;
+ x509_cdp_t *cdp;
+
+ if (list->get_count(list) == 0)
+ {
+ return chunk_empty;
+ }
+
+ enumerator = list->create_enumerator(list);
+ while (enumerator->enumerate(enumerator, &cdp))
+ {
+ chunk_t distributionPoint, crlIssuer = chunk_empty;
+
+ if (cdp->issuer)
+ {
+ crlIssuer = asn1_wrap(ASN1_CONTEXT_C_2, "m",
+ build_generalName(cdp->issuer));
+ }
+ distributionPoint = asn1_wrap(ASN1_SEQUENCE, "mm",
+ asn1_wrap(ASN1_CONTEXT_C_0, "m",
+ asn1_wrap(ASN1_CONTEXT_C_0, "m",
+ asn1_wrap(ASN1_CONTEXT_S_6, "c",
+ chunk_create(cdp->uri, strlen(cdp->uri))))),
+ crlIssuer);
+ crlDistributionPoints = chunk_cat("mm", crlDistributionPoints,
+ distributionPoint);
+ }
+ enumerator->destroy(enumerator);
+
+ return asn1_wrap(ASN1_SEQUENCE, "mm",
+ asn1_build_known_oid(extn),
+ asn1_wrap(ASN1_OCTET_STRING, "m",
+ asn1_wrap(ASN1_SEQUENCE, "m", crlDistributionPoints)));
+}
+
+/**
+>>>>>>> upstream/4.5.1
* Generate and sign a new certificate
*/
static bool generate(private_x509_cert_t *cert, certificate_t *sign_cert,
@@ -1515,12 +2343,22 @@ static bool generate(private_x509_cert_t *cert, certificate_t *sign_cert,
{
chunk_t extensions = chunk_empty, extendedKeyUsage = chunk_empty;
chunk_t serverAuth = chunk_empty, clientAuth = chunk_empty;
+<<<<<<< HEAD
chunk_t ocspSigning = chunk_empty;
chunk_t basicConstraints = chunk_empty;
chunk_t keyUsage = chunk_empty;
chunk_t subjectAltNames = chunk_empty;
chunk_t subjectKeyIdentifier = chunk_empty, authKeyIdentifier = chunk_empty;
chunk_t crlDistributionPoints = chunk_empty, authorityInfoAccess = chunk_empty;
+=======
+ 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, policyMappings = chunk_empty;
+ chunk_t subjectKeyIdentifier = chunk_empty, authKeyIdentifier = chunk_empty;
+ chunk_t crlDistributionPoints = chunk_empty, authorityInfoAccess = chunk_empty;
+ chunk_t policyConstraints = chunk_empty, inhibitAnyPolicy = chunk_empty;
+>>>>>>> upstream/4.5.1
identification_t *issuer, *subject;
chunk_t key_info;
signature_scheme_t scheme;
@@ -1574,6 +2412,7 @@ static bool generate(private_x509_cert_t *cert, certificate_t *sign_cert,
/* encode subjectAltNames */
subjectAltNames = x509_build_subjectAltNames(cert->subjectAltNames);
+<<<<<<< HEAD
/* encode CRL distribution points extension */
enumerator = cert->crl_uris->create_enumerator(cert->crl_uris);
while (enumerator->enumerate(enumerator, &uri))
@@ -1597,6 +2436,10 @@ static bool generate(private_x509_cert_t *cert, certificate_t *sign_cert,
asn1_wrap(ASN1_OCTET_STRING, "m",
asn1_wrap(ASN1_SEQUENCE, "m", crlDistributionPoints)));
}
+=======
+ crlDistributionPoints = x509_build_crlDistributionPoints(cert->crl_uris,
+ OID_CRL_DISTRIBUTION_POINTS);
+>>>>>>> upstream/4.5.1
/* encode OCSP URIs in authorityInfoAccess extension */
enumerator = cert->ocsp_uris->create_enumerator(cert->ocsp_uris);
@@ -1625,11 +2468,18 @@ static bool generate(private_x509_cert_t *cert, certificate_t *sign_cert,
{
chunk_t pathLenConstraint = chunk_empty;
+<<<<<<< HEAD
if (cert->pathLenConstraint != X509_NO_PATH_LEN_CONSTRAINT)
{
char pathlen = (char)cert->pathLenConstraint;
pathLenConstraint = asn1_integer("c", chunk_from_thing(pathlen));
+=======
+ if (cert->pathLenConstraint != X509_NO_CONSTRAINT)
+ {
+ pathLenConstraint = asn1_integer("c",
+ chunk_from_thing(cert->pathLenConstraint));
+>>>>>>> upstream/4.5.1
}
basicConstraints = asn1_wrap(ASN1_SEQUENCE, "mmm",
asn1_build_known_oid(OID_BASIC_CONSTRAINTS),
@@ -1640,6 +2490,7 @@ static bool generate(private_x509_cert_t *cert, certificate_t *sign_cert,
asn1_wrap(ASN1_BOOLEAN, "c",
chunk_from_chars(0xFF)),
pathLenConstraint)));
+<<<<<<< HEAD
keyUsage = asn1_wrap(ASN1_SEQUENCE, "mmm",
asn1_build_known_oid(OID_KEY_USAGE),
asn1_wrap(ASN1_BOOLEAN, "c",
@@ -1647,6 +2498,22 @@ static bool generate(private_x509_cert_t *cert, certificate_t *sign_cert,
asn1_wrap(ASN1_OCTET_STRING, "m",
asn1_wrap(ASN1_BIT_STRING, "c",
chunk_from_chars(0x01, 0x06))));
+=======
+ /* set CertificateSign and implicitly CRLsign */
+ keyUsageBits = chunk_from_chars(0x01, 0x06);
+ }
+ else if (cert->flags & X509_CRL_SIGN)
+ {
+ keyUsageBits = chunk_from_chars(0x01, 0x02);
+ }
+ if (keyUsageBits.len)
+ {
+ keyUsage = asn1_wrap(ASN1_SEQUENCE, "mmm",
+ asn1_build_known_oid(OID_KEY_USAGE),
+ asn1_wrap(ASN1_BOOLEAN, "c", chunk_from_chars(0xFF)),
+ asn1_wrap(ASN1_OCTET_STRING, "m",
+ asn1_wrap(ASN1_BIT_STRING, "c", keyUsageBits)));
+>>>>>>> upstream/4.5.1
}
/* add serverAuth extendedKeyUsage flag */
@@ -1675,7 +2542,11 @@ static bool generate(private_x509_cert_t *cert, certificate_t *sign_cert,
}
/* add subjectKeyIdentifier to CA and OCSP signer certificates */
+<<<<<<< HEAD
if (cert->flags & (X509_CA | X509_OCSP_SIGNER))
+=======
+ if (cert->flags & (X509_CA | X509_OCSP_SIGNER | X509_CRL_SIGN))
+>>>>>>> upstream/4.5.1
{
chunk_t keyid;
@@ -1703,6 +2574,7 @@ static bool generate(private_x509_cert_t *cert, certificate_t *sign_cert,
asn1_wrap(ASN1_CONTEXT_S_0, "c", keyid))));
}
}
+<<<<<<< HEAD
if (basicConstraints.ptr || subjectAltNames.ptr || authKeyIdentifier.ptr ||
crlDistributionPoints.ptr)
{
@@ -1712,6 +2584,155 @@ static bool generate(private_x509_cert_t *cert, certificate_t *sign_cert,
authKeyIdentifier, subjectAltNames,
extendedKeyUsage, crlDistributionPoints,
authorityInfoAccess));
+=======
+
+ if (cert->permitted_names->get_count(cert->permitted_names) ||
+ cert->excluded_names->get_count(cert->excluded_names))
+ {
+ chunk_t permitted = chunk_empty, excluded = chunk_empty, subtree;
+ identification_t *id;
+
+ enumerator = create_name_constraint_enumerator(cert, TRUE);
+ while (enumerator->enumerate(enumerator, &id))
+ {
+ subtree = asn1_wrap(ASN1_SEQUENCE, "m", build_generalName(id));
+ permitted = chunk_cat("mm", permitted, subtree);
+ }
+ enumerator->destroy(enumerator);
+ if (permitted.ptr)
+ {
+ permitted = asn1_wrap(ASN1_CONTEXT_C_0, "m", permitted);
+ }
+
+ enumerator = create_name_constraint_enumerator(cert, FALSE);
+ while (enumerator->enumerate(enumerator, &id))
+ {
+ subtree = asn1_wrap(ASN1_SEQUENCE, "m", build_generalName(id));
+ excluded = chunk_cat("mm", excluded, subtree);
+ }
+ enumerator->destroy(enumerator);
+ if (excluded.ptr)
+ {
+ excluded = asn1_wrap(ASN1_CONTEXT_C_1, "m", excluded);
+ }
+
+ nameConstraints = asn1_wrap(ASN1_SEQUENCE, "mm",
+ asn1_build_known_oid(OID_NAME_CONSTRAINTS),
+ asn1_wrap(ASN1_OCTET_STRING, "m",
+ asn1_wrap(ASN1_SEQUENCE, "mm",
+ permitted, excluded)));
+ }
+
+ if (cert->cert_policies->get_count(cert->cert_policies))
+ {
+ x509_cert_policy_t *policy;
+
+ enumerator = create_cert_policy_enumerator(cert);
+ while (enumerator->enumerate(enumerator, &policy))
+ {
+ chunk_t chunk = chunk_empty, cps = chunk_empty, notice = chunk_empty;
+
+ if (policy->cps_uri)
+ {
+ cps = asn1_wrap(ASN1_SEQUENCE, "mm",
+ asn1_build_known_oid(OID_POLICY_QUALIFIER_CPS),
+ asn1_wrap(ASN1_IA5STRING, "c",
+ chunk_create(policy->cps_uri,
+ strlen(policy->cps_uri))));
+ }
+ if (policy->unotice_text)
+ {
+ notice = asn1_wrap(ASN1_SEQUENCE, "mm",
+ asn1_build_known_oid(OID_POLICY_QUALIFIER_UNOTICE),
+ asn1_wrap(ASN1_SEQUENCE, "m",
+ asn1_wrap(ASN1_VISIBLESTRING, "c",
+ chunk_create(policy->unotice_text,
+ strlen(policy->unotice_text)))));
+ }
+ if (cps.len || notice.len)
+ {
+ chunk = asn1_wrap(ASN1_SEQUENCE, "mm", cps, notice);
+ }
+ chunk = asn1_wrap(ASN1_SEQUENCE, "mm",
+ asn1_wrap(ASN1_OID, "c", policy->oid), chunk);
+ certPolicies = chunk_cat("mm", certPolicies, chunk);
+ }
+ enumerator->destroy(enumerator);
+
+ certPolicies = asn1_wrap(ASN1_SEQUENCE, "mm",
+ asn1_build_known_oid(OID_CERTIFICATE_POLICIES),
+ asn1_wrap(ASN1_OCTET_STRING, "m",
+ 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 (cert->inhibit_mapping != X509_NO_CONSTRAINT ||
+ cert->require_explicit != X509_NO_CONSTRAINT)
+ {
+ chunk_t inhibit = chunk_empty, explicit = chunk_empty;
+
+ if (cert->require_explicit != X509_NO_CONSTRAINT)
+ {
+ explicit = asn1_wrap(ASN1_CONTEXT_C_0, "m",
+ asn1_integer("c",
+ chunk_from_thing(cert->require_explicit)));
+ }
+ if (cert->inhibit_mapping != X509_NO_CONSTRAINT)
+ {
+ inhibit = asn1_wrap(ASN1_CONTEXT_C_1, "m",
+ asn1_integer("c",
+ chunk_from_thing(cert->inhibit_mapping)));
+ }
+ policyConstraints = asn1_wrap(ASN1_SEQUENCE, "mmm",
+ asn1_build_known_oid(OID_POLICY_CONSTRAINTS),
+ asn1_wrap(ASN1_BOOLEAN, "c", chunk_from_chars(0xFF)),
+ asn1_wrap(ASN1_OCTET_STRING, "m",
+ asn1_wrap(ASN1_SEQUENCE, "mm",
+ explicit, inhibit)));
+ }
+
+ if (cert->inhibit_any != X509_NO_CONSTRAINT)
+ {
+ inhibitAnyPolicy = asn1_wrap(ASN1_SEQUENCE, "mmm",
+ asn1_build_known_oid(OID_INHIBIT_ANY_POLICY),
+ asn1_wrap(ASN1_BOOLEAN, "c", chunk_from_chars(0xFF)),
+ asn1_wrap(ASN1_OCTET_STRING, "m",
+ asn1_integer("c",
+ chunk_from_thing(cert->inhibit_any))));
+ }
+
+ if (basicConstraints.ptr || subjectAltNames.ptr || authKeyIdentifier.ptr ||
+ crlDistributionPoints.ptr || nameConstraints.ptr)
+ {
+ extensions = asn1_wrap(ASN1_CONTEXT_C_3, "m",
+ asn1_wrap(ASN1_SEQUENCE, "mmmmmmmmmmmmm",
+ basicConstraints, keyUsage, subjectKeyIdentifier,
+ authKeyIdentifier, subjectAltNames,
+ extendedKeyUsage, crlDistributionPoints,
+ authorityInfoAccess, nameConstraints, certPolicies,
+ policyMappings, policyConstraints, inhibitAnyPolicy));
+>>>>>>> upstream/4.5.1
}
cert->tbsCertificate = asn1_wrap(ASN1_SEQUENCE, "mmmcmcmm",
@@ -1794,6 +2815,10 @@ x509_cert_t *x509_cert_gen(certificate_type_t type, va_list args)
certificate_t *sign_cert = NULL;
private_key_t *sign_key = NULL;
hash_algorithm_t digest_alg = HASH_SHA1;
+<<<<<<< HEAD
+=======
+ u_int constraint;
+>>>>>>> upstream/4.5.1
cert = create_empty();
while (TRUE)
@@ -1837,6 +2862,7 @@ x509_cert_t *x509_cert_gen(certificate_type_t type, va_list args)
{
enumerator_t *enumerator;
linked_list_t *list;
+<<<<<<< HEAD
char *uri;
list = va_arg(args, linked_list_t*);
@@ -1844,6 +2870,19 @@ x509_cert_t *x509_cert_gen(certificate_type_t type, va_list args)
while (enumerator->enumerate(enumerator, &uri))
{
cert->crl_uris->insert_last(cert->crl_uris, strdup(uri));
+=======
+ x509_cdp_t *in, *cdp;
+
+ list = va_arg(args, linked_list_t*);
+ enumerator = list->create_enumerator(list);
+ while (enumerator->enumerate(enumerator, &in))
+ {
+ INIT(cdp,
+ .uri = strdup(in->uri),
+ .issuer = in->issuer ? in->issuer->clone(in->issuer) : NULL,
+ );
+ cert->crl_uris->insert_last(cert->crl_uris, cdp);
+>>>>>>> upstream/4.5.1
}
enumerator->destroy(enumerator);
continue;
@@ -1864,11 +2903,104 @@ x509_cert_t *x509_cert_gen(certificate_type_t type, va_list args)
continue;
}
case BUILD_PATHLEN:
+<<<<<<< HEAD
cert->pathLenConstraint = va_arg(args, int);
if (cert->pathLenConstraint < 0 || cert->pathLenConstraint > 127)
{
cert->pathLenConstraint = X509_NO_PATH_LEN_CONSTRAINT;
}
+=======
+ constraint = va_arg(args, u_int);
+ cert->pathLenConstraint = (constraint < 128) ?
+ constraint : X509_NO_CONSTRAINT;
+ continue;
+ case BUILD_PERMITTED_NAME_CONSTRAINTS:
+ {
+ enumerator_t *enumerator;
+ linked_list_t *list;
+ identification_t *constraint;
+
+ list = va_arg(args, linked_list_t*);
+ enumerator = list->create_enumerator(list);
+ while (enumerator->enumerate(enumerator, &constraint))
+ {
+ cert->permitted_names->insert_last(cert->permitted_names,
+ constraint->clone(constraint));
+ }
+ enumerator->destroy(enumerator);
+ continue;
+ }
+ case BUILD_EXCLUDED_NAME_CONSTRAINTS:
+ {
+ enumerator_t *enumerator;
+ linked_list_t *list;
+ identification_t *constraint;
+
+ list = va_arg(args, linked_list_t*);
+ enumerator = list->create_enumerator(list);
+ while (enumerator->enumerate(enumerator, &constraint))
+ {
+ cert->excluded_names->insert_last(cert->excluded_names,
+ constraint->clone(constraint));
+ }
+ enumerator->destroy(enumerator);
+ continue;
+ }
+ case BUILD_CERTIFICATE_POLICIES:
+ {
+ enumerator_t *enumerator;
+ linked_list_t *list;
+ x509_cert_policy_t *policy, *in;
+
+ list = va_arg(args, linked_list_t*);
+ enumerator = list->create_enumerator(list);
+ while (enumerator->enumerate(enumerator, &in))
+ {
+ INIT(policy,
+ .oid = chunk_clone(in->oid),
+ .cps_uri = strdupnull(in->cps_uri),
+ .unotice_text = strdupnull(in->unotice_text),
+ );
+ cert->cert_policies->insert_last(cert->cert_policies, policy);
+ }
+ 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_POLICY_REQUIRE_EXPLICIT:
+ constraint = va_arg(args, u_int);
+ cert->require_explicit = (constraint < 128) ?
+ constraint : X509_NO_CONSTRAINT;
+ continue;
+ case BUILD_POLICY_INHIBIT_MAPPING:
+ constraint = va_arg(args, u_int);
+ cert->inhibit_mapping = (constraint < 128) ?
+ constraint : X509_NO_CONSTRAINT;
+ continue;
+ case BUILD_POLICY_INHIBIT_ANY:
+ constraint = va_arg(args, u_int);
+ cert->inhibit_any = (constraint < 128) ?
+ constraint : X509_NO_CONSTRAINT;
+>>>>>>> upstream/4.5.1
continue;
case BUILD_NOT_BEFORE_TIME:
cert->notBefore = va_arg(args, time_t);