package com.tinify; import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManagerFactory; import java.io.IOException; import java.io.InputStream; import java.security.GeneralSecurityException; import java.security.KeyStore; import java.security.SecureRandom; import java.security.cert.Certificate; import java.security.cert.CertificateFactory; import java.util.Collection; public class SSLContext { public static SSLSocketFactory getSocketFactory() { try { CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509"); Collection<? extends Certificate> certificates = certificateFactory.generateCertificates(certificateStream()); KeyStore keyStore = newEmptyKeyStore(); int index = 0; for (Certificate certificate : certificates) { String certificateAlias = Integer.toString(index++); keyStore.setCertificateEntry(certificateAlias, certificate); } if (keyStore.size() == 0) { /* The resource stream was empty, no certificates were found. */ throw new ConnectionException("Unable to load any CA certificates.", null); } KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance( KeyManagerFactory.getDefaultAlgorithm()); keyManagerFactory.init(keyStore, null); TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance( TrustManagerFactory.getDefaultAlgorithm()); trustManagerFactory.init(keyStore); javax.net.ssl.SSLContext sslContext = javax.net.ssl.SSLContext.getInstance("TLS"); sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), new SecureRandom()); return sslContext.getSocketFactory(); } catch (GeneralSecurityException | IOException e) { throw new ConnectionException("Error while loading trusted CA certificates.", e); } } public static InputStream certificateStream() throws IOException { return SSLContext.class.getResourceAsStream("/cacert.pem"); } private static KeyStore newEmptyKeyStore() throws GeneralSecurityException { try { KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); /* By convention, a null InputStream creates an empty key store. */ keyStore.load(null, null); return keyStore; } catch (IOException e) { throw new AssertionError(e); } } }