#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;
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;
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;
}
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
*/
{
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;
}
/* 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))
*/
chunk_t certTypeExt;
+ /**
+ * extendedKeyUsage flags
+ */
+ x509_flag_t flags;
+
/**
* Signature scheme
*/
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)
{
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;
- }
- 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;
+ 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);
}
- free(profile);
-
- return flags;
+ return this->flags;
}
METHOD(pkcs10_t, create_subjectAltName_enumerator, enumerator_t*,
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;
));
}
+ /* 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)
));
}
}
this->certTypeExt = object;
break;
+ case OID_EXTENDED_KEY_USAGE:
+ if (!x509_parse_eku_extension(object, level, &this->flags))
+ {
+ goto end;
+ }
+ break;
default:
break;
}
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);
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);
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))
{
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);
"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]"},
{"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"},
.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,
.BI \-\-dn\~ distinguished-name
.OP \-\-san subjectAltName
.OP \-\-profile profile
+.OP \-\-flag flag
.OP \-\-password password
.OP \-\-digest digest
.OP \-\-rsa\-padding padding
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