pki: Use X.509v3 EKU extension in CSR

This commit is contained in:
Andreas Steffen
2023-01-11 19:19:09 +01:00
parent 41b0dff92b
commit 8effb06d6c
5 changed files with 131 additions and 68 deletions
+55 -45
View File
@@ -769,10 +769,9 @@ static const asn1Object_t extendedKeyUsageObjects[] = {
#define EXT_KEY_USAGE_PURPOSE_ID 1
/**
* Extracts extendedKeyUsage OIDs
* Extracts extendedKeyUsage OIDs (shared with x509_pkcs10.c)
*/
static bool parse_extendedKeyUsage(chunk_t blob, int level0,
private_x509_cert_t *this)
bool x509_parse_eku_extension(chunk_t blob, int level0, x509_flag_t *flags)
{
asn1_parser_t *parser;
chunk_t object;
@@ -789,19 +788,19 @@ static bool parse_extendedKeyUsage(chunk_t blob, int level0,
switch (asn1_known_oid(object))
{
case OID_SERVER_AUTH:
this->flags |= X509_SERVER_AUTH;
*flags |= X509_SERVER_AUTH;
break;
case OID_CLIENT_AUTH:
this->flags |= X509_CLIENT_AUTH;
*flags |= X509_CLIENT_AUTH;
break;
case OID_IKE_INTERMEDIATE:
this->flags |= X509_IKE_INTERMEDIATE;
*flags |= X509_IKE_INTERMEDIATE;
break;
case OID_OCSP_SIGNING:
this->flags |= X509_OCSP_SIGNER;
*flags |= X509_OCSP_SIGNER;
break;
case OID_MS_SMARTCARD_LOGON:
this->flags |= X509_MS_SMARTCARD_LOGON;
*flags |= X509_MS_SMARTCARD_LOGON;
break;
default:
break;
@@ -1516,7 +1515,7 @@ static bool parse_certificate(private_x509_cert_t *this)
parse_keyUsage(object, this);
break;
case OID_EXTENDED_KEY_USAGE:
if (!parse_extendedKeyUsage(object, level, this))
if (!x509_parse_eku_extension(object, level, &this->flags))
{
goto end;
}
@@ -2207,6 +2206,50 @@ static chunk_t generate_ts(traffic_selector_t *ts)
return asn1_wrap(ASN1_SEQUENCE, "mm", from, to);
}
/**
* Generate an extendedKeyUsage X.509v3 extension (shared with x509_pkcs10.c)
*/
chunk_t x509_generate_eku_extension(x509_flag_t flags)
{
chunk_t extendedKeyUsage = chunk_empty, ocspSigning = chunk_empty;
chunk_t serverAuth = chunk_empty, clientAuth = chunk_empty;
chunk_t ikeIntermediate = chunk_empty, msSmartcardLogon = chunk_empty;
if (flags & X509_SERVER_AUTH)
{
serverAuth = asn1_build_known_oid(OID_SERVER_AUTH);
}
if (flags & X509_CLIENT_AUTH)
{
clientAuth = asn1_build_known_oid(OID_CLIENT_AUTH);
}
if (flags & X509_IKE_INTERMEDIATE)
{
ikeIntermediate = asn1_build_known_oid(OID_IKE_INTERMEDIATE);
}
if (flags & X509_OCSP_SIGNER)
{
ocspSigning = asn1_build_known_oid(OID_OCSP_SIGNING);
}
if (flags & X509_MS_SMARTCARD_LOGON)
{
msSmartcardLogon = asn1_build_known_oid(OID_MS_SMARTCARD_LOGON);
}
if (serverAuth.ptr || clientAuth.ptr || ikeIntermediate.ptr ||
ocspSigning.ptr || msSmartcardLogon.ptr)
{
extendedKeyUsage = asn1_wrap(ASN1_SEQUENCE, "mm",
asn1_build_known_oid(OID_EXTENDED_KEY_USAGE),
asn1_wrap(ASN1_OCTET_STRING, "m",
asn1_wrap(ASN1_SEQUENCE, "mmmmm",
serverAuth, clientAuth, ikeIntermediate,
ocspSigning, msSmartcardLogon)));
}
return extendedKeyUsage;
}
/**
* Generate and sign a new certificate
*/
@@ -2215,18 +2258,15 @@ static bool generate(private_x509_cert_t *cert, certificate_t *sign_cert,
{
const chunk_t keyUsageCrlSign = chunk_from_chars(0x01, 0x02);
const chunk_t keyUsageCertSignCrlSign = chunk_from_chars(0x01, 0x06);
chunk_t extensions = chunk_empty, extendedKeyUsage = chunk_empty;
chunk_t serverAuth = chunk_empty, clientAuth = chunk_empty;
chunk_t ocspSigning = chunk_empty, certPolicies = chunk_empty;
chunk_t extensions = 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;
chunk_t ikeIntermediate = chunk_empty, msSmartcardLogon = chunk_empty;
chunk_t ipAddrBlocks = chunk_empty, sig_scheme = chunk_empty;
chunk_t criticalExtension = chunk_empty;
chunk_t criticalExtension = chunk_empty, extendedKeyUsage = chunk_empty;
identification_t *issuer, *subject;
chunk_t key_info;
hasher_t *hasher;
@@ -2350,37 +2390,7 @@ static bool generate(private_x509_cert_t *cert, certificate_t *sign_cert,
}
/* add extendedKeyUsage flags */
if (cert->flags & X509_SERVER_AUTH)
{
serverAuth = asn1_build_known_oid(OID_SERVER_AUTH);
}
if (cert->flags & X509_CLIENT_AUTH)
{
clientAuth = asn1_build_known_oid(OID_CLIENT_AUTH);
}
if (cert->flags & X509_IKE_INTERMEDIATE)
{
ikeIntermediate = asn1_build_known_oid(OID_IKE_INTERMEDIATE);
}
if (cert->flags & X509_OCSP_SIGNER)
{
ocspSigning = asn1_build_known_oid(OID_OCSP_SIGNING);
}
if (cert->flags & X509_MS_SMARTCARD_LOGON)
{
msSmartcardLogon = asn1_build_known_oid(OID_MS_SMARTCARD_LOGON);
}
if (serverAuth.ptr || clientAuth.ptr || ikeIntermediate.ptr ||
ocspSigning.ptr || msSmartcardLogon.ptr)
{
extendedKeyUsage = asn1_wrap(ASN1_SEQUENCE, "mm",
asn1_build_known_oid(OID_EXTENDED_KEY_USAGE),
asn1_wrap(ASN1_OCTET_STRING, "m",
asn1_wrap(ASN1_SEQUENCE, "mmmmm",
serverAuth, clientAuth, ikeIntermediate,
ocspSigning, msSmartcardLogon)));
}
extendedKeyUsage = x509_generate_eku_extension(cert->flags);
/* add subjectKeyIdentifier to CA and OCSP signer certificates */
if (cert->flags & (X509_CA | X509_OCSP_SIGNER | X509_CRL_SIGN))
+46 -22
View File
@@ -77,6 +77,11 @@ struct private_x509_pkcs10_t {
*/
chunk_t certTypeExt;
/**
* extendedKeyUsage flags
*/
x509_flag_t flags;
/**
* Signature scheme
*/
@@ -110,6 +115,10 @@ extern bool x509_parse_generalNames(chunk_t blob, int level0, bool implicit,
linked_list_t *list);
extern chunk_t x509_build_subjectAltNames(linked_list_t *list);
extern bool x509_parse_eku_extension(chunk_t blob, int level0, x509_flag_t *flags);
extern chunk_t x509_generate_eku_extension(x509_flag_t flags);
METHOD(certificate_t, get_type, certificate_type_t,
private_x509_pkcs10_t *this)
{
@@ -238,30 +247,31 @@ METHOD(pkcs10_t, get_challengePassword, chunk_t,
METHOD(pkcs10_t, get_flags, x509_flag_t,
private_x509_pkcs10_t *this)
{
x509_flag_t flags = X509_NONE;
char *profile;
if (this->certTypeExt.len > 0)
{
char *profile;
profile = strndup(this->certTypeExt.ptr, this->certTypeExt.len);
profile = strndup(this->certTypeExt.ptr, this->certTypeExt.len);
if (strcaseeq(profile, "server"))
{
flags |= X509_SERVER_AUTH;
if (strcaseeq(profile, "server"))
{
this->flags |= X509_SERVER_AUTH;
}
else if (strcaseeq(profile, "client"))
{
this->flags |= X509_CLIENT_AUTH;
}
else if (strcaseeq(profile, "dual"))
{
this->flags |= (X509_SERVER_AUTH | X509_CLIENT_AUTH);
}
else if (strcaseeq(profile, "ocsp"))
{
this->flags |= X509_OCSP_SIGNER;
}
free(profile);
}
else if (strcaseeq(profile, "client"))
{
flags |= X509_CLIENT_AUTH;
}
else if (strcaseeq(profile, "dual"))
{
flags |= (X509_SERVER_AUTH | X509_CLIENT_AUTH);
}
else if (strcaseeq(profile, "ocsp"))
{
flags |= X509_OCSP_SIGNER;
}
free(profile);
return flags;
return this->flags;
}
METHOD(pkcs10_t, create_subjectAltName_enumerator, enumerator_t*,
@@ -279,6 +289,7 @@ static bool generate(private_x509_pkcs10_t *cert, private_key_t *sign_key,
chunk_t key_info, subjectAltNames, attributes;
chunk_t extensionRequest = chunk_empty, certTypeExt = chunk_empty;
chunk_t challengePassword = chunk_empty, sig_scheme = chunk_empty;
chunk_t extendedKeyUsage = chunk_empty;
identification_t *subject;
subject = cert->subject;
@@ -322,13 +333,17 @@ static bool generate(private_x509_pkcs10_t *cert, private_key_t *sign_key,
));
}
/* encode extendedKeyUsage flags */
extendedKeyUsage = x509_generate_eku_extension(cert->flags);
/* encode extensionRequest attribute */
if (subjectAltNames.ptr || certTypeExt.ptr)
{
extensionRequest = asn1_wrap(ASN1_SEQUENCE, "mm",
asn1_build_known_oid(OID_EXTENSION_REQUEST),
asn1_wrap(ASN1_SET, "m",
asn1_wrap(ASN1_SEQUENCE, "mm", subjectAltNames, certTypeExt)
asn1_wrap(ASN1_SEQUENCE, "mmm",
subjectAltNames, certTypeExt, extendedKeyUsage)
));
}
@@ -452,6 +467,12 @@ static bool parse_extension_request(private_x509_pkcs10_t *this, chunk_t blob, i
}
this->certTypeExt = object;
break;
case OID_EXTENDED_KEY_USAGE:
if (!x509_parse_eku_extension(object, level, &this->flags))
{
goto end;
}
break;
default:
break;
}
@@ -769,6 +790,9 @@ x509_pkcs10_t *x509_pkcs10_gen(certificate_type_t type, va_list args)
case BUILD_CERT_TYPE_EXT:
cert->certTypeExt = chunk_clone(va_arg(args, chunk_t));
continue;
case BUILD_X509_FLAG:
cert->flags |= va_arg(args, x509_flag_t);
continue;
case BUILD_SIGNATURE_SCHEME:
cert->scheme = va_arg(args, signature_params_t*);
cert->scheme = signature_params_clone(cert->scheme);