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) {}
+ }
}
}