/******************************************************************************* * Copyright 2014 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. ******************************************************************************/ /* * 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.moa.id.commons.utils.ssl; import java.io.IOException; import java.security.GeneralSecurityException; import java.security.KeyStore; import java.util.HashMap; import java.util.Map; 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 at.gv.egiz.eaaf.core.impl.utils.KeyStoreUtils; import at.gv.egovernment.moa.logging.Logger; import at.gv.egovernment.moaspss.logging.LoggingContext; import at.gv.egovernment.moaspss.logging.LoggingContextManager; import iaik.pki.DefaultPKIConfiguration; import iaik.pki.PKIException; import iaik.pki.PKIFactory; /** * Utility for a obtaining a secure socket factory using IAIKX509TrustManager. * This TrustManager implementation features CRL checking.
* SSLUtils caches secure socket factories for given ConnectionParameters. * * @author Paul Ivancsics * @version $Id$ */ public class SSLUtils { /** SSLSocketFactory store, mapping URL->SSLSocketFactory **/ private static Map sslSocketFactories = new HashMap(); // /** // * Initializes the SSLSocketFactory store. // */ // public static void initialize() { // sslSocketFactories = new HashMap(); // // JSSE Abhängigkeit // //Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider()); // Security.addProvider(new IAIK()); // //System.setProperty("java.protocol.handler.pkgs", "com.sun.net.ssl.internal.www.protocol"); // // // } /** * IAIK PKI module and MOA-SIG uses a ThreadLocal variable for logging * check if current thread has set this variable and set loggingcontext otherwise * * @param url transactionID for logging */ private static void checkMoaSigLoggingContext(String url) { LoggingContextManager logMgr = LoggingContextManager.getInstance(); if (logMgr.getLoggingContext() == null) { LoggingContext ctx = new LoggingContext(url); logMgr.setLoggingContext(ctx); } } /** * Get SSLSocketFactory with TrustStore and KeyStore implementations * * @param url URL of the Service that should be connected * @param useStandardJavaTrustStore Flag to use standard JVM truststore * @param certStoreRootDirParam Path to certStore, if own truststore is used * @param trustStoreURL Path to truststore, if own truststore is used * @param acceptedServerCertURL Path to whitelist with EE-Server certificats, if own truststore is used * @param chainingMode PKIX-Mode or Onion-Model for certificate validation, if own truststore is used * @param checkRevocation Flag to activate or deactivate revocation checks, if own truststore is used * @param revocationMethodOrder Revocation check order (CLR, OCSP), if own truststore is used * @param clientKeyStoreURL Path to KeyStore for SSL Client-Authentication, or null * @param clientKeyStorePassword KeyStore password * @param clientKeyStoreType KeyStore type * @return * @throws IOException * @throws GeneralSecurityException * @throws SSLConfigurationException * @throws PKIException */ public static SSLSocketFactory getSSLSocketFactory( String url, boolean useStandardJavaTrustStore, String certStoreRootDirParam, String trustStoreURL, String acceptedServerCertURL, String chainingMode, boolean checkRevocation, String[] revocationMethodOrder, String clientKeyStoreURL, String clientKeyStorePassword, String clientKeyStoreType ) throws IOException, GeneralSecurityException, SSLConfigurationException, PKIException { Logger.debug("Get SSLSocketFactory for " + url); // retrieve SSLSocketFactory if already created SSLSocketFactory ssf = (SSLSocketFactory)sslSocketFactories.get(url); if (ssf != null) { checkMoaSigLoggingContext(url); return ssf; } //initialize own trust-store implementation TrustManager[] tms = null; if (useStandardJavaTrustStore) { tms = getTrustManagers( certStoreRootDirParam, chainingMode, trustStoreURL, acceptedServerCertURL, checkRevocation, revocationMethodOrder); } KeyManager[] kms = getKeyManagers( clientKeyStoreType, clientKeyStoreURL, clientKeyStorePassword); SSLContext ctx = SSLContext.getInstance("TLS"); ctx.init(kms, tms, null); ssf = ctx.getSocketFactory(); // store SSLSocketFactory sslSocketFactories.put(url, ssf); checkMoaSigLoggingContext(url); return ssf; } public static void removeSSLSocketFactory(String url) { Logger.info("Remove SSLSocketFactory for URL " + url); if (sslSocketFactories.containsKey(url)) sslSocketFactories.remove(url); } /** * 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; } /** * Initializes an IAIKX509TrustManager for a given trust store, * using configuration data. * * @param conf MOA-ID configuration provider * @param trustStoreURL trust store URL * @param acceptedServerCertURL file URL pointing to directory containing accepted server SSL certificates * @return TrustManager array containing the IAIKX509TrustManager * @throws ConfigurationException on invalid configuration data * @throws IOException on data-reading problems * @throws PKIException while initializing the IAIKX509TrustManager */ private static TrustManager[] getTrustManagers(String certStoreRootDirParam, String chainingMode, String trustStoreURL, String acceptedServerCertURL, boolean checkRevocation, String[] revocationMethodOrder) throws SSLConfigurationException, PKIException, IOException, GeneralSecurityException { DefaultPKIConfiguration cfg = null; if (! PKIFactory.getInstance().isAlreadyConfigured()) { CertStoreConfigurationImpl certStoreConf = new CertStoreConfigurationImpl(certStoreRootDirParam); cfg = new DefaultPKIConfiguration(certStoreConf.getParameters()); cfg.setChainingMode(chainingMode); Logger.info("Set-up PKI module configuration ... "); } PKIProfileImpl profile = new PKIProfileImpl(trustStoreURL, checkRevocation); profile.setPreferredServiceOrder(revocationMethodOrder); // This call fixes a bug occuring when PKIConfiguration is // initialized by the MOA-SP initialization code, in case // MOA-SP is called by API MOAIDTrustManager.initializeLoggingContext(); MOAIDTrustManager tm = new MOAIDTrustManager(acceptedServerCertURL); tm.init(cfg, profile); return new TrustManager[] {tm}; } }