package io.loli.kaze.server;
import java.security.KeyStore;
import java.security.Security;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
import org.littleshoot.proxy.SslEngineSource;
/**
* Basic {@link SslEngineSource} for testing. The {@link SSLContext} uses
* self-signed certificates that are generated lazily if the given key store
* file doesn't yet exist.
*/
public class KazeSslEngineSource implements SslEngineSource {
private String PASSWORD;
private final String PROTOCOL = "TLS";
private final String keyStoreFile;
private final String trustKeyStoreFile;
private final boolean trustAllServers;
private final boolean sendCerts;
private SSLContext sslContext;
public KazeSslEngineSource(String keyStorePath, String trustKeyStorePath,
boolean trustAllServers, boolean sendCerts, String alias,
String password) {
this.PASSWORD = password;
this.trustAllServers = trustAllServers;
this.sendCerts = sendCerts;
this.keyStoreFile = keyStorePath;
this.trustKeyStoreFile = trustKeyStorePath;
initializeSSLContext();
}
@Override
public SSLEngine newSslEngine() {
return sslContext.createSSLEngine();
}
public SSLContext getSslContext() {
return sslContext;
}
private void initializeSSLContext() {
String algorithm = Security
.getProperty("ssl.KeyManagerFactory.algorithm");
if (algorithm == null) {
algorithm = "SunX509";
}
try {
final KeyStore ks = KeyStore.getInstance("JKS");
// ks.load(new FileInputStream("keystore.jks"),
// "changeit".toCharArray());
ks.load(KazeSslEngineSource.class.getResourceAsStream("/"
+ keyStoreFile), PASSWORD.toCharArray());
// Set up key manager factory to use our key store
final KeyManagerFactory kmf = KeyManagerFactory
.getInstance(algorithm);
kmf.init(ks, PASSWORD.toCharArray());
// Set up a trust manager factory to use our key store
TrustManagerFactory tmf = TrustManagerFactory
.getInstance(algorithm);
final KeyStore tks = KeyStore.getInstance("JKS");
tks.load(
KazeSslEngineSource.class.getResourceAsStream("/"
+ trustKeyStoreFile), PASSWORD.toCharArray());
tmf.init(tks);
TrustManager[] trustManagers = null;
if (!trustAllServers) {
trustManagers = tmf.getTrustManagers();
} else {
trustManagers = new TrustManager[] { new X509TrustManager() {
// TrustManager that trusts all servers
@Override
public void checkClientTrusted(X509Certificate[] arg0,
String arg1) throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] arg0,
String arg1) throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
} };
}
KeyManager[] keyManagers = null;
if (sendCerts) {
keyManagers = kmf.getKeyManagers();
} else {
keyManagers = new KeyManager[0];
}
// Initialize the SSLContext to work with our key managers.
sslContext = SSLContext.getInstance(PROTOCOL);
sslContext.init(keyManagers, trustManagers, null);
} catch (final Exception e) {
throw new Error("Failed to initialize the server-side SSLContext",
e);
}
}
}