8153005: Upgrade the default PKCS12 encryption/MAC algorithms

Reviewed-by: mullan
This commit is contained in:
Weijun Wang 2020-10-30 13:23:33 +00:00
parent 8a065ef2e2
commit f77a658557
8 changed files with 399 additions and 340 deletions

View File

@ -65,6 +65,7 @@ import javax.crypto.Mac;
import javax.security.auth.DestroyFailedException; import javax.security.auth.DestroyFailedException;
import javax.security.auth.x500.X500Principal; import javax.security.auth.x500.X500Principal;
import sun.security.action.GetPropertyAction;
import sun.security.tools.KeyStoreUtil; import sun.security.tools.KeyStoreUtil;
import sun.security.util.*; import sun.security.util.*;
import sun.security.pkcs.ContentInfo; import sun.security.pkcs.ContentInfo;
@ -79,48 +80,10 @@ import sun.security.x509.AuthorityKeyIdentifierExtension;
* Implements the PKCS#12 PFX protected using the Password privacy mode. * Implements the PKCS#12 PFX protected using the Password privacy mode.
* The contents are protected using Password integrity mode. * The contents are protected using Password integrity mode.
* *
* Currently these PBE algorithms are used by default: * NOTE: In a PKCS12 keystore, entries are identified by the alias, and
* - PBEWithSHA1AndDESede to encrypt private keys, iteration count 50000. * a localKeyId is required to match the private key with the certificate.
* - PBEWithSHA1AndRC2_40 to encrypt certificates, iteration count 50000. * Trusted certificate entries are identified by the presence of an
* * trustedKeyUsage attribute.
* The default Mac algorithm is HmacPBESHA1, iteration count 100000.
*
* Supported encryption of various implementations :
*
* Software and mode. Certificate encryption Private key encryption
* ---------------------------------------------------------------------
* MSIE4 (domestic 40 bit RC2. 40 bit RC2
* and xport versions)
* PKCS#12 export.
*
* MSIE4, 5 (domestic 40 bit RC2, 40 bit RC2,
* and export versions) 3 key triple DES 3 key triple DES
* PKCS#12 import.
*
* MSIE5 40 bit RC2 3 key triple DES,
* PKCS#12 export. with SHA1 (168 bits)
*
* Netscape Communicator 40 bit RC2 3 key triple DES,
* (domestic and export with SHA1 (168 bits)
* versions) PKCS#12 export
*
* Netscape Communicator 40 bit ciphers only All.
* (export version)
* PKCS#12 import.
*
* Netscape Communicator All. All.
* (domestic or fortified
* version) PKCS#12 import.
*
* OpenSSL PKCS#12 code. All. All.
* ---------------------------------------------------------------------
*
* NOTE: PKCS12 KeyStore supports PrivateKeyEntry and TrustedCertficateEntry.
* PKCS#12 is mainly used to deliver private keys with their associated
* certificate chain and aliases. In a PKCS12 keystore, entries are
* identified by the alias, and a localKeyId is required to match the
* private key with the certificate. Trusted certificate entries are identified
* by the presence of an trustedKeyUsage attribute.
* *
* @author Seema Malkani * @author Seema Malkani
* @author Jeff Nisewanger * @author Jeff Nisewanger
@ -130,6 +93,32 @@ import sun.security.x509.AuthorityKeyIdentifierExtension;
*/ */
public final class PKCS12KeyStore extends KeyStoreSpi { public final class PKCS12KeyStore extends KeyStoreSpi {
// Hardcoded defaults. They should be the same with commented out
// lines inside the java.security file.
private static final String DEFAULT_CERT_PBE_ALGORITHM
= "PBEWithHmacSHA256AndAES_256";
private static final String DEFAULT_KEY_PBE_ALGORITHM
= "PBEWithHmacSHA256AndAES_256";
private static final String DEFAULT_MAC_ALGORITHM = "HmacPBESHA256";
private static final int DEFAULT_CERT_PBE_ITERATION_COUNT = 10000;
private static final int DEFAULT_KEY_PBE_ITERATION_COUNT = 10000;
private static final int DEFAULT_MAC_ITERATION_COUNT = 10000;
// Legacy settings. Used when "keystore.pkcs12.legacy" is set.
private static final String LEGACY_CERT_PBE_ALGORITHM
= "PBEWithSHA1AndRC2_40";
private static final String LEGACY_KEY_PBE_ALGORITHM
= "PBEWithSHA1AndDESede";
private static final String LEGACY_MAC_ALGORITHM = "HmacPBESHA1";
private static final int LEGACY_PBE_ITERATION_COUNT = 50000;
private static final int LEGACY_MAC_ITERATION_COUNT = 100000;
// Big switch. When this system property is set. Legacy settings
// are used no matter what other keystore.pkcs12.* properties are set.
// Note: This is only a system property, there's no same-name
// security property defined.
private static final String USE_LEGACY_PROP = "keystore.pkcs12.legacy";
// special PKCS12 keystore that supports PKCS12 and JKS file formats // special PKCS12 keystore that supports PKCS12 and JKS file formats
public static final class DualFormatPKCS12 extends KeyStoreDelegator { public static final class DualFormatPKCS12 extends KeyStoreDelegator {
public DualFormatPKCS12() { public DualFormatPKCS12() {
@ -845,9 +834,6 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
* Encrypt private key or secret key using Password-based encryption (PBE) * Encrypt private key or secret key using Password-based encryption (PBE)
* as defined in PKCS#5. * as defined in PKCS#5.
* *
* NOTE: By default, pbeWithSHAAnd3-KeyTripleDES-CBC algorithmID is
* used to derive the key and IV.
*
* @return encrypted private key or secret key encoded as * @return encrypted private key or secret key encoded as
* EncryptedPrivateKeyInfo * EncryptedPrivateKeyInfo
*/ */
@ -1866,9 +1852,6 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
* Encrypt the contents using Password-based (PBE) encryption * Encrypt the contents using Password-based (PBE) encryption
* as defined in PKCS #5. * as defined in PKCS #5.
* *
* NOTE: Currently pbeWithSHAAnd40BiteRC2-CBC algorithmID is used
* to derive the key and IV.
*
* @return encrypted contents encoded as EncryptedContentInfo * @return encrypted contents encoded as EncryptedContentInfo
*/ */
private byte[] encryptContent(byte[] data, char[] password) private byte[] encryptContent(byte[] data, char[] password)
@ -2640,25 +2623,42 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
return result; return result;
} }
// 8076190: Customizing the generation of a PKCS12 keystore // The following methods are related to customizing
// the generation of a PKCS12 keystore or private/secret
// key entries.
private static boolean useLegacy() {
return GetPropertyAction.privilegedGetProperty(
USE_LEGACY_PROP) != null;
}
private static String defaultCertProtectionAlgorithm() { private static String defaultCertProtectionAlgorithm() {
if (useLegacy()) {
return LEGACY_CERT_PBE_ALGORITHM;
}
String result = SecurityProperties.privilegedGetOverridable( String result = SecurityProperties.privilegedGetOverridable(
"keystore.pkcs12.certProtectionAlgorithm"); "keystore.pkcs12.certProtectionAlgorithm");
return (result != null && !result.isEmpty()) return (result != null && !result.isEmpty())
? result : "PBEWithSHA1AndRC2_40"; ? result : DEFAULT_CERT_PBE_ALGORITHM;
} }
private static int defaultCertPbeIterationCount() { private static int defaultCertPbeIterationCount() {
if (useLegacy()) {
return LEGACY_PBE_ITERATION_COUNT;
}
String result = SecurityProperties.privilegedGetOverridable( String result = SecurityProperties.privilegedGetOverridable(
"keystore.pkcs12.certPbeIterationCount"); "keystore.pkcs12.certPbeIterationCount");
return (result != null && !result.isEmpty()) return (result != null && !result.isEmpty())
? string2IC("certPbeIterationCount", result) : 50000; ? string2IC("certPbeIterationCount", result)
: DEFAULT_CERT_PBE_ITERATION_COUNT;
} }
// Read both "keystore.pkcs12.keyProtectionAlgorithm" and // Read both "keystore.pkcs12.keyProtectionAlgorithm" and
// "keystore.PKCS12.keyProtectionAlgorithm" for compatibility. // "keystore.PKCS12.keyProtectionAlgorithm" for compatibility.
private static String defaultKeyProtectionAlgorithm() { private static String defaultKeyProtectionAlgorithm() {
if (useLegacy()) {
return LEGACY_KEY_PBE_ALGORITHM;
}
String result = AccessController.doPrivileged(new PrivilegedAction<String>() { String result = AccessController.doPrivileged(new PrivilegedAction<String>() {
public String run() { public String run() {
String result; String result;
@ -2680,28 +2680,39 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
} }
}); });
return (result != null && !result.isEmpty()) return (result != null && !result.isEmpty())
? result : "PBEWithSHA1AndDESede"; ? result : DEFAULT_KEY_PBE_ALGORITHM;
} }
private static int defaultKeyPbeIterationCount() { private static int defaultKeyPbeIterationCount() {
if (useLegacy()) {
return LEGACY_PBE_ITERATION_COUNT;
}
String result = SecurityProperties.privilegedGetOverridable( String result = SecurityProperties.privilegedGetOverridable(
"keystore.pkcs12.keyPbeIterationCount"); "keystore.pkcs12.keyPbeIterationCount");
return (result != null && !result.isEmpty()) return (result != null && !result.isEmpty())
? string2IC("keyPbeIterationCount", result) : 50000; ? string2IC("keyPbeIterationCount", result)
: DEFAULT_KEY_PBE_ITERATION_COUNT;
} }
private static String defaultMacAlgorithm() { private static String defaultMacAlgorithm() {
if (useLegacy()) {
return LEGACY_MAC_ALGORITHM;
}
String result = SecurityProperties.privilegedGetOverridable( String result = SecurityProperties.privilegedGetOverridable(
"keystore.pkcs12.macAlgorithm"); "keystore.pkcs12.macAlgorithm");
return (result != null && !result.isEmpty()) return (result != null && !result.isEmpty())
? result : "HmacPBESHA1"; ? result : DEFAULT_MAC_ALGORITHM;
} }
private static int defaultMacIterationCount() { private static int defaultMacIterationCount() {
if (useLegacy()) {
return LEGACY_MAC_ITERATION_COUNT;
}
String result = SecurityProperties.privilegedGetOverridable( String result = SecurityProperties.privilegedGetOverridable(
"keystore.pkcs12.macIterationCount"); "keystore.pkcs12.macIterationCount");
return (result != null && !result.isEmpty()) return (result != null && !result.isEmpty())
? string2IC("macIterationCount", result) : 100000; ? string2IC("macIterationCount", result)
: DEFAULT_MAC_ITERATION_COUNT;
} }
private static int string2IC(String type, String value) { private static int string2IC(String type, String value) {

View File

@ -1144,33 +1144,33 @@ jceks.key.serialFilter = java.base/java.lang.Enum;java.base/java.security.KeyRep
# The algorithm used to encrypt a certificate. This can be any non-Hmac PBE # The algorithm used to encrypt a certificate. This can be any non-Hmac PBE
# algorithm defined in the Cipher section of the Java Security Standard # algorithm defined in the Cipher section of the Java Security Standard
# Algorithm Names Specification. When set to "NONE", the certificate # Algorithm Names Specification. When set to "NONE", the certificate
# is not encrypted. The default value is "PBEWithSHA1AndRC2_40". # is not encrypted. The default value is "PBEWithHmacSHA256AndAES_256".
#keystore.pkcs12.certProtectionAlgorithm = PBEWithSHA1AndRC2_40 #keystore.pkcs12.certProtectionAlgorithm = PBEWithHmacSHA256AndAES_256
# The iteration count used by the PBE algorithm when encrypting a certificate. # The iteration count used by the PBE algorithm when encrypting a certificate.
# This value must be a positive integer. The default value is 50000. # This value must be a positive integer. The default value is 10000.
#keystore.pkcs12.certPbeIterationCount = 50000 #keystore.pkcs12.certPbeIterationCount = 10000
# The algorithm used to encrypt a private key or secret key. This can be # The algorithm used to encrypt a private key or secret key. This can be
# any non-Hmac PBE algorithm defined in the Cipher section of the Java # any non-Hmac PBE algorithm defined in the Cipher section of the Java
# Security Standard Algorithm Names Specification. The value must not be "NONE". # Security Standard Algorithm Names Specification. The value must not be "NONE".
# The default value is "PBEWithSHA1AndDESede". # The default value is "PBEWithHmacSHA256AndAES_256".
#keystore.pkcs12.keyProtectionAlgorithm = PBEWithSHA1AndDESede #keystore.pkcs12.keyProtectionAlgorithm = PBEWithHmacSHA256AndAES_256
# The iteration count used by the PBE algorithm when encrypting a private key # The iteration count used by the PBE algorithm when encrypting a private key
# or a secret key. This value must be a positive integer. The default value # or a secret key. This value must be a positive integer. The default value
# is 50000. # is 10000.
#keystore.pkcs12.keyPbeIterationCount = 50000 #keystore.pkcs12.keyPbeIterationCount = 10000
# The algorithm used to calculate the optional MacData at the end of a PKCS12 # The algorithm used to calculate the optional MacData at the end of a PKCS12
# file. This can be any HmacPBE algorithm defined in the Mac section of the # file. This can be any HmacPBE algorithm defined in the Mac section of the
# Java Security Standard Algorithm Names Specification. When set to "NONE", # Java Security Standard Algorithm Names Specification. When set to "NONE",
# no Mac is generated. The default value is "HmacPBESHA1". # no Mac is generated. The default value is "HmacPBESHA256".
#keystore.pkcs12.macAlgorithm = HmacPBESHA1 #keystore.pkcs12.macAlgorithm = HmacPBESHA256
# The iteration count used by the MacData algorithm. This value must be a # The iteration count used by the MacData algorithm. This value must be a
# positive integer. The default value is 100000. # positive integer. The default value is 10000.
#keystore.pkcs12.macIterationCount = 100000 #keystore.pkcs12.macIterationCount = 10000
# #
# Enhanced exception message information # Enhanced exception message information
@ -1308,4 +1308,4 @@ jdk.io.permissionsUseCanonicalPath=false
# properties. In the case that both properties are simultaneously set, the # properties. In the case that both properties are simultaneously set, the
# System value prevails. The default value of the property is "false". # System value prevails. The default value of the property is "false".
# #
#jdk.security.allowNonCaAnchor=true #jdk.security.allowNonCaAnchor=true

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -23,7 +23,7 @@
/* /*
* @test * @test
* @bug 8223063 * @bug 8223063 8153005
* @requires os.family == "windows" * @requires os.family == "windows"
* @library /test/lib * @library /test/lib
* @summary Support CNG RSA keys * @summary Support CNG RSA keys
@ -48,7 +48,11 @@ public class VeryLongAlias {
public static void main(String[] args) throws Throwable { public static void main(String[] args) throws Throwable {
SecurityTools.keytool("-genkeypair -storetype pkcs12 -keystore ks" // Using the old algorithms to make sure the file is recognized
// by the certutil command on old versions of Windows.
SecurityTools.keytool(
"-J-Dkeystore.pkcs12.legacy"
+ " -genkeypair -storetype pkcs12 -keystore ks"
+ " -storepass changeit -keyalg RSA -dname CN=A -alias " + " -storepass changeit -keyalg RSA -dname CN=A -alias "
+ alias); + alias);
String id = ((X509Certificate)KeyStore.getInstance( String id = ((X509Certificate)KeyStore.getInstance(

View File

@ -22,217 +22,247 @@
*/ */
import jdk.test.lib.SecurityTools; import jdk.test.lib.SecurityTools;
import sun.security.util.ObjectIdentifier; import sun.security.util.KnownOIDs;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map;
import static jdk.test.lib.security.DerUtils.*; import static jdk.test.lib.security.DerUtils.*;
import static sun.security.pkcs.ContentInfo.DATA_OID; import static sun.security.util.KnownOIDs.*;
import static sun.security.pkcs.ContentInfo.ENCRYPTED_DATA_OID;
import sun.security.util.ObjectIdentifier;
import sun.security.util.KnownOIDs;
/* /*
* @test * @test
* @bug 8076190 8242151 * @bug 8076190 8242151 8153005
* @library /test/lib * @library /test/lib
* @modules java.base/sun.security.pkcs * @modules java.base/sun.security.pkcs
* java.base/sun.security.util * java.base/sun.security.util
* @summary Checks the preferences order of pkcs12 params * @summary Checks the preferences order of pkcs12 params, whether it's
* a system property or a security property, whether the name has
* "pkcs12" or "PKCS12", whether the legacy property is set.
*/ */
public class ParamsPreferences { public class ParamsPreferences {
public static final void main(String[] args) throws Exception { public static final void main(String[] args) throws Exception {
int c = 0; int c = 0;
// with storepass // default
test(c++, "-", "-", test(c++,
oid(KnownOIDs.PBEWithSHA1AndRC2_40), 50000, Map.of(),
oid(KnownOIDs.PBEWithSHA1AndDESede), 50000, Map.of(),
oid(KnownOIDs.SHA_1), 100000); PBES2, HmacSHA256, AES_256$CBC$NoPadding, 10000,
PBES2, HmacSHA256, AES_256$CBC$NoPadding, 10000,
SHA_256, 10000);
// legacy settings
test(c++,
Map.of("keystore.pkcs12.legacy", ""),
Map.of(),
PBEWithSHA1AndRC2_40, 50000,
PBEWithSHA1AndDESede, 50000,
SHA_1, 100000);
// legacy override everything else
test(c++,
Map.of("keystore.pkcs12.legacy", "",
"keystore.pkcs12.certProtectionAlgorithm", "PBEWithHmacSHA256AndAES_128",
"keystore.pkcs12.certPbeIterationCount", 3000,
"keystore.pkcs12.keyProtectionAlgorithm", "PBEWithHmacSHA256AndAES_128",
"keystore.pkcs12.keyPbeIterationCount", 4000,
"keystore.pkcs12.macAlgorithm", "HmacPBESHA384",
"keystore.pkcs12.macIterationCount", 2000),
Map.of(),
PBEWithSHA1AndRC2_40, 50000,
PBEWithSHA1AndDESede, 50000,
SHA_1, 100000);
// password-less with system property // password-less with system property
test(c++, "keystore.pkcs12.certProtectionAlgorithm", "NONE", test(c++,
"keystore.pkcs12.macAlgorithm", "NONE", Map.of("keystore.pkcs12.certProtectionAlgorithm", "NONE",
"-", "-", "keystore.pkcs12.macAlgorithm", "NONE"),
null, 0, Map.of(),
oid(KnownOIDs.PBEWithSHA1AndDESede), 50000, null,
null, 0); PBES2, HmacSHA256, AES_256$CBC$NoPadding, 10000,
null);
// password-less with security property // password-less with security property
test(c++, "-", test(c++,
"keystore.pkcs12.certProtectionAlgorithm", "NONE", Map.of(),
"keystore.pkcs12.macAlgorithm", "NONE", Map.of("keystore.pkcs12.certProtectionAlgorithm", "NONE",
"-", "keystore.pkcs12.macAlgorithm", "NONE"),
null, 0, null,
oid(KnownOIDs.PBEWithSHA1AndDESede), 50000, PBES2, HmacSHA256, AES_256$CBC$NoPadding, 10000,
null, 0); null);
// back to with storepass by overriding security property with system property // back to with storepass by overriding security property with system property
test(c++, "keystore.pkcs12.certProtectionAlgorithm", "PBEWithSHA1AndDESede", test(c++,
"keystore.pkcs12.macAlgorithm", "HmacPBESHA256", Map.of("keystore.pkcs12.certProtectionAlgorithm", "PBEWithSHA1AndDESede",
"-", "keystore.pkcs12.macAlgorithm", "HmacPBESHA256"),
"keystore.pkcs12.certProtectionAlgorithm", "NONE", Map.of("keystore.pkcs12.certProtectionAlgorithm", "NONE",
"keystore.pkcs12.macAlgorithm", "NONE", "keystore.pkcs12.macAlgorithm", "NONE"),
"-", PBEWithSHA1AndDESede, 10000,
oid(KnownOIDs.PBEWithSHA1AndDESede), 50000, PBES2, HmacSHA256, AES_256$CBC$NoPadding, 10000,
oid(KnownOIDs.PBEWithSHA1AndDESede), 50000, SHA_256, 10000);
oid(KnownOIDs.SHA_256), 100000);
// back to with storepass by using "" to force hardcoded default // back to with storepass by using "" to force hardcoded default
test(c++, "keystore.pkcs12.certProtectionAlgorithm", "", test(c++,
"keystore.pkcs12.keyProtectionAlgorithm", "", Map.of("keystore.pkcs12.certProtectionAlgorithm", "",
"keystore.pkcs12.macAlgorithm", "", "keystore.pkcs12.keyProtectionAlgorithm", "",
"-", "keystore.pkcs12.macAlgorithm", ""),
"keystore.pkcs12.certProtectionAlgorithm", "NONE", Map.of("keystore.pkcs12.certProtectionAlgorithm", "NONE",
"keystore.pkcs12.keyProtectionAlgorithm", "PBEWithSHA1AndRC2_40", "keystore.pkcs12.keyProtectionAlgorithm", "PBEWithSHA1AndRC2_40",
"keystore.pkcs12.macAlgorithm", "NONE", "keystore.pkcs12.macAlgorithm", "NONE"),
"-", PBES2, HmacSHA256, AES_256$CBC$NoPadding, 10000,
oid(KnownOIDs.PBEWithSHA1AndRC2_40), 50000, PBES2, HmacSHA256, AES_256$CBC$NoPadding, 10000,
oid(KnownOIDs.PBEWithSHA1AndDESede), 50000, SHA_256, 10000);
oid(KnownOIDs.SHA_1), 100000);
// change everything with system property // change everything with system property
test(c++, "keystore.pkcs12.certProtectionAlgorithm", "PBEWithSHA1AndDESede", test(c++,
"keystore.pkcs12.certPbeIterationCount", 3000, Map.of("keystore.pkcs12.certProtectionAlgorithm", "PBEWithSHA1AndDESede",
"keystore.pkcs12.keyProtectionAlgorithm", "PBEWithSHA1AndRC2_40", "keystore.pkcs12.certPbeIterationCount", 3000,
"keystore.pkcs12.keyPbeIterationCount", 4000, "keystore.pkcs12.keyProtectionAlgorithm", "PBEWithSHA1AndRC2_40",
"keystore.pkcs12.macAlgorithm", "HmacPBESHA256", "keystore.pkcs12.keyPbeIterationCount", 4000,
"keystore.pkcs12.macIterationCount", 2000, "keystore.pkcs12.macAlgorithm", "HmacPBESHA256",
"-", "-", "keystore.pkcs12.macIterationCount", 2000),
oid(KnownOIDs.PBEWithSHA1AndDESede), 3000, Map.of(),
oid(KnownOIDs.PBEWithSHA1AndRC2_40), 4000, PBEWithSHA1AndDESede, 3000,
oid(KnownOIDs.SHA_256), 2000); PBEWithSHA1AndRC2_40, 4000,
SHA_256, 2000);
// change everything with security property // change everything with security property
test(c++, "-", test(c++,
"keystore.pkcs12.certProtectionAlgorithm", "PBEWithSHA1AndDESede", Map.of(),
"keystore.pkcs12.certPbeIterationCount", 3000, Map.of("keystore.pkcs12.certProtectionAlgorithm", "PBEWithSHA1AndDESede",
"keystore.pkcs12.keyProtectionAlgorithm", "PBEWithSHA1AndRC2_40", "keystore.pkcs12.certPbeIterationCount", 3000,
"keystore.pkcs12.keyPbeIterationCount", 4000, "keystore.pkcs12.keyProtectionAlgorithm", "PBEWithSHA1AndRC2_40",
"keystore.pkcs12.macAlgorithm", "HmacPBESHA256", "keystore.pkcs12.keyPbeIterationCount", 4000,
"keystore.pkcs12.macIterationCount", 2000, "keystore.pkcs12.macAlgorithm", "HmacPBESHA256",
"-", "keystore.pkcs12.macIterationCount", 2000),
oid(KnownOIDs.PBEWithSHA1AndDESede), 3000, PBEWithSHA1AndDESede, 3000,
oid(KnownOIDs.PBEWithSHA1AndRC2_40), 4000, PBEWithSHA1AndRC2_40, 4000,
oid(KnownOIDs.SHA_256), 2000); SHA_256, 2000);
// override security property with system property // override security property with system property
test(c++, "keystore.pkcs12.certProtectionAlgorithm", "PBEWithSHA1AndDESede", test(c++,
"keystore.pkcs12.certPbeIterationCount", 13000, Map.of("keystore.pkcs12.certProtectionAlgorithm", "PBEWithSHA1AndDESede",
"keystore.pkcs12.keyProtectionAlgorithm", "PBEWithSHA1AndRC2_40", "keystore.pkcs12.certPbeIterationCount", 13000,
"keystore.pkcs12.keyPbeIterationCount", 14000, "keystore.pkcs12.keyProtectionAlgorithm", "PBEWithSHA1AndRC2_40",
"keystore.pkcs12.macAlgorithm", "HmacPBESHA256", "keystore.pkcs12.keyPbeIterationCount", 14000,
"keystore.pkcs12.macIterationCount", 12000, "keystore.pkcs12.macAlgorithm", "HmacPBESHA256",
"-", "keystore.pkcs12.macIterationCount", 12000),
"keystore.pkcs12.certProtectionAlgorithm", "PBEWithSHA1AndRC2_40", Map.of("keystore.pkcs12.certProtectionAlgorithm", "PBEWithSHA1AndRC2_40",
"keystore.pkcs12.certPbeIterationCount", 3000, "keystore.pkcs12.certPbeIterationCount", 3000,
"keystore.pkcs12.keyProtectionAlgorithm", "PBEWithSHA1AndDESede", "keystore.pkcs12.keyProtectionAlgorithm", "PBEWithSHA1AndDESede",
"keystore.pkcs12.keyPbeIterationCount", 4000, "keystore.pkcs12.keyPbeIterationCount", 4000,
"keystore.pkcs12.macAlgorithm", "HmacPBESHA1", "keystore.pkcs12.macAlgorithm", "HmacPBESHA1",
"keystore.pkcs12.macIterationCount", 2000, "keystore.pkcs12.macIterationCount", 2000),
"-", PBEWithSHA1AndDESede, 13000,
oid(KnownOIDs.PBEWithSHA1AndDESede), 13000, PBEWithSHA1AndRC2_40, 14000,
oid(KnownOIDs.PBEWithSHA1AndRC2_40), 14000, SHA_256, 12000);
oid(KnownOIDs.SHA_256), 12000);
// check keyProtectionAlgorithm old behavior. Preferences of // check keyProtectionAlgorithm old behavior. Preferences of
// 4 different settings. // 4 different settings.
test(c++, "-",
"keystore.PKCS12.keyProtectionAlgorithm", "PBEWithSHA1AndRC2_128",
"-",
oid(KnownOIDs.PBEWithSHA1AndRC2_40), 50000,
oid(KnownOIDs.PBEWithSHA1AndRC2_128), 50000,
oid(KnownOIDs.SHA_1), 100000);
test(c++, "-",
"keystore.PKCS12.keyProtectionAlgorithm", "PBEWithSHA1AndRC2_128",
"keystore.pkcs12.keyProtectionAlgorithm", "PBEWithSHA1AndRC2_40",
"-",
oid(KnownOIDs.PBEWithSHA1AndRC2_40), 50000,
oid(KnownOIDs.PBEWithSHA1AndRC2_40), 50000,
oid(KnownOIDs.SHA_1), 100000);
test(c++, test(c++,
"keystore.PKCS12.keyProtectionAlgorithm", "PBEWithSHA1AndRC4_128", Map.of(),
"-", Map.of("keystore.PKCS12.keyProtectionAlgorithm", "PBEWithSHA1AndRC2_128"),
"keystore.PKCS12.keyProtectionAlgorithm", "PBEWithSHA1AndRC2_128", PBES2, HmacSHA256, AES_256$CBC$NoPadding, 10000,
"keystore.pkcs12.keyProtectionAlgorithm", "PBEWithSHA1AndRC2_40", PBEWithSHA1AndRC2_128, 10000,
"-", SHA_256, 10000);
oid(KnownOIDs.PBEWithSHA1AndRC2_40), 50000,
oid(KnownOIDs.PBEWithSHA1AndRC4_128), 50000,
oid(KnownOIDs.SHA_1), 100000);
test(c++, test(c++,
"keystore.PKCS12.keyProtectionAlgorithm", "PBEWithSHA1AndRC4_128", Map.of(),
"keystore.pkcs12.keyProtectionAlgorithm", "PBEWithSHA1AndRC4_40", Map.of("keystore.PKCS12.keyProtectionAlgorithm", "PBEWithSHA1AndRC2_128",
"-", "keystore.pkcs12.keyProtectionAlgorithm", "PBEWithSHA1AndRC2_40"),
"keystore.PKCS12.keyProtectionAlgorithm", "PBEWithSHA1AndRC2_128", PBES2, HmacSHA256, AES_256$CBC$NoPadding, 10000,
"keystore.pkcs12.keyProtectionAlgorithm", "PBEWithSHA1AndRC2_40", PBEWithSHA1AndRC2_40, 10000,
"-", SHA_256, 10000);
oid(KnownOIDs.PBEWithSHA1AndRC2_40), 50000, test(c++,
oid(KnownOIDs.PBEWithSHA1AndRC4_40), 50000, Map.of("keystore.PKCS12.keyProtectionAlgorithm", "PBEWithSHA1AndRC4_128"),
oid(KnownOIDs.SHA_1), 100000); Map.of("keystore.PKCS12.keyProtectionAlgorithm", "PBEWithSHA1AndRC2_128",
} "keystore.pkcs12.keyProtectionAlgorithm", "PBEWithSHA1AndRC2_40"),
PBES2, HmacSHA256, AES_256$CBC$NoPadding, 10000,
private static ObjectIdentifier oid(KnownOIDs o) { PBEWithSHA1AndRC4_128, 10000,
return ObjectIdentifier.of(o); SHA_256, 10000);
test(c++,
Map.of("keystore.PKCS12.keyProtectionAlgorithm", "PBEWithSHA1AndRC4_128",
"keystore.pkcs12.keyProtectionAlgorithm", "PBEWithSHA1AndRC4_40"),
Map.of("keystore.PKCS12.keyProtectionAlgorithm", "PBEWithSHA1AndRC2_128",
"keystore.pkcs12.keyProtectionAlgorithm", "PBEWithSHA1AndRC2_40"),
PBES2, HmacSHA256, AES_256$CBC$NoPadding, 10000,
PBEWithSHA1AndRC4_40, 10000,
SHA_256, 10000);
} }
/** /**
* Run once. * Run once.
* *
* @param args an array containing system properties and values, "-", * @param sysProps system properties
* security properties and values, "-", expected certPbeAlg, * @param secProps security properties
* certPbeIC, keyPbeAlg, keyPbeIc, macAlg, macIC. * @param args an array expected certPbeAlg (sub algs), certPbeIC,
* keyPbeAlg (sub algs), keyPbeIc, macAlg, macIC.
*/ */
static void test(int n, Object... args) throws Exception { static void test(int n, Map<String, ?> sysProps,
boolean isSysProp = true; Map<String, ?> secProps,
Object... args) throws Exception {
String cmd = "-keystore ks" + n + " -genkeypair -keyalg EC " String cmd = "-keystore ks" + n + " -genkeypair -keyalg EC "
+ "-alias a -dname CN=A -storepass changeit " + "-alias a -dname CN=A -storepass changeit "
+ "-J-Djava.security.properties=" + n + ".conf"; + "-J-Djava.security.properties=" + n + ".conf";
for (var p : sysProps.entrySet()) {
cmd += " -J-D" + p.getKey() + "=" + p.getValue();
}
List<String> jsConf = new ArrayList<>(); List<String> jsConf = new ArrayList<>();
for (int i = 0; i < args.length; i++) { for (var p : secProps.entrySet()) {
if (isSysProp) { jsConf.add(p.getKey() + "=" + p.getValue());
if (args[i].equals("-")) { }
isSysProp = false; Files.write(Path.of(n + ".conf"), jsConf);
} else { System.out.println("--------- test starts ----------");
cmd += " -J-D" + args[i] + "=" + args[++i]; System.out.println(jsConf);
} SecurityTools.keytool(cmd).shouldHaveExitValue(0);
int i = 0;
byte[] data = Files.readAllBytes(Path.of("ks" + n));
// cert pbe alg + ic
KnownOIDs certAlg = (KnownOIDs)args[i++];
if (certAlg == null) {
checkAlg(data, "110c10", Data);
} else {
checkAlg(data, "110c10", EncryptedData);
checkAlg(data, "110c110110", certAlg);
if (certAlg == PBES2) {
checkAlg(data, "110c11011100", PBKDF2WithHmacSHA1);
checkAlg(data, "110c1101110130", args[i++]);
checkAlg(data, "110c11011110", args[i++]);
checkInt(data, "110c110111011", (int) args[i++]);
} else { } else {
if (args[i] == "-") { checkInt(data, "110c1101111", (int) args[i++]);
Files.write(Path.of(n + ".conf"), jsConf);
System.out.println("--------- test starts ----------");
System.out.println(jsConf);
SecurityTools.keytool(cmd).shouldHaveExitValue(0);
byte[] data = Files.readAllBytes(Path.of("ks" + n));
// cert pbe alg + ic
if (args[i+1] == null) {
checkAlg(data, "110c10", DATA_OID);
} else {
checkAlg(data, "110c10", ENCRYPTED_DATA_OID);
checkAlg(data, "110c110110", (ObjectIdentifier)args[i+1]);
checkInt(data, "110c1101111", (int)args[i+2]);
}
// key pbe alg + ic
checkAlg(data, "110c010c01000", (ObjectIdentifier)args[i+3]);
checkInt(data, "110c010c010011", (int)args[i+4]);
// mac alg + ic
if (args[i+5] == null) {
shouldNotExist(data, "2");
} else {
checkAlg(data, "2000", (ObjectIdentifier)args[i+5]);
checkInt(data, "22", (int)args[i+6]);
}
} else {
jsConf.add(args[i] + "=" + args[++i]);
}
} }
} }
// key pbe alg + ic
KnownOIDs keyAlg = (KnownOIDs)args[i++];
checkAlg(data, "110c010c01000", keyAlg);
if (keyAlg == PBES2) {
checkAlg(data, "110c010c0100100", PBKDF2WithHmacSHA1);
checkAlg(data, "110c010c010010130", args[i++]);
checkAlg(data, "110c010c0100110", args[i++]);
checkInt(data, "110c010c01001011", (int) args[i++]);
} else {
checkInt(data, "110c010c010011", (int) args[i++]);
}
// mac alg + ic
KnownOIDs macAlg = (KnownOIDs)args[i++];
if (macAlg == null) {
shouldNotExist(data, "2");
} else {
checkAlg(data, "2000", macAlg);
checkInt(data, "22", (int) args[i++]);
}
} }
} }

View File

@ -23,7 +23,7 @@
/* /*
* @test * @test
* @bug 8076190 8242151 * @bug 8076190 8242151 8153005
* @library /test/lib * @library /test/lib
* @modules java.base/sun.security.pkcs * @modules java.base/sun.security.pkcs
* java.base/sun.security.util * java.base/sun.security.util
@ -41,6 +41,7 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.io.UncheckedIOException; import java.io.UncheckedIOException;
import java.nio.file.DirectoryStream;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.security.KeyStore; import java.security.KeyStore;
@ -48,8 +49,7 @@ import java.util.Base64;
import java.util.Objects; import java.util.Objects;
import static jdk.test.lib.security.DerUtils.*; import static jdk.test.lib.security.DerUtils.*;
import sun.security.util.ObjectIdentifier; import static sun.security.util.KnownOIDs.*;
import sun.security.util.KnownOIDs;
import static sun.security.pkcs.ContentInfo.*; import static sun.security.pkcs.ContentInfo.*;
public class ParamsTest { public class ParamsTest {
@ -57,15 +57,18 @@ public class ParamsTest {
public static void main(String[] args) throws Throwable { public static void main(String[] args) throws Throwable {
// De-BASE64 textual files in ./params to `pwd` // De-BASE64 textual files in ./params to `pwd`
Files.newDirectoryStream(Path.of(System.getProperty("test.src"), "params")) try (DirectoryStream<Path> stream = Files.newDirectoryStream(
.forEach(p -> { Path.of(System.getProperty("test.src"), "params"),
try (InputStream is = Files.newInputStream(p); p -> !p.getFileName().toString().equals("README"))) {
OutputStream os = Files.newOutputStream(p.getFileName())){ stream.forEach(p -> {
Base64.getMimeDecoder().wrap(is).transferTo(os); try (InputStream is = Files.newInputStream(p);
} catch (IOException e) { OutputStream os = Files.newOutputStream(p.getFileName())) {
throw new UncheckedIOException(e); Base64.getMimeDecoder().wrap(is).transferTo(os);
} } catch (IOException e) {
}); throw new UncheckedIOException(e);
}
});
}
byte[] data; byte[] data;
@ -100,34 +103,44 @@ public class ParamsTest {
// Current default pkcs12 setting // Current default pkcs12 setting
keytool("-importkeystore -srckeystore ks -srcstorepass changeit " keytool("-importkeystore -srckeystore ks -srcstorepass changeit "
+ "-destkeystore ksnormal -deststorepass changeit"); + "-destkeystore ksnormal -deststorepass changeit");
data = Files.readAllBytes(Path.of("ksnormal"));
checkInt(data, "22", 100000); // Mac ic
checkAlg(data, "2000", oid(KnownOIDs.SHA_1)); // Mac alg
checkAlg(data, "110c010c01000", oid(KnownOIDs.PBEWithSHA1AndDESede)); // key alg
checkInt(data, "110c010c010011", 50000); // key ic
checkAlg(data, "110c10", ENCRYPTED_DATA_OID);
checkAlg(data, "110c110110", oid(KnownOIDs.PBEWithSHA1AndRC2_40)); // cert alg
checkInt(data, "110c1101111", 50000); // cert ic
data = Files.readAllBytes(Path.of("ksnormal"));
checkInt(data, "22", 10000); // Mac ic
checkAlg(data, "2000", SHA_256); // Mac alg
checkAlg(data, "110c010c01000", PBES2); // key alg
checkInt(data, "110c010c01001011", 10000); // key ic
checkAlg(data, "110c10", ENCRYPTED_DATA_OID);
checkAlg(data, "110c110110", PBES2); // cert alg
check("ksnormal", "a", "changeit", "changeit", true, true, true); check("ksnormal", "a", "changeit", "changeit", true, true, true);
check("ksnormal", "a", null, "changeit", true, false, true); check("ksnormal", "a", null, "changeit", true, false, true);
check("ksnormal", "a", "wrongpass", "-", IOException.class, "-", "-"); check("ksnormal", "a", "wrongpass", "-", IOException.class, "-", "-");
// Import it into a new keystore with legacy algorithms
keytool("-importkeystore -srckeystore ksnormal -srcstorepass changeit "
+ "-destkeystore kslegacyimp -deststorepass changeit "
+ "-J-Dkeystore.pkcs12.legacy");
data = Files.readAllBytes(Path.of("kslegacyimp"));
checkInt(data, "22", 100000); // Mac ic
checkAlg(data, "2000", SHA_1); // Mac alg
checkAlg(data, "110c010c01000", PBEWithSHA1AndDESede); // key alg
checkInt(data, "110c010c010011", 50000); // key ic
checkAlg(data, "110c110110", PBEWithSHA1AndRC2_40); // cert alg
checkInt(data, "110c1101111", 50000); // cert ic
// Add a new entry with password-less settings, still has a storepass // Add a new entry with password-less settings, still has a storepass
keytool("-keystore ksnormal -genkeypair -keyalg DSA " keytool("-keystore ksnormal -genkeypair -keyalg DSA "
+ "-storepass changeit -alias b -dname CN=b " + "-storepass changeit -alias b -dname CN=b "
+ "-J-Dkeystore.pkcs12.certProtectionAlgorithm=NONE " + "-J-Dkeystore.pkcs12.certProtectionAlgorithm=NONE "
+ "-J-Dkeystore.pkcs12.macAlgorithm=NONE"); + "-J-Dkeystore.pkcs12.macAlgorithm=NONE");
data = Files.readAllBytes(Path.of("ksnormal")); data = Files.readAllBytes(Path.of("ksnormal"));
checkInt(data, "22", 100000); // Mac ic checkInt(data, "22", 10000); // Mac ic
checkAlg(data, "2000", oid(KnownOIDs.SHA_1)); // Mac alg checkAlg(data, "2000", SHA_256); // Mac alg
checkAlg(data, "110c010c01000", oid(KnownOIDs.PBEWithSHA1AndDESede)); // key alg checkAlg(data, "110c010c01000", PBES2); // key alg
checkInt(data, "110c010c010011", 50000); // key ic checkInt(data, "110c010c01001011", 10000); // key ic
checkAlg(data, "110c010c11000", oid(KnownOIDs.PBEWithSHA1AndDESede)); // new key alg checkAlg(data, "110c010c11000", PBES2); // new key alg
checkInt(data, "110c010c110011", 50000); // new key ic checkInt(data, "110c010c11001011", 10000); // new key ic
checkAlg(data, "110c10", ENCRYPTED_DATA_OID); checkAlg(data, "110c10", ENCRYPTED_DATA_OID);
checkAlg(data, "110c110110", oid(KnownOIDs.PBEWithSHA1AndRC2_40)); // cert alg checkAlg(data, "110c110110", PBES2); // cert alg
checkInt(data, "110c1101111", 50000); // cert ic
check("ksnormal", "b", null, "changeit", true, false, true); check("ksnormal", "b", null, "changeit", true, false, true);
check("ksnormal", "b", "changeit", "changeit", true, true, true); check("ksnormal", "b", "changeit", "changeit", true, true, true);
@ -139,8 +152,8 @@ public class ParamsTest {
+ "-J-Dkeystore.pkcs12.macAlgorithm=NONE"); + "-J-Dkeystore.pkcs12.macAlgorithm=NONE");
data = Files.readAllBytes(Path.of("ksnopass")); data = Files.readAllBytes(Path.of("ksnopass"));
shouldNotExist(data, "2"); // no Mac shouldNotExist(data, "2"); // no Mac
checkAlg(data, "110c010c01000", oid(KnownOIDs.PBEWithSHA1AndRC4_128)); checkAlg(data, "110c010c01000", PBEWithSHA1AndRC4_128);
checkInt(data, "110c010c010011", 50000); checkInt(data, "110c010c010011", 10000);
checkAlg(data, "110c10", DATA_OID); checkAlg(data, "110c10", DATA_OID);
check("ksnopass", "a", null, "changeit", true, true, true); check("ksnopass", "a", null, "changeit", true, true, true);
check("ksnopass", "a", "changeit", "changeit", true, true, true); check("ksnopass", "a", "changeit", "changeit", true, true, true);
@ -151,10 +164,10 @@ public class ParamsTest {
+ "-storepass changeit -alias b -dname CN=B"); + "-storepass changeit -alias b -dname CN=B");
data = Files.readAllBytes(Path.of("ksnopass")); data = Files.readAllBytes(Path.of("ksnopass"));
shouldNotExist(data, "2"); // no Mac shouldNotExist(data, "2"); // no Mac
checkAlg(data, "110c010c01000", oid(KnownOIDs.PBEWithSHA1AndRC4_128)); checkAlg(data, "110c010c01000", PBEWithSHA1AndRC4_128);
checkInt(data, "110c010c010011", 50000); checkInt(data, "110c010c010011", 10000);
checkAlg(data, "110c010c11000", oid(KnownOIDs.PBEWithSHA1AndDESede)); checkAlg(data, "110c010c11000", PBES2);
checkInt(data, "110c010c110011", 50000); checkInt(data, "110c010c11001011", 10000);
checkAlg(data, "110c10", DATA_OID); checkAlg(data, "110c10", DATA_OID);
check("ksnopass", "a", null, "changeit", true, true, true); check("ksnopass", "a", null, "changeit", true, true, true);
check("ksnopass", "b", null, "changeit", true, true, true); check("ksnopass", "b", null, "changeit", true, true, true);
@ -166,11 +179,11 @@ public class ParamsTest {
+ "-J-Dkeystore.pkcs12.keyPbeIterationCount=7777"); + "-J-Dkeystore.pkcs12.keyPbeIterationCount=7777");
data = Files.readAllBytes(Path.of("ksnewic")); data = Files.readAllBytes(Path.of("ksnewic"));
checkInt(data, "22", 5555); // Mac ic checkInt(data, "22", 5555); // Mac ic
checkAlg(data, "2000", oid(KnownOIDs.SHA_1)); // Mac alg checkAlg(data, "2000", SHA_256); // Mac alg
checkAlg(data, "110c010c01000", oid(KnownOIDs.PBEWithSHA1AndDESede)); // key alg checkAlg(data, "110c010c01000", PBES2); // key alg
checkInt(data, "110c010c010011", 7777); // key ic checkInt(data, "110c010c01001011", 7777); // key ic
checkAlg(data, "110c110110", oid(KnownOIDs.PBEWithSHA1AndRC2_40)); // cert alg checkAlg(data, "110c110110", PBES2); // cert alg
checkInt(data, "110c1101111", 6666); // cert ic checkInt(data, "110c110111011", 6666); // cert ic
// keypbe alg cannot be NONE // keypbe alg cannot be NONE
keytool("-keystore ksnewic -genkeypair -keyalg DSA " keytool("-keystore ksnewic -genkeypair -keyalg DSA "
@ -185,13 +198,13 @@ public class ParamsTest {
+ "-J-Dkeystore.pkcs12.keyProtectionAlgorithm=PBEWithSHA1AndRC4_128"); + "-J-Dkeystore.pkcs12.keyProtectionAlgorithm=PBEWithSHA1AndRC4_128");
data = Files.readAllBytes(Path.of("ksnewic")); data = Files.readAllBytes(Path.of("ksnewic"));
checkInt(data, "22", 5555); // Mac ic checkInt(data, "22", 5555); // Mac ic
checkAlg(data, "2000", oid(KnownOIDs.SHA_1)); // Mac alg checkAlg(data, "2000", SHA_256); // Mac alg
checkAlg(data, "110c010c01000", oid(KnownOIDs.PBEWithSHA1AndDESede)); // key alg checkAlg(data, "110c010c01000", PBES2); // key alg
checkInt(data, "110c010c010011", 7777); // key ic checkInt(data, "110c010c01001011", 7777); // key ic
checkAlg(data, "110c010c11000", oid(KnownOIDs.PBEWithSHA1AndRC4_128)); // new key alg checkAlg(data, "110c010c11000", PBEWithSHA1AndRC4_128); // new key alg
checkInt(data, "110c010c110011", 50000); // new key ic checkInt(data, "110c010c110011", 10000); // new key ic
checkAlg(data, "110c110110", oid(KnownOIDs.PBEWithSHA1AndRC2_40)); // cert alg checkAlg(data, "110c110110", PBES2); // cert alg
checkInt(data, "110c1101111", 6666); // cert ic checkInt(data, "110c110111011", 6666); // cert ic
// Check KeyStore loading multiple keystores // Check KeyStore loading multiple keystores
KeyStore ks = KeyStore.getInstance("pkcs12"); KeyStore ks = KeyStore.getInstance("pkcs12");
@ -201,15 +214,15 @@ public class ParamsTest {
ks.store(fos, "changeit".toCharArray()); ks.store(fos, "changeit".toCharArray());
} }
data = Files.readAllBytes(Path.of("ksnormaldup")); data = Files.readAllBytes(Path.of("ksnormaldup"));
checkInt(data, "22", 100000); // Mac ic checkInt(data, "22", 10000); // Mac ic
checkAlg(data, "2000", oid(KnownOIDs.SHA_1)); // Mac alg checkAlg(data, "2000", SHA_256); // Mac alg
checkAlg(data, "110c010c01000", oid(KnownOIDs.PBEWithSHA1AndDESede)); // key alg checkAlg(data, "110c010c01000", PBES2); // key alg
checkInt(data, "110c010c010011", 50000); // key ic checkInt(data, "110c010c01001011", 10000); // key ic
checkAlg(data, "110c010c11000", oid(KnownOIDs.PBEWithSHA1AndDESede)); // new key alg checkAlg(data, "110c010c11000", PBES2); // new key alg
checkInt(data, "110c010c110011", 50000); // new key ic checkInt(data, "110c010c11001011", 10000); // new key ic
checkAlg(data, "110c10", ENCRYPTED_DATA_OID); checkAlg(data, "110c10", ENCRYPTED_DATA_OID);
checkAlg(data, "110c110110", oid(KnownOIDs.PBEWithSHA1AndRC2_40)); // cert alg checkAlg(data, "110c110110", PBES2); // cert alg
checkInt(data, "110c1101111", 50000); // cert ic checkInt(data, "110c110111011", 10000); // cert ic
try (FileInputStream fis = new FileInputStream("ksnopass"); try (FileInputStream fis = new FileInputStream("ksnopass");
FileOutputStream fos = new FileOutputStream("ksnopassdup")) { FileOutputStream fos = new FileOutputStream("ksnopassdup")) {
@ -218,10 +231,10 @@ public class ParamsTest {
} }
data = Files.readAllBytes(Path.of("ksnopassdup")); data = Files.readAllBytes(Path.of("ksnopassdup"));
shouldNotExist(data, "2"); // no Mac shouldNotExist(data, "2"); // no Mac
checkAlg(data, "110c010c01000", oid(KnownOIDs.PBEWithSHA1AndRC4_128)); checkAlg(data, "110c010c01000", PBEWithSHA1AndRC4_128);
checkInt(data, "110c010c010011", 50000); checkInt(data, "110c010c010011", 10000);
checkAlg(data, "110c010c11000", oid(KnownOIDs.PBEWithSHA1AndDESede)); checkAlg(data, "110c010c11000", PBES2);
checkInt(data, "110c010c110011", 50000); checkInt(data, "110c010c11001011", 10000);
checkAlg(data, "110c10", DATA_OID); checkAlg(data, "110c10", DATA_OID);
try (FileInputStream fis = new FileInputStream("ksnewic"); try (FileInputStream fis = new FileInputStream("ksnewic");
@ -231,13 +244,13 @@ public class ParamsTest {
} }
data = Files.readAllBytes(Path.of("ksnewicdup")); data = Files.readAllBytes(Path.of("ksnewicdup"));
checkInt(data, "22", 5555); // Mac ic checkInt(data, "22", 5555); // Mac ic
checkAlg(data, "2000", oid(KnownOIDs.SHA_1)); // Mac alg checkAlg(data, "2000", SHA_256); // Mac alg
checkAlg(data, "110c010c01000", oid(KnownOIDs.PBEWithSHA1AndDESede)); // key alg checkAlg(data, "110c010c01000", PBES2); // key alg
checkInt(data, "110c010c010011", 7777); // key ic checkInt(data, "110c010c01001011", 7777); // key ic
checkAlg(data, "110c010c11000", oid(KnownOIDs.PBEWithSHA1AndRC4_128)); // new key alg checkAlg(data, "110c010c11000", PBEWithSHA1AndRC4_128); // new key alg
checkInt(data, "110c010c110011", 50000); // new key ic checkInt(data, "110c010c110011", 10000); // new key ic
checkAlg(data, "110c110110", oid(KnownOIDs.PBEWithSHA1AndRC2_40)); // cert alg checkAlg(data, "110c110110", PBES2); // cert alg
checkInt(data, "110c1101111", 6666); // cert ic checkInt(data, "110c110111011", 6666); // cert ic
// Check keytool behavior // Check keytool behavior
@ -434,10 +447,6 @@ public class ParamsTest {
Asserts.assertEQ(expectedKey, actualKey, label + "-key"); Asserts.assertEQ(expectedKey, actualKey, label + "-key");
} }
private static ObjectIdentifier oid(KnownOIDs o) {
return ObjectIdentifier.of(o);
}
static OutputAnalyzer keytool(String s) throws Throwable { static OutputAnalyzer keytool(String s) throws Throwable {
return SecurityTools.keytool(s); return SecurityTools.keytool(s);
} }

View File

@ -1,8 +1,10 @@
1. Preparing data in this directory 1. Preparing data in this directory
Do not use OpenSSL 3.0.0. The default algorithms for pkcs12 are changed.
(
mkdir tmp mkdir tmp
cd tmp cd tmp
keytool -keystore ks -genkeypair -storepass changeit -alias a -dname CN=A keytool -keystore ks -keyalg ec -genkeypair -storepass changeit -alias a -dname CN=A
openssl pkcs12 -in ks -nodes -out kandc -passin pass:changeit openssl pkcs12 -in ks -nodes -out kandc -passin pass:changeit
openssl pkcs12 -export -in kandc -out os2 -name a -passout pass:changeit \ openssl pkcs12 -export -in kandc -out os2 -name a -passout pass:changeit \
-certpbe NONE -nomac -certpbe NONE -nomac
@ -17,37 +19,38 @@ for a in *; do
done done
cd .. cd ..
rm -rf tmp rm -rf tmp
)
2. After running the test, we can go to the scratch directory and run the 2. After running the test, we can go to the scratch directory and run the
following commands to check keytool -> openssl interoperability. following commands to check keytool -> openssl interoperability.
OpenSSL 1.1.0i is used here. Earlier versions might generate different info. OpenSSL 1.1.0i is used here. Earlier versions might generate different info.
( (
openssl pkcs12 -in ks2 -passin pass:changeit -info -nokeys -nocerts 2> t2 || exit 20 openssl pkcs12 -in ksnormal -passin pass:changeit -info -nokeys -nocerts 2> t2 || exit 20
grep "MAC:sha1 Iteration 100000" t2 || exit 21 grep "MAC: sha256, Iteration 10000" t2 || exit 21
grep "Shrouded Keybag: pbeWithSHA1And3-KeyTripleDES-CBC, Iteration 50000" t2 || exit 23 grep "Shrouded Keybag: PBES2, PBKDF2, AES-256-CBC, Iteration 10000, PRF hmacWithSHA256" t2 || exit 23
grep "PKCS7 Encrypted data: pbeWithSHA1And40BitRC2-CBC, Iteration 50000" t2 || exit 24 grep "PKCS7 Encrypted data: PBES2, PBKDF2, AES-256-CBC, Iteration 10000, PRF hmacWithSHA256" t2 || exit 24
openssl pkcs12 -in ks22 -passin pass:changeit -info -nokeys -nocerts 2> t22 || exit 25 openssl pkcs12 -in ksnormaldup -passin pass:changeit -info -nokeys -nocerts 2> t22 || exit 25
diff t2 t22 || exit 26 diff t2 t22 || exit 26
openssl pkcs12 -in ks3 -passin pass:changeit -info -nokeys -nocerts && exit 30 openssl pkcs12 -in ksnopass -passin pass:changeit -info -nokeys -nocerts && exit 30
openssl pkcs12 -in ks3 -passin pass:changeit -info -nokeys -nocerts -nomacver 2> t3 || exit 31 openssl pkcs12 -in ksnopass -passin pass:changeit -info -nokeys -nocerts -nomacver 2> t3 || exit 31
grep "PKCS7 Encrypted data:" t3 && exit 33 grep "PKCS7 Encrypted data:" t3 && exit 33
grep "Shrouded Keybag: pbeWithSHA1And3-KeyTripleDES-CBC, Iteration 50000" t3 || exit 34 grep "Shrouded Keybag: PBES2, PBKDF2, AES-256-CBC, Iteration 10000, PRF hmacWithSHA256" t3 || exit 34
grep "Shrouded Keybag: pbeWithSHA1And128BitRC4, Iteration 50000" t3 || exit 35 grep "Shrouded Keybag: pbeWithSHA1And128BitRC4, Iteration 10000" t3 || exit 35
openssl pkcs12 -in ks33 -passin pass:changeit -info -nokeys -nocerts -nomacver 2> t33 || exit 36 openssl pkcs12 -in ksnopassdup -passin pass:changeit -info -nokeys -nocerts -nomacver 2> t33 || exit 36
diff t3 t33 || exit 37 diff t3 t33 || exit 37
openssl pkcs12 -in ks4 -passin pass:changeit -info -nokeys -nocerts 2> t4 || exit 40 openssl pkcs12 -in ksnewic -passin pass:changeit -info -nokeys -nocerts 2> t4 || exit 40
grep "MAC:sha1 Iteration 5555" t4 || exit 41 grep "MAC: sha256, Iteration 5555" t4 || exit 41
grep "Shrouded Keybag: pbeWithSHA1And3-KeyTripleDES-CBC, Iteration 7777" t4 || exit 43 grep "Shrouded Keybag: PBES2, PBKDF2, AES-256-CBC, Iteration 7777, PRF hmacWithSHA256" t4 || exit 43
grep "Shrouded Keybag: pbeWithSHA1And128BitRC4, Iteration 50000" t4 || exit 44 grep "Shrouded Keybag: pbeWithSHA1And128BitRC4, Iteration 10000" t4 || exit 44
grep "PKCS7 Encrypted data: pbeWithSHA1And40BitRC2-CBC, Iteration 6666" t4 || exit 45 grep "PKCS7 Encrypted data: PBES2, PBKDF2, AES-256-CBC, Iteration 6666, PRF hmacWithSHA256" t4 || exit 45
openssl pkcs12 -in ks44 -passin pass:changeit -info -nokeys -nocerts 2> t44 || exit 46 openssl pkcs12 -in ksnewicdup -passin pass:changeit -info -nokeys -nocerts 2> t44 || exit 46
diff t4 t44 || exit 47 diff t4 t44 || exit 47
echo Succeed echo Succeed

View File

@ -108,10 +108,9 @@ public class GenerateAll {
oa.shouldHaveExitValue(0); oa.shouldHaveExitValue(0);
kt("-alias " + alias + " -export -file " + alias + ".crt"); kt("-alias " + alias + " -export -file " + alias + ".crt");
byte[] crt = Files.readAllBytes(Path.of(alias + ".crt")); byte[] crt = Files.readAllBytes(Path.of(alias + ".crt"));
ObjectIdentifier oid = oid(expected); DerUtils.checkAlg(crt, "020", expected); // tbsCertificate.signature
DerUtils.checkAlg(crt, "020", oid); // tbsCertificate.signature DerUtils.checkAlg(crt, "0600", expected); // tbsCertificate.subjectPublicKeyInfo.algorithm
DerUtils.checkAlg(crt, "0600", oid); // tbsCertificate.subjectPublicKeyInfo.algorithm DerUtils.checkAlg(crt, "10", expected); // signatureAlgorithm
DerUtils.checkAlg(crt, "10", oid); // signatureAlgorithm
} }
} }
@ -179,18 +178,18 @@ public class GenerateAll {
} }
byte[] crt = read(alias + ".self"); byte[] crt = read(alias + ".self");
DerUtils.checkAlg(crt, "020", oid(sigAlg)); // tbsCertificate.signature DerUtils.checkAlg(crt, "020", sigAlg); // tbsCertificate.signature
DerUtils.checkAlg(crt, "0600", oid(keyAlg)); // tbsCertificate.subjectPublicKeyInfo.algorithm DerUtils.checkAlg(crt, "0600", keyAlg); // tbsCertificate.subjectPublicKeyInfo.algorithm
assertEquals( assertEquals(
DerUtils.innerDerValue(crt, "02"), // tbsCertificate.signature DerUtils.innerDerValue(crt, "02"), // tbsCertificate.signature
DerUtils.innerDerValue(crt, "1")); // signatureAlgorithm DerUtils.innerDerValue(crt, "1")); // signatureAlgorithm
byte[] req = read(alias + ".req"); byte[] req = read(alias + ".req");
DerUtils.checkAlg(req, "10", oid(sigAlg)); // signatureAlgorithm DerUtils.checkAlg(req, "10", sigAlg); // signatureAlgorithm
DerUtils.checkAlg(req, "0200", oid(keyAlg)); // certificationRequestInfo.subjectPKInfo.algorithm DerUtils.checkAlg(req, "0200", keyAlg); // certificationRequestInfo.subjectPKInfo.algorithm
byte[] crl = read(alias + ".crl"); byte[] crl = read(alias + ".crl");
DerUtils.checkAlg(crl, "000", oid(sigAlg)); // tbsCertList.signature DerUtils.checkAlg(crl, "000", sigAlg); // tbsCertList.signature
assertEquals( assertEquals(
DerUtils.innerDerValue(crl, "00"), // tbsCertList.signature DerUtils.innerDerValue(crl, "00"), // tbsCertList.signature
DerUtils.innerDerValue(crl, "1")); // signatureAlgorithm DerUtils.innerDerValue(crl, "1")); // signatureAlgorithm
@ -200,13 +199,13 @@ public class GenerateAll {
"META-INF/" + alias.toUpperCase() + "." + ext); "META-INF/" + alias.toUpperCase() + "." + ext);
byte[] p7 = jf.getInputStream(je).readAllBytes(); byte[] p7 = jf.getInputStream(je).readAllBytes();
// SignerInfo.digestAlgorithm // SignerInfo.digestAlgorithm
DerUtils.checkAlg(p7, "104020", oid(expDigAlg)); DerUtils.checkAlg(p7, "104020", expDigAlg);
// SignerInfo.signatureAlgorithm // SignerInfo.signatureAlgorithm
if (DerUtils.innerDerValue(p7, "10403").isContextSpecific()) { if (DerUtils.innerDerValue(p7, "10403").isContextSpecific()) {
// SignerInfo has signedAttributes at 104030 // SignerInfo has signedAttributes at 104030
DerUtils.checkAlg(p7, "104040", oid(expEncAlg)); DerUtils.checkAlg(p7, "104040", expEncAlg);
} else { } else {
DerUtils.checkAlg(p7, "104030", oid(expEncAlg)); DerUtils.checkAlg(p7, "104030", expEncAlg);
} }
} }
} }
@ -216,14 +215,6 @@ public class GenerateAll {
js("-verify a.jar -verbose -certs"); js("-verify a.jar -verbose -certs");
} }
static ObjectIdentifier oid(String name) {
return ObjectIdentifier.of(KnownOIDs.findMatch(name));
}
static ObjectIdentifier oid(KnownOIDs ko) {
return ObjectIdentifier.of(ko);
}
static byte[] read(String f) throws IOException { static byte[] read(String f) throws IOException {
try (var v = Files.lines(Path.of(f))) { try (var v = Files.lines(Path.of(f))) {
return Base64.getDecoder().decode(v.filter(s -> !s.startsWith("-----")) return Base64.getDecoder().decode(v.filter(s -> !s.startsWith("-----"))

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -25,6 +25,7 @@ package jdk.test.lib.security;
import jdk.test.lib.Asserts; import jdk.test.lib.Asserts;
import sun.security.util.DerInputStream; import sun.security.util.DerInputStream;
import sun.security.util.DerValue; import sun.security.util.DerValue;
import sun.security.util.KnownOIDs;
import sun.security.util.ObjectIdentifier; import sun.security.util.ObjectIdentifier;
import java.io.IOException; import java.io.IOException;
@ -95,8 +96,18 @@ public class DerUtils {
* Ensures that the inner DerValue is the expected ObjectIdentifier. * Ensures that the inner DerValue is the expected ObjectIdentifier.
*/ */
public static void checkAlg(byte[] der, String location, public static void checkAlg(byte[] der, String location,
ObjectIdentifier expected) throws Exception { Object expected) throws Exception {
Asserts.assertEQ(innerDerValue(der, location).getOID(), expected); ObjectIdentifier oid;
if (expected instanceof ObjectIdentifier) {
oid = (ObjectIdentifier)expected;
} else if (expected instanceof KnownOIDs) {
oid = ObjectIdentifier.of((KnownOIDs) expected);
} else if (expected instanceof String) {
oid = ObjectIdentifier.of(KnownOIDs.findMatch((String)expected));
} else {
throw new IllegalArgumentException(expected.toString());
}
Asserts.assertEQ(innerDerValue(der, location).getOID(), oid);
} }
/** /**