KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > axis > components > net > JSSE14SocketFactory


1 /*
2  * Copyright 1999-2004 The Apache Software Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.jboss.axis.components.net;
18
19 import java.io.File JavaDoc;
20 import java.io.FileInputStream JavaDoc;
21 import java.io.FileNotFoundException JavaDoc;
22 import java.io.IOException JavaDoc;
23 import java.io.InputStream JavaDoc;
24 import java.net.Socket JavaDoc;
25 import java.security.KeyStore JavaDoc;
26 import java.security.Principal JavaDoc;
27 import java.security.PrivateKey JavaDoc;
28 import java.security.SecureRandom JavaDoc;
29 import java.security.cert.X509Certificate JavaDoc;
30 import java.util.HashMap JavaDoc;
31 import java.util.Hashtable JavaDoc;
32
33 import javax.net.ssl.KeyManager;
34 import javax.net.ssl.KeyManagerFactory;
35 import javax.net.ssl.SSLContext;
36 import javax.net.ssl.TrustManager;
37 import javax.net.ssl.TrustManagerFactory;
38 import javax.net.ssl.X509KeyManager;
39
40 import org.jboss.logging.Logger;
41
42 /**
43  * SSL server socket factory. It _requires_ a valid RSA key and JSSE. This is
44  * derived from the tomcat source.
45  *
46  * @author Harish Prabandham
47  * @author Costin Manolache
48  * @author Stefan Freyr Stefansson
49  * @author EKR -- renamed to JSSESocketFactory
50  * @author Jan Luehe
51  * @author <a HREF="jason.greene@jboss.com">Jason T. Greene</a>
52  */

53 public class JSSE14SocketFactory extends JSSESocketFactory implements
54       SecureSocketFactory
55 {
56
57    private static Logger log = Logger.getLogger(JSSE14SocketFactory.class);
58
59    /**
60     * Field defaultkeyStoreType
61     */

62    static String JavaDoc defaultKeyStoreType = "JKS";
63
64    /**
65     * Field defaultProtocol
66     */

67    static String JavaDoc defaultProtocol = "TLS";
68
69    /**
70     * Field defaultAlgorithm
71     */

72    static String JavaDoc defaultAlgorithm = "SunX509";
73
74    /**
75     * Field defaultkeyStoreFile
76     */

77    static String JavaDoc defaultKeyStoreFile = System.getProperty("user.home")
78          + "/.keystore";
79
80    /**
81     * Field defaultKeyPass
82     */

83    static String JavaDoc defaultKeyStorePassword = "changeit";
84
85    /**
86     * Constructor JSSESocketFactory
87     *
88     * @param options
89     */

90    public JSSE14SocketFactory(HashMap JavaDoc options)
91    {
92       super((options == null) ? new HashMap JavaDoc() : options);
93    }
94
95    protected String JavaDoc getKeyStoreType()
96    {
97       String JavaDoc keyStoreType = (String JavaDoc)options.get("keyStoreType");
98       if (keyStoreType == null)
99          keyStoreType = System.getProperty("javax.net.ssl.keyStoreType");
100
101       if (keyStoreType == null)
102          keyStoreType = defaultKeyStoreType;
103
104       return keyStoreType;
105    }
106
107    protected String JavaDoc getTrustStorePassword()
108    {
109       String JavaDoc trustStorePassword = (String JavaDoc)options.get("trustStorePassword");
110       if (trustStorePassword == null)
111       {
112          trustStorePassword = System
113                .getProperty("javax.net.ssl.trustStorePassword");
114       }
115       if (trustStorePassword == null)
116       {
117          trustStorePassword = getKeyStorePassword();
118       }
119       if (log.isDebugEnabled())
120       {
121          log.debug("TrustPass = " + trustStorePassword);
122       }
123       return trustStorePassword;
124    }
125
126    protected String JavaDoc getTrustStoreType()
127    {
128       String JavaDoc truststoreType = (String JavaDoc)options.get("trustStoreType");
129       if (truststoreType == null)
130          truststoreType = System.getProperty("javax.net.ssl.trustStoreType");
131
132       if (truststoreType == null)
133          truststoreType = defaultKeyStoreType;
134
135       if (log.isDebugEnabled())
136       {
137          log.debug("trustType = " + truststoreType);
138       }
139
140       return truststoreType;
141    }
142
143    /**
144     * Reads the keyStore and initializes the SSL socket factory.
145     */

146    protected void initFactory() throws IOException JavaDoc
147    {
148       try
149       {
150          // SSL protocol variant (e.g., TLS, SSL v3, etc.)
151
String JavaDoc protocol = (String JavaDoc)options.get("protocol");
152          if (protocol == null)
153          {
154             protocol = defaultProtocol;
155          }
156
157          // Certificate encoding algorithm (e.g., SunX509)
158
String JavaDoc algorithm = (String JavaDoc)options.get("algorithm");
159          if (algorithm == null)
160          {
161             algorithm = defaultAlgorithm;
162          }
163
164          String JavaDoc trustAlgorithm = (String JavaDoc)options.get("truststoreAlgorithm");
165          if (trustAlgorithm == null)
166          {
167             trustAlgorithm = algorithm;
168          }
169
170          String JavaDoc keyStoreType = getKeyStoreType();
171          String JavaDoc trustStoreType = getTrustStoreType();
172
173          // Create and init SSLContext
174
SSLContext context = SSLContext.getInstance(protocol);
175          context.init(getKeyManagers(keyStoreType, algorithm, (String JavaDoc)options
176                .get("keyAlias")), getTrustManagers(trustAlgorithm,
177                trustStoreType), new SecureRandom JavaDoc());
178
179          // create proxy
180
sslFactory = context.getSocketFactory();
181       }
182       catch (IOException JavaDoc e)
183       {
184          throw e;
185       }
186       catch (RuntimeException JavaDoc e)
187       {
188          throw e;
189       }
190       catch (Exception JavaDoc e)
191       {
192          throw new IOException JavaDoc(e.getMessage());
193       }
194    }
195
196    /**
197     * Gets the initialized key managers.
198     */

199    protected KeyManager[] getKeyManagers(String JavaDoc type, String JavaDoc algorithm,
200          String JavaDoc keyAlias) throws Exception JavaDoc
201    {
202
203       KeyManager[] kms = null;
204
205       String JavaDoc keyStorePass = getKeyStorePassword();
206
207       KeyStore JavaDoc ks = getKeyStore(type, keyStorePass);
208       if (keyAlias != null && !ks.isKeyEntry(keyAlias))
209       {
210          throw new IOException JavaDoc("Could not find alias in keyStore: " + keyAlias);
211       }
212
213       KeyManagerFactory kmf = KeyManagerFactory.getInstance(algorithm);
214       kmf.init(ks, keyStorePass.toCharArray());
215
216       kms = kmf.getKeyManagers();
217       if (keyAlias != null)
218       {
219          if (defaultKeyStoreType.equals(type))
220          {
221             keyAlias = keyAlias.toLowerCase();
222          }
223          for (int i = 0; i < kms.length; i++)
224          {
225             kms[i] = new JSSEKeyManager((X509KeyManager)kms[i], keyAlias);
226          }
227       }
228
229       return kms;
230    }
231
232    /*
233     * Gets the SSL keystore password.
234     */

235    protected String JavaDoc getKeyStorePassword()
236    {
237       String JavaDoc keyStorePassword = (String JavaDoc)options.get("keyStorePassword");
238       if (keyStorePassword == null)
239          keyStorePassword = System.getProperty("javax.net.ssl.keyStorePassword");
240
241       if (keyStorePassword == null)
242          keyStorePassword = defaultKeyStorePassword;
243
244       return keyStorePassword;
245    }
246
247    /*
248     * Gets the SSL server's keystore.
249     */

250    protected KeyStore JavaDoc getKeyStore(String JavaDoc type, String JavaDoc pass) throws IOException JavaDoc
251    {
252       String JavaDoc keyStoreFile = (String JavaDoc)options.get("keyStore");
253       if (keyStoreFile == null)
254          keyStoreFile = System.getProperty("javax.net.ssl.keyStore");
255
256       if (keyStoreFile == null)
257          keyStoreFile = defaultKeyStoreFile;
258
259       return getStore(type, keyStoreFile, pass);
260    }
261
262    /**
263     * Gets the intialized trust managers.
264     */

265    protected TrustManager[] getTrustManagers(String JavaDoc algorithm, String JavaDoc type)
266          throws Exception JavaDoc
267    {
268
269       TrustManager[] tms = null;
270
271       KeyStore JavaDoc trustStore = getTrustStore(type, getTrustStorePassword());
272       if (trustStore != null)
273       {
274          TrustManagerFactory tmf = TrustManagerFactory.getInstance(algorithm);
275          tmf.init(trustStore);
276          tms = tmf.getTrustManagers();
277       }
278
279       return tms;
280    }
281
282    protected KeyStore JavaDoc getTrustStore(String JavaDoc type, String JavaDoc pass)
283          throws IOException JavaDoc
284    {
285       KeyStore JavaDoc trustStore = null;
286
287       String JavaDoc trustStoreFile = (String JavaDoc)options.get("trustStore");
288       if (trustStoreFile == null)
289       {
290          trustStoreFile = System.getProperty("javax.net.ssl.trustStore");
291       }
292       if (log.isDebugEnabled())
293       {
294          log.debug("Truststore = " + trustStoreFile);
295       }
296
297       if (trustStoreFile != null && pass != null)
298       {
299          trustStore = getStore(type, trustStoreFile, pass);
300       }
301
302       return trustStore;
303    }
304
305    /*
306     * Gets the key- or truststore with the specified type, path, and password.
307     */

308    private KeyStore JavaDoc getStore(String JavaDoc type, String JavaDoc path, String JavaDoc pass)
309          throws IOException JavaDoc
310    {
311
312       KeyStore JavaDoc ks = null;
313       InputStream JavaDoc istream = null;
314       try
315       {
316          ks = KeyStore.getInstance(type);
317          File JavaDoc keyStoreFile = new File JavaDoc(path);
318          istream = new FileInputStream JavaDoc(keyStoreFile);
319
320          ks.load(istream, pass.toCharArray());
321          istream.close();
322          istream = null;
323       }
324       catch (FileNotFoundException JavaDoc fnfe)
325       {
326          throw fnfe;
327       }
328       catch (IOException JavaDoc ioe)
329       {
330          throw ioe;
331       }
332       catch (Exception JavaDoc ex)
333       {
334          ex.printStackTrace();
335          throw new IOException JavaDoc("Exception trying to load keystore " + path
336                + ": " + ex.getMessage());
337       }
338       finally
339       {
340          if (istream != null)
341          {
342             try
343             {
344                istream.close();
345             }
346             catch (IOException JavaDoc ioe)
347             {
348                // Do nothing
349
}
350          }
351       }
352
353       return ks;
354    }
355
356    public static final class JSSEKeyManager implements X509KeyManager
357    {
358
359       private X509KeyManager delegate;
360
361       private String JavaDoc clientKeyAlias;
362
363       /**
364        * Constructor.
365        *
366        * @param mgr
367        * The X509KeyManager used as a delegate
368        * @param serverKeyAlias
369        * The alias name of the server's keypair and supporting
370        * certificate chain
371        */

372       public JSSEKeyManager(X509KeyManager mgr, String JavaDoc clientKeyAlias)
373       {
374          this.delegate = mgr;
375          this.clientKeyAlias = clientKeyAlias;
376       }
377
378       /**
379        * Choose an alias to authenticate the client side of a secure socket,
380        * given the public key type and the list of certificate issuer
381        * authorities recognized by the peer (if any).
382        *
383        * @param keyType
384        * The key algorithm type name(s), ordered with the
385        * most-preferred key type first
386        * @param issuers
387        * The list of acceptable CA issuer subject names, or null if it
388        * does not matter which issuers are used
389        * @param socket
390        * The socket to be used for this connection. This parameter can
391        * be null, in which case this method will return the most
392        * generic alias to use
393        *
394        * @return The alias name for the desired key, or null if there are no
395        * matches
396        */

397       public String JavaDoc chooseClientAlias(String JavaDoc[] keyType, Principal JavaDoc[] issuers,
398             Socket JavaDoc socket)
399       {
400          return clientKeyAlias;
401       }
402
403       /**
404        * Returns this key manager's server key alias that was provided in the
405        * constructor.
406        *
407        * @param keyType
408        * The key algorithm type name (ignored)
409        * @param issuers
410        * The list of acceptable CA issuer subject names, or null if it
411        * does not matter which issuers are used (ignored)
412        * @param socket
413        * The socket to be used for this connection. This parameter can
414        * be null, in which case this method will return the most
415        * generic alias to use (ignored)
416        *
417        * @return Alias name for the desired key
418        */

419       public String JavaDoc chooseServerAlias(String JavaDoc keyType, Principal JavaDoc[] issuers,
420             Socket JavaDoc socket)
421       {
422          return delegate.chooseServerAlias(keyType, issuers, socket);
423       }
424
425       /**
426        * Returns the certificate chain associated with the given alias.
427        *
428        * @param alias
429        * The alias name
430        *
431        * @return Certificate chain (ordered with the user's certificate first
432        * and the root certificate authority last), or null if the alias
433        * can't be found
434        */

435       public X509Certificate JavaDoc[] getCertificateChain(String JavaDoc alias)
436       {
437          return delegate.getCertificateChain(alias);
438       }
439
440       /**
441        * Get the matching aliases for authenticating the client side of a secure
442        * socket, given the public key type and the list of certificate issuer
443        * authorities recognized by the peer (if any).
444        *
445        * @param keyType
446        * The key algorithm type name
447        * @param issuers
448        * The list of acceptable CA issuer subject names, or null if it
449        * does not matter which issuers are used
450        *
451        * @return Array of the matching alias names, or null if there were no
452        * matches
453        */

454       public String JavaDoc[] getClientAliases(String JavaDoc keyType, Principal JavaDoc[] issuers)
455       {
456          return delegate.getClientAliases(keyType, issuers);
457       }
458
459       /**
460        * Get the matching aliases for authenticating the server side of a secure
461        * socket, given the public key type and the list of certificate issuer
462        * authorities recognized by the peer (if any).
463        *
464        * @param keyType
465        * The key algorithm type name
466        * @param issuers
467        * The list of acceptable CA issuer subject names, or null if it
468        * does not matter which issuers are used
469        *
470        * @return Array of the matching alias names, or null if there were no
471        * matches
472        */

473       public String JavaDoc[] getServerAliases(String JavaDoc keyType, Principal JavaDoc[] issuers)
474       {
475          return delegate.getServerAliases(keyType, issuers);
476       }
477
478       /**
479        * Returns the key associated with the given alias.
480        *
481        * @param alias
482        * The alias name
483        *
484        * @return The requested key, or null if the alias can't be found
485        */

486       public PrivateKey JavaDoc getPrivateKey(String JavaDoc alias)
487       {
488          return delegate.getPrivateKey(alias);
489       }
490    }
491
492 }
493
Popular Tags