Convert jdkTrustedKeyUsage to be a pkcs12 cmd line option

Creating JDK compatible pkcs12 files requires a bit more than just
adding the Trusted Key Usage OID to a certbag in the pkcs12 file.
Additionally the JDK currently requires that pkcs12 files setting this
oid _not_ contain any additional keys, and in response will produce
unpredictable results.

This could be solved by implying --nokeys when the pkcs12 utility is run
and the config option is set, but thatcould confuse users who didn't
specify nokeys on the command line.  As such, remove the config file
setting for this feature, and replace it with a -jdktrust command line
option, that is documented to assert nokeys when a users specifies the
new command line option.

Fixes #22215

Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/22422)
This commit is contained in:
Neil Horman 2023-10-18 10:01:21 -04:00 committed by Matt Caswell
parent 7757f5ef73
commit 21f7a09ca2
6 changed files with 22 additions and 42 deletions

View File

@ -388,10 +388,3 @@ oldcert = $insta::certout # insta.cert.pem
# Certificate revocation # Certificate revocation
cmd = rr cmd = rr
oldcert = $insta::certout # insta.cert.pem oldcert = $insta::certout # insta.cert.pem
[pkcs12]
certBagAttr = cb_attr
# Uncomment this if you need Java compatible PKCS12 files
[cb_attr]
#jdkTrustedKeyUsage = anyExtendedKeyUsage

View File

@ -388,10 +388,3 @@ oldcert = $insta::certout # insta.cert.pem
# Certificate revocation # Certificate revocation
cmd = rr cmd = rr
oldcert = $insta::certout # insta.cert.pem oldcert = $insta::certout # insta.cert.pem
[pkcs12]
certBagAttr = cb_attr
# Uncomment this if you need Java compatible PKCS12 files
[cb_attr]
#jdkTrustedKeyUsage = anyExtendedKeyUsage

View File

@ -71,7 +71,7 @@ typedef enum OPTION_choice {
OPT_NAME, OPT_CSP, OPT_CANAME, OPT_NAME, OPT_CSP, OPT_CANAME,
OPT_IN, OPT_OUT, OPT_PASSIN, OPT_PASSOUT, OPT_PASSWORD, OPT_CAPATH, OPT_IN, OPT_OUT, OPT_PASSIN, OPT_PASSOUT, OPT_PASSWORD, OPT_CAPATH,
OPT_CAFILE, OPT_CASTORE, OPT_NOCAPATH, OPT_NOCAFILE, OPT_NOCASTORE, OPT_ENGINE, OPT_CAFILE, OPT_CASTORE, OPT_NOCAPATH, OPT_NOCAFILE, OPT_NOCASTORE, OPT_ENGINE,
OPT_R_ENUM, OPT_PROV_ENUM, OPT_R_ENUM, OPT_PROV_ENUM, OPT_JDKTRUST,
#ifndef OPENSSL_NO_DES #ifndef OPENSSL_NO_DES
OPT_LEGACY_ALG OPT_LEGACY_ALG
#endif #endif
@ -154,6 +154,7 @@ const OPTIONS pkcs12_options[] = {
{"maciter", OPT_MACITER, '-', "Unused, kept for backwards compatibility"}, {"maciter", OPT_MACITER, '-', "Unused, kept for backwards compatibility"},
{"macsaltlen", OPT_MACSALTLEN, 'p', "Specify the salt len for MAC"}, {"macsaltlen", OPT_MACSALTLEN, 'p', "Specify the salt len for MAC"},
{"nomac", OPT_NOMAC, '-', "Don't generate MAC"}, {"nomac", OPT_NOMAC, '-', "Don't generate MAC"},
{"jdktrust", OPT_JDKTRUST, 's', "Mark certificate in PKCS#12 store as trusted for JDK compatibility"},
{NULL} {NULL}
}; };
@ -165,6 +166,7 @@ int pkcs12_main(int argc, char **argv)
char *name = NULL, *csp_name = NULL; char *name = NULL, *csp_name = NULL;
char pass[PASSWD_BUF_SIZE] = "", macpass[PASSWD_BUF_SIZE] = ""; char pass[PASSWD_BUF_SIZE] = "", macpass[PASSWD_BUF_SIZE] = "";
int export_pkcs12 = 0, options = 0, chain = 0, twopass = 0, keytype = 0; int export_pkcs12 = 0, options = 0, chain = 0, twopass = 0, keytype = 0;
char *jdktrust = NULL;
#ifndef OPENSSL_NO_DES #ifndef OPENSSL_NO_DES
int use_legacy = 0; int use_legacy = 0;
#endif #endif
@ -222,6 +224,11 @@ int pkcs12_main(int argc, char **argv)
case OPT_NOOUT: case OPT_NOOUT:
options |= (NOKEYS | NOCERTS); options |= (NOKEYS | NOCERTS);
break; break;
case OPT_JDKTRUST:
jdktrust = opt_arg();
/* Adding jdk trust implies nokeys */
options |= NOKEYS;
break;
case OPT_INFO: case OPT_INFO:
options |= INFO; options |= INFO;
break; break;
@ -530,9 +537,6 @@ int pkcs12_main(int argc, char **argv)
int i; int i;
CONF *conf = NULL; CONF *conf = NULL;
ASN1_OBJECT *obj = NULL; ASN1_OBJECT *obj = NULL;
STACK_OF(CONF_VALUE) *cb_sk = NULL;
const char *cb_attr = NULL;
const CONF_VALUE *val = NULL;
if ((options & (NOCERTS | NOKEYS)) == (NOCERTS | NOKEYS)) { if ((options & (NOCERTS | NOKEYS)) == (NOCERTS | NOKEYS)) {
BIO_printf(bio_err, "Nothing to export due to -noout or -nocerts and -nokeys\n"); BIO_printf(bio_err, "Nothing to export due to -noout or -nocerts and -nokeys\n");
@ -682,20 +686,9 @@ int pkcs12_main(int argc, char **argv)
goto export_end; goto export_end;
if (!app_load_modules(conf)) if (!app_load_modules(conf))
goto export_end; goto export_end;
/* Find the cert bag section */
cb_attr = app_conf_try_string(conf, "pkcs12", "certBagAttr"); if (jdktrust != NULL) {
if (cb_attr != NULL) { obj = OBJ_txt2obj(jdktrust, 0);
if ((cb_sk = NCONF_get_section(conf, cb_attr)) != NULL) {
for (i = 0; i < sk_CONF_VALUE_num(cb_sk); i++) {
val = sk_CONF_VALUE_value(cb_sk, i);
if (strcmp(val->name, "jdkTrustedKeyUsage") == 0) {
obj = OBJ_txt2obj(val->value, 0);
break;
}
}
} else {
ERR_clear_error();
}
} }
p12 = PKCS12_create_ex2(cpass, name, key, ee_cert, certs, p12 = PKCS12_create_ex2(cpass, name, key, ee_cert, certs,

View File

@ -68,6 +68,7 @@ PKCS#12 output (export) options:
[B<-maciter>] [B<-maciter>]
[B<-macsaltlen>] [B<-macsaltlen>]
[B<-nomac>] [B<-nomac>]
[B<-jdktrust> I<usage>]
=head1 DESCRIPTION =head1 DESCRIPTION
@ -381,6 +382,15 @@ Do not attempt to provide the MAC integrity. This can be useful with the FIPS
provider as the PKCS12 MAC requires PKCS12KDF which is not an approved FIPS provider as the PKCS12 MAC requires PKCS12KDF which is not an approved FIPS
algorithm and cannot be supported by the FIPS provider. algorithm and cannot be supported by the FIPS provider.
=item B<-jdktrust>
Export pkcs12 file in a format compatible with Java keystore usage. This option
accepts a string parameter indicating the trust oid name to be granted to the
certificate it is associated with. Currently only "anyExtendedKeyUsage" is
defined. Note that, as Java keystores do not accept PKCS12 files with both
trusted certificates and keypairs, use of this option implies the setting of the
B<-nokeys> option
=back =back
=head1 NOTES =head1 NOTES

View File

@ -172,9 +172,8 @@ ok(grep(/Trusted key usage (Oracle)/, @pkcs12info) == 0,
# Test with Oracle Trusted Key Usage specified in openssl.cnf # Test with Oracle Trusted Key Usage specified in openssl.cnf
{ {
$ENV{OPENSSL_CONF} = srctop_file("test", "recipes", "80-test_pkcs12_data", "jdk_trusted.cnf");
ok(run(app(["openssl", "pkcs12", "-export", "-out", $outfile7, ok(run(app(["openssl", "pkcs12", "-export", "-out", $outfile7,
"-in", srctop_file(@path, "ee-cert.pem"), "-jdktrust", "anyExtendedKeyUsage", "-in", srctop_file(@path, "ee-cert.pem"),
"-nokeys", "-passout", "pass:", "-certpbe", "NONE"])), "-nokeys", "-passout", "pass:", "-certpbe", "NONE"])),
"test nokeys single cert"); "test nokeys single cert");

View File

@ -1,8 +0,0 @@
#
[pkcs12]
certBagAttr = cb_attr
# Uncomment this if you need Java compatible PKCS12 files
[cb_attr]
jdkTrustedKeyUsage = anyExtendedKeyUsage