/** * */ package com.trendrr.oss; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.SecureRandom; 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.TrustManager; import javax.net.ssl.TrustManagerFactory; import javax.net.ssl.X509TrustManager; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * * Builder to get to the SSLContext. * * To create a self signed server cert: * http://www.sslshopper.com/article-most-common-java-keytool-keystore-commands.html * * keytool -genkey -keyalg RSA -alias selfsigned -keystore keystore.jks -storepass password -validity 1360 -keysize 2048 * * * @author Dustin Norlander * @created Feb 15, 2011 * */ public class SSLContextBuilder { protected static Log log = LogFactory.getLog(SSLContextBuilder.class); private String certificatePassword = null; private String keystorePassword = null; private InputStream stream = null; private String protocol = "TLS"; private KeyStore ks; private String algorithm = null; private TrustManager tm[] = null; private SecureRandom random = null; private boolean client = false; /** * New builder instance. * * set client to true if this is clientside, false for serverside * * @param client */ public SSLContextBuilder(boolean client) { //set sensible defaults try { this.ks = KeyStore.getInstance("JKS"); } catch (KeyStoreException e) { log.error("Caught", e); } algorithm = Security.getProperty("ssl.KeyManagerFactory.algorithm"); if (algorithm == null) { algorithm = "SunX509"; } this.random = new SecureRandom(); } public SSLContext toSSLContext() throws Exception { try { KeyManager km[] = null; SSLContext context = SSLContext.getInstance(this.protocol); if (this.stream != null) { ks.load(this.stream, this.keystorePassword.toCharArray()); // Set up key manager factory to use our key store KeyManagerFactory kmf = KeyManagerFactory.getInstance(algorithm); kmf.init(ks, this.certificatePassword.toCharArray()); km = kmf.getKeyManagers(); } context.init(km, this.getTrustManager(), this.random); return context; } catch (Exception e) { throw new Exception( "Failed to initialize the server-side SSLContext", e); } finally { if (this.stream !=null) { try {this.stream.close();} catch (Exception x){} } } } private TrustManager[] getTrustManager() { if (this.tm != null) return this.tm; if (this.client) { // we are in client mode and do not want to perform server cert // authentication // return a trust manager that trusts all certs return new TrustManager[] { new X509TrustManager() { public void checkClientTrusted(final X509Certificate[] chain, final String authType) { } public void checkServerTrusted(final X509Certificate[] chain, final String authType) { } public X509Certificate[] getAcceptedIssuers() { return null; } } }; } // // else // { // TrustManagerFactory trustMgrFactory; // KeyStore trustStore = SSLSupport.loadKeystore(trustStorePath, trustStorePassword); // trustMgrFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); // trustMgrFactory.init(trustStore); // return trustMgrFactory.getTrustManagers(); // } return null; } /** * sets the SecureRandom. * @param rand * @return */ public SSLContextBuilder secureRandom(SecureRandom rand) { this.random = rand; return this; } /** * set the TrustManager. Believe this is only used for clients validating server certs * @param tm * @return */ public SSLContextBuilder trustManager(TrustManager[] tm) { this.tm = tm; return this; } public SSLContextBuilder certificatePassword(String password) { this.certificatePassword = password; return this; } public SSLContextBuilder keystorePassword(String password) { this.keystorePassword = password; return this; } /** * sets the protocol. defaults to "TLS" * @param protocol * @return */ public SSLContextBuilder protocol(String protocol) { this.protocol = protocol; return this; } public SSLContextBuilder keystoreFilename(String filename) { try { this.stream = FileHelper.fileStream(filename); } catch (Exception e) { log.error("Caught", e); } return this; } public SSLContextBuilder keystoreBytes(byte[] bytes) { try { this.stream = new ByteArrayInputStream(bytes); } catch (Exception e) { log.error("Caught", e); } return this; } public SSLContextBuilder keystoreStream(InputStream stream) { this.stream = stream; return this; } public SSLContextBuilder keystore(KeyStore ks) { this.ks = ks; return this; } }