KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > SnowMailClient > MailEngine > VerifiedSSLSocketFactory


1 package SnowMailClient.MailEngine;
2
3 import snow.utils.gui.Icons;
4 import java.awt.Insets JavaDoc;
5 import SnowMailClient.Language.Language;
6 import snow.utils.storage.FileUtils;
7 import java.util.*;
8 import java.awt.event.*;
9 import java.awt.BorderLayout JavaDoc;
10 import java.awt.FlowLayout JavaDoc;
11 import javax.swing.*;
12 import java.util.Arrays JavaDoc;
13 import java.security.cert.X509Certificate JavaDoc;
14 import java.security.*;
15 import java.io.*;
16 import javax.net.*;
17 import javax.net.ssl.*;
18 import java.net.*;
19
20 /** Asks to validate.
21 * Manages the trusted certs. (in the file).
22 */

23 public final class VerifiedSSLSocketFactory implements X509TrustManager
24 {
25    private KeyStore truststore;
26    private File truststoreFile = new File("ssl.truststore");
27    private char[] trustPass = null; // no pass: null
28
private JFrame parent = null;
29    private SSLSocketFactory socketFactory = null;
30    private static VerifiedSSLSocketFactory instance;
31
32 // some may be added in the list but not in the file.
33
private final List<X509Certificate JavaDoc> allTrustedCerts = new ArrayList<X509Certificate JavaDoc>();
34
35      /*
36       * The default X509TrustManager returned by SunX509. We'll delegate
37       * decisions to it, and fall back to the logic in this class if the
38       * default X509TrustManager doesn't trust it.
39       */

40   // private X509TrustManager sunJSSEX509TrustManager;
41

42    /** Constructor. */
43    private VerifiedSSLSocketFactory() throws Exception JavaDoc
44    {
45
46       truststore = KeyStore.getInstance("JKS");
47       truststoreFile = new File(System.getProperty("javax.net.ssl.trustStore",
48          // default
49
System.getProperty("user.home")+"/snowmail/trustStore.certificates"
50       ));
51
52       try
53       {
54         if( truststoreFile.exists())
55         {
56            FileInputStream fis = new FileInputStream(truststoreFile);
57            truststore.load(fis, trustPass);
58            fis.close();
59
60            System.out.println("Truststore loaded from "+truststoreFile);
61
62            List<String JavaDoc> alis = Collections.list(truststore.aliases());
63            System.out.println(""+alis.size()+" certificates in truststore");
64            for(String JavaDoc ali : alis)
65            {
66               System.out.println(""+ali);
67               if(truststore.getCertificate(ali) instanceof X509Certificate JavaDoc)
68               {
69                 X509Certificate JavaDoc ci = (X509Certificate JavaDoc) truststore.getCertificate(ali);
70                 //System.out.println(""+ci);
71
allTrustedCerts.add(ci);
72               }
73               else
74               {
75                 System.out.println("NOT X509: "+truststore.getCertificate(ali).getClass());
76               }
77            }
78         }
79         else
80         {
81            truststore = null;
82            // NOT valid if not initialized (i.e. loaded from a valid one).
83
}
84       }catch(Exception JavaDoc e)
85       {
86          System.out.println("CANNOT READ THE TRUSTSTORE");
87          e.printStackTrace();
88       }
89
90       SSLContext ctx = SSLContext.getInstance("TLS");
91       TrustManager[] tms = new TrustManager[]{ this };
92       ctx.init(null, tms, null);
93
94       socketFactory = (SSLSocketFactory) ctx.getSocketFactory();
95    }
96
97    public static VerifiedSSLSocketFactory getInstance() throws Exception JavaDoc
98    {
99       if(instance==null)
100       {
101          instance = new VerifiedSSLSocketFactory();
102       }
103       return instance;
104    }
105
106    public SSLSocketFactory getSocketFactory() { return socketFactory; }
107
108    public KeyStore getTruststore() { return truststore; }
109    public File getTruststoreFile() { return truststoreFile; }
110
111    public void test(String JavaDoc host, int port) throws Exception JavaDoc
112    {
113       Socket ssls = socketFactory.createSocket(host, port);
114
115       System.out.println("con made.");
116
117       ssls.getOutputStream().write("get ingex.html".getBytes());
118       ssls.getOutputStream().flush();
119
120       readToConsole(ssls.getInputStream());
121       System.out.println("end.");
122       System.exit(0);
123    }
124
125
126    private void saveKeystore()
127    {
128       if(truststore==null)
129       {
130          new Throwable JavaDoc("null truststore").printStackTrace();
131          return;
132       }
133
134       try
135       {
136          File nf = new File(truststoreFile.getAbsolutePath()+".new");
137
138          FileOutputStream fis = new FileOutputStream(nf);
139          truststore.store(fis, "".toCharArray());
140          fis.close();
141
142          //TODO BETTER: FileUtils.rename;
143
nf.renameTo(truststoreFile);
144       }
145       catch(Exception JavaDoc e)
146       {
147          e.printStackTrace();
148       }
149    }
150
151
152
153    // implements X509TrustManager
154
public void checkClientTrusted( X509Certificate JavaDoc[] chain, String JavaDoc authType )
155    {
156       System.out.println("#### checkClientTrusted");
157    }
158
159    /** Called when creating a socket. pass the chain given by the server.
160    * // implements X509TrustManager
161    */

162    public void checkServerTrusted( final X509Certificate JavaDoc[] chain, final String JavaDoc authType ) // RSA
163
{
164       System.out.println("#### checkServerTrusted "+authType);
165       //System.out.println(""+Arrays.toString(chain));
166

167       if(chain!=null && chain.length==1)
168       {
169          if(allTrustedCerts.contains(chain[0]))
170          {
171             System.out.println(" found in the trusted list!");
172             return;
173          }
174       }
175
176
177       //truststore.setCertificateEntry()
178
final JDialog d = new JDialog(parent, "Check certificate ("+authType+")", true);
179
180       JTabbedPane tp = new JTabbedPane() ;
181       d.add(tp, BorderLayout.CENTER);
182
183       for(X509Certificate JavaDoc ci : chain)
184       {
185         JTextPane tpi = new JTextPane();
186         tpi.setText(""+Arrays.toString(chain));
187         JScrollPane sp = new JScrollPane(tpi);
188
189         tp.add(ci.getIssuerX500Principal().getName(), sp);
190       }
191       d.setSize(600,600);
192       d.setLocationRelativeTo(null);
193
194       final boolean[] acc = new boolean[]{false};
195       JPanel cp = new JPanel(new FlowLayout JavaDoc(FlowLayout.LEFT,5,5));
196       cp.add(new JLabel(Language.translate("Do you trust this certificate chain ?")+" "));
197       d.add(cp, BorderLayout.SOUTH);
198
199       JButton yes = new JButton(Language.translate("yes"), new Icons.OkIcon(10,10,true));
200       yes.setMargin(new Insets JavaDoc(0,1,0,1));
201       cp.add(yes);
202       yes.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) {
203         acc[0] = true;
204         d.setVisible(false);
205
206         // add to the truststore (?)
207
try
208         {
209           if(truststore!=null)
210           {
211             for(X509Certificate JavaDoc ci : chain)
212             {
213               truststore.setCertificateEntry(ci.getIssuerX500Principal().getName(), ci);
214             }
215
216             saveKeystore();
217           }
218         }
219         catch(Exception JavaDoc e)
220         {
221            e.printStackTrace();
222         }
223       } });
224
225       JButton y1 = new JButton(Language.translate("yes for this session"), new Icons.OkIcon(10,10,true));
226       y1.setMargin(new Insets JavaDoc(0,1,0,1));
227       cp.add(y1);
228       y1.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) {
229         acc[0] = true;
230         d.setVisible(false);
231       } });
232
233       JButton no = new JButton(Language.translate("no"), new Icons.CrossIcon(10,10,true));
234       no.setMargin(new Insets JavaDoc(0,1,0,1));
235       cp.add(no);
236       no.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) {
237         acc[0] = false;
238         d.setVisible(false);
239       } });
240
241       d.setVisible(true); // MODAL.
242

243       if(!acc[0]) throw new RuntimeException JavaDoc(
244        Language.translate("Connection refused: certificate not validated by yourself"));
245
246       //accepted: always add in the list
247
for(X509Certificate JavaDoc ci : chain)
248       {
249          allTrustedCerts.add(ci);
250       }
251    }
252
253    // implements X509TrustManager
254
public X509Certificate JavaDoc[] getAcceptedIssuers( )
255    {
256       return allTrustedCerts.toArray(new X509Certificate JavaDoc[allTrustedCerts.size()]);
257    }
258
259    public void addTrusted(X509Certificate JavaDoc cert, boolean addToFile) throws Exception JavaDoc
260    {
261       allTrustedCerts.add(cert);
262       if(addToFile)
263       {
264          if(truststore!=null)
265          {
266            truststore.setCertificateEntry(""+System.currentTimeMillis(), cert);
267            saveKeystore();
268          }
269          else
270          {
271             //??
272
}
273       }
274    }
275
276    public void removeTrusted(X509Certificate JavaDoc cert) throws Exception JavaDoc
277    {
278       allTrustedCerts.remove(cert);
279          if(truststore!=null)
280          {
281            if(truststore.getCertificateAlias(cert)!=null)
282            {
283                truststore.deleteEntry(truststore.getCertificateAlias(cert));
284                saveKeystore();
285            }
286          }
287          else
288          {
289             //??
290
}
291    }
292
293    // TEST
294
private void readToConsole(InputStream is) throws Exception JavaDoc
295    {
296       byte[] b = new byte[128];
297       int read = -1;
298       System.out.println("START");
299       while((read=is.read(b))!=-1)
300       {
301          System.out.print(new String JavaDoc(b,0,read));
302          System.out.flush();
303       }
304       System.out.println("END");
305    }
306
307
308    public static void main(String JavaDoc[] args) throws Exception JavaDoc
309    {
310 // getInstance().test("pop.gmail.com", 995);
311
// getInstance().test("smtp.gmail.com", ?);
312
getInstance().test("mail.moovant.com", 995);
313    }
314
315 }
Popular Tags