8155847: SHA groups needed for jdk.security.provider.preferred
Reviewed-by: valeriep, mullan
--- a/jdk/src/java.base/share/classes/sun/security/jca/ProviderList.java Thu May 19 20:14:17 2016 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/jca/ProviderList.java Thu May 19 16:05:33 2016 -0700
@@ -650,12 +650,29 @@
}
}
+ /* Defined Groups for jdk.security.provider.preferred */
+ private static final String SHA2Group[] = { "SHA-224", "SHA-256",
+ "SHA-384", "SHA-512", "SHA-512/224", "SHA-512/256" };
+ private static final String HmacSHA2Group[] = { "HmacSHA224",
+ "HmacSHA256", "HmacSHA384", "HmacSHA512"};
+ private static final String SHA2RSAGroup[] = { "SHA224withRSA",
+ "SHA256withRSA", "SHA384withRSA", "SHA512withRSA"};
+ private static final String SHA2DSAGroup[] = { "SHA224withDSA",
+ "SHA256withDSA", "SHA384withDSA", "SHA512withDSA"};
+ private static final String SHA2ECDSAGroup[] = { "SHA224withECDSA",
+ "SHA256withECDSA", "SHA384withECDSA", "SHA512withECDSA"};
+ private static final String SHA3Group[] = { "SHA3-224", "SHA3-256",
+ "SHA3-384", "SHA3-512" };
+ private static final String HmacSHA3Group[] = { "HmacSHA3-224",
+ "HmacSHA3-256", "HmacSHA3-384", "HmacSHA3-512"};
+
// Individual preferred property entry from jdk.security.provider.preferred
- private class PreferredEntry {
- String type = null;
- String algorithm;
- String provider;
- String alternateName = null;
+ private static class PreferredEntry {
+ private String type = null;
+ private String algorithm;
+ private String provider;
+ private String alternateNames[] = null;
+ private boolean group = false;
PreferredEntry(String t, String p) {
int i = t.indexOf('.');
@@ -667,47 +684,83 @@
}
provider = p;
- if (algorithm.compareToIgnoreCase("SHA1") == 0) {
- alternateName = "SHA-1";
+ // Group definitions
+ if (type != null && type.compareToIgnoreCase("Group") == 0) {
+ // Currently intrinsic algorithm groups
+ if (algorithm.compareToIgnoreCase("SHA2") == 0) {
+ alternateNames = SHA2Group;
+ } else if (algorithm.compareToIgnoreCase("HmacSHA2") == 0) {
+ alternateNames = HmacSHA2Group;
+ } else if (algorithm.compareToIgnoreCase("SHA2RSA") == 0) {
+ alternateNames = SHA2RSAGroup;
+ } else if (algorithm.compareToIgnoreCase("SHA2DSA") == 0) {
+ alternateNames = SHA2DSAGroup;
+ } else if (algorithm.compareToIgnoreCase("SHA2ECDSA") == 0) {
+ alternateNames = SHA2ECDSAGroup;
+ } else if (algorithm.compareToIgnoreCase("SHA3") == 0) {
+ alternateNames = SHA3Group;
+ } else if (algorithm.compareToIgnoreCase("HmacSHA3") == 0) {
+ alternateNames = HmacSHA3Group;
+ }
+ if (alternateNames != null) {
+ group = true;
+ }
+
+ // If the algorithm name given is SHA1
+ } else if (algorithm.compareToIgnoreCase("SHA1") == 0) {
+ alternateNames = new String[] { "SHA-1" };
} else if (algorithm.compareToIgnoreCase("SHA-1") == 0) {
- alternateName = "SHA1";
+ alternateNames = new String[] { "SHA1" };
}
}
boolean match(String t, String a) {
if (debug != null) {
- debug.println("Config match: " + toString() + " == [" + t +
- ", " + a + "]");
+ debug.println("Config check: " + toString() + " == " +
+ print(t, a, null));
}
// Compare service type if configured
- if (type != null && type.compareToIgnoreCase(t) != 0) {
+ if (type != null && !group && type.compareToIgnoreCase(t) != 0) {
return false;
}
// Compare the algorithm string.
- if (a.compareToIgnoreCase(algorithm) == 0) {
+ if (!group && a.compareToIgnoreCase(algorithm) == 0) {
if (debug != null) {
- debug.println("Config entry found: " + toString());
+ debug.println("Config entry matched: " + toString());
}
return true;
}
- if (alternateName != null &&
- a.compareToIgnoreCase(alternateName) == 0) {
- if (debug != null) {
- debug.println("Config entry found (alternateName): " +
- toString());
+ if (alternateNames != null) {
+ for (String alt : alternateNames) {
+ if (debug != null) {
+ debug.println("AltName check: " + print(type, alt,
+ provider));
+ }
+ if (a.compareToIgnoreCase(alt) == 0) {
+ if (debug != null) {
+ debug.println("AltName entry matched: " +
+ provider);
+ }
+ return true;
+ }
}
- return true;
}
// No match
return false;
}
+ // Print debugging output of PreferredEntry
+ private String print(String t, String a, String p) {
+ return "[" + ((t != null) ? t : "" ) + ", " + a +
+ ((p != null) ? " : " + p : "" ) + "] ";
+ }
+
public String toString() {
- return "[" + type + ", " + algorithm + " : " + provider + "] ";
+ return print(type, algorithm, provider);
}
}
--- a/jdk/src/java.base/share/conf/security/java.security Thu May 19 20:14:17 2016 +0000
+++ b/jdk/src/java.base/share/conf/security/java.security Thu May 19 16:05:33 2016 -0700
@@ -105,15 +105,30 @@
# The provider is the name of the provider. Any provider that does not
# also appear in the registered list will be ignored.
#
+# There is a special serviceType for this property only to group a set of
+# algorithms together. The type is "Group" and is followed by an algorithm
+# keyword. Groups are to simplify and lessen the entries on the property
+# line. Current groups are:
+# Group.SHA2 = SHA-224, SHA-256, SHA-384, SHA-512, SHA-512/224, SHA-512/256
+# Group.HmacSHA2 = HmacSHA224, HmacSHA256, HmacSHA384, HmacSHA512
+# Group.SHA2RSA = SHA224withRSA, SHA256withRSA, SHA384withRSA, SHA512withRSA
+# Group.SHA2DSA = SHA224withDSA, SHA256withDSA, SHA384withDSA, SHA512withDSA
+# Group.SHA2ECDSA = SHA224withECDSA, SHA256withECDSA, SHA384withECDSA, \
+# SHA512withECDSA
+# Group.SHA3 = SHA3-224, SHA3-256, SHA3-384, SHA3-512
+# Group.HmacSHA3 = HmacSHA3-224, HmacSHA3-256, HmacSHA3-384, HmacSHA3-512
+#
# Example:
# jdk.security.provider.preferred=AES/GCM/NoPadding:SunJCE, \
-# MessageDigest.SHA-256:SUN
+# MessageDigest.SHA-256:SUN, Group.HmacSHA2:SunJCE
#ifdef solaris-sparc
-jdk.security.provider.preferred=AES:SunJCE, SHA1:SUN, SHA-224:SUN, \
- SHA-256:SUN, SHA-384:SUN, SHA-512:SUN
+jdk.security.provider.preferred=AES:SunJCE, SHA1:SUN, Group.SHA2:SUN, \
+ HmacSHA1:SunJCE, Group.HmacSHA2:SunJCE
#endif
#ifdef solaris-x86
-jdk.security.provider.preferred=AES:SunJCE, RSA:SunRsaSign
+jdk.security.provider.preferred=AES:SunJCE, SHA1:SUN, Group.SHA2:SUN, \
+ HmacSHA1:SunJCE, Group.HmacSHA2:SunJCE, RSA:SunRsaSign, \
+ SHA1withRSA:SunRsaSign, Group.SHA2RSA:SunRsaSign
#endif
@@ -613,14 +628,14 @@
# "CertConstraint" specifies additional constraints for
# certificates that contain algorithms that are restricted:
#
-# "jdkCA" prohibits the specified algorithm only if the algorithm is used
-# in a certificate chain that terminates at a marked trust anchor in the
-# lib/security/cacerts keystore. All other chains are not affected.
-# If the jdkCA constraint is not set, then all chains using the
-# specified algorithm are restricted. jdkCA may only be used once in
+# "jdkCA" prohibits the specified algorithm only if the algorithm is used
+# in a certificate chain that terminates at a marked trust anchor in the
+# lib/security/cacerts keystore. All other chains are not affected.
+# If the jdkCA constraint is not set, then all chains using the
+# specified algorithm are restricted. jdkCA may only be used once in
# a DisabledAlgorithm expression.
-# Example: To apply this constraint to SHA-1 certificates, include
-# the following: "SHA1 jdkCA"
+# Example: To apply this constraint to SHA-1 certificates, include
+# the following: "SHA1 jdkCA"
#
# When an algorithm must satisfy more than one constraint, it must be
# delimited by an ampersand '&'. For example, to restrict certificates in a
--- a/jdk/test/sun/security/jca/PreferredProviderTest.java Thu May 19 20:14:17 2016 +0000
+++ b/jdk/test/sun/security/jca/PreferredProviderTest.java Thu May 19 16:05:33 2016 -0700
@@ -25,15 +25,17 @@
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.Security;
+import java.security.Signature;
import java.security.Provider;
import java.util.Arrays;
import java.util.List;
import javax.crypto.Cipher;
+import javax.crypto.Mac;
import javax.crypto.NoSuchPaddingException;
/**
* @test
- * @bug 8076359 8133151 8145344 8150512
+ * @bug 8076359 8133151 8145344 8150512 8155847
* @summary Test the value for new jdk.security.provider.preferred
* security property
*/
@@ -61,8 +63,8 @@
//java.security file which will be verified.
switch (type) {
case "sparcv9":
- preferredProp = "AES:SunJCE, SHA1:SUN, SHA-224:SUN,"
- + " SHA-256:SUN, SHA-384:SUN, SHA-512:SUN";
+ preferredProp = "AES:SunJCE, SHA1:SUN, Group.SHA2:SUN, " +
+ "HmacSHA1:SunJCE, Group.HmacSHA2:SunJCE";
verifyPreferredProviderProperty(os, type, preferredProp);
verifyDigestProvider(os, type, Arrays.asList(
@@ -71,14 +73,51 @@
new DataTuple("SHA-224", "SUN"),
new DataTuple("SHA-256", "SUN"),
new DataTuple("SHA-384", "SUN"),
- new DataTuple("SHA-512", "SUN")));
+ new DataTuple("SHA-512", "SUN"),
+ new DataTuple("SHA-512/224", "SUN"),
+ new DataTuple("SHA-512/256", "SUN")));
+
+ verifyMacProvider(os, type, Arrays.asList(
+ new DataTuple("HmacSHA1", "SunJCE"),
+ new DataTuple("HmacSHA224", "SunJCE"),
+ new DataTuple("HmacSHA256", "SunJCE"),
+ new DataTuple("HmacSHA384", "SunJCE"),
+ new DataTuple("HmacSHA512", "SunJCE")));
break;
case "amd64":
- preferredProp = "AES:SunJCE, RSA:SunRsaSign";
+ preferredProp = "AES:SunJCE, SHA1:SUN, Group.SHA2:SUN, " +
+ "HmacSHA1:SunJCE, Group.HmacSHA2:SunJCE, " +
+ "RSA:SunRsaSign, SHA1withRSA:SunRsaSign, " +
+ "Group.SHA2RSA:SunRsaSign";
+
verifyPreferredProviderProperty(os, type, preferredProp);
verifyKeyFactoryProvider(os, type, Arrays.asList(
new DataTuple("RSA", "SunRsaSign")));
+
+ verifyDigestProvider(os, type, Arrays.asList(
+ new DataTuple("SHA1", "SUN"),
+ new DataTuple("SHA-1", "SUN"),
+ new DataTuple("SHA-224", "SUN"),
+ new DataTuple("SHA-256", "SUN"),
+ new DataTuple("SHA-384", "SUN"),
+ new DataTuple("SHA-512", "SUN"),
+ new DataTuple("SHA-512/224", "SUN"),
+ new DataTuple("SHA-512/256", "SUN")));
+
+ verifyMacProvider(os, type, Arrays.asList(
+ new DataTuple("HmacSHA1", "SunJCE"),
+ new DataTuple("HmacSHA224", "SunJCE"),
+ new DataTuple("HmacSHA256", "SunJCE"),
+ new DataTuple("HmacSHA384", "SunJCE"),
+ new DataTuple("HmacSHA512", "SunJCE")));
+
+ verifySignatureProvider(os, type, Arrays.asList(
+ new DataTuple("SHA1withRSA", "SunRsaSign"),
+ new DataTuple("SHA224withRSA", "SunRsaSign"),
+ new DataTuple("SHA256withRSA", "SunRsaSign"),
+ new DataTuple("SHA384withRSA", "SunRsaSign"),
+ new DataTuple("SHA512withRSA", "SunRsaSign")));
break;
}
verifyDigestProvider(os, type, Arrays.asList(
@@ -99,6 +138,8 @@
String preferredProvider
= Security.getProperty("jdk.security.provider.preferred");
if (!preferredProvider.equals(preferred)) {
+ System.out.println("Expected: " + preferred + "\nResult: " +
+ preferredProvider);
throw new RuntimeException(String.format(
"Test Failed: wrong jdk.security.provider.preferred value "
+ "on %s-%s", os, arch));
@@ -120,6 +161,19 @@
"Preferred MessageDigest algorithm verification successful.");
}
+ private static void verifyMacProvider(String os, String arch,
+ List<DataTuple> algoProviders) throws NoSuchAlgorithmException {
+ for (DataTuple dataTuple : algoProviders) {
+ System.out.printf(
+ "Verifying Mac for '%s'%n", dataTuple.algorithm);
+ Mac mac = Mac.getInstance(dataTuple.algorithm);
+ matchProvider(mac.getProvider(), dataTuple.provider,
+ dataTuple.algorithm, os, arch);
+ }
+ System.out.println(
+ "Preferred Mac algorithm verification successful.");
+ }
+
private static void verifyKeyFactoryProvider(String os, String arch,
List<DataTuple> algoProviders) throws NoSuchAlgorithmException {
for (DataTuple dataTuple : algoProviders) {
@@ -133,6 +187,19 @@
"Preferred KeyFactory algorithm verification successful.");
}
+ private static void verifySignatureProvider(String os, String arch,
+ List<DataTuple> algoProviders) throws NoSuchAlgorithmException {
+ for (DataTuple dataTuple : algoProviders) {
+ System.out.printf(
+ "Verifying Signature for '%s'%n", dataTuple.algorithm);
+ Signature si = Signature.getInstance(dataTuple.algorithm);
+ matchProvider(si.getProvider(), dataTuple.provider,
+ dataTuple.algorithm, os, arch);
+ }
+ System.out.println(
+ "Preferred Signature algorithm verification successful.");
+ }
+
private static void matchProvider(Provider provider, String expected,
String algo, String os, String arch) {
if (!provider.getName().equals(expected)) {