pki: Allow inclusion of [unsupported] critical X.509 extension

This commit is contained in:
Andreas Steffen
2019-05-08 14:56:48 +02:00
committed by Tobias Brunner
parent b213204b3b
commit df6441a13f
10 changed files with 96 additions and 17 deletions
+20 -2
View File
@@ -171,6 +171,11 @@ struct private_x509_cert_t {
*/
chunk_t authKeySerialNumber;
/**
* Optional OID of an [unsupported] critical extension
*/
chunk_t critical_extension_oid;
/**
* Path Length Constraint
*/
@@ -1951,6 +1956,7 @@ METHOD(certificate_t, destroy, void,
chunk_free(&this->authKeyIdentifier);
chunk_free(&this->encoding);
chunk_free(&this->encoding_hash);
chunk_free(&this->critical_extension_oid);
if (!this->parsed)
{ /* only parsed certificates point these fields to "encoded" */
chunk_free(&this->signature);
@@ -2203,6 +2209,7 @@ static bool generate(private_x509_cert_t *cert, certificate_t *sign_cert,
chunk_t policyConstraints = chunk_empty, inhibitAnyPolicy = chunk_empty;
chunk_t ikeIntermediate = chunk_empty, msSmartcardLogon = chunk_empty;
chunk_t ipAddrBlocks = chunk_empty, sig_scheme = chunk_empty;
chunk_t criticalExtension = chunk_empty;
identification_t *issuer, *subject;
chunk_t key_info;
hasher_t *hasher;
@@ -2570,17 +2577,25 @@ static bool generate(private_x509_cert_t *cert, certificate_t *sign_cert,
chunk_from_thing(cert->inhibit_any))));
}
if (cert->critical_extension_oid.len > 0)
{
criticalExtension = asn1_wrap(ASN1_SEQUENCE, "mmm",
asn1_simple_object(ASN1_OID, cert->critical_extension_oid),
asn1_simple_object(ASN1_BOOLEAN, chunk_from_chars(0xFF)),
asn1_simple_object(ASN1_OCTET_STRING, chunk_empty));
}
if (basicConstraints.ptr || subjectAltNames.ptr || authKeyIdentifier.ptr ||
crlDistributionPoints.ptr || nameConstraints.ptr || ipAddrBlocks.ptr)
{
extensions = asn1_wrap(ASN1_CONTEXT_C_3, "m",
asn1_wrap(ASN1_SEQUENCE, "mmmmmmmmmmmmmm",
asn1_wrap(ASN1_SEQUENCE, "mmmmmmmmmmmmmmm",
basicConstraints, keyUsage, subjectKeyIdentifier,
authKeyIdentifier, subjectAltNames,
extendedKeyUsage, crlDistributionPoints,
authorityInfoAccess, nameConstraints, certPolicies,
policyMappings, policyConstraints, inhibitAnyPolicy,
ipAddrBlocks));
ipAddrBlocks, criticalExtension));
}
cert->tbsCertificate = asn1_wrap(ASN1_SEQUENCE, "mmccmcmm",
@@ -2864,6 +2879,9 @@ x509_cert_t *x509_cert_gen(certificate_type_t type, va_list args)
case BUILD_DIGEST_ALG:
digest_alg = va_arg(args, int);
continue;
case BUILD_CRITICAL_EXTENSION:
cert->critical_extension_oid = chunk_clone(va_arg(args, chunk_t));
continue;
case BUILD_END:
break;
default:
+21 -3
View File
@@ -116,6 +116,11 @@ struct private_x509_crl_t {
*/
chunk_t authKeySerialNumber;
/**
* Optional OID of an [unsupported] critical extension
*/
chunk_t critical_extension_oid;
/**
* Number of BaseCRL, if a delta CRL
*/
@@ -605,6 +610,7 @@ METHOD(certificate_t, destroy, void,
DESTROY_IF(this->issuer);
free(this->authKeyIdentifier.ptr);
free(this->encoding.ptr);
free(this->critical_extension_oid.ptr);
if (this->generated)
{
free(this->crlNumber.ptr);
@@ -718,7 +724,7 @@ static bool generate(private_x509_crl_t *this, certificate_t *cert,
{
chunk_t extensions = chunk_empty, certList = chunk_empty, serial;
chunk_t crlDistributionPoints = chunk_empty, baseCrlNumber = chunk_empty;
chunk_t sig_scheme = chunk_empty;
chunk_t sig_scheme = chunk_empty, criticalExtension = chunk_empty;
enumerator_t *enumerator;
crl_reason_t reason;
time_t date;
@@ -784,8 +790,16 @@ static bool generate(private_x509_crl_t *this, certificate_t *cert,
asn1_integer("c", this->baseCrlNumber)));
}
if (this->critical_extension_oid.len > 0)
{
criticalExtension = asn1_wrap(ASN1_SEQUENCE, "mmm",
asn1_simple_object(ASN1_OID, this->critical_extension_oid),
asn1_simple_object(ASN1_BOOLEAN, chunk_from_chars(0xFF)),
asn1_simple_object(ASN1_OCTET_STRING, chunk_empty));
}
extensions = asn1_wrap(ASN1_CONTEXT_C_0, "m",
asn1_wrap(ASN1_SEQUENCE, "mmmm",
asn1_wrap(ASN1_SEQUENCE, "mmmmm",
asn1_wrap(ASN1_SEQUENCE, "mm",
asn1_build_known_oid(OID_AUTHORITY_KEY_ID),
asn1_wrap(ASN1_OCTET_STRING, "m",
@@ -796,7 +810,8 @@ static bool generate(private_x509_crl_t *this, certificate_t *cert,
asn1_build_known_oid(OID_CRL_NUMBER),
asn1_wrap(ASN1_OCTET_STRING, "m",
asn1_integer("c", this->crlNumber))),
crlDistributionPoints, baseCrlNumber));
crlDistributionPoints, baseCrlNumber,
criticalExtension));
this->tbsCertList = asn1_wrap(ASN1_SEQUENCE, "cccmmmm",
ASN1_INTEGER_1,
@@ -887,6 +902,9 @@ x509_crl_t *x509_crl_gen(certificate_type_t type, va_list args)
enumerator->destroy(enumerator);
continue;
}
case BUILD_CRITICAL_EXTENSION:
crl->critical_extension_oid = chunk_clone(va_arg(args, chunk_t));
continue;
case BUILD_END:
break;
default: