package org.wiztools.restclient.util;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.security.KeyFactory;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import javax.xml.bind.DatatypeConverter;
import org.wiztools.restclient.bean.KeyStoreType;
/**
*
* @author subhash
*/
public final class SSLUtil {
private SSLUtil() {}
public static final String PEM_PWD = "changeit";
public static KeyStore getKeyStore(File file, KeyStoreType type, char[] password)
throws KeyStoreException,
IOException,
InvalidKeySpecException,
NoSuchAlgorithmException,
CertificateException {
if(type == KeyStoreType.PEM) {
return getPemKeyStore(file);
}
// Other KeyStore types:
KeyStore store = KeyStore.getInstance(type.name());
if(file != null) {
try(FileInputStream instream = new FileInputStream(file)) {
store.load(instream, password);
}
}
return store;
}
private static KeyStore getPemKeyStore(File file)
throws KeyStoreException,
IOException,
InvalidKeySpecException,
NoSuchAlgorithmException,
CertificateException {
KeyStore store = KeyStore.getInstance(KeyStore.getDefaultType());
store.load(null);
if(file != null) {
byte[] certAndKey = Files.readAllBytes(file.toPath());
byte[] certBytes = parseDERFromPEM(certAndKey,
"-----BEGIN .*CERTIFICATE-----", "-----END .*CERTIFICATE-----");
byte[] pvtKeyBytes = parseDERFromPEM(certAndKey,
"-----BEGIN .*PRIVATE KEY-----", "-----END .*PRIVATE KEY-----");
byte[] pubKeyBytes = parseDERFromPEM(certAndKey,
"-----BEGIN .*PUBLIC KEY-----", "-----END .*PUBLIC KEY-----");
X509Certificate cert = null;
if(certBytes != null) {
cert = generateCertFromDER(certBytes);
String alias = cert.getSubjectX500Principal().getName();
store.setCertificateEntry(alias, cert);
}
Certificate[] chain = cert==null?
new Certificate[]{}: new Certificate[] {cert};
if(pvtKeyBytes != null) {
RSAPrivateKey key = generatePvtKeyFromDER(pvtKeyBytes);
store.setKeyEntry("key-alias", key, PEM_PWD.toCharArray(),
chain);
}
if(pubKeyBytes != null) {
RSAPublicKey key = generatePubKeyFromDER(pubKeyBytes);
store.setKeyEntry("pubkey-alias", key, PEM_PWD.toCharArray(),
null);
}
}
return store;
}
protected static byte[] parseDERFromPEM(byte[] pem, String beginDelimiter, String endDelimiter) {
String data = new String(pem);
String[] tokens = data.split(beginDelimiter);
if(tokens.length < 2) { // no results found!
return null;
}
tokens = tokens[1].split(endDelimiter);
if(tokens.length < 2) { // no results found!
return null;
}
return DatatypeConverter.parseBase64Binary(tokens[0]);
}
protected static RSAPrivateKey generatePvtKeyFromDER(byte[] keyBytes) throws InvalidKeySpecException, NoSuchAlgorithmException {
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory factory = KeyFactory.getInstance("RSA");
return (RSAPrivateKey)factory.generatePrivate(spec);
}
protected static RSAPublicKey generatePubKeyFromDER(byte[] keyBytes) throws InvalidKeySpecException, NoSuchAlgorithmException {
X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
KeyFactory factory = KeyFactory.getInstance("RSA");
return (RSAPublicKey)factory.generatePublic(spec);
}
protected static X509Certificate generateCertFromDER(byte[] certBytes) throws CertificateException {
CertificateFactory factory = CertificateFactory.getInstance("X.509");
return (X509Certificate)factory.generateCertificate(new ByteArrayInputStream(certBytes));
}
}