in src/com/amazon/corretto/crypto/provider/Loader.java [246:302]
private synchronized static Path createTmpFile(final String prefix, final String suffix) throws IOException {
final Path urandomPath = Paths.get("/dev/urandom");
if (!Files.exists(urandomPath)) {
throw new AssertionError("/dev/urandom must exist for bootstrapping");
}
final Path tmpDir = Paths.get(System.getProperty("java.io.tmpdir"));
if (!Files.isDirectory(tmpDir)) {
throw new AssertionError("java.io.tmpdir is not valid: " + tmpDir);
}
final FileAttribute<Set<PosixFilePermission>> permissions =
PosixFilePermissions.asFileAttribute(new HashSet<>(Arrays.asList(
PosixFilePermission.OWNER_READ,
PosixFilePermission.OWNER_WRITE,
PosixFilePermission.OWNER_EXECUTE
)));
final byte[] rndBytes = new byte[Long.BYTES]; // Default java tmp files use this much entropy
final int RETRY_LIMIT = 1000;
try (InputStream rndStream = Files.newInputStream(urandomPath, StandardOpenOption.READ)) {
int attempt = 0;
// We keep doing this until we can create something new or fail badly
while (attempt < RETRY_LIMIT) {
attempt++;
if (rndStream.read(rndBytes) != rndBytes.length) {
throw new AssertionError("Unable to read enough entropy");
}
final StringBuilder fileName = new StringBuilder(prefix);
for (byte b : rndBytes) {
// We convert to an unsigned integer first to avoid sign-bit extension when converting to hex.
String hexByte = Integer.toHexString(Byte.toUnsignedInt(b));
if (hexByte.length() == 1) {
fileName.append('0');
}
fileName.append(hexByte);
}
fileName.append(suffix);
final Path tmpFile = tmpDir.resolve(fileName.toString());
try {
final Path result = Files.createFile(tmpFile, permissions);
if (DebugFlag.VERBOSELOGS.isEnabled()) {
LOG.log(Level.FINE, "Created temporary library file after " + attempt + " attempts");
}
return result;
} catch (final FileAlreadyExistsException ex) {
// We ignore and retry this exception
} catch (final Exception ex) {
// Any other exception is bad and we may need to quash.
throw new AssertionError("Unable to create temporary file");
}
}
}
throw new AssertionError("Unable to create temporary file. Retries exceeded.");
}