2024-06-07 03:07:38 +03:00

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;
}
}