1
/* Copyright (c) 2001-2008, The HSQL Development Group
4
* Redistribution and use in source and binary forms, with or without
5
* modification, are permitted provided that the following conditions are met:
7
* Redistributions of source code must retain the above copyright notice, this
8
* list of conditions and the following disclaimer.
10
* Redistributions in binary form must reproduce the above copyright notice,
11
* this list of conditions and the following disclaimer in the documentation
12
* and/or other materials provided with the distribution.
14
* Neither the name of the HSQL Development Group nor the names of its
15
* contributors may be used to endorse or promote products derived from this
16
* software without specific prior written permission.
18
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21
* ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
22
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
import java.io.FileInputStream;
35
import java.net.InetAddress;
36
import java.net.ServerSocket;
37
import java.net.Socket;
38
import java.security.InvalidAlgorithmParameterException;
39
import java.security.KeyStore;
40
import java.security.KeyStoreException;
41
import java.security.NoSuchAlgorithmException;
42
import java.security.Principal;
43
import java.security.PrivateKey;
44
import java.security.UnrecoverableKeyException;
45
import java.security.cert.CertificateException;
46
import java.security.cert.X509Certificate;
48
import javax.net.ssl.KeyManager;
49
import javax.net.ssl.KeyManagerFactorySpi;
50
import javax.net.ssl.ManagerFactoryParameters;
51
import javax.net.ssl.SSLContext;
52
import javax.net.ssl.SSLEngine;
53
import javax.net.ssl.SSLServerSocket;
54
import javax.net.ssl.SSLServerSocketFactory;
55
import javax.net.ssl.SSLSocket;
56
import javax.net.ssl.SSLSocketFactory;
57
import javax.net.ssl.TrustManager;
58
import javax.net.ssl.TrustManagerFactorySpi;
59
import javax.net.ssl.X509ExtendedKeyManager;
60
import org.apache.log4j.Logger;
61
import com.sun.net.ssl.internal.ssl.X509ExtendedTrustManager;
64
* We need to override the way that hsqldb gets its secure sockets to use our internally mananged credentials.
66
public final class HsqlSocketFactorySecure extends HsqlSocketFactory {
67
private static Logger LOG = Logger.getLogger( HsqlSocketFactorySecure.class );
68
protected SSLSocketFactory socketFactory;
69
protected SSLServerSocketFactory serverSocketFactory;
70
private static final String PROTOCOL = "TLS";
71
private static SSLContext SERVER_CONTEXT = null;
72
private static SSLContext CLIENT_CONTEXT = null;
73
private static String KEYS = System.getProperty("euca.var.dir") + File.separator + "keys";
74
private static String KEYSTORE = KEYS + File.separator + "euca.p12";
75
private static String EUCALYPTUS = "eucalyptus";
76
private static PrivateKey pk = null;
77
private static X509Certificate cert = null;
79
SSLContext serverContext = null;
80
SSLContext clientContext = null;
81
System.setProperty( "javax.net.ssl.trustStore", KEYSTORE );
82
System.setProperty( "javax.net.ssl.keyStore", KEYSTORE );
83
System.setProperty( "javax.net.ssl.trustStoreType", "PKCS12" );
84
System.setProperty( "javax.net.ssl.keyStoreType", "PKCS12" );
85
System.setProperty( "javax.net.ssl.trustStorePassword", EUCALYPTUS );
86
System.setProperty( "javax.net.ssl.keyStorePassword", EUCALYPTUS );
87
System.setProperty( "javax.net.debug", "none" );//set this to "ssl" for debugging.
89
serverContext = SSLContext.getInstance( "TLS" );
90
serverContext.init( HsqlSocketFactorySecure.SimpleKeyManager.getKeyManagers( ), HsqlSocketFactorySecure.SimpleTrustManager.getTrustManagers( ), null );
91
} catch ( Exception e ) {
93
throw new Error( "Failed to initialize the server-side SSLContext", e );
97
clientContext = SSLContext.getInstance( "TLS" );
98
clientContext.init( HsqlSocketFactorySecure.SimpleKeyManager.getKeyManagers( ), HsqlSocketFactorySecure.SimpleTrustManager.getTrustManagers( ), null );
99
} catch ( Exception e ) {
101
throw new Error( "Failed to initialize the client-side SSLContext", e );
104
SERVER_CONTEXT = serverContext;
105
CLIENT_CONTEXT = clientContext;
108
private static void loadKeystore( ) {
110
KeyStore keyStore = KeyStore.getInstance( "pkcs12", "BC" );
111
if ( ( new File( KEYSTORE ) ).exists( ) ) {
112
final FileInputStream fin = new FileInputStream( KEYSTORE );
113
keyStore.load( fin, EUCALYPTUS.toCharArray( ) );
115
pk = ( PrivateKey ) keyStore.getKey( EUCALYPTUS, EUCALYPTUS.toCharArray( ) );
116
cert = ( X509Certificate ) keyStore.getCertificate( EUCALYPTUS );
118
} catch ( Throwable t ) {
123
public static SSLContext getServerContext( ) {
124
return SERVER_CONTEXT;
127
public static SSLEngine getServerEngine() {
128
SSLEngine engine = HsqlSocketFactorySecure.getServerContext( ).createSSLEngine( );
129
engine.setUseClientMode( false );
132
public static SSLContext getClientContext( ) {
133
return CLIENT_CONTEXT;
136
public static class SimpleKeyManager extends KeyManagerFactorySpi {
137
private static KeyManager singleton = new SimplePKCS12KeyManager( );
139
public static KeyManager[] getKeyManagers( ) {
140
return new KeyManager[] { singleton };
144
protected KeyManager[] engineGetKeyManagers( ) {
145
return new KeyManager[] { singleton };
149
protected void engineInit( ManagerFactoryParameters spec ) throws InvalidAlgorithmParameterException {}
152
protected void engineInit( KeyStore ks, char[] password ) throws KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException {}
154
public static class SimplePKCS12KeyManager extends X509ExtendedKeyManager {
157
public String chooseClientAlias( String[] arg0, Principal[] arg1, Socket arg2 ) {
162
public String chooseServerAlias( String arg0, Principal[] arg1, Socket arg2 ) {
167
public X509Certificate[] getCertificateChain( String arg0 ) {
168
if ( EUCALYPTUS.equals( arg0 ) ) {
176
public String[] getClientAliases( String arg0, Principal[] arg1 ) {
177
return new String[] { EUCALYPTUS };
181
public PrivateKey getPrivateKey( String arg0 ) {
182
if ( EUCALYPTUS.equals( arg0 ) ) {
190
public String[] getServerAliases( String arg0, Principal[] arg1 ) {
191
return new String[] { EUCALYPTUS };
195
public String chooseEngineClientAlias( String[] keyType, Principal[] issuers, SSLEngine engine ) {
200
public String chooseEngineServerAlias( String keyType, Principal[] issuers, SSLEngine engine ) {
208
private static PrivateKey trustedKey = null;
209
private static X509Certificate trusted = getTrustedCertificate( );
210
private static X509Certificate[] trustedCerts = new X509Certificate[] { trusted };
212
private static X509Certificate getTrustedCertificate( ) {
214
synchronized ( HsqlSocketFactorySecure.class ) {
215
if ( trusted == null ) {
221
} catch ( Exception e ) {
223
throw new RuntimeException( e );
227
public static class SimpleTrustManager extends TrustManagerFactorySpi {
228
private static Logger LOG = Logger.getLogger( HsqlSocketFactorySecure.SimpleTrustManager.class );
230
private static final TrustManager singleton = new SimpleX509TrustManager( );
232
public static TrustManager[] getTrustManagers( ) {
233
return new TrustManager[] { singleton };
237
protected TrustManager[] engineGetTrustManagers( ) {
238
return getTrustManagers( );
242
protected void engineInit( KeyStore keystore ) throws KeyStoreException {}
245
protected void engineInit( ManagerFactoryParameters managerFactoryParameters ) throws InvalidAlgorithmParameterException {}
247
public static class SimpleX509TrustManager extends X509ExtendedTrustManager {
250
public void checkClientTrusted( X509Certificate[] arg0, String arg1 ) throws CertificateException {}
253
public void checkServerTrusted( X509Certificate[] chain, String authType ) throws CertificateException {}
256
public X509Certificate[] getAcceptedIssuers( ) {
261
public void checkClientTrusted( X509Certificate[] arg0, String arg1, String arg2, String arg3 ) throws CertificateException {}
264
public void checkServerTrusted( X509Certificate[] arg0, String arg1, String arg2, String arg3 ) throws CertificateException {}
269
protected HsqlSocketFactorySecure( ) throws Exception {}
271
public void configureSocket( Socket socket ) {
272
super.configureSocket( socket );
275
public ServerSocket createServerSocket( int port ) throws Exception {
276
return ( SSLServerSocket ) getServerSocketFactoryImpl( ).createServerSocket( port );
279
public ServerSocket createServerSocket( int port, String address ) throws Exception {
280
InetAddress addr = InetAddress.getByName( address );
281
return ( SSLServerSocket ) getServerSocketFactoryImpl( ).createServerSocket( port, 128, addr );
284
public Socket createSocket( String host, int port ) throws Exception {
285
SSLSocket socket = ( SSLSocket ) getSocketFactoryImpl( ).createSocket( host, port );
286
socket.startHandshake( );
290
public boolean isSecure( ) {
294
protected SSLServerSocketFactory getServerSocketFactoryImpl( ) throws Exception {
295
synchronized ( HsqlSocketFactorySecure.class ) {
296
if ( serverSocketFactory == null ) {
297
serverSocketFactory = HsqlSocketFactorySecure.getServerContext( ).getServerSocketFactory( );
300
return ( SSLServerSocketFactory ) serverSocketFactory;
303
protected SSLSocketFactory getSocketFactoryImpl( ) throws Exception {
304
synchronized ( HsqlSocketFactorySecure.class ) {
305
if ( socketFactory == null ) {
306
socketFactory = HsqlSocketFactorySecure.getClientContext( ).getSocketFactory( );
309
return ( SSLSocketFactory ) socketFactory;