private synchronized static Path createTmpFile()

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.");
    }