KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > slamd > example > JSSEBlindTrustSocketFactory


1 /*
2  * Sun Public License
3  *
4  * The contents of this file are subject to the Sun Public License Version
5  * 1.0 (the "License"). You may not use this file except in compliance with
6  * the License. A copy of the License is available at http://www.sun.com/
7  *
8  * The Original Code is the SLAMD Distributed Load Generation Engine.
9  * The Initial Developer of the Original Code is Neil A. Wilson.
10  * Portions created by Neil A. Wilson are Copyright (C) 2004-2005.
11  * Some preexisting portions Copyright (C) 2002-2005 Sun Microsystems, Inc.
12  * All Rights Reserved.
13  *
14  * Contributor(s): Neil A. Wilson
15  */

16 package com.sun.slamd.example;
17
18
19
20 import java.io.*;
21 import java.net.*;
22 import java.security.*;
23 import java.security.cert.*;
24 import javax.net.ssl.*;
25 import netscape.ldap.*;
26
27
28
29 /**
30  * This class provides an implementation of an SSL socket factory that will use
31  * JSSE to create the SSL socket. In addition, it will implement a trust
32  * mechanism in such a way that it will blindly trust any certificate that the
33  * server presents to it, regardless of what we might think is wrong with it.
34  *
35  *
36  * @author Neil A. Wilson
37  */

38 public class JSSEBlindTrustSocketFactory
39        extends SSLSocketFactory
40        implements LDAPSocketFactory, X509TrustManager
41 {
42   // Indicates whether debug mode will be enabled (will print a message to
43
// standard error whenever any method is called).
44
boolean debugMode;
45
46   // Indicates whether the SSL session should be immediately invalidated to
47
// prevent session reuse.
48
boolean disableSessionReuse;
49
50   // The SSL context that will be used to manage all things SSL.
51
SSLContext sslContext;
52
53   // The SSL socket factory that will actually be used to create the sockets.
54
SSLSocketFactory sslSocketFactory;
55
56   // The set cipher names that should be used when creating sockets.
57
String JavaDoc[] cipherNames;
58
59
60
61   /**
62    * Creates a new instance of this LDAP socket factory.
63    *
64    * @throws LDAPException If a problem occurs while initializing this socket
65    * factory.
66    */

67   public JSSEBlindTrustSocketFactory()
68          throws LDAPException
69   {
70     this(false);
71   }
72
73
74
75   /**
76    * Creates a new instance of this LDAP socket factory, optionally operating in
77    * debug mode.
78    *
79    * @param debugMode Indicates whether to operate in debug mode. If this is
80    * enabled, a message will be printed to standard error
81    * any time of of the methods of this class is called.
82    *
83    * @throws LDAPException If a problem occurs while initializing this socket
84    * factory.
85    */

86   public JSSEBlindTrustSocketFactory(boolean debugMode)
87          throws LDAPException
88   {
89     this.debugMode = debugMode;
90
91
92     // Indicate that we will be using JSSE for the SSL-based connections.
93
Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
94     System.setProperty("java.protocol.handler.pkgs",
95                        "com.sun.net.ssl.internal.www.protocol");
96
97
98     // Get the default SSL context.
99
try
100     {
101       sslContext = SSLContext.getInstance("SSLv3");
102     }
103     catch (NoSuchAlgorithmException nsae)
104     {
105       throw new LDAPException("Unable to initialize the SSL context: " + nsae);
106     }
107
108
109     // Initialize the SSL context with our own trust manager (this class) to
110
// use when determining whether to trust a client certificate.
111
try
112     {
113       sslContext.init(null, new TrustManager[] { this }, null);
114     }
115     catch (KeyManagementException kme)
116     {
117       throw new LDAPException("Unable to register a new trust manager with " +
118                               "the SSL context: " + kme);
119     }
120
121
122     // Get the socket factory to use when creating the certificates.
123
sslSocketFactory = sslContext.getSocketFactory();
124
125
126     // Set the values of the remaining instance variables.
127
disableSessionReuse = false;
128     cipherNames = sslSocketFactory.getDefaultCipherSuites();
129
130
131     // If we are in debug mode, indicate that the socket factory has been
132
// created.
133
if (debugMode)
134     {
135       System.err.println("New JSSEBlindTrustSocketFactory created");
136     }
137   }
138
139
140
141   /**
142    * Determines whether the provided client certificate should be trusted. In
143    * this case, the certificate will always be trusted.
144    *
145    * @param chain The peer certificate chain.
146    * @param authType The authentication type based on the client certificate.
147    */

148   public void checkClientTrusted(X509Certificate[] chain, String JavaDoc authType)
149   {
150     // No implementation required. If we don't throw an exception, then there
151
// is no problem with the cert.
152
if (debugMode)
153     {
154       System.err.println("checkClientTrusted() invoked");
155     }
156   }
157
158
159
160   /**
161    * Determines whether the provided server certificate should be trusted. In
162    * this case, the certificate will always be trusted.
163    *
164    * @param chain The peer certificate chain.
165    * @param authType The authentication type based on the server certificate.
166    */

167   public void checkServerTrusted(X509Certificate[] chain, String JavaDoc authType)
168   {
169     // No implementation required. If we don't throw an exception, then there
170
// is no problem with the cert.
171
if (debugMode)
172     {
173       System.err.println("checkServerTrusted() invoked");
174     }
175   }
176
177
178
179   /**
180    * Retrieves an array of CA certificates that are trusted for authenticating
181    * peers.
182    *
183    * @return An empty array, because we don't care about any list of CAs.
184    */

185   public X509Certificate[] getAcceptedIssuers()
186   {
187     if (debugMode)
188     {
189       System.err.println("getAcceptedIssuers() invoked");
190     }
191
192     return new X509Certificate[0];
193   }
194
195
196
197   /**
198    * Establishes an SSL socket to the provided host and port that can be used by
199    * the LDAP SDK for Java for communicating with an LDAP directory server.
200    *
201    * @param host The address of the server to which the connection is to be
202    * established.
203    * @param port The port number of the server to which the connection is to
204    * be established.
205    *
206    * @return The SSL socket that may be used for communicating with the
207    * directory server.
208    *
209    * @throws LDAPException If a problem occurs while trying to establish the
210    * connection.
211    */

212   public Socket makeSocket(String JavaDoc host, int port)
213          throws LDAPException
214   {
215     if (debugMode)
216     {
217       System.err.println("makeSocket(" + host + "," + port + ") invoked");
218     }
219
220     try
221     {
222       SSLSocket s = (SSLSocket) sslSocketFactory.createSocket(host, port);
223       s.setEnabledCipherSuites(cipherNames);
224
225       if (disableSessionReuse)
226       {
227         s.getSession().invalidate();
228       }
229
230       return s;
231     }
232     catch (Exception JavaDoc e)
233     {
234       throw new LDAPException("Unable to establish the SSL connection: " + e);
235     }
236   }
237
238
239
240   /**
241    * Creates a new SSL socket connected to the specified host and port.
242    *
243    * @param host The address of the system to which the SSL socket should be
244    * connected.
245    * @param port The port on the target system to which the SSL socket should
246    * be connected.
247    *
248    * @throws IOException If a problem occurs while creating the SSL socket.
249    */

250   public Socket createSocket(String JavaDoc host, int port)
251          throws IOException
252   {
253     SSLSocket s = (SSLSocket) sslSocketFactory.createSocket(host, port);
254     s.setEnabledCipherSuites(cipherNames);
255
256     if (disableSessionReuse)
257     {
258       s.getSession().invalidate();
259     }
260
261     return s;
262   }
263
264
265
266   /**
267    * Creates a new SSL socket connected to the specified host and port.
268    *
269    * @param host The address of the system to which the SSL socket should
270    * be connected.
271    * @param port The port on the target system to which the SSL socket
272    * should be connected.
273    * @param localHost The address on the local system from which the socket
274    * should originate.
275    * @param localPort The port on the local system from which the socket
276    * should originate.
277    *
278    * @throws IOException If a problem occurs while creating the SSL socket.
279    */

280   public Socket createSocket(String JavaDoc host, int port, InetAddress localHost,
281                              int localPort)
282          throws IOException
283   {
284     SSLSocket s = (SSLSocket) sslSocketFactory.createSocket(host, port,
285                                                             localHost,
286                                                             localPort);
287     s.setEnabledCipherSuites(cipherNames);
288
289     if (disableSessionReuse)
290     {
291       s.getSession().invalidate();
292     }
293
294     return s;
295   }
296
297
298
299   /**
300    * Creates a new SSL socket connected to the specified host and port.
301    *
302    * @param host The address of the system to which the SSL socket should be
303    * connected.
304    * @param port The port on the target system to which the SSL socket should
305    * be connected.
306    *
307    * @throws IOException If a problem occurs while creating the SSL socket.
308    */

309   public Socket createSocket(InetAddress host, int port)
310          throws IOException
311   {
312     SSLSocket s = (SSLSocket) sslSocketFactory.createSocket(host, port);
313     s.setEnabledCipherSuites(cipherNames);
314
315     if (disableSessionReuse)
316     {
317       s.getSession().invalidate();
318     }
319
320     return s;
321   }
322
323
324
325   /**
326    * Creates a new SSL socket connected to the specified host and port.
327    *
328    * @param host The address of the system to which the SSL socket
329    * should be connected.
330    * @param port The port on the target system to which the SSL socket
331    * should be connected.
332    * @param localAddress The address on the local system from which the socket
333    * should originate.
334    * @param localPort The port on the local system from which the socket
335    * should originate.
336    *
337    * @throws IOException If a problem occurs while creating the SSL socket.
338    */

339   public Socket createSocket(InetAddress host, int port,
340                              InetAddress localAddress, int localPort)
341          throws IOException
342   {
343     SSLSocket s = (SSLSocket) sslSocketFactory.createSocket(host, port,
344                                                             localAddress,
345                                                             localPort);
346     s.setEnabledCipherSuites(cipherNames);
347
348     if (disableSessionReuse)
349     {
350       s.getSession().invalidate();
351     }
352
353     return s;
354   }
355
356
357
358   /**
359    * Converts the provided socket to an SSL socket using this socket factory.
360    *
361    * @param socket The socket to convert to an SSL socket.
362    * @param host The host to which the socket is connected.
363    * @param port The port to which the socket is connected.
364    * @param autoClose Indicates whether the underlying socket should be closed
365    * when the returned SSL socket is closed.
366    *
367    * @throws IOException If a problem occurs while creating the SSL socket.
368    */

369   public Socket createSocket(Socket socket, String JavaDoc host, int port,
370                              boolean autoClose)
371          throws IOException
372   {
373     SSLSocket s = (SSLSocket) sslSocketFactory.createSocket(socket, host,
374                                                             port, autoClose);
375     s.setEnabledCipherSuites(cipherNames);
376
377     if (disableSessionReuse)
378     {
379       s.getSession().invalidate();
380     }
381
382     return s;
383   }
384
385
386
387   /**
388    * Retrieves the names of the ciphers that should be used for SSL sockets
389    * created by this socket factory.
390    *
391    * @return The names of the ciphers that should be used for SSL sockets
392    * created by this socket factory.
393    */

394   public String JavaDoc[] getCiphers()
395   {
396     return cipherNames;
397   }
398
399
400
401   /**
402    * Specifies the name of the cipher that should be used for SSL sockets
403    * created by this socket factory.
404    *
405    * @param cipherName The name of the cipher that should be used for SSL
406    * sockets created by this socket factory.
407    */

408   public void setCipher(String JavaDoc cipherName)
409   {
410     if (cipherName == null)
411     {
412       cipherNames = sslSocketFactory.getDefaultCipherSuites();
413     }
414     else
415     {
416       cipherNames = new String JavaDoc[] { cipherName };
417     }
418   }
419
420
421
422   /**
423    * Specifies the names of the cipher that should be used for SSL sockets
424    * created by this socket factory.
425    *
426    * @param cipherNames The names of the cipher that should be used for SSL
427    * sockets created by this socket factory.
428    */

429   public void setCiphers(String JavaDoc[] cipherNames)
430   {
431     if (cipherNames == null)
432     {
433       this.cipherNames = sslSocketFactory.getDefaultCipherSuites();
434     }
435     else
436     {
437       this.cipherNames = cipherNames;
438     }
439   }
440
441
442
443   /**
444    * Retrieves the set of cipher suites that are enabled by default.
445    *
446    * @return The set of cipher suites that are enabled by default.
447    */

448   public String JavaDoc[] getDefaultCipherSuites()
449   {
450     return cipherNames;
451   }
452
453
454
455   /**
456    * Retrieves the set of cipher suites that can be used to create SSL sockets.
457    *
458    * @return The set of cipher suites that can be used to create SSL sockets.
459    */

460   public String JavaDoc[] getSupportedCipherSuites()
461   {
462     return cipherNames;
463   }
464
465
466
467   /**
468    * Indicates whether SSL sessions may be reused across multiple connections.
469    *
470    * @return <CODE>true</CODE> if SSL sessions may be reused across multiple
471    * connections, or <CODE>false</CODE> if not.
472    */

473   public boolean getDisableSessionReuse()
474   {
475     return disableSessionReuse;
476   }
477
478
479
480   /**
481    * Specifies whether to disable SSL session reuse across multiple connections.
482    *
483    * @param disableSessionReuse Indicates whether to disable SSL session
484    * reuse across multiple connections.
485    */

486   public void setDisableSessionReuse(boolean disableSessionReuse)
487   {
488     this.disableSessionReuse = disableSessionReuse;
489   }
490 }
491
492
Popular Tags