8155847: SHA groups needed for jdk.security.provider.preferred

Reviewed-by: valeriep, mullan
This commit is contained in:
Anthony Scarpino 2016-05-19 16:05:33 -07:00
parent 56af81d2e4
commit 6f2785f741
3 changed files with 171 additions and 36 deletions

View File

@ -650,12 +650,29 @@ public final class ProviderList {
}
}
/* 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 @@ public final class ProviderList {
}
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);
}
}

View File

@ -105,15 +105,30 @@ security.provider.tbd=SunPKCS11
# 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 @@ krb5.kdc.bad.policy = tryLast
# "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

View File

@ -25,15 +25,17 @@ import java.security.MessageDigest;
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 @@ public class PreferredProviderTest {
//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 @@ public class PreferredProviderTest {
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 @@ public class PreferredProviderTest {
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 @@ public class PreferredProviderTest {
"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 @@ public class PreferredProviderTest {
"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)) {