package co.codewizards.cloudstore.rest.client.ssl; import static co.codewizards.cloudstore.core.util.Util.*; import static co.codewizards.cloudstore.core.oio.OioFileFactory.*; import java.net.URL; import java.security.GeneralSecurityException; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; import co.codewizards.cloudstore.core.config.ConfigDir; import co.codewizards.cloudstore.core.oio.File; import co.codewizards.cloudstore.core.util.AssertUtil; public final class SSLContextBuilder { private URL remoteURL; private File trustStoreFile; private DynamicX509TrustManagerCallback callback; private SSLContextBuilder() { } public static SSLContextBuilder create() { return new SSLContextBuilder(); } public DynamicX509TrustManagerCallback getCallback() { return callback; } public void setCallback(final DynamicX509TrustManagerCallback callback) { this.callback = callback; } public SSLContextBuilder callback(final DynamicX509TrustManagerCallback callback) { setCallback(callback); return this; } public URL getRemoteURL() { return remoteURL; } public void setRemoteURL(final URL remoteURL) { this.remoteURL = remoteURL; } public SSLContextBuilder remoteURL(final URL remoteURL) { setRemoteURL(remoteURL); return this; } public File getTrustStoreFile() { return trustStoreFile; } public void setTrustStoreFile(final File trustStoreFile) { this.trustStoreFile = trustStoreFile; } public SSLContextBuilder trustStoreFile(final File trustStoreFile) { setTrustStoreFile(trustStoreFile); return this; } public SSLContext build() throws GeneralSecurityException { final File trustStoreFile = getTrustStoreFile(); if (trustStoreFile != null) { if (getRemoteURL() != null) throw new IllegalStateException("remoteURL and trustStoreFile are both set! Only one of these should be set!"); return getSSLContext(trustStoreFile, getCallback()); } else return getSSLContext(getRemoteURL(), getCallback()); } private SSLContext getSSLContext(final File trustStoreFile, final DynamicX509TrustManagerCallback callback) throws GeneralSecurityException { AssertUtil.assertNotNull(trustStoreFile, "trustStoreFile"); AssertUtil.assertNotNull(callback, "callback"); final TrustManager[] trustManagers = new TrustManager[] { new DynamicX509TrustManager(trustStoreFile, callback) }; // http://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html#SSLContext // http://en.wikipedia.org/wiki/Secure_Sockets_Layer#Cipher final SSLContext sslContext = SSLContext.getInstance("TLSv1.2"); sslContext.init(null, trustManagers, null); return sslContext; } private SSLContext getSSLContext(final URL remoteURL, final DynamicX509TrustManagerCallback callback) throws GeneralSecurityException { AssertUtil.assertNotNull(remoteURL, "remoteURL"); AssertUtil.assertNotNull(callback, "callback"); String trustStoreFileName = remoteURL.getHost(); if (remoteURL.getPort() >= 0) trustStoreFileName += "_" + remoteURL.getPort(); trustStoreFileName += ".truststore"; final File sslClient = createFile(ConfigDir.getInstance().getFile(), "ssl.client"); if (!sslClient.isDirectory()) sslClient.mkdirs(); if (!sslClient.isDirectory()) throw new IllegalStateException("Could not create directory (permissions?): " + sslClient); return getSSLContext(createFile(sslClient, trustStoreFileName), callback); } }