package com.intrbiz.bergamot.agent;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Security;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.security.spec.PKCS8EncodedKeySpec;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openssl.PEMParser;
import org.bouncycastle.openssl.jcajce.JcaPEMWriter;
import org.bouncycastle.util.io.pem.PemObject;
import org.bouncycastle.util.io.pem.PemReader;
public class KeyStoreUtil
{
static
{
// as much as I dislike this, we need the BC provider to load a PEM formatted cert reliably!
Security.addProvider(new BouncyCastleProvider());
}
public static KeyStore loadClientAuthKeyStore(String password, File clientKeyFile, File clientCertFile, File caCertFile) throws IOException
{
try
{
Certificate caCert = loadCertificate(caCertFile);
Certificate clientCert = loadCertificate(clientCertFile);
Key clientKey = loadKey(clientKeyFile);
// create the keystore
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(null, null);
// add the ca
ks.setCertificateEntry("ca", caCert);
// add the client cert
ks.setCertificateEntry("client", clientCert);
// add the client key
ks.setKeyEntry("client-key", clientKey, password.toCharArray(), new Certificate[] { clientCert, caCert });
return ks;
}
catch (Exception e)
{
throw new IOException("Failed to create client auth keystore", e);
}
}
public static KeyStore loadClientAuthKeyStore(String password, String clientKeyFileData, String clientCertFileData, String caCertFileData) throws IOException
{
try
{
Certificate caCert = loadCertificate(caCertFileData);
Certificate clientCert = loadCertificate(clientCertFileData);
Key clientKey = loadKey(clientKeyFileData);
// create the keystore
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(null, null);
// add the ca
ks.setCertificateEntry("ca", caCert);
// add the client cert
ks.setCertificateEntry("client", clientCert);
// add the client key
ks.setKeyEntry("client-key", clientKey, password.toCharArray(), new Certificate[] { clientCert, caCert });
return ks;
}
catch (Exception e)
{
throw new IOException("Failed to create client auth keystore", e);
}
}
public static KeyStore loadClientAuthKeyStore(String password, String clientKeyFileData, String clientCertFileData, String siteCaCertFileData, String caCertFileData) throws IOException
{
try
{
Certificate caCert = loadCertificate(caCertFileData);
Certificate siteCaCert = loadCertificate(siteCaCertFileData);
Certificate clientCert = loadCertificate(clientCertFileData);
Key clientKey = loadKey(clientKeyFileData);
// create the keystore
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(null, null);
// add the ca
ks.setCertificateEntry("ca", caCert);
// add the site ca
ks.setCertificateEntry("site-ca", siteCaCert);
// add the client cert
ks.setCertificateEntry("client", clientCert);
// add the client key
ks.setKeyEntry("client-key", clientKey, password.toCharArray(), new Certificate[] { clientCert, siteCaCert, caCert });
return ks;
}
catch (Exception e)
{
throw new IOException("Failed to create client auth keystore", e);
}
}
public static KeyStore loadTrustKeyStore(File caCertFile) throws IOException
{
try
{
Certificate caCert = loadCertificate(caCertFile);
// create the keystore
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(null, null);
// add the ca
ks.setCertificateEntry("ca", caCert);
return ks;
}
catch (Exception e)
{
throw new IOException("Failed to create trust keystore", e);
}
}
public static KeyStore loadTrustKeyStore(String caCertFileData) throws IOException
{
try
{
Certificate caCert = loadCertificate(caCertFileData);
// create the keystore
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(null, null);
// add the ca
ks.setCertificateEntry("ca", caCert);
return ks;
}
catch (Exception e)
{
throw new IOException("Failed to create trust keystore", e);
}
}
public static PrivateKey loadKey(File file) throws IOException
{
try
{
// need to use some BC classes to parse PEM files
// fecking Java, POS at times
PemReader pr = new PemReader(new FileReader(file));
try
{
PemObject obj = pr.readPemObject();
KeyFactory kf = KeyFactory.getInstance("RSA");
PrivateKey key = kf.generatePrivate(new PKCS8EncodedKeySpec(obj.getContent()));
return key;
}
finally
{
pr.close();
}
}
catch (Exception e)
{
throw new IOException("Error loading key", e);
}
}
public static PrivateKey loadKey(String data) throws IOException
{
try
{
// need to use some BC classes to parse PEM files
// fecking Java, POS at times
PemReader pr = new PemReader(new StringReader(data));
try
{
PemObject obj = pr.readPemObject();
KeyFactory kf = KeyFactory.getInstance("RSA");
PrivateKey key = kf.generatePrivate(new PKCS8EncodedKeySpec(obj.getContent()));
return key;
}
finally
{
pr.close();
}
}
catch (Exception e)
{
throw new IOException("Error loading key", e);
}
}
public static Certificate loadCertificate(Reader reader) throws IOException
{
try
{
PEMParser pr = new PEMParser(reader);
try
{
X509CertificateHolder theCertHolder = (X509CertificateHolder) pr.readObject();
// extract the actual fucking certificate
X509Certificate theCert = new JcaX509CertificateConverter().getCertificate(theCertHolder);
return theCert;
}
finally
{
pr.close();
}
}
catch (Exception e)
{
throw new IOException("Failed to parse PEM formatted certificate", e);
}
}
public static Certificate loadCertificate(File file) throws IOException
{
return loadCertificate(new FileReader(file));
}
public static Certificate loadCertificate(String data) throws IOException
{
return loadCertificate(new StringReader(data));
}
public static String savePublicKey(PublicKey key)
{
try
{
StringWriter sw = new StringWriter();
JcaPEMWriter pw = new JcaPEMWriter(sw);
try
{
pw.writeObject(key);
}
finally
{
pw.close();
}
return sw.toString();
}
catch (IOException e)
{
e.printStackTrace();
}
return null;
}
public static String saveKey(PrivateKey key)
{
try
{
StringWriter sw = new StringWriter();
JcaPEMWriter pw = new JcaPEMWriter(sw);
try
{
pw.writeObject(key);
}
finally
{
pw.close();
}
return sw.toString();
}
catch (IOException e)
{
}
return null;
}
public static String saveCertificate(Certificate cert)
{
try
{
StringWriter sw = new StringWriter();
JcaPEMWriter pw = new JcaPEMWriter(sw);
try
{
pw.writeObject(cert);
}
finally
{
pw.close();
}
return sw.toString();
}
catch (IOException e)
{
}
return null;
}
}