All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.mike10004.seleniumhelp.OpensslKeystoreFileCreator Maven / Gradle / Ivy

package com.github.mike10004.seleniumhelp;

import io.github.mike10004.subprocess.ProcessResult;
import io.github.mike10004.subprocess.Subprocess;
import com.google.common.io.Files;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.function.Function;

import static java.util.Objects.requireNonNull;

/**
 * Keystore file creator implementation that uses an {@code openssl} executable.
 */
public class OpensslKeystoreFileCreator implements KeystoreFileCreator {

    private static final String EXEC_NAME_KEYTOOL = "keytool";
    private static final String EXEC_NAME_OPENSSL = "openssl";

    private static final Logger log = LoggerFactory.getLogger(OpensslKeystoreFileCreator.class);

    private final ExecutableConfig keytoolConfig;
    private final ExecutableConfig opensslConfig;
    private final File scratchDir;

    public OpensslKeystoreFileCreator() {
        this(ExecutableConfig.byNameOnly(EXEC_NAME_KEYTOOL), ExecutableConfig.byNameOnly(EXEC_NAME_OPENSSL));
    }

    public OpensslKeystoreFileCreator(ExecutableConfig keytoolConfig, ExecutableConfig opensslConfig) {
        this.keytoolConfig = requireNonNull(keytoolConfig);
        this.opensslConfig = requireNonNull(opensslConfig);
        scratchDir = FileUtils.getTempDirectory();
    }

    /**
     * Creates a PKCS12-format file.
     *
     * 

* See https://stackoverflow.com/questions/652916/converting-a-java-keystore-into-pem-format * for instructions on how to convert the .keystore file into a .pem file that can be installed * into browsers like Firefox. * *

In short, if {@code $KEYSTORE_FILE} is the file generated by this program, execute: *

     *     $ keytool -importkeystore -srckeystore $KEYSTORE_FILE -destkeystore temp.p12 -srcstoretype jks  -deststoretype pkcs12
     *     $ openssl pkcs12 -in temp.p12 -out exported-keystore.pem
     * 
*

The contents of `exported-keystore.pem` will be in PEM format. */ @Override public void createPKCS12File(KeystoreInput keystore, File p12File) throws IOException { File keystoreFile = File.createTempFile("AutoCertificateAndKeySource", ".keystore", scratchDir); try { keystore.getBytes().copyTo(Files.asByteSink(keystoreFile)); String keystorePassword = keystore.getPassword(); { Subprocess program = keytoolConfig.subprocessBuilder() .arg("-importkeystore") .args("-srckeystore", keystoreFile.getAbsolutePath()) .args("-srcstoretype", "jks") .args("-srcstorepass", keystorePassword) .args("-destkeystore", p12File.getAbsolutePath()) .args("-deststoretype", "pkcs12") .args("-deststorepass", keystorePassword) .build(); executeSubprocessAndCheckResult(program, keytoolResult -> { throw new NonzeroExitFromCertProgramException("keytool", keytoolResult); }); if (p12File.length() <= 0) { throw new AutoCertificateAndKeySource.CertificateGenerationException("pkcs12 file has invalid length: " + p12File.length()); } log.debug("pkcs12: {} ({} bytes)%n", p12File, p12File.length()); } } finally { FileUtils.forceDelete(keystoreFile); } } @SuppressWarnings("RedundantThrows") @Override public void createPemFile(File pkcs12File, String keystorePassword, File pemFile) throws IOException { Subprocess subprocess = opensslConfig.subprocessBuilder() .arg("pkcs12") .args("-in", pkcs12File.getAbsolutePath()) .args("-passin", "pass:" + keystorePassword) .arg("-nodes") .args("-out", pemFile.getAbsolutePath()) .build(); executeSubprocessAndCheckResult(subprocess, opensslResult -> { return new NonzeroExitFromCertProgramException("openssl", opensslResult); }); log.debug("pem: {} ({} bytes)", pemFile, pemFile.length()); } private void executeSubprocessAndCheckResult(Subprocess subprocess, Function, X> nonzeroExitReaction) throws X { ProcessResult result; try { result = Subprocesses.executeAndWait(subprocess, Charset.defaultCharset(), null); } catch (InterruptedException e) { throw new AutoCertificateAndKeySource.CertificateGenerationException(e); } if (result.exitCode() != 0) { log.error("exit code {} from {} with arguments {}", result.exitCode(), subprocess.executable(), subprocess.arguments()); String stdout = StringUtils.abbreviateMiddle(result.content().stdout(), "[...]", 256); String stderr = StringUtils.abbreviateMiddle(result.content().stderr(), "[...]", 256); log.error("stderr {}", stderr.isEmpty() ? "" : stderr); log.error("stdout {}", stdout.isEmpty() ? "" : stdout); X ex = nonzeroExitReaction.apply(result); if (ex != null) { throw ex; } } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy