Added support for generating NameConstraints in x509 plugin
This commit is contained in:
@@ -44,6 +44,8 @@ ENUM(builder_part_names, BUILD_FROM_FILE, BUILD_END,
|
|||||||
"BUILD_CRL_ISSUER",
|
"BUILD_CRL_ISSUER",
|
||||||
"BUILD_OCSP_ACCESS_LOCATIONS",
|
"BUILD_OCSP_ACCESS_LOCATIONS",
|
||||||
"BUILD_PATHLEN",
|
"BUILD_PATHLEN",
|
||||||
|
"BUILD_PERMITTED_NAME_CONSTRAINTS",
|
||||||
|
"BUILD_EXCLUDED_NAME_CONSTRAINTS",
|
||||||
"BUILD_X509_FLAG",
|
"BUILD_X509_FLAG",
|
||||||
"BUILD_REVOKED_ENUMERATOR",
|
"BUILD_REVOKED_ENUMERATOR",
|
||||||
"BUILD_CHALLENGE_PWD",
|
"BUILD_CHALLENGE_PWD",
|
||||||
|
|||||||
@@ -95,6 +95,10 @@ enum builder_part_t {
|
|||||||
BUILD_OCSP_ACCESS_LOCATIONS,
|
BUILD_OCSP_ACCESS_LOCATIONS,
|
||||||
/** certificate path length constraint */
|
/** certificate path length constraint */
|
||||||
BUILD_PATHLEN,
|
BUILD_PATHLEN,
|
||||||
|
/** permitted X509 name constraints, linked_list_t* of identification_t* */
|
||||||
|
BUILD_PERMITTED_NAME_CONSTRAINTS,
|
||||||
|
/** excluded X509 name constraints, linked_list_t* of identification_t* */
|
||||||
|
BUILD_EXCLUDED_NAME_CONSTRAINTS,
|
||||||
/** 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) */
|
||||||
|
|||||||
@@ -1693,7 +1693,7 @@ static bool generate(private_x509_cert_t *cert, certificate_t *sign_cert,
|
|||||||
chunk_t extensions = chunk_empty, extendedKeyUsage = chunk_empty;
|
chunk_t extensions = chunk_empty, extendedKeyUsage = chunk_empty;
|
||||||
chunk_t serverAuth = chunk_empty, clientAuth = chunk_empty;
|
chunk_t serverAuth = chunk_empty, clientAuth = chunk_empty;
|
||||||
chunk_t ocspSigning = chunk_empty;
|
chunk_t ocspSigning = chunk_empty;
|
||||||
chunk_t basicConstraints = chunk_empty;
|
chunk_t basicConstraints = chunk_empty, nameConstraints = chunk_empty;
|
||||||
chunk_t keyUsage = chunk_empty, keyUsageBits = chunk_empty;
|
chunk_t keyUsage = chunk_empty, keyUsageBits = chunk_empty;
|
||||||
chunk_t subjectAltNames = chunk_empty;
|
chunk_t subjectAltNames = chunk_empty;
|
||||||
chunk_t subjectKeyIdentifier = chunk_empty, authKeyIdentifier = chunk_empty;
|
chunk_t subjectKeyIdentifier = chunk_empty, authKeyIdentifier = chunk_empty;
|
||||||
@@ -1900,15 +1900,53 @@ static bool generate(private_x509_cert_t *cert, certificate_t *sign_cert,
|
|||||||
asn1_wrap(ASN1_CONTEXT_S_0, "c", keyid))));
|
asn1_wrap(ASN1_CONTEXT_S_0, "c", keyid))));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 (basicConstraints.ptr || subjectAltNames.ptr || authKeyIdentifier.ptr ||
|
if (basicConstraints.ptr || subjectAltNames.ptr || authKeyIdentifier.ptr ||
|
||||||
crlDistributionPoints.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, "mmmmmmmm",
|
asn1_wrap(ASN1_SEQUENCE, "mmmmmmmmm",
|
||||||
basicConstraints, keyUsage, subjectKeyIdentifier,
|
basicConstraints, keyUsage, subjectKeyIdentifier,
|
||||||
authKeyIdentifier, subjectAltNames,
|
authKeyIdentifier, subjectAltNames,
|
||||||
extendedKeyUsage, crlDistributionPoints,
|
extendedKeyUsage, crlDistributionPoints,
|
||||||
authorityInfoAccess));
|
authorityInfoAccess, nameConstraints));
|
||||||
}
|
}
|
||||||
|
|
||||||
cert->tbsCertificate = asn1_wrap(ASN1_SEQUENCE, "mmmcmcmm",
|
cert->tbsCertificate = asn1_wrap(ASN1_SEQUENCE, "mmmcmcmm",
|
||||||
@@ -2079,6 +2117,38 @@ x509_cert_t *x509_cert_gen(certificate_type_t type, va_list args)
|
|||||||
cert->pathLenConstraint = X509_NO_PATH_LEN_CONSTRAINT;
|
cert->pathLenConstraint = X509_NO_PATH_LEN_CONSTRAINT;
|
||||||
}
|
}
|
||||||
continue;
|
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_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