/*
* Copyright 2003 Federal Chancellery Austria
* MOA-ID has been developed in a cooperation between BRZ, the Federal
* Chancellery Austria - ICT staff unit, and Graz University of Technology.
*
* Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
* the European Commission - subsequent versions of the EUPL (the "Licence");
* You may not use this work except in compliance with the Licence.
* You may obtain a copy of the Licence at:
* http://www.osor.eu/eupl/
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the Licence is distributed on an "AS IS" basis,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the Licence for the specific language governing permissions and
* limitations under the Licence.
*
* This product combines work with different licenses. See the "NOTICE" text
* file for details on the various modules and licenses.
* The "NOTICE" text file is part of the distribution. Any derivative works
* that you distribute must include a readable copy of the "NOTICE" text file.
*/
package at.gv.egovernment.moaspss.util;
import java.io.IOException;
import java.io.InputStream;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.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 {
final TrustManager[] tms = getTrustManagers(trustStoreType, trustStoreInputStream, trustStorePassword);
final SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(null, tms, null);
final 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 {
final SSLContext ctx = getSSLContext(
trustStore, clientKeyStoreType, clientKeyStoreURL, clientKeyStorePassword);
final 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 {
final TrustManager[] tms = getTrustManagers(trustStore);
final KeyManager[] kms = getKeyManagers(clientKeyStoreType, clientKeyStoreURL, clientKeyStorePassword);
final SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(kms, tms, null);
return ctx;
}
/**
* Loads the trust store from an input stream and gets the
* TrustManager
s 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 TrustManager
s 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.
final KeyStore trustStore = KeyStoreUtils.loadKeyStore(trustStoreType, trustStoreInputStream,
trustStorePassword);
return getTrustManagers(trustStore);
}
/**
* Gets the TrustManager
s from a default
* TrustManagerFactory
, initialized from the given trust store.
*
* @param trustStore the trust store to use
* @return TrustManager
s 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
final String alg = TrustManagerFactory.getDefaultAlgorithm();
final TrustManagerFactory tmFact = TrustManagerFactory.getInstance(alg);
tmFact.init(trustStore);
// And now get the TrustManagers
final TrustManager[] tms = tmFact.getTrustManagers();
return tms;
}
/**
* Loads the client key store from file and gets the KeyManager
s
* 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 KeyManager
s 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.
final KeyStore clientKeyStore = KeyStoreUtils.loadKeyStore(
clientKeyStoreType, clientKeyStoreURL, clientKeyStorePassword);
return getKeyManagers(clientKeyStore, clientKeyStorePassword);
}
/**
* Gets the KeyManager
s 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 KeyManager
s 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
final String alg = KeyManagerFactory.getDefaultAlgorithm();
final KeyManagerFactory kmFact = KeyManagerFactory.getInstance(alg);
char[] password = null;
if (clientKeyStorePassword != null) {
password = clientKeyStorePassword.toCharArray();
}
kmFact.init(clientKeyStore, password);
// And now get the KeyManagers
final KeyManager[] kms = kmFact.getKeyManagers();
return kms;
}
}