141 lines
5.2 KiB
Java
141 lines
5.2 KiB
Java
package com.alterdekim.hearthhack.util;
|
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import org.bouncycastle.cert.X509CertificateHolder;
|
|
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
|
|
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
|
import org.bouncycastle.openssl.PEMDecryptorProvider;
|
|
import org.bouncycastle.openssl.PEMEncryptedKeyPair;
|
|
import org.bouncycastle.openssl.PEMKeyPair;
|
|
import org.bouncycastle.openssl.PEMParser;
|
|
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
|
|
import org.bouncycastle.openssl.jcajce.JcePEMDecryptorProviderBuilder;
|
|
|
|
import javax.net.ssl.*;
|
|
import java.io.FileReader;
|
|
import java.security.KeyPair;
|
|
import java.security.KeyStore;
|
|
import java.security.Security;
|
|
import java.security.cert.Certificate;
|
|
import java.security.cert.X509Certificate;
|
|
|
|
@Slf4j
|
|
public class Util {
|
|
|
|
private static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray();
|
|
|
|
public static SSLServerSocketFactory getSocketFactory(final String caCrtFile, final String crtFile, final String keyFile,
|
|
final String password) {
|
|
try {
|
|
|
|
/**
|
|
* Add BouncyCastle as a Security Provider
|
|
*/
|
|
Security.addProvider(new BouncyCastleProvider());
|
|
|
|
JcaX509CertificateConverter certificateConverter = new JcaX509CertificateConverter().setProvider("BC");
|
|
|
|
/**
|
|
* Load Certificate Authority (CA) certificate
|
|
*/
|
|
PEMParser reader = new PEMParser(new FileReader(caCrtFile));
|
|
X509CertificateHolder caCertHolder = (X509CertificateHolder) reader.readObject();
|
|
reader.close();
|
|
|
|
X509Certificate caCert = certificateConverter.getCertificate(caCertHolder);
|
|
|
|
/**
|
|
* Load client certificate
|
|
*/
|
|
reader = new PEMParser(new FileReader(crtFile));
|
|
X509CertificateHolder certHolder = (X509CertificateHolder) reader.readObject();
|
|
reader.close();
|
|
|
|
X509Certificate cert = certificateConverter.getCertificate(certHolder);
|
|
|
|
/**
|
|
* Load client private key
|
|
*/
|
|
reader = new PEMParser(new FileReader(keyFile));
|
|
Object keyObject = reader.readObject();
|
|
reader.close();
|
|
|
|
|
|
PEMDecryptorProvider provider = new JcePEMDecryptorProviderBuilder().build(password.toCharArray());
|
|
JcaPEMKeyConverter keyConverter = new JcaPEMKeyConverter().setProvider("BC");
|
|
|
|
KeyPair key;
|
|
|
|
if (keyObject instanceof PEMEncryptedKeyPair) {
|
|
key = keyConverter.getKeyPair(((PEMEncryptedKeyPair) keyObject).decryptKeyPair(provider));
|
|
} else {
|
|
key = keyConverter.getKeyPair((PEMKeyPair) keyObject);
|
|
}
|
|
|
|
/**
|
|
* CA certificate is used to authenticate server
|
|
*/
|
|
KeyStore caKeyStore = KeyStore.getInstance(KeyStore.getDefaultType());
|
|
caKeyStore.load(null, null);
|
|
caKeyStore.setCertificateEntry("ca-certificate", caCert);
|
|
|
|
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(
|
|
TrustManagerFactory.getDefaultAlgorithm());
|
|
trustManagerFactory.init(caKeyStore);
|
|
|
|
/**
|
|
* Client key and certificates are sent to server so it can authenticate the client
|
|
*/
|
|
KeyStore clientKeyStore = KeyStore.getInstance(KeyStore.getDefaultType());
|
|
clientKeyStore.load(null, null);
|
|
clientKeyStore.setCertificateEntry("certificate", cert);
|
|
clientKeyStore.setKeyEntry("private-key", key.getPrivate(), password.toCharArray(),
|
|
new Certificate[]{cert});
|
|
|
|
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(
|
|
KeyManagerFactory.getDefaultAlgorithm());
|
|
keyManagerFactory.init(clientKeyStore, password.toCharArray());
|
|
|
|
/**
|
|
* Create SSL socket factory
|
|
*/
|
|
SSLContext context = SSLContext.getInstance("TLSv1.2");
|
|
context.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null);
|
|
|
|
/**
|
|
* Return the newly created socket factory object
|
|
*/
|
|
return context.getServerSocketFactory();
|
|
|
|
} catch (Exception e) {
|
|
e.printStackTrace();
|
|
}
|
|
|
|
return null;
|
|
}
|
|
public static String bytesToHex(byte[] bytes) {
|
|
char[] hexChars = new char[bytes.length * 2];
|
|
for (int j = 0; j < bytes.length; j++) {
|
|
int v = bytes[j] & 0xFF;
|
|
hexChars[j * 2] = HEX_ARRAY[v >>> 4];
|
|
hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F];
|
|
}
|
|
return new String(hexChars);
|
|
}
|
|
|
|
public static byte[] hexStringToByteArray(String s) {
|
|
int len = s.length();
|
|
byte[] data = new byte[len / 2];
|
|
for (int i = 0; i < len; i += 2) {
|
|
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
|
|
+ Character.digit(s.charAt(i+1), 16));
|
|
}
|
|
return data;
|
|
}
|
|
|
|
public static String intToHex(int i) {
|
|
String s = Integer.toHexString(i).toUpperCase();
|
|
return s.length() % 2 == 0 ? s : "0" + s;
|
|
}
|
|
}
|