2
* JBoss, Home of Professional Open Source
3
* Copyright 2005, JBoss Inc., and individual contributors as indicated
4
* by the @authors tag. See the copyright.txt in the distribution for a
5
* full listing of individual contributors.
7
* This is free software; you can redistribute it and/or modify it
8
* under the terms of the GNU Lesser General Public License as
9
* published by the Free Software Foundation; either version 2.1 of
10
* the License, or (at your option) any later version.
12
* This software is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
* Lesser General Public License for more details.
17
* You should have received a copy of the GNU Lesser General Public
18
* License along with this software; if not, write to the Free
19
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
22
package org.jboss.remoting.security;
24
import org.jboss.logging.Logger;
25
import org.jboss.remoting.serialization.ClassLoaderUtility;
26
import org.jboss.remoting.util.SecurityUtility;
27
import org.jboss.remoting.util.socket.RemotingKeyManager;
29
import javax.net.ServerSocketFactory;
30
import javax.net.SocketFactory;
31
import javax.net.ssl.KeyManager;
32
import javax.net.ssl.KeyManagerFactory;
33
import javax.net.ssl.SSLContext;
34
import javax.net.ssl.SSLServerSocketFactory;
35
import javax.net.ssl.SSLSocketFactory;
36
import javax.net.ssl.TrustManager;
37
import javax.net.ssl.TrustManagerFactory;
38
import javax.net.ssl.X509KeyManager;
39
import javax.net.ssl.X509TrustManager;
41
import java.io.IOException;
42
import java.io.InputStream;
43
import java.lang.reflect.Method;
44
import java.net.MalformedURLException;
46
import java.security.AccessController;
47
import java.security.KeyStore;
48
import java.security.KeyStoreException;
49
import java.security.NoSuchAlgorithmException;
50
import java.security.NoSuchProviderException;
51
import java.security.PrivilegedAction;
52
import java.security.PrivilegedActionException;
53
import java.security.PrivilegedExceptionAction;
54
import java.security.Provider;
55
import java.security.SecureRandom;
56
import java.security.UnrecoverableKeyException;
57
import java.security.cert.CertificateException;
58
import java.security.cert.X509Certificate;
62
* A class that contains code that remoting factories need to build customized server and client SSL sockets.
64
* @author <a href="mailto:mazz@jboss.com">John Mazzitelli</a>
65
* @author <a href="mailto:telrod@jboss.com">Tom Elrod</a>
67
* @version $Revision: 5689 $
69
public class SSLSocketBuilder implements SSLSocketBuilderMBean, Cloneable
72
* Constant defining the config property used to define the SSL provider to use.
74
public static final String REMOTING_SSL_PROVIDER_NAME = "org.jboss.remoting.sslProviderName";
77
* Constant defining the config property used to define the SSL socket protocol to use.
79
public static final String REMOTING_SSL_PROTOCOL = "org.jboss.remoting.sslProtocol";
82
* If the protocol isn't specified, this will be the default.
85
public static final String DEFAULT_SSL_PROTOCOL = "TLS";
88
* Constant defining the config property used to define if the sockets will be in
89
* client or server mode.
91
public static final String REMOTING_SOCKET_USE_CLIENT_MODE = "org.jboss.remoting.socket.useClientMode";
94
* Constant defining the config property used to define if the server sockets will be in
95
* client or server mode.
97
public static final String REMOTING_SERVER_SOCKET_USE_CLIENT_MODE = "org.jboss.remoting.serversocket.useClientMode";
100
* Constant defining the config property used to define if sockets need or want
101
* client authentication. This configuration option is only useful for sockets in the server mode.
102
* The value of such a property is one of the CLIENT_AUTH_MODE_XXX constants.
104
public static final String REMOTING_CLIENT_AUTH_MODE = "org.jboss.remoting.clientAuthMode";
107
* Client auth mode that indicates client authentication will not be peformed.
109
public static final String CLIENT_AUTH_MODE_NONE = "none";
112
* Client auth mode that indicates that we want client authentication but it isn't required.
114
public static final String CLIENT_AUTH_MODE_WANT = "want";
117
* Client auth mode that indicates that client authentication is required.
119
public static final String CLIENT_AUTH_MODE_NEED = "need";
122
* Constant defining the config property used to define if a client should attempt to
123
* authenticate a server certificate as one it trusts. The value of such a property is
126
public static final String REMOTING_SERVER_AUTH_MODE = "org.jboss.remoting.serverAuthMode";
129
* Constant defining the config property used to define where JBoss/Remoting will
130
* look for the keystore file. This can be relative to the thread's
131
* classloader or can be an absolute path on the file system or can be a URL.
133
public static final String REMOTING_KEY_STORE_FILE_PATH = "org.jboss.remoting.keyStore";
136
* Constant defining the config property that defines the keystore's type.
138
public static final String REMOTING_KEY_STORE_TYPE = "org.jboss.remoting.keyStoreType";
141
* Constant defining the config property that defines the key management algorithm
142
* used by the keystore.
144
public static final String REMOTING_KEY_STORE_ALGORITHM = "org.jboss.remoting.keyStoreAlgorithm";
147
* Constant defining the config property that defines the password of the keystore.
149
public static final String REMOTING_KEY_STORE_PASSWORD = "org.jboss.remoting.keyStorePassword";
152
* Constant defining the config property that indicates the client's alias as found in the keystore.
154
public static final String REMOTING_KEY_ALIAS = "org.jboss.remoting.keyAlias";
157
* Constant defining the config property that indicates the key password for the keys in the key store.
159
public static final String REMOTING_KEY_PASSWORD = "org.jboss.remoting.keyPassword";
162
* Constant that defines the standard system property that the javax.net.ssl
163
* classes look for when locating the keystore file.
165
public static final String STANDARD_KEY_STORE_FILE_PATH = "javax.net.ssl.keyStore";
168
* Constant that defines the standard system property that the javax.net.ssl
169
* classes look for when needing to know what type the keystore file is.
171
public static final String STANDARD_KEY_STORE_TYPE = "javax.net.ssl.keyStoreType";
174
* Constant that defines the standard system property that the javax.net.ssl
175
* classes look for when needing the keystore password.
177
public static final String STANDARD_KEY_STORE_PASSWORD = "javax.net.ssl.keyStorePassword";
180
* Default key/trust store type if one not set as bean property, via config, or via system property.
183
public static final String DEFAULT_KEY_STORE_TYPE = "JKS";
186
* Default key/trust store algorithm if one net set as bean property or via config.
187
* Value is 'SunX509'.
189
public static final String DEFAULT_KEY_STORE_ALGORITHM = "SunX509";
192
* Constant defining the config property used to define where JBoss/Remoting
193
* will look for the truststore file. This can be relative to the thread's
194
* classloader or can be an absolute path on the file system.
196
public static final String REMOTING_TRUST_STORE_FILE_PATH = "org.jboss.remoting.trustStore";
199
* Constant defining the config property that defines the truststore's type.
201
public static final String REMOTING_TRUST_STORE_TYPE = "org.jboss.remoting.trustStoreType";
204
* Constant defining the config property that defines the key management
205
* algorithm used by the truststore.
207
public static final String REMOTING_TRUST_STORE_ALGORITHM = "org.jboss.remoting.trustStoreAlgorithm";
210
* Constant defining the config property that defines the password of the keystore.
212
public static final String REMOTING_TRUST_STORE_PASSWORD = "org.jboss.remoting.trustStorePassword";
215
* Constant that defines the standard system property that the javax.net.ssl
216
* classes look for when locating the truststore file.
218
public static final String STANDARD_TRUST_STORE_FILE_PATH = "javax.net.ssl.trustStore";
221
* Constant that defines the standard system property that the javax.net.ssl
222
* classes look for when needing to know what type the truststore file is.
224
public static final String STANDARD_TRUST_STORE_TYPE = "javax.net.ssl.trustStoreType";
227
* Constant that defines the standard system property that the javax.net.ssl
228
* classes look for when needing the truststore password.
230
public static final String STANDARD_TRUST_STORE_PASSWORD = "javax.net.ssl.trustStorePassword";
233
* System property key to define the fully qualified class name of default socket factory to use
234
* when not using custom config.
236
public static final String REMOTING_DEFAULT_SOCKET_FACTORY_CLASS = "org.jboss.remoting.defaultSocketFactory";
238
public static final String NONE_STORE = "NONE";
240
private SSLContext sslContextServerSocketFactory = null; // context that builds the server socket factories
241
private SSLContext sslContextSocketFactory = null; // context that builds the socket factories
242
private Provider provider = null;
243
private String providerName = null;
244
private String secureSocketProtocol = null;
246
private KeyManager[] keyManagers = null;
247
private TrustManager[] trustManagers = null;
248
private SecureRandom secureRandom = null;
250
private URL keyStoreFilePath = null;
251
private String keyStoreType = null;
252
private String keyStoreAlgorithm = null;
253
private String keyStorePassword = null;
254
private String keyAlias = null;
255
private String keyPassword = null;
257
private URL trustStoreFilePath = null;
258
private String trustStoreType = null;
259
private String trustStoreAlgorithm = null;
260
private String trustStorePassword = null;
262
private Map config = null;
263
private Boolean socketUseClientMode = null;
264
private Boolean serverSocketUseClientMode = null;
265
private String clientAuthMode = null;
266
private Boolean serverAuthMode = null;
268
private boolean useSSLServerSocketFactory = true;
269
private boolean useSSLSocketFactory = true;
271
private static final Logger log = Logger.getLogger(SSLSocketBuilder.class);
273
private static URL NONE_STORE_URL;
279
NONE_STORE_URL = new URL("file:NONE");
280
} catch (MalformedURLException e)
282
log.info("unexpected URL exception", e);
287
* Constructor for {@link SSLSocketBuilder} that does not have
288
* any configuration so it falls back to all defaults.
290
public SSLSocketBuilder()
296
* Constructor for {@link SSLSocketBuilder} that allows the caller to
297
* override the default settings for the various SSL configuration
300
* @param config configuration with properties defining things like where the
301
* keystore and truststore files are, their types, etc.
303
public SSLSocketBuilder(Map config)
305
this.config = config;
309
* @see org.jboss.remoting.security.SSLSocketBuilderMBean#setUseSSLServerSocketFactory(boolean)
311
public void setUseSSLServerSocketFactory(boolean shouldUse)
313
this.useSSLServerSocketFactory = shouldUse;
317
* @see org.jboss.remoting.security.SSLSocketBuilderMBean#getUseSSLServerSocketFactory()
319
public boolean getUseSSLServerSocketFactory()
321
return useSSLServerSocketFactory;
325
* @see org.jboss.remoting.security.SSLSocketBuilderMBean#setUseSSLSocketFactory(boolean)
327
public void setUseSSLSocketFactory(boolean shouldUse)
329
this.useSSLSocketFactory = shouldUse;
333
* @see org.jboss.remoting.security.SSLSocketBuilderMBean#getUseSSLSocketFactory()
335
public boolean getUseSSLSocketFactory()
337
return useSSLSocketFactory;
341
* @see org.jboss.remoting.security.SSLSocketBuilderMBean#createSSLServerSocketFactory()
343
public ServerSocketFactory createSSLServerSocketFactory() throws IOException
345
return createSSLServerSocketFactory( null );
349
* @see org.jboss.remoting.security.SSLSocketBuilderMBean#createSSLServerSocketFactory(org.jboss.remoting.security.CustomSSLServerSocketFactory)
351
public ServerSocketFactory createSSLServerSocketFactory(CustomSSLServerSocketFactory wrapper) throws IOException
353
ServerSocketFactory ssf = null;
355
if( getUseSSLServerSocketFactory() )
357
ssf = SSLServerSocketFactory.getDefault();
363
wrapper = new CustomSSLServerSocketFactory(null, this);
366
ssf = createCustomServerSocketFactory(wrapper);
373
* This creates a fully custom SSL server socket factory using this object's configuration.
375
* @param wrapper the wrapper where the created factory will be stored
377
* @return the SSLServerSocketFactory
379
* @throws IOException
381
protected ServerSocketFactory createCustomServerSocketFactory(CustomSSLServerSocketFactory wrapper) throws IOException
383
if (sslContextServerSocketFactory == null)
385
createServerSocketFactorySSLContext();
386
initializeServerSocketFactorySSLContext();
389
ServerSocketFactory ssf = sslContextServerSocketFactory.getServerSocketFactory();
391
wrapper.setFactory((SSLServerSocketFactory) ssf);
397
* @see org.jboss.remoting.security.SSLSocketBuilderMBean#createSSLSocketFactory()
399
public SocketFactory createSSLSocketFactory() throws IOException
401
return createSSLSocketFactory(null);
406
* @see org.jboss.remoting.security.SSLSocketBuilderMBean#createSSLSocketFactory(org.jboss.remoting.security.CustomSSLSocketFactory)
408
public SocketFactory createSSLSocketFactory(CustomSSLSocketFactory wrapper) throws IOException
410
SocketFactory sf = null;
412
if (getUseSSLSocketFactory())
414
String defaultFactoryName = getSystemProperty(REMOTING_DEFAULT_SOCKET_FACTORY_CLASS);
416
if (defaultFactoryName != null)
420
final Class sfClass = ClassLoaderUtility.loadClass(defaultFactoryName, SSLSocketBuilder.class);
421
Method m = getMethod(sfClass, "getDefault", null);
425
throw new RuntimeException(
426
"Could not create the socket factory "
428
+ " because the class "
430
+ " doesn't provide the getDefault method.");
432
sf = (SocketFactory) m.invoke(null, null);
436
throw new RuntimeException(
437
"Could not create the socket factory "
438
+ defaultFactoryName, ex);
443
sf = SSLSocketFactory.getDefault();
450
wrapper = new CustomSSLSocketFactory(null, this);
453
sf = createCustomSocketFactory(wrapper);
460
* This creates a fully custom SSL socket factory using this object's configuration.
462
* @param wrapper the wrapper where the created factory will be stored
464
* @return the wrapper with the new factory stored in it
466
* @throws IOException
468
protected SocketFactory createCustomSocketFactory(CustomSSLSocketFactory wrapper) throws IOException
470
if (sslContextSocketFactory == null)
472
createSocketFactorySSLContext();
473
initializeSocketFactorySSLContext();
476
SocketFactory sf = sslContextSocketFactory.getSocketFactory();
478
wrapper.setFactory((SSLSocketFactory) sf);
485
* @see org.jboss.remoting.security.SSLSocketBuilderMBean#getServerSocketFactorySSLContext()
487
public SSLContext getServerSocketFactorySSLContext()
489
return sslContextServerSocketFactory;
493
* @see org.jboss.remoting.security.SSLSocketBuilderMBean#getSocketFactorySSLContext()
495
public SSLContext getSocketFactorySSLContext()
497
return sslContextSocketFactory;
501
* @see org.jboss.remoting.security.SSLSocketBuilderMBean#getSecureSocketProtocol()
503
public String getSecureSocketProtocol()
505
if (secureSocketProtocol == null)
509
secureSocketProtocol = (String) config.get(REMOTING_SSL_PROTOCOL);
511
if (secureSocketProtocol == null)
513
secureSocketProtocol = DEFAULT_SSL_PROTOCOL;
517
return secureSocketProtocol;
521
* @see org.jboss.remoting.security.SSLSocketBuilderMBean#setSecureSocketProtocol(String)
523
public void setSecureSocketProtocol(String protocol)
525
if(protocol != null && protocol.length() > 0)
527
this.secureSocketProtocol = protocol;
531
throw new IllegalArgumentException("Can not set remoting socket factory with null protocol");
536
* @see org.jboss.remoting.security.SSLSocketBuilderMBean#getProvider()
538
public Provider getProvider()
544
* @see org.jboss.remoting.security.SSLSocketBuilderMBean#setProvider(java.security.Provider)
546
public void setProvider(Provider provider)
548
this.provider = provider;
552
* @see org.jboss.remoting.security.SSLSocketBuilderMBean#getProviderName()
554
public String getProviderName()
556
if (providerName == null)
560
providerName = (String) config.get(REMOTING_SSL_PROVIDER_NAME);
567
* @see org.jboss.remoting.security.SSLSocketBuilderMBean#setProviderName(java.lang.String)
569
public void setProviderName(String providerName)
571
this.providerName = providerName;
575
* @see org.jboss.remoting.security.SSLSocketBuilderMBean#getSecureRandom()
577
public SecureRandom getSecureRandom()
579
if(secureRandom != null)
584
secureRandom = new SecureRandom();
590
* @see org.jboss.remoting.security.SSLSocketBuilderMBean#setSecureRandom(java.security.SecureRandom)
592
public void setSecureRandom(SecureRandom secureRandom)
594
this.secureRandom = secureRandom;
598
* @see org.jboss.remoting.security.SSLSocketBuilderMBean#getKeyStoreURL()
600
public String getKeyStoreURL()
602
URL keyStore = getKeyStore();
605
return keyStore.toString();
614
* @see org.jboss.remoting.security.SSLSocketBuilderMBean#getKeyStore()
616
public URL getKeyStore()
618
if(keyStoreFilePath != null)
620
return keyStoreFilePath;
625
String path = (String) config.get(REMOTING_KEY_STORE_FILE_PATH);
626
if(path != null && path.length() > 0)
628
setKeyStoreURL( path );
632
if(keyStoreFilePath == null)
634
String path = getSystemProperty(STANDARD_KEY_STORE_FILE_PATH);;
635
if(path != null && path.length() > 0)
637
setKeyStoreURL( path );
641
return keyStoreFilePath;
645
* @see org.jboss.remoting.security.SSLSocketBuilderMBean#setKeyStoreURL(java.lang.String)
647
public void setKeyStoreURL(String keyStoreFilePath)
651
this.keyStoreFilePath = validateStoreURL(keyStoreFilePath);
653
catch (IOException e)
655
throw new RuntimeException( "Cannot validate the store URL: " + keyStoreFilePath , e );
660
* @see org.jboss.remoting.security.SSLSocketBuilderMBean#setKeyStore(java.net.URL)
662
public void setKeyStore(URL keyStore)
664
this.keyStoreFilePath = keyStore;
668
* @see org.jboss.remoting.security.SSLSocketBuilderMBean#getKeyStoreType()
670
public String getKeyStoreType()
672
if(keyStoreType != null)
679
String type = (String)config.get(REMOTING_KEY_STORE_TYPE);
680
if(type != null && type.length() > 0)
686
if(keyStoreType == null)
688
keyStoreType = getSystemProperty(STANDARD_KEY_STORE_TYPE);
689
if(keyStoreType == null)
691
keyStoreType = DEFAULT_KEY_STORE_TYPE;
699
* @see org.jboss.remoting.security.SSLSocketBuilderMBean#setKeyStoreType(java.lang.String)
701
public void setKeyStoreType(String keyStoreType)
703
this.keyStoreType = keyStoreType;
707
* @see org.jboss.remoting.security.SSLSocketBuilderMBean#getKeyStoreAlgorithm()
709
public String getKeyStoreAlgorithm()
711
if(keyStoreAlgorithm != null)
713
return keyStoreAlgorithm;
718
String alg = (String)config.get(REMOTING_KEY_STORE_ALGORITHM);
719
if(alg != null && alg.length() > 0)
721
keyStoreAlgorithm = alg;
725
if(keyStoreAlgorithm == null)
727
keyStoreAlgorithm = DEFAULT_KEY_STORE_ALGORITHM;
730
return keyStoreAlgorithm;
734
* @see org.jboss.remoting.security.SSLSocketBuilderMBean#setKeyStoreAlgorithm(java.lang.String)
736
public void setKeyStoreAlgorithm(String algorithm)
738
this.keyStoreAlgorithm = algorithm;
742
* Returns the password used to gain access to the keystore.
744
* @return keystore password
746
public String getKeyStorePassword()
748
if(keyStorePassword != null)
750
return keyStorePassword;
755
String passwd = (String)config.get(REMOTING_KEY_STORE_PASSWORD);
756
if(passwd != null && passwd.length() > 0)
758
keyStorePassword = passwd;
762
if(keyStorePassword == null)
764
keyStorePassword = getSystemProperty(STANDARD_KEY_STORE_PASSWORD);
767
return keyStorePassword;
771
* @see org.jboss.remoting.security.SSLSocketBuilderMBean#setKeyStorePassword(java.lang.String)
773
public void setKeyStorePassword(String keyStorePassword)
775
this.keyStorePassword = keyStorePassword;
779
* @see org.jboss.remoting.security.SSLSocketBuilderMBean#getTrustStoreURL()
781
public String getTrustStoreURL()
783
URL trustStore = getTrustStore();
784
if(trustStore != null)
786
return trustStore.toString();
795
* @see org.jboss.remoting.security.SSLSocketBuilderMBean#getTrustStore()
797
public URL getTrustStore()
799
if(trustStoreFilePath != null)
801
return trustStoreFilePath;
806
String path = (String)config.get(REMOTING_TRUST_STORE_FILE_PATH);
807
if(path != null && path.length() > 0)
809
setTrustStoreURL( path );
813
if(trustStoreFilePath == null)
815
String path = getSystemProperty(STANDARD_TRUST_STORE_FILE_PATH);
816
if(path != null && path.length() > 0)
818
setTrustStoreURL( path );
822
return trustStoreFilePath;
826
* @see org.jboss.remoting.security.SSLSocketBuilderMBean#setTrustStore(java.net.URL)
828
public void setTrustStore(URL trustStore)
830
this.trustStoreFilePath = trustStore;
834
* @see org.jboss.remoting.security.SSLSocketBuilderMBean#setTrustStoreURL(java.lang.String)
836
public void setTrustStoreURL(String trustStoreFilePath)
840
this.trustStoreFilePath = validateStoreURL(trustStoreFilePath);
842
catch (IOException e)
844
throw new RuntimeException( "Cannot validate the store URL: " + trustStoreFilePath , e );
849
* @see org.jboss.remoting.security.SSLSocketBuilderMBean#getTrustStoreType()
851
public String getTrustStoreType()
853
if(trustStoreType != null)
855
return trustStoreType;
860
String type = (String)config.get(REMOTING_TRUST_STORE_TYPE);
861
if(type != null && type.length() > 0)
863
trustStoreType = type;
867
if(trustStoreType == null)
869
trustStoreType = getSystemProperty(STANDARD_TRUST_STORE_TYPE);
870
if(trustStoreType == null)
872
trustStoreType = getKeyStoreType();
876
return trustStoreType;
880
* @see org.jboss.remoting.security.SSLSocketBuilderMBean#setTrustStoreType(java.lang.String)
882
public void setTrustStoreType(String trustStoreType)
884
this.trustStoreType = trustStoreType;
888
* @see org.jboss.remoting.security.SSLSocketBuilderMBean#getTrustStoreAlgorithm()
890
public String getTrustStoreAlgorithm()
892
if(trustStoreAlgorithm != null)
894
return trustStoreAlgorithm;
899
String alg = (String)config.get(REMOTING_TRUST_STORE_ALGORITHM);
900
if(alg != null && alg.length() > 0)
902
trustStoreAlgorithm = alg;
906
if(trustStoreAlgorithm == null)
908
trustStoreAlgorithm = getKeyStoreAlgorithm();
911
return trustStoreAlgorithm;
915
* @see org.jboss.remoting.security.SSLSocketBuilderMBean#setTrustStoreAlgorithm(java.lang.String)
917
public void setTrustStoreAlgorithm(String algorithm)
919
this.trustStoreAlgorithm = algorithm;
923
* Returns the password used to gain access to the truststore.
925
* @return truststore password
927
public String getTrustStorePassword()
929
if(trustStorePassword != null)
931
return trustStorePassword;
936
String passwd = (String)config.get(REMOTING_TRUST_STORE_PASSWORD);
937
if(passwd != null && passwd.length() > 0)
939
trustStorePassword = passwd;
943
if(trustStorePassword == null)
945
trustStorePassword = getSystemProperty(STANDARD_TRUST_STORE_PASSWORD);
946
if(trustStorePassword == null)
948
trustStorePassword = getKeyStorePassword();
952
return trustStorePassword;
956
* @see org.jboss.remoting.security.SSLSocketBuilderMBean#setTrustStorePassword(java.lang.String)
958
public void setTrustStorePassword(String trustStorePassword)
960
this.trustStorePassword = trustStorePassword;
964
* @see org.jboss.remoting.security.SSLSocketBuilderMBean#getKeyAlias()
966
public String getKeyAlias()
974
keyAlias = (String)config.get(REMOTING_KEY_ALIAS);
980
* @see org.jboss.remoting.security.SSLSocketBuilderMBean#setKeyAlias(java.lang.String)
982
public void setKeyAlias(String alias)
984
this.keyAlias = alias;
988
* Returns the password to use for the keys within the key store.
989
* If this value is not set, this will return <code>null</code> but
990
* when this value is needed by this class, the value for the key store
991
* password will be used instead.
993
* @return key password
995
public String getKeyPassword()
997
if(keyPassword != null)
1004
String passwd = (String)config.get(REMOTING_KEY_PASSWORD);
1005
if(passwd != null && passwd.length() > 0)
1007
keyPassword = passwd;
1015
* @see org.jboss.remoting.security.SSLSocketBuilderMBean#setKeyPassword(java.lang.String)
1017
public void setKeyPassword(String keyPassword)
1019
this.keyPassword = keyPassword;
1023
* @see org.jboss.remoting.security.SSLSocketBuilderMBean#isSocketUseClientMode()
1025
public boolean isSocketUseClientMode( )
1027
if (socketUseClientMode == null)
1029
if (config != null && config.containsKey(REMOTING_SOCKET_USE_CLIENT_MODE))
1031
socketUseClientMode = Boolean.valueOf((String) config.get(REMOTING_SOCKET_USE_CLIENT_MODE));
1035
socketUseClientMode = Boolean.TRUE;
1039
return socketUseClientMode.booleanValue();
1043
* @see org.jboss.remoting.security.SSLSocketBuilderMBean#isServerSocketUseClientMode()
1045
public boolean isServerSocketUseClientMode( )
1047
if (serverSocketUseClientMode == null)
1049
if (config != null && config.containsKey(REMOTING_SERVER_SOCKET_USE_CLIENT_MODE))
1051
serverSocketUseClientMode = Boolean.valueOf((String) config.get(REMOTING_SERVER_SOCKET_USE_CLIENT_MODE));
1055
serverSocketUseClientMode = Boolean.FALSE;
1059
return serverSocketUseClientMode.booleanValue();
1063
* @see org.jboss.remoting.security.SSLSocketBuilderMBean#setSocketUseClientMode(boolean)
1065
public void setSocketUseClientMode( boolean useClientMode )
1067
this.socketUseClientMode = Boolean.valueOf(useClientMode);
1071
* @see org.jboss.remoting.security.SSLSocketBuilderMBean#setServerSocketUseClientMode(boolean)
1073
public void setServerSocketUseClientMode( boolean useClientMode )
1075
this.serverSocketUseClientMode = Boolean.valueOf(useClientMode);
1079
* @see org.jboss.remoting.security.SSLSocketBuilderMBean#isClientAuthModeNone()
1081
public boolean isClientAuthModeNone()
1083
return CLIENT_AUTH_MODE_NONE.equals(getClientAuthMode());
1087
* @see org.jboss.remoting.security.SSLSocketBuilderMBean#isClientAuthModeWant()
1089
public boolean isClientAuthModeWant()
1091
return CLIENT_AUTH_MODE_WANT.equals(getClientAuthMode());
1095
* @see org.jboss.remoting.security.SSLSocketBuilderMBean#isClientAuthModeNeed()
1097
public boolean isClientAuthModeNeed()
1099
return CLIENT_AUTH_MODE_NEED.equals(getClientAuthMode());
1103
* @see org.jboss.remoting.security.SSLSocketBuilderMBean#getClientAuthMode()
1105
public String getClientAuthMode()
1107
if (clientAuthMode == null)
1109
if (config != null && config.containsKey(REMOTING_CLIENT_AUTH_MODE))
1111
setClientAuthMode( (String) config.get(REMOTING_CLIENT_AUTH_MODE) );
1115
clientAuthMode = CLIENT_AUTH_MODE_NONE;
1119
return clientAuthMode;
1123
* @see org.jboss.remoting.security.SSLSocketBuilderMBean#setClientAuthMode(java.lang.String)
1125
public void setClientAuthMode(String mode)
1127
if ( mode == null ||
1128
(!mode.equalsIgnoreCase(CLIENT_AUTH_MODE_NONE)
1129
&& !mode.equalsIgnoreCase(CLIENT_AUTH_MODE_WANT)
1130
&& !mode.equalsIgnoreCase(CLIENT_AUTH_MODE_NEED)))
1132
log.warn("Client authentication mode is invalid [" + mode + "]; falling back to NEED mode");
1133
clientAuthMode = CLIENT_AUTH_MODE_NEED;
1137
clientAuthMode = mode;
1144
* @see org.jboss.remoting.security.SSLSocketBuilderMBean#isServerAuthMode()
1146
public boolean isServerAuthMode()
1148
if (serverAuthMode == null)
1150
if (config != null && config.containsKey(REMOTING_SERVER_AUTH_MODE))
1152
serverAuthMode = Boolean.valueOf( (String) config.get(REMOTING_SERVER_AUTH_MODE) );
1156
serverAuthMode = Boolean.TRUE;
1160
return serverAuthMode.booleanValue();
1164
* @see org.jboss.remoting.security.SSLSocketBuilderMBean#setServerAuthMode(boolean)
1166
public void setServerAuthMode(boolean mode)
1168
serverAuthMode = Boolean.valueOf(mode);
1172
* Creates (but does not initialize) the SSL context used by this object
1173
* to create server socket factories.
1174
* The provider/protocol is used to determine what SSL context to use.
1175
* Call {@link #initializeServerSocketFactorySSLContext()} if you want
1176
* to create and initialize in one method call.
1177
* If the server socket factory SSL context was already created, this will create
1178
* a new one and remove the old one.
1180
* @throws IOException
1182
protected void createServerSocketFactorySSLContext()
1187
if(getProvider() != null)
1189
sslContextServerSocketFactory = SSLContext.getInstance(getSecureSocketProtocol(), getProvider());
1191
else if(getProviderName() != null)
1193
sslContextServerSocketFactory = SSLContext.getInstance(getSecureSocketProtocol(), getProviderName());
1197
sslContextServerSocketFactory = SSLContext.getInstance(getSecureSocketProtocol());
1202
IOException ioe = new IOException("Error creating server socket factory SSL context: " + e.getMessage());
1203
ioe.setStackTrace(e.getStackTrace());
1211
* Creates (but does not initialize) the SSL context used by this object
1212
* to create socket factories.
1213
* The provider/protocol is used to determine what SSL context to use.
1214
* Call {@link #initializeSocketFactorySSLContext()} if you want
1215
* to create and initialize in one method call.
1216
* If the socket factory SSL context was already created, this will create
1217
* a new one and remove the old one.
1219
* @throws IOException
1221
protected void createSocketFactorySSLContext()
1226
if(getProvider() != null)
1228
sslContextSocketFactory = SSLContext.getInstance(getSecureSocketProtocol(), getProvider());
1230
else if(getProviderName() != null)
1232
sslContextSocketFactory = SSLContext.getInstance(getSecureSocketProtocol(), getProviderName());
1236
sslContextSocketFactory = SSLContext.getInstance(getSecureSocketProtocol());
1241
IOException ioe = new IOException("Error creating socket factory SSL context: " + e.getMessage());
1242
ioe.setStackTrace(e.getStackTrace());
1250
* Initializes the SSL context used by this object that will create the server socket factories.
1251
* If the SSL context is not yet created, this method will also create it.
1252
* The provider/protocol is used to determine what SSL context to use. Key and trust managers
1253
* are loaded and a secure random object is created and the SSL context for the
1254
* protocol/provider is initialized with them.
1256
* @throws IOException
1258
protected void initializeServerSocketFactorySSLContext()
1263
if (sslContextServerSocketFactory == null)
1265
createServerSocketFactorySSLContext();
1270
keyManagers = loadKeyManagers();
1272
catch (NullStoreURLException e)
1274
if (isServerSocketUseClientMode())
1277
log.debug("Could not find keytore url. " + e.getMessage());
1281
// because this ssl context will create server socket factories, will throw if can not find keystore
1282
IOException ioe = new IOException("Can not find keystore url.");
1290
boolean isClientMode = isServerSocketUseClientMode();
1291
trustManagers = loadTrustManagers(isClientMode);
1293
catch (NullStoreURLException e)
1295
trustManagers = null;
1296
log.debug("Could not find truststore url. " + e.getMessage());
1299
secureRandom = getSecureRandom();
1301
sslContextServerSocketFactory.init(keyManagers, trustManagers, secureRandom);
1305
IOException ioe = new IOException("Error initializing server socket factory SSL context: " + e.getMessage());
1306
ioe.setStackTrace(e.getStackTrace());
1314
* Initializes the SSL context used by this object that will create the socket factories.
1315
* If the SSL context is not yet created, this method will also create it.
1316
* The provider/protocol is used to determine what SSL context to use. Key and trust managers
1317
* are loaded and a secure random object is created and the SSL context for the
1318
* protocol/provider is initialized with them.
1320
* @throws IOException
1322
protected void initializeSocketFactorySSLContext()
1327
if (sslContextSocketFactory == null)
1329
createSocketFactorySSLContext();
1334
keyManagers = loadKeyManagers();
1336
catch (NullStoreURLException e)
1338
if (isSocketUseClientMode())
1340
// this is allowable since would be the normal scenario
1342
log.debug("Could not find keystore url. " + e.getMessage());
1346
IOException ioe = new IOException("Can not find keystore url.");
1354
boolean isClientMode = isSocketUseClientMode();
1355
trustManagers = loadTrustManagers(isClientMode);
1357
catch (NullStoreURLException e)
1359
// If the keyManagers is not null, could possibly be using in client mode
1360
// so want to allow it. Otherwise, need to throw exception as will not be able
1361
// to use in client mode or not
1362
if(keyManagers != null)
1364
trustManagers = null;
1365
log.debug("Could not find truststore url. " + e.getMessage());
1369
IOException ioe = new IOException("Can not find truststore url.");
1375
secureRandom = getSecureRandom();
1377
sslContextSocketFactory.init(keyManagers, trustManagers, secureRandom);
1381
IOException ioe = new IOException("Error initializing socket factory SSL context: " + e.getMessage());
1382
ioe.setStackTrace(e.getStackTrace());
1390
* Loads the trust managers based on this object's truststore.
1392
* @return array of trust managers that should be loaded in this object's SSL context
1394
* @throws NoSuchProviderException
1395
* @throws NoSuchAlgorithmException
1396
* @throws IOException
1397
* @throws CertificateException
1398
* @throws KeyStoreException
1399
* @throws NullStoreURLException
1401
protected TrustManager[] loadTrustManagers(boolean isClientMode)
1402
throws NoSuchProviderException, NoSuchAlgorithmException, IOException, CertificateException, KeyStoreException, NullStoreURLException
1404
if(isClientMode && !isServerAuthMode())
1406
// we are in client mode and do not want to perform server cert authentication
1407
// return a trust manager that trusts all certs
1408
trustManagers = new TrustManager[] {
1409
new X509TrustManager() {
1410
public void checkClientTrusted( X509Certificate[] chain, String authType ) {}
1411
public void checkServerTrusted( X509Certificate[] chain, String authType ) {}
1412
public X509Certificate[] getAcceptedIssuers() { return null; }
1417
String tsType = getTrustStoreType();
1418
String tsPasswd = getTrustStorePassword();
1419
URL tsPathURL = getTrustStore();
1421
String tsAlg = getTrustStoreAlgorithm();
1423
TrustManagerFactory trustMgrFactory;
1424
KeyStore trustStore = loadKeyStore(tsType, tsPathURL, tsPasswd);
1426
if (getProvider() != null)
1428
trustMgrFactory = TrustManagerFactory.getInstance(tsAlg, getProvider());
1430
else if (getProviderName() != null)
1432
trustMgrFactory = TrustManagerFactory.getInstance(tsAlg, getProviderName());
1436
trustMgrFactory = TrustManagerFactory.getInstance(tsAlg);
1439
if (trustStore != null)
1441
trustMgrFactory.init(trustStore);
1443
trustManagers = trustMgrFactory.getTrustManagers();
1447
return trustManagers;
1451
* Loads the key managers based on this object's truststore.
1453
* @return array of key managers that should be loaded in this object's SSL context
1455
* @throws NoSuchProviderException
1456
* @throws NoSuchAlgorithmException
1457
* @throws IOException
1458
* @throws CertificateException
1459
* @throws KeyStoreException
1460
* @throws UnrecoverableKeyException
1461
* @throws NullStoreURLException
1463
protected KeyManager[] loadKeyManagers()
1464
throws NoSuchProviderException, NoSuchAlgorithmException, IOException, CertificateException,
1465
KeyStoreException, UnrecoverableKeyException, NullStoreURLException
1467
String ksPasswd = getKeyStorePassword();
1468
String ksType = getKeyStoreType();
1469
URL ksPathURL = getKeyStore();
1471
KeyStore keyStore = loadKeyStore(ksType, ksPathURL, ksPasswd);
1473
if(keyStore != null)
1475
String alias = getKeyAlias();
1477
// check that keystore contains supplied alias (if there is one)
1480
boolean containsAlias = keyStore.isKeyEntry(alias);
1483
// can not continue as supplied alias does not exist as key entry
1484
throw new IOException("Can not find key entry for key store (" + ksPathURL + ") with given alias (" + alias + ")");
1488
KeyManagerFactory keyMgrFactory = null;
1489
String alg = getKeyStoreAlgorithm();
1491
if(getProvider() != null)
1493
keyMgrFactory = KeyManagerFactory.getInstance(alg, getProvider());
1495
else if(getProviderName() != null)
1497
keyMgrFactory = KeyManagerFactory.getInstance(alg, getProviderName());
1501
keyMgrFactory = KeyManagerFactory.getInstance(alg);
1504
// get they key password, if it isn't defined, use the key store password
1505
String keyPasswd = getKeyPassword();
1506
if (keyPasswd == null || keyPasswd.length() == 0)
1508
keyPasswd = ksPasswd;
1511
char[] keyPasswdCharArray = keyPasswd == null ? null : keyPasswd.toCharArray();
1512
keyMgrFactory.init(keyStore, keyPasswdCharArray);
1513
keyManagers = keyMgrFactory.getKeyManagers();
1515
// if alias provided, use helper impl to hard wire alias name to be used
1518
//TODO: -TME Need careful review of if this is really needed or not.
1519
for(int x = 0; x < keyManagers.length; x++)
1521
keyManagers[x] = new RemotingKeyManager((X509KeyManager)keyManagers[x], alias);
1530
* Loads a key store file and returns it.
1532
* @param storeType the type of store file
1533
* @param storePathURL the URL to the file - may be relative to the current thread's classloader
1534
* or may be absolute path to a file on the file system.
1535
* @param storePassword password to gain access to the store file
1537
* @return the key store
1539
* @throws KeyStoreException
1540
* @throws NoSuchProviderException
1541
* @throws IOException
1542
* @throws NoSuchAlgorithmException
1543
* @throws CertificateException
1544
* @throws NullStoreURLException
1546
protected KeyStore loadKeyStore(String storeType, URL storePathURL, String storePassword)
1547
throws KeyStoreException, NoSuchProviderException, IOException, NoSuchAlgorithmException, CertificateException, NullStoreURLException
1549
KeyStore keyStore = null;
1551
if(getProvider() != null)
1553
keyStore = KeyStore.getInstance(storeType, getProvider());
1555
else if(getProviderName() != null)
1557
keyStore = KeyStore.getInstance(storeType, getProviderName());
1561
keyStore = KeyStore.getInstance(storeType);
1564
if ( storePathURL == null )
1566
throw new NullStoreURLException("Can not find store file for url because store url is null.");
1569
URL url = storePathURL == NONE_STORE_URL ? null : storePathURL;
1571
// now that keystore instance created, need to load data from file
1572
InputStream keyStoreInputStream = null;
1578
keyStoreInputStream = url.openStream();
1581
// is ok for password to be null, as will just be used to check integrity of store
1582
char[] password = storePassword != null ? storePassword.toCharArray() : null;
1583
keyStore.load(keyStoreInputStream, password);
1587
if(keyStoreInputStream != null)
1591
keyStoreInputStream.close();
1593
catch(IOException e)
1597
keyStoreInputStream = null;
1605
* Given a store file path, this will verify that the store actually exists.
1606
* First, it checks to see if its a valid URL, then it checks to see if the
1607
* file path is found in the file system and finally will be checked to see
1608
* if it can be found as a resource within the current thread's classloader.
1609
* An exception is thrown if the store cannot be found.
1611
* @param storePath the path which can be a URL, path to a resource in classloader
1612
* or a file path on the file system.
1614
* @return the URL of the file that was found
1616
* @throws IOException if the store could not be found
1618
protected URL validateStoreURL(String storePath) throws IOException
1620
if (NONE_STORE.equals(storePath))
1622
return NONE_STORE_URL;
1627
// First see if this is a URL
1630
url = new URL(storePath);
1632
catch(MalformedURLException e)
1634
// Not a URL or a protocol without a handler so...
1635
// next try to locate this as file path
1636
final File tst = new File(storePath);
1637
Boolean exists = (Boolean) AccessController.doPrivileged( new PrivilegedAction()
1641
return new Boolean(tst.exists());
1645
if(exists.booleanValue())
1651
// not a file either, lastly try to locate this as a classpath resource
1654
ClassLoader loader = (ClassLoader) AccessController.doPrivileged( new PrivilegedAction()
1658
return Thread.currentThread().getContextClassLoader();
1661
url = loader.getResource(storePath);
1666
// Fail if no valid key store was located
1669
String msg = "Failed to find url=" + storePath + " as a URL, file or resource";
1670
throw new MalformedURLException(msg);
1676
public Object clone()
1680
return super.clone();
1682
catch (CloneNotSupportedException e)
1688
//*******************************************************************
1690
// The following are just needed in order to make it a service mbean.
1691
// They are just NOOPs (no implementation).
1692
//*******************************************************************
1695
* @see org.jboss.remoting.security.SSLSocketBuilderMBean#create()
1697
public void create() throws Exception
1703
* @see org.jboss.remoting.security.SSLSocketBuilderMBean#start()
1705
public void start() throws Exception
1711
* @see org.jboss.remoting.security.SSLSocketBuilderMBean#stop()
1719
* @see org.jboss.remoting.security.SSLSocketBuilderMBean#destroy()
1721
public void destroy()
1726
//*******************************************************************
1728
//*******************************************************************
1731
* Used to indicate a store URL was not specified and thus the store is not available.
1733
protected class NullStoreURLException extends Exception
1735
private static final long serialVersionUID = 1L;
1738
* @see Exception#Exception(String)
1740
public NullStoreURLException(String message)
1746
static private String getSystemProperty(final String name)
1748
if (SecurityUtility.skipAccessControl())
1749
return System.getProperty(name);
1751
String value = null;
1754
value = (String)AccessController.doPrivileged( new PrivilegedExceptionAction()
1756
public Object run() throws Exception
1758
return System.getProperty(name);
1762
catch (PrivilegedActionException e)
1764
throw (RuntimeException) e.getCause();
1770
static private Method getMethod(final Class c, final String name, final Class[] parameterTypes)
1771
throws NoSuchMethodException
1773
if (SecurityUtility.skipAccessControl())
1775
return c.getMethod(name, parameterTypes);
1780
return (Method) AccessController.doPrivileged( new PrivilegedExceptionAction()
1782
public Object run() throws NoSuchMethodException
1784
return c.getMethod(name, parameterTypes);
1788
catch (PrivilegedActionException e)
1790
throw (NoSuchMethodException) e.getCause();
b'\\ No newline at end of file'