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

com.peterphi.std.crypto.openssl.OpenSSLPKCS12 Maven / Gradle / Ivy

There is a newer version: 10.1.5
Show newest version
package com.peterphi.std.crypto.openssl;

import com.peterphi.std.system.exec.Exec;
import com.peterphi.std.system.exec.Execed;
import org.apache.log4j.Logger;

import java.io.File;
import java.io.IOException;
import java.util.UUID;

public class OpenSSLPKCS12
{
	private static final Logger log = Logger.getLogger(OpenSSLPKCS12.class);

	public static final String OPENSSL = "openssl";
	public static final boolean USE_GENERIC_TEMP_DIRECTORY = false;


	/**
	 * Recreates a PKCS12 KeyStore using OpenSSL; this is a workaround a BouncyCastle-Firefox compatibility bug
	 *
	 * @param p12
	 * 		The PKCS12 Keystore to filter
	 * @param p12Password
	 * 		The password for the keystore
	 *
	 * @throws IOException
	 * 		if a catastrophic unexpected failure occurs during execution
	 * @throws IllegalArgumentException
	 * 		if the PKCS12 keystore doesn't exist
	 * @throws IllegalStateException
	 * 		if openssl exits with a failure condition
	 */
	public static void filterP12(File p12, String p12Password) throws IOException
	{
		if (!p12.exists())
			throw new IllegalArgumentException("p12 file does not exist: " + p12.getPath());

		final File pem;
		if (USE_GENERIC_TEMP_DIRECTORY)
			pem = File.createTempFile(UUID.randomUUID().toString(), "");
		else
			pem = new File(p12.getAbsolutePath() + ".pem.tmp");

		final String pemPassword = UUID.randomUUID().toString();

		try
		{
			P12toPEM(p12, p12Password, pem, pemPassword);
			PEMtoP12(pem, pemPassword, p12, p12Password);
		}
		finally
		{
			if (pem.exists())
				if (!pem.delete())
					log.warn("[OpenSSLPKCS12] {filterP12} Could not delete temporary PEM file " + pem);

		}
	}


	/**
	 * @param p12
	 * @param p12Password
	 * @param toPEM
	 * @param pemPassword
	 *
	 * @throws IOException
	 * 		if a catastrophic unexpected failure occurs during execution
	 * @throws IllegalArgumentException
	 * 		if the PKCS12 keystore doesn't exist
	 * @throws IllegalStateException
	 * 		if openssl exits with a failure condition
	 */
	public static void P12toPEM(File p12, String p12Password, File toPEM, String pemPassword) throws IOException
	{
		if (!p12.exists())
			throw new IllegalArgumentException("p12 file does not exist: " + p12.getPath());

		Execed openssl = Exec.utilityAs(null,
		                                OPENSSL,
		                                "pkcs12",
		                                "-in",
		                                p12.getPath(),
		                                "-out",
		                                toPEM.getPath(),
		                                "-passin",
		                                "pass:" + p12Password,
		                                "-nodes");

		int returnCode = openssl.waitForExit();

		if (returnCode != 0)
			throw new IllegalStateException("Unexpected openssl exit code " + returnCode + "; output:\n" +
			                                openssl.getStandardOut());
	}


	/**
	 * @param pem
	 * 		the PEM file containing the keys & certificates to put in a P12
	 * @param pemPassword
	 * 		The password for any encrypted keys in the PEM
	 * @param toP12
	 * 		The PKCS12 file
	 * @param p12Password
	 * 		the password to put on the PKCS12 keystore
	 *
	 * @throws IOException
	 * 		if a catastrophic unexpected failure occurs during execution
	 * @throws IllegalArgumentException
	 * 		if the PEM keystore doesn't exist
	 * @throws IllegalStateException
	 * 		if openssl exits with a failure condition
	 */
	public static void PEMtoP12(File pem, String pemPassword, File toP12, String p12Password) throws IOException
	{
		if (!pem.exists())
			throw new IllegalArgumentException("pem file does not exist: " + pem.getPath());

		Execed openssl = Exec.utilityAs(null,
		                                OPENSSL,
		                                "pkcs12",
		                                "-nodes",
		                                "-in",
		                                pem.getPath(),
		                                "-out",
		                                toP12.getPath(),
		                                "-export",
		                                "-passin",
		                                "pass:" + pemPassword,
		                                "-passout",
		                                "pass:" + p12Password);
		int returnCode = openssl.waitForExit();

		if (returnCode != 0)
			throw new IllegalStateException("Unexpected openssl exit code " + returnCode + "; output:\n" +
			                                openssl.getStandardOut());
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy