package com.eucalyptus.auth.util; import java.io.File; import java.net.Socket; import java.security.InvalidAlgorithmParameterException; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.Principal; import java.security.PrivateKey; import java.security.UnrecoverableKeyException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import javax.net.ssl.KeyManager; import javax.net.ssl.KeyManagerFactorySpi; import javax.net.ssl.ManagerFactoryParameters; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLEngine; import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManagerFactorySpi; import javax.net.ssl.X509ExtendedKeyManager; import org.apache.log4j.Logger; import com.eucalyptus.bootstrap.Component; import com.eucalyptus.system.SubDirectory; import com.sun.net.ssl.internal.ssl.X509ExtendedTrustManager; public class SslSetup { private static Logger LOG = Logger.getLogger( SslSetup.class ); private static final String PROTOCOL = "TLS"; private static SSLContext SERVER_CONTEXT = null; private static SSLContext CLIENT_CONTEXT = null; static { SSLContext serverContext = null; SSLContext clientContext = null; System.setProperty( "javax.net.ssl.trustStore", SubDirectory.KEYS.toString( ) + File.separator + "euca.p12" ); System.setProperty( "javax.net.ssl.keyStore", SubDirectory.KEYS.toString( ) + File.separator + "euca.p12" ); System.setProperty( "javax.net.ssl.trustStoreType", "PKCS12" ); System.setProperty( "javax.net.ssl.keyStoreType", "PKCS12" ); System.setProperty( "javax.net.ssl.trustStorePassword", Component.eucalyptus.name( ) ); System.setProperty( "javax.net.ssl.keyStorePassword", Component.eucalyptus.name( ) ); System.setProperty( "javax.net.debug", "ssl" );//set this to "ssl" for debugging. try { serverContext = SSLContext.getInstance( "TLS" ); serverContext.init( SslSetup.SimpleKeyManager.getKeyManagers( ), SslSetup.SimpleTrustManager.getTrustManagers( ), null ); } catch ( Exception e ) { LOG.debug( e, e ); throw new Error( "Failed to initialize the server-side SSLContext", e ); } try { clientContext = SSLContext.getInstance( "TLS" ); clientContext.init( SslSetup.SimpleKeyManager.getKeyManagers( ), SslSetup.SimpleTrustManager.getTrustManagers( ), null ); } catch ( Exception e ) { LOG.debug( e, e ); throw new Error( "Failed to initialize the client-side SSLContext", e ); } SERVER_CONTEXT = serverContext; CLIENT_CONTEXT = clientContext; } public static SSLContext getServerContext( ) { return SERVER_CONTEXT; } public static SSLEngine getServerEngine() { SSLEngine engine = SslSetup.getServerContext( ).createSSLEngine( ); engine.setUseClientMode( false ); return engine; } public static SSLContext getClientContext( ) { return CLIENT_CONTEXT; } public static class SimpleKeyManager extends KeyManagerFactorySpi { private static KeyManager singleton = new SimplePKCS12KeyManager( ); public static KeyManager[] getKeyManagers( ) { return new KeyManager[] { singleton }; } @Override protected KeyManager[] engineGetKeyManagers( ) { return new KeyManager[] { singleton }; } @Override protected void engineInit( ManagerFactoryParameters spec ) throws InvalidAlgorithmParameterException {} @Override protected void engineInit( KeyStore ks, char[] password ) throws KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException {} public static class SimplePKCS12KeyManager extends X509ExtendedKeyManager { @Override public String chooseClientAlias( String[] arg0, Principal[] arg1, Socket arg2 ) { return Component.eucalyptus.name( ); } @Override public String chooseServerAlias( String arg0, Principal[] arg1, Socket arg2 ) { return Component.eucalyptus.name( ); } @Override public X509Certificate[] getCertificateChain( String arg0 ) { if ( Component.eucalyptus.name( ).equals( arg0 ) ) { return trustedCerts; } else { return null; } } @Override public String[] getClientAliases( String arg0, Principal[] arg1 ) { return new String[] { Component.eucalyptus.name( ) }; } @Override public PrivateKey getPrivateKey( String arg0 ) { if ( Component.eucalyptus.name( ).equals( arg0 ) ) { return trustedKey; } else { return null; } } @Override public String[] getServerAliases( String arg0, Principal[] arg1 ) { return new String[] { Component.eucalyptus.name( ) }; } @Override public String chooseEngineClientAlias( String[] keyType, Principal[] issuers, SSLEngine engine ) { return Component.eucalyptus.name( ); } @Override public String chooseEngineServerAlias( String keyType, Principal[] issuers, SSLEngine engine ) { return Component.eucalyptus.name( ); } } } private static PrivateKey trustedKey = null; private static X509Certificate trusted = getTrustedCertificate( ); private static X509Certificate[] trustedCerts = new X509Certificate[] { trusted }; private static X509Certificate getTrustedCertificate( ) { try { synchronized ( SslSetup.class ) { if ( trusted == null ) { trusted = ( X509Certificate ) EucaKeyStore.getInstance( ).getCertificate( Component.eucalyptus.name( ) ); trustedKey = EucaKeyStore.getInstance( ).getKeyPair( Component.eucalyptus.name( ), Component.eucalyptus.name( ) ).getPrivate( ); } return trusted; } } catch ( Exception e ) { LOG.error( e, e ); throw new RuntimeException( e ); } } public static class SimpleTrustManager extends TrustManagerFactorySpi { private static Logger LOG = Logger.getLogger( SslSetup.SimpleTrustManager.class ); private static final TrustManager singleton = new SimpleX509TrustManager( ); public static TrustManager[] getTrustManagers( ) { return new TrustManager[] { singleton }; } @Override protected TrustManager[] engineGetTrustManagers( ) { return getTrustManagers( ); } @Override protected void engineInit( KeyStore keystore ) throws KeyStoreException {} @Override protected void engineInit( ManagerFactoryParameters managerFactoryParameters ) throws InvalidAlgorithmParameterException {} public static class SimpleX509TrustManager extends X509ExtendedTrustManager { @Override public void checkClientTrusted( X509Certificate[] arg0, String arg1 ) throws CertificateException {} @Override public void checkServerTrusted( X509Certificate[] chain, String authType ) throws CertificateException {} @Override public X509Certificate[] getAcceptedIssuers( ) { return trustedCerts; } @Override public void checkClientTrusted( X509Certificate[] arg0, String arg1, String arg2, String arg3 ) throws CertificateException {} @Override public void checkServerTrusted( X509Certificate[] arg0, String arg1, String arg2, String arg3 ) throws CertificateException {} } } }