8228613: java.security.Provider#getServices order is no longer deterministic
authorvaleriep
Wed, 14 Aug 2019 00:57:15 +0000
changeset 57736 7f75db20c209
parent 57735 7ba5e49258de
child 57737 6bbb4af131e3
8228613: java.security.Provider#getServices order is no longer deterministic Summary: Changed to use SunEntries.DEF_SECURE_RANDOM_ALGO instead of relying on ordering of SecureRandom services Reviewed-by: weijun
src/java.base/share/classes/java/security/SecureRandom.java
src/java.base/share/classes/sun/security/provider/SunEntries.java
test/jdk/java/security/SecureRandom/DefaultAlgo.java
--- a/src/java.base/share/classes/java/security/SecureRandom.java	Tue Aug 13 15:49:11 2019 -0700
+++ b/src/java.base/share/classes/java/security/SecureRandom.java	Wed Aug 14 00:57:15 2019 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -32,6 +32,7 @@
 
 import sun.security.jca.*;
 import sun.security.jca.GetInstance.Instance;
+import sun.security.provider.SunEntries;
 import sun.security.util.Debug;
 
 /**
@@ -875,6 +876,13 @@
      */
     private static String getPrngAlgorithm() {
         for (Provider p : Providers.getProviderList().providers()) {
+            // For SUN provider, we use SunEntries.DEFF_SECURE_RANDOM_ALGO
+            // as the default SecureRandom algorithm; for other providers,
+            // we continue to iterate through to the 1st SecureRandom
+            // service
+            if (p.getName().equals("SUN")) {
+                return SunEntries.DEF_SECURE_RANDOM_ALGO;
+            }
             for (Service s : p.getServices()) {
                 if (s.getType().equals("SecureRandom")) {
                     return s.getAlgorithm();
--- a/src/java.base/share/classes/sun/security/provider/SunEntries.java	Tue Aug 13 15:49:11 2019 -0700
+++ b/src/java.base/share/classes/sun/security/provider/SunEntries.java	Wed Aug 14 00:57:15 2019 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -77,6 +77,9 @@
 
 public final class SunEntries {
 
+    // the default algo used by SecureRandom class for new SecureRandom() calls
+    public static final String DEF_SECURE_RANDOM_ALGO;
+
     // create an aliases List from the specified aliases
     public static List<String> createAliases(String ... aliases) {
         return Arrays.asList(aliases);
@@ -89,7 +92,6 @@
         return Arrays.asList(result);
     }
 
-    // extend LinkedHashSet to preserve the ordering (needed by SecureRandom?)
     SunEntries(Provider p) {
         services = new LinkedHashSet<>(50, 0.9f);
 
@@ -99,41 +101,27 @@
         HashMap<String, String> attrs = new HashMap<>(3);
 
         /*
-         * SecureRandom
-         *
-         * Register these first to speed up "new SecureRandom()",
-         * which iterates through the list of algorithms
+         * SecureRandom engines
          */
-        // register the native PRNG, if available
-        // if user selected /dev/urandom, we put it before SHA1PRNG,
-        // otherwise after it
-        boolean nativeAvailable = NativePRNG.isAvailable();
-        boolean useNativePRNG = seedSource.equals(URL_DEV_URANDOM) ||
-            seedSource.equals(URL_DEV_RANDOM);
-
         attrs.put("ThreadSafe", "true");
-        if (nativeAvailable && useNativePRNG) {
+        if (NativePRNG.isAvailable()) {
             add(p, "SecureRandom", "NativePRNG",
-               "sun.security.provider.NativePRNG", null, attrs);
+                    "sun.security.provider.NativePRNG",
+                    null, attrs);
         }
-        attrs.put("ImplementedIn", "Software");
-        add(p, "SecureRandom", "DRBG", "sun.security.provider.DRBG", null, attrs);
-        add(p, "SecureRandom", "SHA1PRNG",
-            "sun.security.provider.SecureRandom", null, attrs);
-        attrs.remove("ImplementedIn");
-        if (nativeAvailable && !useNativePRNG) {
-            add(p, "SecureRandom", "NativePRNG", "sun.security.provider.NativePRNG",
-               null, attrs);
-        }
-
         if (NativePRNG.Blocking.isAvailable()) {
             add(p, "SecureRandom", "NativePRNGBlocking",
-                "sun.security.provider.NativePRNG$Blocking", null, attrs);
+                    "sun.security.provider.NativePRNG$Blocking", null, attrs);
         }
         if (NativePRNG.NonBlocking.isAvailable()) {
             add(p, "SecureRandom", "NativePRNGNonBlocking",
-                "sun.security.provider.NativePRNG$NonBlocking", null, attrs);
+                    "sun.security.provider.NativePRNG$NonBlocking", null, attrs);
         }
+        attrs.put("ImplementedIn", "Software");
+        add(p, "SecureRandom", "DRBG", "sun.security.provider.DRBG",
+               null, attrs);
+        add(p, "SecureRandom", "SHA1PRNG",
+                "sun.security.provider.SecureRandom", null, attrs);
 
         /*
          * Signature engines
@@ -148,9 +136,9 @@
 
         add(p, "Signature", "SHA1withDSA",
                 "sun.security.provider.DSA$SHA1withDSA",
-                createAliasesWithOid("1.2.840.10040.4.3", "DSA", "DSS", "SHA/DSA",
-                    "SHA-1/DSA", "SHA1/DSA", "SHAwithDSA", "DSAWithSHA1",
-                    "1.3.14.3.2.13", "1.3.14.3.2.27"), attrs);
+                createAliasesWithOid("1.2.840.10040.4.3", "DSA", "DSS",
+                    "SHA/DSA", "SHA-1/DSA", "SHA1/DSA", "SHAwithDSA",
+                    "DSAWithSHA1", "1.3.14.3.2.13", "1.3.14.3.2.27"), attrs);
         add(p, "Signature", "NONEwithDSA", "sun.security.provider.DSA$RawDSA",
                 createAliases("RawDSA"), attrs);
 
@@ -195,7 +183,8 @@
          * Algorithm Parameter Generator engines
          */
         add(p, "AlgorithmParameterGenerator", "DSA",
-            "sun.security.provider.DSAParameterGenerator", dsaAliases, attrs);
+                "sun.security.provider.DSAParameterGenerator", dsaAliases,
+                attrs);
         attrs.remove("KeySize");
 
         /*
@@ -307,8 +296,8 @@
     }
 
     private void add(Provider p, String type, String algo, String cn,
-             List<String> aliases, HashMap<String, String> attrs) {
-         services.add(new Provider.Service(p, type, algo, cn, aliases, attrs));
+            List<String> aliases, HashMap<String, String> attrs) {
+        services.add(new Provider.Service(p, type, algo, cn, aliases, attrs));
     }
 
     private LinkedHashSet<Provider.Service> services;
@@ -344,6 +333,11 @@
                 return egdSource;
             }
         });
+
+        DEF_SECURE_RANDOM_ALGO  = (NativePRNG.isAvailable() &&
+            (seedSource.equals(URL_DEV_URANDOM) ||
+             seedSource.equals(URL_DEV_RANDOM)) ?
+            "NativePRNG" : "DRBG");
     }
 
     static String getSeedSource() {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/security/SecureRandom/DefaultAlgo.java	Wed Aug 14 00:57:15 2019 +0000
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import static java.lang.System.out;
+import java.security.SecureRandom;
+import sun.security.provider.SunEntries;
+
+/**
+ * @test
+ * @bug 8228613
+ * @summary Ensure that the default SecureRandom algo matches
+ *     SunEntries.DEF_SECURE_RANDOM_ALGO when SUN provider is used
+ * @modules java.base/sun.security.provider
+ */
+public class DefaultAlgo {
+
+    public static void main(String[] args) throws Exception {
+        SecureRandom sr = new SecureRandom();
+        String actualAlg = sr.getAlgorithm();
+        out.println("Default SecureRandom algo: " + actualAlg);
+        if (sr.getProvider().getName().equals("SUN")) {
+            // when using Sun provider, compare and check if the algorithm
+            // matches SunEntries.DEF_SECURE_RANDOM_ALGO
+            if (actualAlg.equals(SunEntries.DEF_SECURE_RANDOM_ALGO)) {
+                out.println("Test Passed");
+            } else {
+                throw new RuntimeException("Failed: Expected " +
+                        SunEntries.DEF_SECURE_RANDOM_ALGO);
+            }
+        } else {
+            out.println("Skip test for non-Sun provider: " + sr.getProvider());
+        }
+    }
+}