package at.gv.egovernment.moa.util; import java.io.IOException; import java.io.InputStream; import java.security.GeneralSecurityException; import java.security.KeyStore; import javax.net.ssl.SSLSocketFactory; import com.sun.net.ssl.KeyManager; import com.sun.net.ssl.KeyManagerFactory; import com.sun.net.ssl.SSLContext; import com.sun.net.ssl.TrustManager; import com.sun.net.ssl.TrustManagerFactory; /** * Utility for connecting to server applications via SSL. * * @author Paul Ivancsics * @version $Id$ */ public class SSLUtils { /** * Creates an SSLSocketFactory which utilizes the given trust store. * * @param trustStoreType key store type of trust store * @param trustStoreInputStream input stream for reading JKS trust store containing * trusted server certificates; if null, the default * trust store will be utilized * @param trustStorePassword if provided, it will be used to check * the integrity of the trust store; if omitted, it will not be checked * @return SSLSocketFactory to be used by an HttpsURLConnection * @throws IOException thrown while reading from the input stream * @throws GeneralSecurityException thrown while creating the socket factory */ public static SSLSocketFactory getSSLSocketFactory( String trustStoreType, InputStream trustStoreInputStream, String trustStorePassword) throws IOException, GeneralSecurityException { TrustManager[] tms = getTrustManagers(trustStoreType, trustStoreInputStream, trustStorePassword); SSLContext ctx = SSLContext.getInstance("TLS"); ctx.init(null, tms, null); SSLSocketFactory sf = ctx.getSocketFactory(); return sf; } /** * Creates an SSLSocketFactory which utilizes the * given trust store and keystore. * * @param trustStore trust store containing trusted server certificates; * if null, the default trust store will be utilized * @param clientKeyStoreType key store type of clientKeyStore * @param clientKeyStoreURL URL of key store containing keys to be used for * client authentication; if null, the default key store will be utilized * @param clientKeyStorePassword if provided, it will be used to check * the integrity of the client key store; if omitted, it will not be checked * @return SSLSocketFactory to be used by an HttpsURLConnection * @throws IOException thrown while reading key store file * @throws GeneralSecurityException thrown while creating the socket factory */ public static SSLSocketFactory getSSLSocketFactory( KeyStore trustStore, String clientKeyStoreType, String clientKeyStoreURL, String clientKeyStorePassword) throws IOException, GeneralSecurityException { SSLContext ctx = getSSLContext( trustStore, clientKeyStoreType, clientKeyStoreURL, clientKeyStorePassword); SSLSocketFactory sf = ctx.getSocketFactory(); return sf; } /** * Creates an SSLContext initialized for the * given trust store and keystore. * * @param trustStore trust store containing trusted server certificates; * if null, the default trust store will be utilized * @param clientKeyStoreType key store type of clientKeyStore * @param clientKeyStoreURL URL of key store containing keys to be used for * client authentication; if null, the default key store will be utilized * @param clientKeyStorePassword if provided, it will be used to check * the integrity of the client key store; if omitted, it will not be checked * @return SSLContext to be used for creating an SSLSocketFactory * @throws IOException thrown while reading key store file * @throws GeneralSecurityException thrown while creating the SSL context */ public static SSLContext getSSLContext( KeyStore trustStore, String clientKeyStoreType, String clientKeyStoreURL, String clientKeyStorePassword) throws IOException, GeneralSecurityException { //System.setProperty("javax.net.debug", "all"); TrustManager[] tms = getTrustManagers(trustStore); KeyManager[] kms = getKeyManagers(clientKeyStoreType, clientKeyStoreURL, clientKeyStorePassword); SSLContext ctx = SSLContext.getInstance("TLS"); ctx.init(kms, tms, null); return ctx; } /** * Loads the trust store from an input stream and gets the * TrustManagers from a default TrustManagerFactory, * initialized from the given trust store. * @param trustStoreType key store type of trust store * @param trustStoreInputStream input stream for reading JKS trust store containing * trusted server certificates; if null, the default * trust store will be utilized * @param trustStorePassword if provided, it will be used to check * the integrity of the trust store; if omitted, it will not be checked * @return TrustManagers to be used for creating an * SSLSocketFactory utilizing the given trust store * @throws IOException thrown while reading from the input stream * @throws GeneralSecurityException thrown while initializing the * default TrustManagerFactory */ protected static TrustManager[] getTrustManagers( String trustStoreType, InputStream trustStoreInputStream, String trustStorePassword) throws IOException, GeneralSecurityException { if (trustStoreInputStream == null) return null; // Set up the TrustStore to use. We need to load the file into // a KeyStore instance. KeyStore trustStore = KeyStoreUtils.loadKeyStore(trustStoreType, trustStoreInputStream, trustStorePassword); return getTrustManagers(trustStore); } /** * Gets the TrustManagers from a default TrustManagerFactory, * initialized from the given trust store. * * @param trustStore the trust store to use * @return TrustManagers to be used for creating an * SSLSocketFactory utilizing the given trust store * @throws GeneralSecurityException thrown while initializing the * default TrustManagerFactory */ protected static TrustManager[] getTrustManagers(KeyStore trustStore) throws GeneralSecurityException { if (trustStore == null) return null; // Initialize the default TrustManagerFactory with this KeyStore String alg=TrustManagerFactory.getDefaultAlgorithm(); TrustManagerFactory tmFact=TrustManagerFactory.getInstance(alg); tmFact.init(trustStore); // And now get the TrustManagers TrustManager[] tms=tmFact.getTrustManagers(); return tms; } /** * Loads the client key store from file and gets the * KeyManagers from a default KeyManagerFactory, * initialized from the given client key store. * @param clientKeyStoreType key store type of clientKeyStore * @param clientKeyStoreURL URL of key store containing keys to be used for * client authentication; if null, the default key store will be utilized * @param clientKeyStorePassword password used to check the integrity of the client key store; * if null, it will not be checked * @return KeyManagers to be used for creating an * SSLSocketFactory utilizing the given client key store * @throws IOException thrown while reading from the key store file * @throws GeneralSecurityException thrown while initializing the * default KeyManagerFactory */ public static KeyManager[] getKeyManagers ( String clientKeyStoreType, String clientKeyStoreURL, String clientKeyStorePassword) throws IOException, GeneralSecurityException { if (clientKeyStoreURL == null) return null; // Set up the KeyStore to use. We need to load the file into // a KeyStore instance. KeyStore clientKeyStore = KeyStoreUtils.loadKeyStore( clientKeyStoreType, clientKeyStoreURL, clientKeyStorePassword); return getKeyManagers(clientKeyStore, clientKeyStorePassword); } /** * Gets the KeyManagers from a default KeyManagerFactory, * initialized from the given client key store. * @param clientKeyStore client key store * @param clientKeyStorePassword if provided, it will be used to check * the integrity of the client key store; if omitted, it will not be checked * @return KeyManagers to be used for creating an * SSLSocketFactory utilizing the given client key store * @throws GeneralSecurityException thrown while initializing the * default KeyManagerFactory */ public static KeyManager[] getKeyManagers ( KeyStore clientKeyStore, String clientKeyStorePassword) throws GeneralSecurityException { if (clientKeyStore == null) return null; // Now we initialize the default KeyManagerFactory with this KeyStore String alg=KeyManagerFactory.getDefaultAlgorithm(); KeyManagerFactory kmFact=KeyManagerFactory.getInstance(alg); char[] password = null; if (clientKeyStorePassword != null) password = clientKeyStorePassword.toCharArray(); kmFact.init(clientKeyStore, password); // And now get the KeyManagers KeyManager[] kms=kmFact.getKeyManagers(); return kms; } }