src/share/classes/sun/security/provider/SeedGenerator.java

Print this page

        

@@ -73,13 +73,17 @@
 import java.net.*;
 import java.nio.file.DirectoryStream;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.util.Random;
+
+import sun.misc.VM;
+import sun.reflect.CallerSensitive;
+import sun.reflect.Reflection;
 import sun.security.util.Debug;
 
-abstract class SeedGenerator {
+public abstract class SeedGenerator implements AutoCloseable {
 
     // Static instance is created at link time
     private static SeedGenerator instance;
 
     private static final Debug debug = Debug.getInstance("provider");

@@ -100,11 +104,13 @@
          * URLSeedGenerator to read from /dev/[u]random
          */
         if (egdSource.equals(SunEntries.URL_DEV_RANDOM) ||
                 egdSource.equals(SunEntries.URL_DEV_URANDOM)) {
             try {
-                instance = new NativeSeedGenerator(egdSource);
+                instance = new NativeSeedGenerator(egdSource) {
+                    @Override public void close() {} // never close shared instance
+                };
                 if (debug != null) {
                     debug.println(
                         "Using operating system seed generator" + egdSource);
                 }
             } catch (IOException e) {

@@ -113,11 +119,13 @@
                                   + "generator: " + e.toString());
                 }
             }
         } else if (egdSource.length() != 0) {
             try {
-                instance = new URLSeedGenerator(egdSource);
+                instance = new URLSeedGenerator(egdSource) {
+                    @Override public void close() {} // never close shared instance
+                };
                 if (debug != null) {
                     debug.println("Using URL seed generator reading from "
                                   + egdSource);
                 }
             } catch (IOException e) {

@@ -131,22 +139,50 @@
         // Fall back to ThreadedSeedGenerator
         if (instance == null) {
             if (debug != null) {
                 debug.println("Using default threaded seed generator");
             }
-            instance = new ThreadedSeedGenerator();
+            instance = new ThreadedSeedGenerator(); // close() is a no-op here
+        }
+    }
+
+    @CallerSensitive
+    public static SeedGenerator getNativeInstance() {
+        Class<?> caller = Reflection.getCallerClass();
+        if (!VM.isSystemDomainLoader(caller.getClassLoader())) {
+            throw new SecurityException("Internal API");
+        }
+        try {
+            return new NativeSeedGenerator(SunEntries.URL_DEV_URANDOM);
+        } catch (IOException e) {
+            // fall-back to default shared instance
+            return instance;
         }
     }
 
+    @CallerSensitive
+    public static SeedGenerator getDefaultInstance() {
+        Class<?> caller = Reflection.getCallerClass();
+        if (!VM.isSystemDomainLoader(caller.getClassLoader())) {
+            throw new SecurityException("Internal API");
+        }
+        return instance;
+    }
+
     /**
      * Fill result with bytes from the queue. Wait for it if it isn't ready.
      */
-    static public void generateSeed(byte[] result) {
+    static void generateSeed(byte[] result) {
         instance.getSeedBytes(result);
     }
 
-    abstract void getSeedBytes(byte[] result);
+    public abstract void getSeedBytes(byte[] result);
+
+    @Override
+    public void close() {
+        // nothing to close by default
+    }
 
     /**
      * Retrieve some system information, hashed.
      */
     static byte[] getSystemEntropy() {

@@ -382,11 +418,11 @@
                     "SeedGenerator thread generated an exception.", e);
             }
         }
 
         @Override
-        void getSeedBytes(byte[] result) {
+        public void getSeedBytes(byte[] result) {
             for (int i = 0; i < result.length; i++) {
                 result[i] = getSeedByte();
             }
         }
 

@@ -525,11 +561,11 @@
                     "Failed to open " + deviceName, e.getCause());
             }
         }
 
         @Override
-        void getSeedBytes(byte[] result) {
+        public void getSeedBytes(byte[] result) {
             int len = result.length;
             int read = 0;
             try {
                 while (read < len) {
                     int count = seedStream.read(result, read, len - read);

@@ -544,7 +580,14 @@
             } catch (IOException ioe) {
                 throw new InternalError("URLSeedGenerator " + deviceName +
                     " generated exception: " + ioe.getMessage(), ioe);
             }
         }
+
+        @Override
+        public void close() {
+            try {
+                seedStream.close();
+            } catch (IOException ignore) {}
+        }
     }
 }