mirror of
https://github.com/strongswan/strongswan.git
synced 2025-10-03 00:00:24 -04:00
pki: Use X.509v3 EKU extension in CSR
This commit is contained in:
parent
41b0dff92b
commit
8effb06d6c
@ -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))
|
||||
|
@ -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);
|
||||
|
@ -43,6 +43,7 @@ static int req()
|
||||
chunk_t encoding = chunk_empty;
|
||||
chunk_t challenge_password = chunk_empty;
|
||||
chunk_t cert_type_ext = chunk_empty;
|
||||
x509_flag_t flags = 0;
|
||||
char *arg;
|
||||
bool pss = lib->settings->get_bool(lib->settings, "%s.rsa_pss", FALSE,
|
||||
lib->ns);
|
||||
@ -78,6 +79,24 @@ static int req()
|
||||
goto usage;
|
||||
}
|
||||
continue;
|
||||
case 'e':
|
||||
if (streq(arg, "serverAuth"))
|
||||
{
|
||||
flags |= X509_SERVER_AUTH;
|
||||
}
|
||||
else if (streq(arg, "clientAuth"))
|
||||
{
|
||||
flags |= X509_CLIENT_AUTH;
|
||||
}
|
||||
else if (streq(arg, "ocspSigning"))
|
||||
{
|
||||
flags |= X509_OCSP_SIGNER;
|
||||
}
|
||||
else if (streq(arg, "msSmartcardLogon"))
|
||||
{
|
||||
flags |= X509_MS_SMARTCARD_LOGON;
|
||||
}
|
||||
continue;
|
||||
case 'g': /* --digest */
|
||||
if (!enum_from_name(hash_algorithm_short_names, arg, &digest))
|
||||
{
|
||||
@ -213,6 +232,7 @@ static int req()
|
||||
BUILD_SUBJECT, id,
|
||||
BUILD_SUBJECT_ALTNAMES, san,
|
||||
BUILD_CHALLENGE_PWD, challenge_password,
|
||||
BUILD_X509_FLAG, flags,
|
||||
BUILD_CERT_TYPE_EXT, cert_type_ext,
|
||||
BUILD_SIGNATURE_SCHEME, scheme,
|
||||
BUILD_END);
|
||||
@ -264,6 +284,7 @@ static void __attribute__ ((constructor))reg()
|
||||
"create a PKCS#10 certificate request",
|
||||
{"[--in file|--keyid hex] [--type rsa|ecdsa|bliss|priv]",
|
||||
" --oldreq file|--dn distinguished-name [--san subjectAltName]+",
|
||||
"[--flag serverAuth|clientAuth|ocspSigning|msSmartcardLogon]+",
|
||||
"[--profile server|client|dual|ocsp] [--password challengePassword]",
|
||||
"[--digest sha1|sha224|sha256|sha384|sha512|sha3_224|sha3_256|sha3_384|sha3_512]",
|
||||
"[--rsa-padding pkcs1|pss] [--outform der|pem]"},
|
||||
@ -275,6 +296,7 @@ static void __attribute__ ((constructor))reg()
|
||||
{"oldreq", 'o', 1, "old certificate request to be used as a template"},
|
||||
{"dn", 'd', 1, "subject distinguished name"},
|
||||
{"san", 'a', 1, "subjectAltName to include in cert request"},
|
||||
{"flag", 'e', 1, "include extendedKeyUsage flag"},
|
||||
{"profile", 'P', 1, "certificate profile name to include in cert request"},
|
||||
{"password", 'p', 1, "challengePassword to include in cert request"},
|
||||
{"digest", 'g', 1, "digest for signature creation, default: key-specific"},
|
||||
|
@ -125,7 +125,8 @@ Serial number in hex. It is randomly allocated by default.
|
||||
.TP
|
||||
.BI "\-e, \-\-flag " flag
|
||||
Add extendedKeyUsage flag. One of \fIserverAuth\fR, \fIclientAuth\fR,
|
||||
\fIcrlSign\fR, or \fIocspSigning\fR. Can be used multiple times.
|
||||
\fIcrlSign\fR, \fIocspSigning\fR or \fImsSmartcardLogon\fR. Can be used multiple
|
||||
times.
|
||||
.TP
|
||||
.BI "\-g, \-\-digest " digest
|
||||
Digest to use for signature creation. One of \fImd5\fR, \fIsha1\fR,
|
||||
|
@ -14,6 +14,7 @@ pki \-\-req \- Create a PKCS#10 certificate request
|
||||
.BI \-\-dn\~ distinguished-name
|
||||
.OP \-\-san subjectAltName
|
||||
.OP \-\-profile profile
|
||||
.OP \-\-flag flag
|
||||
.OP \-\-password password
|
||||
.OP \-\-digest digest
|
||||
.OP \-\-rsa\-padding padding
|
||||
@ -91,6 +92,11 @@ UTF8 string. Supported e.g. by
|
||||
translated into corresponding Extended Key Usage (EKU) flags in the generated
|
||||
X.509 certificate.
|
||||
.TP
|
||||
.BI "\-e, \-\-flag " flag
|
||||
Add extendedKeyUsage flag. One of \fIserverAuth\fR, \fIclientAuth\fR,
|
||||
\fIocspSigning\fR or \fImsSmartcardLogon\fR. Can be used multiple times. Adds an
|
||||
X.509v3 EKU extension containing these flags to the certificate request.
|
||||
.TP
|
||||
.BI "\-p, \-\-password " password
|
||||
The challengePassword to include in the certificate request.
|
||||
.TP
|
||||
|
Loading…
x
Reference in New Issue
Block a user