KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > ca > commons > security > JXTrustManager


1 package com.ca.commons.security;
2
3 import com.ca.commons.cbutil.CBIntText;
4
5 import javax.net.ssl.*;
6 import java.io.*;
7 import java.security.*;
8 import java.security.cert.*;
9 import java.awt.*;
10
11 public class JXTrustManager
12         implements X509TrustManager
13 {
14     public static String JavaDoc CERTSTORE = "lbecacerts";
15     public static String JavaDoc CERTSTORE_PASSWORD = "changeit";
16     private X509TrustManager trustManager;
17     private EvaluateCertGUI verifier;
18     private Frame owner;
19     private KeyStore caKeyStore;
20     private String JavaDoc caKeyStorePath;
21     private String JavaDoc caKeyStoreType;
22     private char[] caPassphrase;
23
24     /**
25      * <p>This takes an array of existing trust managers, and returns an array of
26      * extended Trust Managers that include our own code to allow the user to
27      * select new certificates at run time.</p>
28      * @param arrayOfTrustManagers; must be of type X509TrustManager...
29      * @return an array of JXTrustManagers incorporating the passed in managers.
30      * @throws javax.net.ssl.SSLException
31      */

32     public static X509TrustManager[] convert(TrustManager[] arrayOfTrustManagers, KeyStore keystore,
33                                              String JavaDoc caKeystorePath, char[] caPassphrase, String JavaDoc caKeystoreType, Frame rootFrame)
34             throws SSLException
35     {
36         int numberOfManagers = arrayOfTrustManagers.length;
37         X509TrustManager[] returnArray = new X509TrustManager[numberOfManagers];
38         for (int i = 0; i < numberOfManagers; i++)
39         {
40             TrustManager old = arrayOfTrustManagers[i];
41             if (old == null)
42                 throw new SSLException("unexpected SSL error - null trust manager found in trust array: element " + i + " of " + numberOfManagers);
43
44             try
45             {
46                 returnArray[i] = new JXTrustManager((X509TrustManager) old, keystore, caKeystorePath, caPassphrase, caKeystoreType, rootFrame);
47             }
48             catch (ClassCastException JavaDoc e)
49             {
50                 throw new SSLException("unexpected SSL error - non X509 trust manager found in trust array: element " + i + " of " + numberOfManagers + " is of type " + old.getClass());
51             }
52         }
53         return returnArray;
54     }
55
56     /**
57      * <p>The local constructor for the TrustManager</p>
58      * @param baseTrustManager
59      * @param keystore
60      * @param certAuthorityKeystorePath
61      */

62     private JXTrustManager(X509TrustManager baseTrustManager, KeyStore keystore,
63                            String JavaDoc certAuthorityKeystorePath, char[] certAuthorityPassphrase, String JavaDoc certAuthorityKeystoreType,
64                            Frame rootFrame)
65     {
66         trustManager = baseTrustManager;
67         caKeyStore = keystore;
68         caKeyStorePath = certAuthorityKeystorePath;
69         caKeyStoreType = certAuthorityKeystoreType;
70         caPassphrase = certAuthorityPassphrase;
71         owner = rootFrame;
72     }
73
74     public X509Certificate[] getAcceptedIssuers()
75     {
76         return trustManager.getAcceptedIssuers();
77     }
78
79     private X509Certificate getCACert(X509Certificate chain[])
80     {
81         X509Certificate ca = chain[chain.length - 1];
82         // check that root certificate is self-signed.
83
if (ca.getSubjectDN().equals(ca.getIssuerDN()))
84             return ca;
85         else
86             return null;
87     }
88
89     /**
90      * <p>Returns whether a particular certificate is one of the
91      * accepted issuers</p>
92      * @param caCert
93      * @return
94      */

95     private boolean rootCertIsKnown(X509Certificate caCert)
96     {
97         X509Certificate certificates[] = getAcceptedIssuers();
98         if (certificates == null)
99             return false;
100         for (int i = 0; i < certificates.length; i++)
101             if (caCert.equals(certificates[i]))
102                 return true;
103
104         return false;
105     }
106
107     public void checkClientTrusted(X509Certificate chain[], String JavaDoc authType)
108             throws CertificateException
109     {
110         trustManager.checkClientTrusted(chain, authType);
111     }
112
113     /**
114      * <p>This is the meat of the class, where we verify whether or not a particular
115      * certificate is to be trusted. If it is already in the keystore, then well and good,
116      * otherwise we ask the user whether to allow it or not...</p>
117      *
118      * @param chain a list of certificates forming an certificate chain - these are the certs being checked.
119      * @param authType the type of authentication being used; usually 'RSA' I believe...
120      * @throws java.security.cert.CertificateException if the certificate is not valid.
121      */

122     public void checkServerTrusted(X509Certificate chain[], String JavaDoc authType)
123             throws CertificateException
124     {
125         try
126         {
127             trustManager.checkServerTrusted(chain, authType); // this will throw an exception if unsuccessfull
128
// ... otherwise the cert is o.k., so just continue...
129
}
130         /**
131          * The certificate we've been given is unknown
132          */

133         catch (CertificateException e)
134         {
135             // SOME USERS MAY WISH TO DISALLOW THIS FEATURE.
136
if ("false".equals(System.getProperty("option.ssl.import.cert.during.connection")))
137                 throw e;
138
139             X509Certificate certificateAuthorityCert = getCACert(chain);
140             if (certificateAuthorityCert == null)
141                 throw new CertificateException("Invalid Server Certificate: server certificate could not be verified, and the CA certificate is missing from the certificate chain. raw error: " + e);
142
143             if (rootCertIsKnown(certificateAuthorityCert))
144                 throw new CertificateException("Invalid Server Certificate: The server certificate could not be verified, as it has a bad chain back to a known CA. raw error: " + e);
145
146             if (verifier == null)
147                 verifier = new EvaluateCertGUI(owner);
148
149             switch (verifier.isTrusted(certificateAuthorityCert))
150             {
151                 case EvaluateCertGUI.REJECT:
152                     throw new CertificateException("user chose not to trust unknown certificate");
153
154                 case EvaluateCertGUI.ACCEPT_ONCE:
155                     // do nothing, thus signifying acceptance within this method only??
156
return;
157
158                 case EvaluateCertGUI.ACCEPT_ALWAYS:
159                     try
160                     {
161                         saveStore(certificateAuthorityCert);
162                     }
163                     catch (KeyStoreException e1)
164                     {
165                         throw new CertificateException("unable to save certificate in keystore! " + e1);
166                     }
167                     return;
168             }
169         }
170     }
171
172     /**
173      * <p>This saves the certificate in the cert authority keystore.</p>
174      * @param cert the new certificate to save.
175      * @throws KeyStoreException
176      */

177     private void saveStore(X509Certificate cert)
178         throws KeyStoreException
179     {
180         try
181         {
182             // SPECIAL HANDLING TO TRY DEFAULT PASSWORD FIRST.
183
if (caPassphrase == null)
184                 caPassphrase = "changeit".toCharArray(); // neat feature or filthy hack? ... you be the judge...
185

186             try
187             {
188                 caKeyStore.load(new FileInputStream(caKeyStorePath), caPassphrase); // if this works, we have a valid password.
189
}
190             catch (IOException e)
191             {
192                 setupKeyStoreAndPassword();
193             }
194
195             if (caKeyStore == null)
196                 throw new KeyStoreException("unable to open keystore - no valid password or no valid file.");
197
198             String JavaDoc alias = cert.getSubjectDN() + " (" + cert.getSerialNumber().toString() + ")";
199             caKeyStore.setCertificateEntry(alias, cert);
200             FileOutputStream fos = new FileOutputStream(caKeyStorePath);
201             caKeyStore.store(fos, caPassphrase);
202             fos.close();
203         }
204         catch (IOException e)
205         {
206             KeyStoreException kse = new KeyStoreException("unable to access keystore file");
207             kse.initCause(e);
208             throw kse;
209         }
210         catch (GeneralSecurityException e)
211         {
212             if (e instanceof KeyStoreException)
213                 throw (KeyStoreException)e;
214             else
215                 throw new KeyStoreException("unable to save keystore " + caKeyStorePath + " error was: " + e);
216         }
217     }
218     private boolean setupKeyStoreAndPassword()
219     {
220         String JavaDoc message = CBIntText.get("Enter Key Store Password");
221         while ((caPassphrase = KeystoreGUI.getPassword(owner, message)) != null)
222         {
223             caKeyStore = KeystoreGUI.readKeyStore(caPassphrase, caKeyStoreType, caKeyStorePath);
224
225             if (caKeyStore != null)
226                 return true; // we have a valid keystore!
227

228             // this message is only displayed if we go around the loop again.
229
message = CBIntText.get("Password incorrect. Please try again.");
230         }
231         return false;
232     }
233
234 }
Popular Tags