Added support for policyConstraints to x509 plugin
This commit is contained in:
@@ -55,7 +55,7 @@
|
|||||||
0x00 "anyPolicy" OID_ANY_POLICY
|
0x00 "anyPolicy" OID_ANY_POLICY
|
||||||
0x21 "policyMappings" OID_POLICY_MAPPINGS
|
0x21 "policyMappings" OID_POLICY_MAPPINGS
|
||||||
0x23 "authorityKeyIdentifier" OID_AUTHORITY_KEY_ID
|
0x23 "authorityKeyIdentifier" OID_AUTHORITY_KEY_ID
|
||||||
0x24 "policyConstraints"
|
0x24 "policyConstraints" OID_POLICY_CONSTRAINTS
|
||||||
0x25 "extendedKeyUsage" OID_EXTENDED_KEY_USAGE
|
0x25 "extendedKeyUsage" OID_EXTENDED_KEY_USAGE
|
||||||
0x00 "anyExtendedKeyUsage"
|
0x00 "anyExtendedKeyUsage"
|
||||||
0x2E "freshestCRL" OID_FRESHEST_CRL
|
0x2E "freshestCRL" OID_FRESHEST_CRL
|
||||||
|
|||||||
@@ -48,6 +48,8 @@ ENUM(builder_part_names, BUILD_FROM_FILE, BUILD_END,
|
|||||||
"BUILD_EXCLUDED_NAME_CONSTRAINTS",
|
"BUILD_EXCLUDED_NAME_CONSTRAINTS",
|
||||||
"BUILD_CERTIFICATE_POLICIES",
|
"BUILD_CERTIFICATE_POLICIES",
|
||||||
"BUILD_POLICY_MAPPINGS",
|
"BUILD_POLICY_MAPPINGS",
|
||||||
|
"BUILD_POLICY_CONSTRAINT_EXPLICIT",
|
||||||
|
"BUILD_POLICY_CONSTRAINT_INHIBIT",
|
||||||
"BUILD_X509_FLAG",
|
"BUILD_X509_FLAG",
|
||||||
"BUILD_REVOKED_ENUMERATOR",
|
"BUILD_REVOKED_ENUMERATOR",
|
||||||
"BUILD_CHALLENGE_PWD",
|
"BUILD_CHALLENGE_PWD",
|
||||||
|
|||||||
@@ -103,6 +103,10 @@ enum builder_part_t {
|
|||||||
BUILD_CERTIFICATE_POLICIES,
|
BUILD_CERTIFICATE_POLICIES,
|
||||||
/** policyMapping OIDs, linked_list_t* of x509_policy_mapping_t* */
|
/** policyMapping OIDs, linked_list_t* of x509_policy_mapping_t* */
|
||||||
BUILD_POLICY_MAPPINGS,
|
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 */
|
/** enforce an additional X509 flag, x509_flag_t */
|
||||||
BUILD_X509_FLAG,
|
BUILD_X509_FLAG,
|
||||||
/** enumerator_t over (chunk_t serial, time_t date, crl_reason_t reason) */
|
/** enumerator_t over (chunk_t serial, time_t date, crl_reason_t reason) */
|
||||||
|
|||||||
@@ -121,10 +121,18 @@ struct x509_t {
|
|||||||
/**
|
/**
|
||||||
* Get an optional path length constraint.
|
* 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);
|
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.
|
* Create an enumerator over all subjectAltNames.
|
||||||
*
|
*
|
||||||
@@ -174,6 +182,8 @@ struct x509_t {
|
|||||||
* @return enumerator over x509_policy_mapping
|
* @return enumerator over x509_policy_mapping
|
||||||
*/
|
*/
|
||||||
enumerator_t* (*create_policy_mapping_enumerator)(x509_t *this);
|
enumerator_t* (*create_policy_mapping_enumerator)(x509_t *this);
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /** X509_H_ @}*/
|
#endif /** X509_H_ @}*/
|
||||||
|
|||||||
@@ -277,6 +277,12 @@ METHOD(x509_t, get_pathLenConstraint, int,
|
|||||||
return this->pathlen;
|
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*,
|
METHOD(x509_t, create_subjectAltName_enumerator, enumerator_t*,
|
||||||
private_openssl_x509_t *this)
|
private_openssl_x509_t *this)
|
||||||
{
|
{
|
||||||
@@ -568,6 +574,7 @@ static private_openssl_x509_t *create_empty()
|
|||||||
.get_subjectKeyIdentifier = _get_subjectKeyIdentifier,
|
.get_subjectKeyIdentifier = _get_subjectKeyIdentifier,
|
||||||
.get_authKeyIdentifier = _get_authKeyIdentifier,
|
.get_authKeyIdentifier = _get_authKeyIdentifier,
|
||||||
.get_pathLenConstraint = _get_pathLenConstraint,
|
.get_pathLenConstraint = _get_pathLenConstraint,
|
||||||
|
.get_policyConstraint = _get_policyConstraint,
|
||||||
.create_subjectAltName_enumerator = _create_subjectAltName_enumerator,
|
.create_subjectAltName_enumerator = _create_subjectAltName_enumerator,
|
||||||
.create_crl_uri_enumerator = _create_crl_uri_enumerator,
|
.create_crl_uri_enumerator = _create_crl_uri_enumerator,
|
||||||
.create_ocsp_uri_enumerator = _create_ocsp_uri_enumerator,
|
.create_ocsp_uri_enumerator = _create_ocsp_uri_enumerator,
|
||||||
|
|||||||
@@ -174,7 +174,17 @@ struct private_x509_cert_t {
|
|||||||
/**
|
/**
|
||||||
* Path Length Constraint
|
* Path Length Constraint
|
||||||
*/
|
*/
|
||||||
int pathLenConstraint;
|
char pathLenConstraint;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* requireExplicitPolicy Constraint
|
||||||
|
*/
|
||||||
|
char explicit_policy_constraint;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* inhibitPolicyMapping Constraint
|
||||||
|
*/
|
||||||
|
char inhibit_policy_constraint;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* x509 constraints and other flags
|
* x509 constraints and other flags
|
||||||
@@ -1030,6 +1040,66 @@ static void parse_policyMappings(chunk_t blob, int level0,
|
|||||||
parser->destroy(parser);
|
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:
|
||||||
|
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
|
* ASN.1 definition of ipAddrBlocks according to RFC 3779
|
||||||
*/
|
*/
|
||||||
@@ -1348,6 +1418,9 @@ static bool parse_certificate(private_x509_cert_t *this)
|
|||||||
case OID_POLICY_MAPPINGS:
|
case OID_POLICY_MAPPINGS:
|
||||||
parse_policyMappings(object, level, this);
|
parse_policyMappings(object, level, this);
|
||||||
break;
|
break;
|
||||||
|
case OID_POLICY_CONSTRAINTS:
|
||||||
|
parse_policyConstraints(object, level, this);
|
||||||
|
break;
|
||||||
case OID_NS_REVOCATION_URL:
|
case OID_NS_REVOCATION_URL:
|
||||||
case OID_NS_CA_REVOCATION_URL:
|
case OID_NS_CA_REVOCATION_URL:
|
||||||
case OID_NS_CA_POLICY_URL:
|
case OID_NS_CA_POLICY_URL:
|
||||||
@@ -1646,6 +1719,16 @@ METHOD(x509_t, get_pathLenConstraint, int,
|
|||||||
return this->pathLenConstraint;
|
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*,
|
METHOD(x509_t, create_subjectAltName_enumerator, enumerator_t*,
|
||||||
private_x509_cert_t *this)
|
private_x509_cert_t *this)
|
||||||
{
|
{
|
||||||
@@ -1782,6 +1865,7 @@ static private_x509_cert_t* create_empty(void)
|
|||||||
.get_subjectKeyIdentifier = _get_subjectKeyIdentifier,
|
.get_subjectKeyIdentifier = _get_subjectKeyIdentifier,
|
||||||
.get_authKeyIdentifier = _get_authKeyIdentifier,
|
.get_authKeyIdentifier = _get_authKeyIdentifier,
|
||||||
.get_pathLenConstraint = _get_pathLenConstraint,
|
.get_pathLenConstraint = _get_pathLenConstraint,
|
||||||
|
.get_policyConstraint = _get_policyConstraint,
|
||||||
.create_subjectAltName_enumerator = _create_subjectAltName_enumerator,
|
.create_subjectAltName_enumerator = _create_subjectAltName_enumerator,
|
||||||
.create_crl_uri_enumerator = _create_crl_uri_enumerator,
|
.create_crl_uri_enumerator = _create_crl_uri_enumerator,
|
||||||
.create_ocsp_uri_enumerator = _create_ocsp_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(),
|
.cert_policies = linked_list_create(),
|
||||||
.policy_mappings = linked_list_create(),
|
.policy_mappings = linked_list_create(),
|
||||||
.pathLenConstraint = X509_NO_CONSTRAINT,
|
.pathLenConstraint = X509_NO_CONSTRAINT,
|
||||||
|
.explicit_policy_constraint = X509_NO_CONSTRAINT,
|
||||||
|
.inhibit_policy_constraint = X509_NO_CONSTRAINT,
|
||||||
.ref = 1,
|
.ref = 1,
|
||||||
);
|
);
|
||||||
return this;
|
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 subjectAltNames = chunk_empty, policyMappings = chunk_empty;
|
||||||
chunk_t subjectKeyIdentifier = chunk_empty, authKeyIdentifier = chunk_empty;
|
chunk_t subjectKeyIdentifier = chunk_empty, authKeyIdentifier = chunk_empty;
|
||||||
chunk_t crlDistributionPoints = chunk_empty, authorityInfoAccess = chunk_empty;
|
chunk_t crlDistributionPoints = chunk_empty, authorityInfoAccess = chunk_empty;
|
||||||
|
chunk_t policyConstraints = chunk_empty;
|
||||||
identification_t *issuer, *subject;
|
identification_t *issuer, *subject;
|
||||||
crl_uri_t *entry;
|
crl_uri_t *entry;
|
||||||
chunk_t key_info;
|
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)
|
if (cert->pathLenConstraint != X509_NO_CONSTRAINT)
|
||||||
{
|
{
|
||||||
char pathlen = (char)cert->pathLenConstraint;
|
pathLenConstraint = asn1_integer("c",
|
||||||
|
chunk_from_thing(cert->pathLenConstraint));
|
||||||
pathLenConstraint = asn1_integer("c", chunk_from_thing(pathlen));
|
|
||||||
}
|
}
|
||||||
basicConstraints = asn1_wrap(ASN1_SEQUENCE, "mmm",
|
basicConstraints = asn1_wrap(ASN1_SEQUENCE, "mmm",
|
||||||
asn1_build_known_oid(OID_BASIC_CONSTRAINTS),
|
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)));
|
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 ||
|
if (basicConstraints.ptr || subjectAltNames.ptr || authKeyIdentifier.ptr ||
|
||||||
crlDistributionPoints.ptr || nameConstraints.ptr)
|
crlDistributionPoints.ptr || nameConstraints.ptr)
|
||||||
{
|
{
|
||||||
extensions = asn1_wrap(ASN1_CONTEXT_C_3, "m",
|
extensions = asn1_wrap(ASN1_CONTEXT_C_3, "m",
|
||||||
asn1_wrap(ASN1_SEQUENCE, "mmmmmmmmmmm",
|
asn1_wrap(ASN1_SEQUENCE, "mmmmmmmmmmmm",
|
||||||
basicConstraints, keyUsage, subjectKeyIdentifier,
|
basicConstraints, keyUsage, subjectKeyIdentifier,
|
||||||
authKeyIdentifier, subjectAltNames,
|
authKeyIdentifier, subjectAltNames,
|
||||||
extendedKeyUsage, crlDistributionPoints,
|
extendedKeyUsage, crlDistributionPoints,
|
||||||
authorityInfoAccess, nameConstraints, certPolicies,
|
authorityInfoAccess, nameConstraints, certPolicies,
|
||||||
policyMappings));
|
policyMappings, policyConstraints));
|
||||||
}
|
}
|
||||||
|
|
||||||
cert->tbsCertificate = asn1_wrap(ASN1_SEQUENCE, "mmmcmcmm",
|
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);
|
enumerator->destroy(enumerator);
|
||||||
continue;
|
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:
|
case BUILD_NOT_BEFORE_TIME:
|
||||||
cert->notBefore = va_arg(args, time_t);
|
cert->notBefore = va_arg(args, time_t);
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
Reference in New Issue
Block a user