KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > security > SSLUtils


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23 package com.sun.enterprise.security;
24
25 import java.io.IOException JavaDoc;
26 import java.io.File JavaDoc;
27 import java.security.Key JavaDoc;
28 import java.security.KeyStore JavaDoc;
29 import java.security.KeyStore.PrivateKeyEntry;
30 import java.security.KeyStoreException JavaDoc;
31 import java.security.NoSuchAlgorithmException JavaDoc;
32 import java.security.PrivateKey JavaDoc;
33 import java.security.cert.CertificateException JavaDoc;
34 import java.util.ArrayList JavaDoc;
35 import java.util.Enumeration JavaDoc;
36 import java.util.HashMap JavaDoc;
37 import java.util.Properties JavaDoc;
38 import java.security.AccessController JavaDoc;
39 import java.security.PrivilegedAction JavaDoc;
40 import java.security.cert.Certificate JavaDoc;
41 import javax.net.ssl.HttpsURLConnection;
42 import javax.net.ssl.KeyManagerFactory;
43 import javax.net.ssl.SSLContext;
44 import javax.net.ssl.TrustManagerFactory;
45 import javax.net.ssl.KeyManager;
46 import javax.net.ssl.TrustManager;
47 import javax.net.ssl.X509KeyManager;
48 import javax.net.ssl.X509TrustManager;
49
50
51 import com.sun.enterprise.config.clientbeans.Ssl;
52 import com.sun.enterprise.iiop.IIOPSSLSocketFactory;
53 import com.sun.enterprise.security.auth.login.ClientCertificateLoginModule;
54 import com.sun.enterprise.security.ssl.UnifiedX509KeyManager;
55 import com.sun.enterprise.security.ssl.UnifiedX509TrustManager;
56 import com.sun.enterprise.server.pluggable.SecuritySupport;
57 import com.sun.web.security.SSLSocketFactory;
58
59 import java.util.logging.*;
60 import com.sun.logging.*;
61
62 /**
63  * Handy class containing static functions.
64  * @author Harpreet Singh
65  * @author Vivek Nagar
66  * @author Shing Wai Chan
67  */

68 public final class SSLUtils {
69     private static final String JavaDoc defaultKeyStorePass = "changeit";
70     private static final String JavaDoc defaultTrustStorePass = "changeit";
71
72     private static final String JavaDoc keystoreProp = "javax.net.ssl.keyStore";
73     //private static final String truststoreProp = "javax.net.ssl.trustStore";
74
private static final String JavaDoc keystorePassProp = "javax.net.ssl.keyStorePassword";
75     private static final String JavaDoc truststorePassProp = "javax.net.ssl.trustStorePassword";
76
77     private static Logger _logger=null;
78     private static SecuritySupport secSupp = null;
79     private static boolean hasKey = false;
80     private static KeyManager keyManager = null;
81     private static TrustManager trustManager = null;
82     private static KeyStore JavaDoc mergedTrustStore = null;
83
84     static{
85         _logger=LogDomains.getLogger(LogDomains.SECURITY_LOGGER);
86
87     com.sun.enterprise.security.KeyTool.initProvider();
88
89         secSupp = SecurityUtil.getSecuritySupport();
90         try {
91             KeyStore JavaDoc[] keyStores = getKeyStores();
92             initKeyManagers(keyStores, secSupp.getKeyStorePasswords());
93             initTrustManagers(getTrustStores());
94             if (keyStores != null && keyStores.length > 0) {
95                 for (int i = 0; i < keyStores.length; i++) {
96                     Enumeration JavaDoc aliases = keyStores[i].aliases();
97                     while (aliases.hasMoreElements()) {
98                         String JavaDoc alias = (String JavaDoc)aliases.nextElement();
99                         if (keyStores[i].isKeyEntry(alias)) {
100                             hasKey = true;
101                             break;
102                         }
103                     }
104                     if (hasKey) {
105                         break;
106                     }
107                 }
108             }
109
110             mergedTrustStore = mergingTrustStores(secSupp.getTrustStores());
111         } catch(Exception JavaDoc ex) {
112             if (_logger.isLoggable(Level.FINE)) {
113                 _logger.log(Level.FINE, "SSLUtils static init fails.", ex);
114             }
115             throw new IllegalStateException JavaDoc(ex);
116         }
117     }
118
119     //XXX initStoresAtStartup may call more than once, should clean up later
120
private static boolean initialized = false;
121
122     private static Ssl appclientSsl = null;
123
124     private static HashMap JavaDoc fullCipherNameMap = new HashMap JavaDoc();
125
126     // This is a copy of the previous method. Its a copy as it seemed
127
// better to have a copy than keep public static variables to store state.
128
// Called at startup
129
// @todo remove this method
130
public static void initStoresAtStartup()
131     throws Exception JavaDoc
132     {
133         if (initialized) {
134             return;
135         }
136
137     SSLSocketFactory.setManagers(getKeyManagers(), getTrustManagers());
138         // Creating a default SSLContext and HttpsURLConnection for clients
139
// that use Https
140
SSLContext ctx = SSLContext.getInstance("TLS");
141     ctx.init(getKeyManagers(), getTrustManagers(), null);
142
143         HttpsURLConnection.setDefaultSSLSocketFactory(ctx.getSocketFactory());
144         // setting old JSSE 1.0 HttpsURLConnection
145
com.sun.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(ctx.getSocketFactory());
146
147         initialized = true;
148     }
149
150     public static KeyStore JavaDoc[] getKeyStores() throws Exception JavaDoc{
151         return secSupp.getKeyStores();
152     }
153
154     public static KeyStore JavaDoc getKeyStore() throws Exception JavaDoc{
155         return getKeyStores()[0];
156     }
157
158     public static KeyStore JavaDoc[] getTrustStores() throws Exception JavaDoc{
159         return secSupp.getTrustStores();
160     }
161
162     public static KeyStore JavaDoc getTrustStore() throws Exception JavaDoc{
163         return getTrustStores()[0];
164     }
165
166     /**
167      * This API is for temporary purpose. It will be removed once JSR 196
168      * is updated.
169      */

170     public static KeyStore JavaDoc getMergedTrustStore() {
171         return mergedTrustStore;
172     }
173
174     public static KeyManager[] getKeyManagers() throws Exception JavaDoc{
175         return new KeyManager[] { keyManager };
176     }
177
178     public static TrustManager[] getTrustManagers() throws Exception JavaDoc{
179         return new TrustManager[] { trustManager };
180     }
181
182     public static void setAppclientSsl(Ssl ssl){
183         appclientSsl = ssl;
184     }
185
186     public static Ssl getAppclientSsl() {
187         return appclientSsl;
188     }
189
190     public static String JavaDoc getKeyStorePass () {
191         //XXX need to revisit if the value should be cached
192
return System.getProperty(keystorePassProp, defaultKeyStorePass);
193     }
194
195     public static String JavaDoc getTrustStorePass () {
196         //XXX need to revisit if the value should be cached
197
return System.getProperty(truststorePassProp, defaultTrustStorePass);
198     }
199
200     /**
201      * This method checks whether a private key is available or not.
202      */

203     public static boolean isKeyAvailable() {
204         return hasKey;
205     }
206
207     /**
208      * Check whether given String is of the form [&lt;TokenName&gt;:]alias
209      * where alias is an key entry.
210      * @param certNickname
211      * @return boolean
212      */

213     public static boolean isTokenKeyAlias(String JavaDoc certNickname) throws Exception JavaDoc {
214         boolean isTokenKeyAlias = false;
215         if (certNickname != null) {
216             int ind = certNickname.indexOf(':');
217             KeyStore JavaDoc[] kstores = getKeyStores();
218             int count = -1;
219             String JavaDoc aliasName = null;
220             if (ind != -1) {
221                 String JavaDoc[] tokens = secSupp.getTokenNames();
222                 String JavaDoc tokenName = certNickname.substring(0, ind);
223                 aliasName = certNickname.substring(ind + 1);
224                 for (int i = 0; i < tokens.length; i++) {
225                     if (tokenName.equals(tokens[i])) {
226                         count = i;
227                     }
228                 }
229             }
230
231             if (count != -1) {
232                 isTokenKeyAlias = kstores[count].isKeyEntry(aliasName);
233             } else {
234                 for (int i = 0; i < kstores.length; i++) {
235                     if (kstores[i].isKeyEntry(certNickname)) {
236                         isTokenKeyAlias = true;
237                         break;
238                     }
239                 }
240             }
241         }
242         return isTokenKeyAlias;
243     }
244
245     /**
246      * Get a PrivateKeyEntry with certNickName is of the form
247      * [&lt;TokenName&gt;:]alias where alias is an key entry.
248      * @param certNickname
249      * @return PrivateKeyEntry
250      */

251     public static PrivateKeyEntry getPrivateKeyEntryFromTokenAlias(
252             String JavaDoc certNickname) throws Exception JavaDoc {
253         PrivateKeyEntry privKeyEntry = null;
254         if (certNickname != null) {
255             int ind = certNickname.indexOf(':');
256             KeyStore JavaDoc[] kstores = getKeyStores();
257             int count = -1;
258             String JavaDoc aliasName = certNickname;
259             if (ind != -1) {
260                 String JavaDoc[] tokens = secSupp.getTokenNames();
261                 String JavaDoc tokenName = certNickname.substring(0, ind);
262                 aliasName = certNickname.substring(ind + 1);
263                 for (int i = 0; i < tokens.length; i++) {
264                     if (tokenName.equals(tokens[i])) {
265                         count = i;
266                     }
267                 }
268             }
269
270             String JavaDoc[] passwords = secSupp.getKeyStorePasswords();
271             if (count != -1 && passwords.length >= count) {
272                 Key JavaDoc key = kstores[count].getKey(
273                         aliasName, passwords[count].toCharArray());
274                 if (key instanceof PrivateKey JavaDoc) {
275                     PrivateKey JavaDoc privKey = (PrivateKey JavaDoc)key;
276                     Certificate JavaDoc[] certs = kstores[count].getCertificateChain(
277                             aliasName);
278                     privKeyEntry = new PrivateKeyEntry(privKey, certs);
279                 }
280             } else {
281                 for (int i = 0; i < kstores.length; i++) {
282                     Key JavaDoc key = kstores[i].getKey(
283                             aliasName, passwords[i].toCharArray());
284                     if (key != null && key instanceof PrivateKey JavaDoc) {
285                         PrivateKey JavaDoc privKey = (PrivateKey JavaDoc)key;
286                         Certificate JavaDoc[] certs =
287                                 kstores[i].getCertificateChain(
288                                 aliasName);
289                         privKeyEntry = new PrivateKeyEntry(privKey, certs);
290                         break;
291                     }
292                 }
293             }
294             passwords = null;
295         }
296
297         return privKeyEntry;
298     }
299
300     private static void initKeyManagers(KeyStore JavaDoc[] kstores, String JavaDoc[] pwds)
301             throws Exception JavaDoc {
302
303         ArrayList JavaDoc keyManagers = new ArrayList JavaDoc();
304         for (int i = 0; i < kstores.length; i++) {
305         KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
306         kmf.init(kstores[i], pwds[i].toCharArray());
307             KeyManager[] kmgrs = kmf.getKeyManagers();
308             if (kmgrs != null) {
309                 for (int j = 0; j < kmgrs.length; j++) {
310                      keyManagers.add(kmgrs[j]);
311                 }
312             }
313         }
314
315         keyManager = new UnifiedX509KeyManager(
316             (X509KeyManager [])keyManagers.toArray(
317                 new X509KeyManager[keyManagers.size()]),
318             secSupp.getTokenNames());
319     }
320     
321     private static void initTrustManagers(KeyStore JavaDoc[] tstores) throws Exception JavaDoc {
322         ArrayList JavaDoc trustManagers = new ArrayList JavaDoc();
323         for (int i = 0; i < tstores.length; i++) {
324         TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
325         tmf.init(tstores[i]);
326             TrustManager[] tmgrs = tmf.getTrustManagers();
327             if (tmgrs != null) {
328                 for (int j = 0; j < tmgrs.length; j++) {
329                      trustManagers.add(tmgrs[j]);
330                 }
331             }
332         }
333         if (trustManagers.size() == 1) {
334             trustManager = (TrustManager)trustManagers.get(0);
335         } else {
336             trustManager = new UnifiedX509TrustManager((X509TrustManager [])trustManagers.toArray(new X509TrustManager[trustManagers.size()]));
337         }
338     }
339
340     //XXX temporary solution, need update after JSR 196
341
protected static KeyStore JavaDoc mergingTrustStores(KeyStore JavaDoc[] trustStores)
342             throws IOException JavaDoc, KeyStoreException JavaDoc,
343             NoSuchAlgorithmException JavaDoc, CertificateException JavaDoc {
344         KeyStore JavaDoc mergedStore = null;
345         try {
346             mergedStore = KeyStore.getInstance("CaseExactJKS");
347         } catch(KeyStoreException JavaDoc ex) {
348             mergedStore = KeyStore.getInstance("JKS");
349         }
350         String JavaDoc[] passwords = secSupp.getKeyStorePasswords();
351         mergedStore.load(null,
352                 passwords[passwords.length - 1].toCharArray());
353
354         String JavaDoc[] tokens = secSupp.getTokenNames();
355         for (int i = 0; i < trustStores.length; i++) {
356             Enumeration JavaDoc aliases = trustStores[i].aliases();
357             while (aliases.hasMoreElements()) {
358                 String JavaDoc alias = (String JavaDoc)aliases.nextElement();
359                 Certificate JavaDoc cert = trustStores[i].getCertificate(alias);
360
361                 //need to preserve the token:alias name format
362
String JavaDoc alias2 = (i < tokens.length - 1)? tokens[i] + ":" + alias : alias;
363
364                 String JavaDoc alias3 = alias2;
365                 boolean alreadyInStore = false;
366                 Certificate JavaDoc aCert = null;
367                 int count = 1;
368                 while ((aCert = mergedStore.getCertificate(alias3)) != null) {
369                     if (aCert.equals(cert)) {
370                         alreadyInStore = true;
371                         break;
372                     }
373                     alias3 = alias2 + "__" + count++;
374                 }
375                 if (!alreadyInStore) {
376                     mergedStore.setCertificateEntry(alias3, cert);
377                 }
378             }
379         }
380         return mergedStore;
381      }
382 }
383
Popular Tags