EMMA Coverage Report (generated Wed Sep 01 15:39:27 CEST 2010)
[all classes][net.kwfgrid.gwes.client]

COVERAGE SUMMARY FOR SOURCE FILE [CertUtils.java]

nameclass, %method, %block, %line, %
CertUtils.java0%   (0/1)0%   (0/20)0%   (0/1168)0%   (0/246)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class CertUtils0%   (0/1)0%   (0/20)0%   (0/1168)0%   (0/246)
<static initializer> 0%   (0/1)0%   (0/4)0%   (0/1)
CertUtils (): void 0%   (0/1)0%   (0/23)0%   (0/8)
addCertificateToTrustStore (String): boolean 0%   (0/1)0%   (0/86)0%   (0/18)
checkClientTrusted (X509Certificate [], String): void 0%   (0/1)0%   (0/7)0%   (0/2)
checkServerTrusted (X509Certificate [], String): void 0%   (0/1)0%   (0/9)0%   (0/3)
copyDefaultJavaTruststore (): void 0%   (0/1)0%   (0/73)0%   (0/11)
getAcceptedIssuers (): X509Certificate [] 0%   (0/1)0%   (0/7)0%   (0/2)
getInstance (): CertUtils 0%   (0/1)0%   (0/8)0%   (0/3)
installCert (String, int): boolean 0%   (0/1)0%   (0/352)0%   (0/94)
loadKeyStore (): void 0%   (0/1)0%   (0/57)0%   (0/9)
loadTrustStore (): void 0%   (0/1)0%   (0/57)0%   (0/9)
main (String []): void 0%   (0/1)0%   (0/65)0%   (0/20)
printCertificateChain (): void 0%   (0/1)0%   (0/123)0%   (0/17)
setDefaultSystemProperties (): void 0%   (0/1)0%   (0/79)0%   (0/15)
setTrustStorePassword (): void 0%   (0/1)0%   (0/33)0%   (0/7)
toHexString (byte []): String 0%   (0/1)0%   (0/51)0%   (0/7)
writeEmptyKeyStore (): void 0%   (0/1)0%   (0/32)0%   (0/5)
writeEmptyTrustStore (): void 0%   (0/1)0%   (0/32)0%   (0/5)
writeKeyStore (): void 0%   (0/1)0%   (0/35)0%   (0/5)
writeTrustStore (): void 0%   (0/1)0%   (0/35)0%   (0/5)

1package net.kwfgrid.gwes.client;
2 
3/*
4 * Copyright 2006 Sun Microsystems, Inc.  All Rights Reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 *   - Redistributions of source code must retain the above copyright
11 *     notice, this list of conditions and the following disclaimer.
12 *
13 *   - Redistributions in binary form must reproduce the above copyright
14 *     notice, this list of conditions and the following disclaimer in the
15 *     documentation and/or other materials provided with the distribution.
16 *
17 *   - Neither the name of Sun Microsystems nor the names of its
18 *     contributors may be used to endorse or promote products derived
19 *     from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
22 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
23 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
25 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33 
34import java.io.*;
35import org.apache.commons.io.IOUtils;
36 
37import java.security.*;
38import java.security.cert.*;
39 
40import javax.net.ssl.*;
41 
42public class CertUtils implements X509TrustManager {
43 
44    private X509Certificate[] chain;
45 
46    private String truststoreFileName;
47    private String truststorePassphrase;
48    private File truststoreFile;
49    private KeyStore truststore;
50    private X509TrustManager tm;
51 
52    private String keystoreFileName;
53    private String keystorePassphrase;
54    private File keystoreFile;
55    private KeyStore keystore;
56    private X509KeyManager[] kms;
57 
58    private static CertUtils ourInstance;
59 
60    /**
61     * Get a singleton of CertUtils.
62     * @return
63     * @throws IOException
64     * @throws NoSuchAlgorithmException
65     * @throws KeyManagementException
66     * @throws KeyStoreException
67     * @throws CertificateException
68     */
69    public synchronized static CertUtils getInstance() throws IOException, NoSuchAlgorithmException, KeyManagementException, KeyStoreException, CertificateException {
70        if (CertUtils.ourInstance == null) {
71            CertUtils.ourInstance = new CertUtils();
72        }
73        return CertUtils.ourInstance;
74    }
75 
76    /**
77     * Private Constructor because of singleton pattern. Use #getInstance instead.
78     * @throws IOException
79     * @throws KeyStoreException
80     * @throws NoSuchAlgorithmException
81     * @throws CertificateException
82     * @throws KeyManagementException
83     */
84    private CertUtils() throws KeyStoreException, NoSuchAlgorithmException, CertificateException, KeyManagementException {
85            chain = null;
86            setDefaultSystemProperties();
87            truststoreFileName = System.getProperty("javax.net.ssl.trustStore");
88            truststorePassphrase = System.getProperty("javax.net.ssl.trustStorePassword");
89            keystoreFileName = System.getProperty("javax.net.ssl.keyStore");
90            keystorePassphrase = System.getProperty("javax.net.ssl.keyStorePassword");
91    }
92 
93    static void setDefaultSystemProperties() {
94        if (System.getProperty("javax.net.ssl.trustStore") == null) {
95            String store = System.getProperty("user.home")+"/.gwes-truststore.jks";
96            System.out.println("Using default SSL trust store '"+store+"'...");
97            System.setProperty("javax.net.ssl.trustStore",store);
98        }
99        if (System.getProperty("javax.net.ssl.trustStorePassword") == null) {
100            System.out.println("Using default SSL trust store password 'changeit'...");
101            System.setProperty("javax.net.ssl.trustStorePassword","changeit");
102        }
103        if (System.getProperty("javax.net.ssl.keyStore") == null) {
104            String store = System.getProperty("user.home")+"/.gwes-keystore.jks";
105            System.out.println("Using default SSL key store '"+store+"'...");
106            System.setProperty("javax.net.ssl.keyStore",store);
107        }
108        if (System.getProperty("javax.net.ssl.keyStorePassword") == null) {
109            System.out.println("Using default SSL key store password 'changeit'...");
110            System.setProperty("javax.net.ssl.keyStorePassword","changeit");
111        }
112    }
113 
114    private void copyDefaultJavaTruststore() throws IOException {
115        // copy default from java security directory and store with password.
116        File javadir = new File(System.getProperty("java.home") + File.separatorChar + "lib" + File.separatorChar + "security");
117        File javastore = new File(javadir, "jssecacerts");
118        if (!javastore.isFile()) {
119            javastore = new File(javadir, "cacerts");
120        }
121        System.out.println("Copying default truststore from "+javastore.getAbsolutePath() + " to "+ truststoreFile.getAbsolutePath() +"...");
122        FileInputStream in = new FileInputStream(javastore);
123        FileOutputStream out = new FileOutputStream(truststoreFile);
124        IOUtils.copy(in,out);
125        IOUtils.closeQuietly(in);
126        IOUtils.closeQuietly(out);
127    }
128 
129    /**
130     * Returns <code>true</code> if some certificate has been installed, <code>false</code> otherwise.
131     * @param host
132     * @param port
133     * @return
134     * @throws NoSuchAlgorithmException
135     * @throws KeyStoreException
136     * @throws IOException
137     * @throws KeyManagementException
138     * @throws CertificateException
139     */
140    public synchronized boolean installCert(String host, int port) throws NoSuchAlgorithmException, KeyStoreException, IOException, KeyManagementException, CertificateException {
141        System.out.println("Opening connection to " + host + ":" + port + "...");
142        chain = null;
143 
144        // setup truststore
145        try {
146            truststoreFile = new File(truststoreFileName);
147            if (!truststoreFile.isFile()) {
148//            copyDefaultJavaTruststore();
149//            setTrustStorePassword();
150                writeEmptyTrustStore();
151            }
152            loadTrustStore();
153            TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
154            tmf.init(truststore);
155            tm =  (X509TrustManager) tmf.getTrustManagers()[0];
156        } catch (IOException e) {
157            System.out.println("##############################################################################################");
158            System.out.println("TrustStore IOException:");
159            System.out.println(e.getMessage());
160            System.out.println("##############################################################################################");
161            System.out.println("Please use Java property -Djavax.net.ssl.trustStorePassword=<TrustStorePassword> for setting passphrase!");
162            return false;
163        }
164 
165        // setup keystore
166        try {
167            keystoreFile = new File(keystoreFileName);
168            if (!keystoreFile.isFile()) {
169                writeEmptyKeyStore();
170            }
171            loadKeyStore();
172            KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
173            kmf.init(keystore, keystorePassphrase.toCharArray());
174            kms = new X509KeyManager[]{(X509KeyManager)kmf.getKeyManagers()[0]};
175        } catch (FileNotFoundException e) {
176            System.out.println("##############################################################################################");
177            System.out.println("KeyStore FileNotFoundException:");
178            System.out.println(e.getMessage());
179            System.out.println("##############################################################################################");
180            System.out.println("Please create private keystore '"+keystoreFile+"'!");
181            return false;
182        } catch (IOException e) {
183            System.out.println("##############################################################################################");
184            System.out.println("KeyStore IOException:");
185            System.out.println(e.getMessage());
186            System.out.println("##############################################################################################");
187            System.out.println("Please use Java property -Djavax.net.ssl.keyStorePassword=<KeyStorePassword> for setting passphrase!");
188            return false;
189        } catch (UnrecoverableKeyException e) {
190            System.out.println("##############################################################################################");
191            System.out.println("UnrecoverableKeyException:");
192            System.out.println(e.getMessage());
193            System.out.println("##############################################################################################");
194            System.out.println("Please check the passphrase of the key within the keystore '"+keystoreFile+"'!");
195            return false;
196        }
197 
198        // setup context
199        SSLContext context = SSLContext.getInstance("TLS");
200        context.init(kms, new TrustManager[]{this}, null);
201        SSLSocketFactory socketFactory = context.getSocketFactory();
202        SSLSocket socket = (SSLSocket) socketFactory.createSocket(host, port);
203        socket.setSoTimeout(10000);
204        try {
205            System.out.println("Starting SSL handshake...");
206            socket.startHandshake();
207            socket.close();
208            System.out.println();
209            System.out.println("No errors, certificate is already trusted");
210            printCertificateChain();
211            return false;
212        } catch (javax.net.ssl.SSLHandshakeException e) {
213            System.out.println();
214            System.out.println("##############################################################################################");
215            System.out.println("SSL Handshake Exception:");
216            System.out.println(e.getMessage());
217            System.out.println("##############################################################################################");
218            if (chain == null) {
219                System.out.println("Could not obtain server certificate chain");
220                return false;
221            }
222 
223            // PKIX path building failed --> server cert not trusted
224            if (e.getCause() instanceof sun.security.validator.ValidatorException) {
225                System.out.println("Server certificate not trusted.");
226                return addCertificateToTrustStore(host);
227            }
228            // Other handshake exception
229            if (e.getMessage().indexOf("Received fatal alert: bad_certificate")!=-1) {
230                System.out.println("Please import your private key and certificate into keystore '"+keystoreFileName+"'!");
231                System.out.println("For example using 'keytool':");
232                System.out.println("  keytool -importkeystore -srckeystore <user.p12> -srcstoretype pkcs12 -srcstorepass <keypass> -destkeystore "+keystoreFileName+" -deststoretype jks -deststorepass <keypass>");
233                System.out.println("Replace <user.p12> by the filename of your PKCS12 user key/cert and <keypass> by the corresponding passphrase!");
234                return false;
235            }
236            System.out.println("Unsupported Exception:");
237            e.printStackTrace(System.out);
238        } catch (javax.net.ssl.SSLException e) {
239            System.out.println();
240            System.out.println("##############################################################################################");
241            System.out.println("SSL Exception:");
242            System.out.println(e.getMessage());
243            System.out.println("##############################################################################################");
244            if (chain == null) {
245                System.out.println("Could not obtain server certificate chain");
246                return false;
247            }
248            if (e.getMessage().indexOf("the trustAnchors parameter must be non-empty") != -1) {
249                System.out.println("Truststore is empty. Add server certificate.");
250                return addCertificateToTrustStore(host);
251            }
252            System.out.println("Unsupported Exception:");
253            e.printStackTrace(System.out);
254        }
255 
256        return false;
257    }
258 
259    private boolean addCertificateToTrustStore(String host) throws NoSuchAlgorithmException, IOException, KeyStoreException, CertificateException {
260        printCertificateChain();
261        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
262        System.out.println("Enter certificate to add to truststore or 'q' to quit: [1]");
263        String line = reader.readLine().trim();
264        int k;
265        try {
266            k = (line.length() == 0) ? 0 : Integer.parseInt(line) - 1;
267        } catch (NumberFormatException e) {
268            System.out.println("truststore not changed");
269            return false;
270        }
271 
272        X509Certificate cert = chain[k];
273        String alias = host + "-" + (k + 1);
274        truststore.setCertificateEntry(alias, cert);
275        writeTrustStore();
276 
277        System.out.println();
278        System.out.println(cert);
279        System.out.println();
280        System.out.println("Added certificate to truststore '"+ truststoreFile.getAbsolutePath() + "' using alias '" + alias + "'");
281        return true;
282    }
283 
284    private void writeEmptyTrustStore() throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException {
285        System.out.println("Creating empty truststore '" + truststoreFile + "'...");
286        truststore = KeyStore.getInstance(KeyStore.getDefaultType());
287        truststore.load(null,(truststorePassphrase ==null ? null : truststorePassphrase.toCharArray()));
288        writeTrustStore();
289    }
290 
291    private void writeEmptyKeyStore() throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException {
292        System.out.println("Creating empty keystore '" + keystoreFile + "'...");
293        keystore = KeyStore.getInstance(KeyStore.getDefaultType());
294        keystore.load(null,(keystorePassphrase ==null ? null : keystorePassphrase.toCharArray()));
295        writeKeyStore();
296    }
297 
298    private void loadTrustStore() throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException {
299        // load ca certificate truststore
300        System.out.println("Loading truststore '" + truststoreFile + "'...");
301        truststore = KeyStore.getInstance(KeyStore.getDefaultType());
302        if (truststoreFile.length()>0L) {
303            InputStream in = new FileInputStream(truststoreFile);
304            truststore.load(in, (truststorePassphrase ==null ? null : truststorePassphrase.toCharArray()));
305            in.close();
306        } else {
307            truststore.load(null, (truststorePassphrase ==null ? null : truststorePassphrase.toCharArray()));
308        }
309    }
310 
311    private void loadKeyStore() throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException {
312        // load keystore
313        System.out.println("Loading keystore '" + keystoreFile + "'...");
314        keystore = KeyStore.getInstance(KeyStore.getDefaultType());
315        if (keystoreFile.length()>0L) {
316            InputStream in = new FileInputStream(keystoreFile);
317            keystore.load(in, (keystorePassphrase ==null ? null : keystorePassphrase.toCharArray()));
318            in.close();
319        } else {
320            keystore.load(null, (keystorePassphrase ==null ? null : keystorePassphrase.toCharArray()));
321        }
322    }
323 
324    private void writeTrustStore() throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException {
325        System.out.println("Writing truststore '" + truststoreFile + "'...");
326        OutputStream out = new FileOutputStream(truststoreFile);
327        truststore.store(out, (truststorePassphrase ==null ? "".toCharArray() : truststorePassphrase.toCharArray()));
328        out.close();
329    }
330 
331    private void writeKeyStore() throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException {
332        System.out.println("Writing keystore '" + keystoreFile + "'...");
333        OutputStream out = new FileOutputStream(keystoreFile);
334        keystore.store(out, (keystorePassphrase ==null ? "".toCharArray() : keystorePassphrase.toCharArray()));
335        out.close();
336    }
337 
338    private void setTrustStorePassword() throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException {
339        System.out.println("Setting password for new truststore '" + truststoreFile + "'...");
340        InputStream in = new FileInputStream(truststoreFile);
341        truststore = KeyStore.getInstance(KeyStore.getDefaultType());
342        truststore.load(in, null);
343        in.close();
344        writeTrustStore();
345    }
346 
347    private void printCertificateChain() throws CertificateEncodingException, NoSuchAlgorithmException {
348        System.out.println();
349        System.out.println("Server sent " + chain.length + " certificate(s):");
350        System.out.println();
351        MessageDigest sha1 = MessageDigest.getInstance("SHA1");
352        MessageDigest md5 = MessageDigest.getInstance("MD5");
353        for (int i = 0; i < chain.length; i++) {
354            X509Certificate cert = chain[i];
355            System.out.println
356                    (" " + (i + 1) + " Subject    " + cert.getSubjectDN());
357            System.out.println("   Issuer     " + cert.getIssuerDN());
358            sha1.update(cert.getEncoded());
359            System.out.println("   Valid from "+cert.getNotBefore());
360            System.out.println("   Valid util "+cert.getNotAfter());
361            System.out.println("   sha1       " + toHexString(sha1.digest()));
362            md5.update(cert.getEncoded());
363            System.out.println("   md5        " + toHexString(md5.digest()));
364            System.out.println();
365        }
366    }
367 
368    private static final char[] HEXDIGITS = "0123456789abcdef".toCharArray();
369 
370    private static String toHexString(byte[] bytes) {
371        StringBuilder sb = new StringBuilder(bytes.length * 3);
372        for (int b : bytes) {
373            b &= 0xff;
374            sb.append(HEXDIGITS[b >> 4]);
375            sb.append(HEXDIGITS[b & 15]);
376            sb.append(' ');
377        }
378        return sb.toString();
379    }
380 
381    public X509Certificate[] getAcceptedIssuers() {
382        System.out.println("UnsupportedOperationException: getAcceptedIssuers()...");
383        throw new UnsupportedOperationException();
384    }
385 
386    public void checkClientTrusted(X509Certificate[] chain, String authType)
387            throws CertificateException {
388        System.out.println("UnsupportedOperationException: checkClientTrusted()...");
389        throw new UnsupportedOperationException();
390    }
391 
392    public void checkServerTrusted(X509Certificate[] chain, String authType)
393            throws CertificateException {
394        this.chain = chain;
395        tm.checkServerTrusted(chain, authType);
396    }
397 
398    public static void main(String[] args) throws Exception {
399        String host;
400        int port;
401        if (args.length == 1) {
402            String[] c = args[0].split(":");
403            host = c[0];
404            port = (c.length == 1) ? 443 : Integer.parseInt(c[1]);
405        } else {
406            System.out.println("--------------------------------------------------------------");
407            System.out.println("Usage: java CertUtils <host>[:port]");
408            System.out.println("--------------------------------------------------------------");
409            System.out.println("     The following java properties are supported:");
410            System.out.println("       -Djavax.net.ssl.trustStore=<TrustStoreFileName>");
411            System.out.println("       -Djavax.net.ssl.trustStorePassword=<TrustStorePassword>");
412            System.out.println("       -Djavax.net.ssl.keyStore=<KeyStoreFileName>");
413            System.out.println("       -Djavax.net.ssl.keyStorePassword=<KeyStorePassword>");
414            System.out.println("--------------------------------------------------------------");
415            return;
416        }
417 
418        boolean next = true;
419        while (next) {
420            next = CertUtils.getInstance().installCert(host,port);
421        }
422        
423    }
424 
425}

[all classes][net.kwfgrid.gwes.client]
EMMA 2.0.5312 (C) Vladimir Roubtsov