KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > suberic > pooka > ssl > PookaTrustManager


1 package net.suberic.pooka.ssl;
2
3 import java.io.*;
4
5 import java.security.cert.*;
6 import javax.mail.internet.MimeUtility JavaDoc;
7 import javax.net.ssl.*;
8
9
10 /**
11  * This wraps the default X509TrustManager so that we can handle untrusted
12  * certificate chains.
13  */

14 public class PookaTrustManager implements X509TrustManager {
15
16   X509TrustManager wrappedManager = null;
17
18   String JavaDoc certificateRepositoryFile = null;
19
20   java.util.Set JavaDoc rejectedCerts = new java.util.HashSet JavaDoc();
21
22   java.util.Set JavaDoc trustedCerts = new java.util.HashSet JavaDoc();
23
24   boolean mUseCertFile = true;
25
26   /**
27    * Creates a new TrustManager that wraps the given manager.
28    */

29   public PookaTrustManager(TrustManager[] pWrappedManagers, String JavaDoc pCertFile) {
30     this(pWrappedManagers, pCertFile, true);
31   }
32
33   /**
34    * Creates a new TrustManager that wraps the given manager.
35    */

36   public PookaTrustManager(TrustManager[] pWrappedManagers, String JavaDoc pCertFile, boolean pUseCertFile) {
37     super();
38
39     mUseCertFile = pUseCertFile;
40     if (mUseCertFile)
41       certificateRepositoryFile = pCertFile;
42
43     for (int i = 0; i < pWrappedManagers.length; i++) {
44       if (pWrappedManagers[i] instanceof X509TrustManager)
45         wrappedManager = (X509TrustManager) pWrappedManagers[i];
46     }
47
48     loadAccepted();
49   }
50
51   /**
52    * Returns whether or not the client with the given certificates is
53    * trusted or not.
54    */

55   public void checkClientTrusted(X509Certificate[] cert, String JavaDoc authType) throws CertificateException {
56     if (wrappedManager != null) {
57       CertificateException trustException = null;
58       try {
59         wrappedManager.checkClientTrusted(cert, authType);
60       } catch (CertificateException e) {
61         trustException = e;
62       }
63       if (trustException != null) {
64         if (localIsTrusted(cert))
65           return;
66         else
67           throw trustException;
68       }
69     }
70     // if the respones from the wrappedManager was false, or if there is no
71
// wrappedManager, then check out local db.
72
else if (! localIsTrusted(cert))
73       throw new CertificateException("Certificate not trusted.");
74   }
75
76   /**
77    * Returns whether or not the server with the given certificates is
78    * trusted or not.
79    */

80   public void checkServerTrusted(X509Certificate[] cert, String JavaDoc authType) throws CertificateException {
81     if (wrappedManager != null) {
82       CertificateException trustException = null;
83       try {
84         wrappedManager.checkServerTrusted(cert, authType);
85       }
86       catch (CertificateException e) {
87         trustException = e;
88       }
89
90       if (trustException != null) {
91         // if this isn't acceptable by default, ask.
92
if (localIsTrusted(cert))
93           return;
94         else
95           throw trustException;
96       }
97     } else
98       if (! localIsTrusted(cert))
99         throw new CertificateException("Certificate not trusted.");
100   }
101
102   /**
103    * Return an array of certificate authority certificates
104    * which are trusted for authenticating peers.
105    */

106   public X509Certificate[] getAcceptedIssuers() {
107     return wrappedManager.getAcceptedIssuers();
108   }
109
110   /**
111    * Checks to see if this certificate is in the local certificate store.
112    * If it's not, then we ask if it should be.
113    */

114   public boolean localIsTrusted(X509Certificate[] cert) {
115     if (cert == null || cert.length < 1)
116       return false;
117
118     boolean found = false;
119
120     boolean rejected = false;
121
122     for (int i = 0; ! found && ! rejected && i < cert.length; i++) {
123       if (trustedCerts.contains(cert[i]))
124         found = true;
125       else if (rejectedCerts.contains(cert[i]))
126         rejected = true;
127     }
128
129     if (found)
130       return true;
131     else if (rejected)
132       return false;
133
134     // if it hasn't been checked already, then ask.
135

136     boolean response = askIsTrusted(cert);
137
138     if (response) {
139       addToTrusted(cert);
140     } else {
141       addToRejected(cert);
142     }
143
144     return response;
145   }
146
147   /**
148    * Interactively figures out whether or not we want to trust this
149    * (default untrusted) certificate.
150    */

151   public boolean askIsTrusted(X509Certificate[] cert) {
152     X509Certificate certToPrint = null;
153     for (int i = 0; i < cert.length && certToPrint == null; i++) {
154       if (cert[i] != null)
155         certToPrint = cert[i];
156     }
157
158     int response = -1;
159     if (certToPrint != null) {
160       StringBuffer JavaDoc msg = new StringBuffer JavaDoc("The following certificates are not trusted. Accpet them anyway?\n\n");
161       msg.append("Issuer: ");
162       msg.append(certToPrint.getIssuerDN().getName());
163       msg.append("\n");
164       response = net.suberic.pooka.Pooka.getUIFactory().showConfirmDialog(msg.toString(), "Accpet SSL certificate?", javax.swing.JOptionPane.YES_NO_OPTION);
165     } else {
166       response = net.suberic.pooka.Pooka.getUIFactory().showConfirmDialog("The certificate(s) for this server are not trusted. Accpet them anyway?", "Accpet SSL certificate?", javax.swing.JOptionPane.YES_NO_OPTION);
167     }
168
169     if (response == javax.swing.JOptionPane.YES_OPTION)
170       return true;
171     else
172       return false;
173   }
174
175   /**
176    * Adds the given certificate(s) to the local trusted store.
177    */

178   public void addToTrusted(X509Certificate[] cert) {
179     if (cert != null) {
180       BufferedWriter fw = null;
181
182       if (mUseCertFile) {
183         if (certificateRepositoryFile != null && ! certificateRepositoryFile.equals("")) {
184           try {
185             // see if we can open the file.
186
fw = new BufferedWriter(new FileWriter(certificateRepositoryFile, true));
187           } catch (IOException ioe) {
188             final Exception JavaDoc e = ioe;
189             javax.swing.SwingUtilities.invokeLater(new Runnable JavaDoc() {
190                 public void run() {
191                   net.suberic.pooka.Pooka.getUIFactory().showError("Error opening SSL certificate file: " + certificateRepositoryFile, e);
192                 }
193               });
194           }
195         } else {
196           // don't give warning if we're not using a local certificate file.
197
javax.swing.SwingUtilities.invokeLater(new Runnable JavaDoc() {
198               public void run() {
199                 net.suberic.pooka.Pooka.getUIFactory().showError("Warning: no certificate file set.\nCertificate will only be accepted for this session.\nGo to Configuation->Preferences->SSL to set a certificate file.");
200               }
201             });
202         }
203       }
204
205       try {
206         for (int i = 0; i < cert.length; i++) {
207           if (cert[i] != null) {
208             trustedCerts.add(cert[i]);
209
210             if (fw != null) {
211               fw.write("-----BEGIN CERTIFICATE-----");
212               fw.newLine();
213               ByteArrayOutputStream baos = new ByteArrayOutputStream();
214               OutputStream encOutputStream = MimeUtility.encode(baos, "base64");
215               encOutputStream.write(cert[i].getEncoded());
216               fw.write(baos.toString());
217               fw.newLine();
218               fw.write("-----END CERTIFICATE-----");
219               fw.newLine();
220             }
221           }
222         }
223
224         fw.flush();
225       } catch (Exception JavaDoc e) {
226         // FIXME
227
} finally {
228         if (fw != null) {
229           try {
230             fw.close();
231           } catch (Exception JavaDoc e) {
232           }
233         }
234       }
235     }
236
237   }
238
239   /**
240    * Adds the given certificate(s) to the rejected list.
241    */

242   public void addToRejected(X509Certificate[] cert) {
243     if (cert != null) {
244       for (int i = 0; i < cert.length; i++) {
245         if (cert[i] != null)
246           rejectedCerts.add(cert[i]);
247       }
248     }
249   }
250
251   /**
252    * Loads the already-accepted certificated from the local file.
253    */

254   public void loadAccepted() {
255     FileInputStream fis = null;
256     if (mUseCertFile && certificateRepositoryFile != null) {
257       try {
258         fis = new FileInputStream(certificateRepositoryFile);
259         DataInputStream dis = new DataInputStream(fis);
260         CertificateFactory cf = CertificateFactory.getInstance("X.509");
261         byte[] bytes = new byte[dis.available()];
262         dis.readFully(bytes);
263         ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
264         while (bais.available() > 0) {
265           Certificate cert = cf.generateCertificate(bais);
266
267           trustedCerts.add(cert);
268         }
269       } catch (Exception JavaDoc ioe) {
270         // FIXME -- nothing for now.
271
} finally {
272         try {
273           if (fis != null)
274             fis.close();
275         } catch (Exception JavaDoc e) {
276
277         }
278       }
279     }
280
281   }
282 }
283
284
Popular Tags