/* vim: set ts=2 et sw=2 cindent fo=qroca: */
package com.globant.google.mendoza.malbec.transport;
import java.io.InputStream;
import java.security.KeyStore;
import javax.net.ServerSocketFactory;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManagerFactory;
/** Helper methods to generate the client and server socket factories from the
* truststore and keystore files.
*/
public final class SSLUtility {
/** Private constructor, there must be no instances of this class.
*/
private SSLUtility() {
}
/** Builds a ssl server socket factory.
*
* @param keyStoreStream An input stream that contains the key store. This
* key store must have the certificate to present to the client. The alias is
* supported at this time. It cannot be null.
*
* @param keyStorePassword The password used to decrypt the key store stream.
* It cannot be null.
*
* @param keyPassword The password used to decrypt the certificate stored in
* the key store stream. It cannot be null.
*
* @return Returns a socket factory that can be used to create ssl sockets to
* use from the server side.
*/
public static ServerSocketFactory createServerSocketFactory(final InputStream
keyStoreStream, final String keyStorePassword,
final String keyPassword) {
if (keyStoreStream == null) {
throw new IllegalArgumentException("the key store stream cannot be"
+ " null");
}
if (keyStorePassword == null) {
throw new IllegalArgumentException("the key store password cannot be"
+ " null");
}
if (keyPassword == null) {
throw new IllegalArgumentException("the key password cannot be null");
}
ServerSocketFactory factory = null;
try {
KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(keyStoreStream, keyStorePassword.toCharArray());
KeyManagerFactory keyManagerFactory;
keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
keyManagerFactory.init(keyStore, keyPassword.toCharArray());
SSLContext context = SSLContext.getInstance("SSLv3");
context.init(keyManagerFactory.getKeyManagers(), null, null);
factory = context.getServerSocketFactory();
} catch (RuntimeException e) {
// We do not encapsulate runtime exceptions.
throw e;
} catch (Exception e) {
throw new RuntimeException("Unable to create socket factory", e);
}
return factory;
}
/** Builds a ssl client socket factory.
*
* @param trustStoreStream An input stream that contains the trust store.
* This trust store must have all the certificates that the client trusts.
* It cannot be null.
*
* @param trustStorePassword The password used to decrypt the trust store
* stream. It cannot be null.
*
* @return Returns a socket factory that can be used to create ssl sockets to
* use from the client side.
*/
public static SSLSocketFactory createClientSocketFactory(final InputStream
trustStoreStream, final String trustStorePassword) {
if (trustStoreStream == null) {
throw new IllegalArgumentException("the trust store stream cannot be"
+ " null");
}
if (trustStorePassword == null) {
throw new IllegalArgumentException("the trust store password cannot be"
+ " null");
}
SSLSocketFactory factory = null;
try {
KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(trustStoreStream, trustStorePassword.toCharArray());
TrustManagerFactory trustFactory =
TrustManagerFactory.getInstance("SunX509");
trustFactory.init(keyStore);
SSLContext sslc = SSLContext.getInstance("SSLv3");
sslc.init(null, trustFactory.getTrustManagers(), null);
factory = (SSLSocketFactory) sslc.getSocketFactory();
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new RuntimeException("Unable to create client socket factory", e);
}
return factory;
}
}