KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javax > rmi > ssl > SslRMIClientSocketFactory


1 /*
2  * @(#)file SslRMIClientSocketFactory.java
3  * @(#)author Sun Microsystems, Inc.
4  * @(#)version 1.16
5  * @(#)date 04/06/01
6  *
7  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
8  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
9  */

10
11 package javax.rmi.ssl;
12
13 import java.io.IOException JavaDoc;
14 import java.io.Serializable JavaDoc;
15 import java.net.Socket JavaDoc;
16 import java.rmi.server.RMIClientSocketFactory JavaDoc;
17 import java.util.StringTokenizer JavaDoc;
18 import javax.net.SocketFactory;
19 import javax.net.ssl.SSLSocket;
20 import javax.net.ssl.SSLSocketFactory;
21
22 /**
23  * <p>An <code>SslRMIClientSocketFactory</code> instance is used by the RMI
24  * runtime in order to obtain client sockets for RMI calls via SSL.</p>
25  *
26  * <p>This class implements <code>RMIClientSocketFactory</code> over
27  * the Secure Sockets Layer (SSL) or Transport Layer Security (TLS)
28  * protocols.</p>
29  *
30  * <p>This class creates SSL sockets using the default
31  * <code>SSLSocketFactory</code> (see {@link
32  * SSLSocketFactory#getDefault}). All instances of this class are
33  * functionally equivalent. In particular, they all share the same
34  * truststore, and the same keystore when client authentication is
35  * required by the server. This behavior can be modified in
36  * subclasses by overriding the {@link #createSocket(String,int)}
37  * method; in that case, {@link #equals(Object) equals} and {@link
38  * #hashCode() hashCode} may also need to be overridden.</p>
39  *
40  * <p>If the system property
41  * <code>javax.rmi.ssl.client.enabledCipherSuites</code> is specified,
42  * the {@link #createSocket(String,int)} method will call {@link
43  * SSLSocket#setEnabledCipherSuites(String[])} before returning the
44  * socket. The value of this system property is a string that is a
45  * comma-separated list of SSL/TLS cipher suites to enable.</p>
46  *
47  * <p>If the system property
48  * <code>javax.rmi.ssl.client.enabledProtocols</code> is specified,
49  * the {@link #createSocket(String,int)} method will call {@link
50  * SSLSocket#setEnabledProtocols(String[])} before returning the
51  * socket. The value of this system property is a string that is a
52  * comma-separated list of SSL/TLS protocol versions to enable.</p>
53  *
54  * @see javax.net.ssl.SSLSocketFactory
55  * @see javax.rmi.ssl.SslRMIServerSocketFactory
56  * @since 1.5
57  */

58 public class SslRMIClientSocketFactory
59     implements RMIClientSocketFactory JavaDoc, Serializable JavaDoc {
60
61     /**
62      * <p>Creates a new <code>SslRMIClientSocketFactory</code>.</p>
63      */

64     public SslRMIClientSocketFactory() {
65         // We don't force the initialization of the default SSLSocketFactory
66
// at construction time - because the RMI client socket factory is
67
// created on the server side, where that initialization is a priori
68
// meaningless, unless both server and client run in the same JVM.
69
// We could possibly override readObject() to force this initialization,
70
// but it might not be a good idea to actually mix this with possible
71
// deserialization problems.
72
// So contrarily to what we do for the server side, the initialization
73
// of the SSLSocketFactory will be delayed until the first time
74
// createSocket() is called - note that the default SSLSocketFactory
75
// might already have been initialized anyway if someone in the JVM
76
// already called SSLSocketFactory.getDefault().
77
//
78
}
79
80     /**
81      * <p>Creates an SSL socket.</p>
82      *
83      * <p>If the system property
84      * <code>javax.rmi.ssl.client.enabledCipherSuites</code> is
85      * specified, this method will call {@link
86      * SSLSocket#setEnabledCipherSuites(String[])} before returning
87      * the socket. The value of this system property is a string that
88      * is a comma-separated list of SSL/TLS cipher suites to
89      * enable.</p>
90      *
91      * <p>If the system property
92      * <code>javax.rmi.ssl.client.enabledProtocols</code> is
93      * specified, this method will call {@link
94      * SSLSocket#setEnabledProtocols(String[])} before returning the
95      * socket. The value of this system property is a string that is a
96      * comma-separated list of SSL/TLS protocol versions to
97      * enable.</p>
98      */

99     public Socket JavaDoc createSocket(String JavaDoc host, int port) throws IOException JavaDoc {
100         // Retrieve the SSLSocketFactory
101
//
102
final SocketFactory JavaDoc sslSocketFactory = getDefaultClientSocketFactory();
103         // Create the SSLSocket
104
//
105
final SSLSocket sslSocket = (SSLSocket)
106             sslSocketFactory.createSocket(host, port);
107         // Set the SSLSocket Enabled Cipher Suites
108
//
109
final String JavaDoc enabledCipherSuites = (String JavaDoc)
110             System.getProperty("javax.rmi.ssl.client.enabledCipherSuites");
111         if (enabledCipherSuites != null) {
112             StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(enabledCipherSuites, ",");
113             int tokens = st.countTokens();
114             String JavaDoc enabledCipherSuitesList[] = new String JavaDoc[tokens];
115             for (int i = 0 ; i < tokens; i++) {
116                 enabledCipherSuitesList[i] = st.nextToken();
117             }
118         try {
119         sslSocket.setEnabledCipherSuites(enabledCipherSuitesList);
120         } catch (IllegalArgumentException JavaDoc e) {
121         throw (IOException JavaDoc)
122             new IOException JavaDoc(e.getMessage()).initCause(e);
123         }
124         }
125         // Set the SSLSocket Enabled Protocols
126
//
127
final String JavaDoc enabledProtocols = (String JavaDoc)
128             System.getProperty("javax.rmi.ssl.client.enabledProtocols");
129         if (enabledProtocols != null) {
130             StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(enabledProtocols, ",");
131             int tokens = st.countTokens();
132             String JavaDoc enabledProtocolsList[] = new String JavaDoc[tokens];
133             for (int i = 0 ; i < tokens; i++) {
134                 enabledProtocolsList[i] = st.nextToken();
135             }
136         try {
137         sslSocket.setEnabledProtocols(enabledProtocolsList);
138         } catch (IllegalArgumentException JavaDoc e) {
139         throw (IOException JavaDoc)
140             new IOException JavaDoc(e.getMessage()).initCause(e);
141         }
142         }
143         // Return the preconfigured SSLSocket
144
//
145
return sslSocket;
146     }
147
148     /**
149      * <p>Indicates whether some other object is "equal to" this one.</p>
150      *
151      * <p>Because all instances of this class are functionally equivalent
152      * (they all use the default
153      * <code>SSLSocketFactory</code>), this method simply returns
154      * <code>this.getClass().equals(obj.getClass())</code>.</p>
155      *
156      * <p>A subclass should override this method (as well
157      * as {@link #hashCode()}) if its instances are not all
158      * functionally equivalent.</p>
159      */

160     public boolean equals(Object JavaDoc obj) {
161         if (obj == null) return false;
162         if (obj == this) return true;
163         return this.getClass().equals(obj.getClass());
164     }
165
166     /**
167      * <p>Returns a hash code value for this
168      * <code>SslRMIClientSocketFactory</code>.</p>
169      *
170      * @return a hash code value for this
171      * <code>SslRMIClientSocketFactory</code>.
172      */

173     public int hashCode() {
174         return this.getClass().hashCode();
175     }
176
177     // We use a static field because:
178
//
179
// SSLSocketFactory.getDefault() always returns the same object
180
// (at least on Sun's implementation), and we want to make sure
181
// that the Javadoc & the implementation stay in sync.
182
//
183
// If someone needs to have different SslRMIClientSocketFactory factories
184
// with different underlying SSLSocketFactory objects using different key
185
// and trust stores, he can always do so by subclassing this class and
186
// overriding createSocket(String host, int port).
187
//
188
private static SocketFactory JavaDoc defaultSocketFactory = null;
189
190     private static synchronized SocketFactory JavaDoc getDefaultClientSocketFactory() {
191         if (defaultSocketFactory == null)
192             defaultSocketFactory = SSLSocketFactory.getDefault();
193         return defaultSocketFactory;
194     }
195
196     private static final long serialVersionUID = -8310631444933958385L;
197 }
198
Popular Tags