1 package net.suberic.pooka.ssl; 2 3 import java.io.*; 4 5 import java.security.cert.*; 6 import javax.mail.internet.MimeUtility ; 7 import javax.net.ssl.*; 8 9 10 14 public class PookaTrustManager implements X509TrustManager { 15 16 X509TrustManager wrappedManager = null; 17 18 String certificateRepositoryFile = null; 19 20 java.util.Set rejectedCerts = new java.util.HashSet (); 21 22 java.util.Set trustedCerts = new java.util.HashSet (); 23 24 boolean mUseCertFile = true; 25 26 29 public PookaTrustManager(TrustManager[] pWrappedManagers, String pCertFile) { 30 this(pWrappedManagers, pCertFile, true); 31 } 32 33 36 public PookaTrustManager(TrustManager[] pWrappedManagers, String 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 55 public void checkClientTrusted(X509Certificate[] cert, String 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 else if (! localIsTrusted(cert)) 73 throw new CertificateException("Certificate not trusted."); 74 } 75 76 80 public void checkServerTrusted(X509Certificate[] cert, String 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 (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 106 public X509Certificate[] getAcceptedIssuers() { 107 return wrappedManager.getAcceptedIssuers(); 108 } 109 110 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 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 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 msg = new StringBuffer ("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 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 fw = new BufferedWriter(new FileWriter(certificateRepositoryFile, true)); 187 } catch (IOException ioe) { 188 final Exception e = ioe; 189 javax.swing.SwingUtilities.invokeLater(new Runnable () { 190 public void run() { 191 net.suberic.pooka.Pooka.getUIFactory().showError("Error opening SSL certificate file: " + certificateRepositoryFile, e); 192 } 193 }); 194 } 195 } else { 196 javax.swing.SwingUtilities.invokeLater(new Runnable () { 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 e) { 226 } finally { 228 if (fw != null) { 229 try { 230 fw.close(); 231 } catch (Exception e) { 232 } 233 } 234 } 235 } 236 237 } 238 239 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 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 ioe) { 270 } finally { 272 try { 273 if (fis != null) 274 fis.close(); 275 } catch (Exception e) { 276 277 } 278 } 279 } 280 281 } 282 } 283 284 | Popular Tags |