View Javadoc

1   /*
2   Copyright (C) 2000 - 2007 Grid Systems, S.A.
3   
4   This program is free software; you can redistribute it and/or modify
5   it under the terms of the GNU General Public License, version 2, as
6   published by the Free Software Foundation.
7   
8   This program is distributed in the hope that it will be useful,
9   but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU General Public License for more details.
12  
13  You should have received a copy of the GNU General Public License
14  along with this program; if not, write to the Free Software
15  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  */
17  package com.gridsystems.innergrid.api;
18  
19  import java.io.File;
20  import java.io.FileInputStream;
21  import java.io.FileNotFoundException;
22  import java.io.IOException;
23  import java.io.InputStream;
24  import java.security.KeyManagementException;
25  import java.security.KeyStore;
26  import java.security.KeyStoreException;
27  import java.security.NoSuchAlgorithmException;
28  import java.security.UnrecoverableKeyException;
29  import java.security.cert.CertificateException;
30  
31  import javax.net.ssl.KeyManagerFactory;
32  import javax.net.ssl.SSLContext;
33  import javax.net.ssl.SSLSocketFactory;
34  import javax.net.ssl.TrustManager;
35  import javax.net.ssl.TrustManagerFactory;
36  
37  import com.gridsystems.innergrid.kernel.KernelException;
38  
39  /**
40   * SSLConnectionInfo implementation to accept any certificate from a given keystore file.
41   *
42   * @author Xmas
43   * @author Rodrigo Ruiz
44   * @version 2.0
45   */
46  public class AcceptCertificateOfKeyStore implements SSLConnectionInfo {
47  
48    /**
49     * Path to the Keystore file.
50     */
51    private File keystorefile;
52  
53    /**
54     * Password to access the Keystore file.
55     */
56    private String keystorepassword;
57  
58    /**
59     * Constructor.
60     *
61     * @param kfilepath a string with the path to the Keystore file.
62     * @param kpassword a string with the password to access the Keystore file.
63     */
64    public AcceptCertificateOfKeyStore(String kfilepath, String kpassword) {
65      this(new File(kfilepath), kpassword);
66    }
67  
68    /**
69     * Constructor.
70     *
71     * @param kfile     The Keystore file.
72     * @param kpassword The password to access the Keystore file.
73     */
74    public AcceptCertificateOfKeyStore(File kfile, String kpassword) {
75      keystorefile = kfile;
76      keystorepassword = kpassword;
77    }
78  
79    /**
80     * Gets the path to the Keystore file.
81     *
82     * @return a string with the path to the Keystore file.
83     */
84    public String getKeystoreFile() {
85      return keystorefile.getPath();
86    }
87  
88    /**
89     * Gets the path to the Keystore file.
90     *
91     * @return a string with the path to the Keystore file.
92     */
93    public File getKeystore() {
94      return keystorefile;
95    }
96  
97    /**
98     * Gets the password to access the Keystore file.
99     *
100    * @return a string with the password to access the Keystore file.
101    */
102   public String getKeystorePassword() {
103     return (keystorepassword);
104   }
105 
106   /**
107    * Get SSL Socket Factory For use with KeyStore file.
108    *
109    * @return A SSLSocketFactory to establish connection
110    * @throws KernelException If error
111    */
112   public SSLSocketFactory getSSLSocketFactory() throws KernelException {
113 
114     File keystoreFile = getKeystore();
115     if (!keystoreFile.exists()) {
116       // CLT032=Can not read keystore file ({0})
117       throw new CKernelException("CLT032", keystoreFile.getPath());
118     }
119 
120     String keystorePass = getKeystorePassword();
121     if (keystorePass == null) {
122       keystorePass = "changeit";
123     }
124 
125     // You can't use ssl without a server certificate.
126     // Create a KeyStore ( to get server certs )
127     KeyStore kstore = initKeyStore(keystoreFile, keystorePass);
128 
129     //  protocol for the SSL ie - TLS, SSL v3 etc.
130     final String algorithm = "SunX509";
131 
132     try {
133 
134       //  Key manager will extract the server key
135       KeyManagerFactory kmf = KeyManagerFactory.getInstance(algorithm);
136       kmf.init(kstore, keystorePass.toCharArray());
137 
138       //  Algorithm used to encode the certificate ie - SunX509
139       TrustManagerFactory tmf;
140       tmf = TrustManagerFactory.getInstance(algorithm);
141       tmf.init(kstore);
142 
143       //  If client authentication is needed, set up TrustManager
144       TrustManager[] tm = null;
145       tm = tmf.getTrustManagers();
146 
147       // Create a SSLContext ( to create the ssl factory )
148       // This is the only way to use server sockets with JSSE 1.0.1
149       final String protocol = "TLS";
150       SSLContext context = SSLContext.getInstance(protocol); // SSL
151 
152       // initialize context with the key managers
153       context.init(kmf.getKeyManagers(), tm, new java.security.SecureRandom());
154       return (SSLSocketFactory) context.getSocketFactory();
155 
156     } catch (NoSuchAlgorithmException e) {
157       // CLT031=Certificate verify failed
158       throw new CKernelException(e, "CLT031");
159     } catch (KeyStoreException e) {
160       // CLT031=Certificate verify failed
161       throw new CKernelException(e, "CLT031");
162     } catch (UnrecoverableKeyException e) {
163       // CLT031=Certificate verify failed
164       throw new CKernelException(e, "CLT031");
165     } catch (KeyManagementException e) {
166       // CLT031=Certificate verify failed
167       throw new CKernelException(e, "CLT031");
168     }
169   }
170 
171   /**
172    * Initializes a keystore.
173    *
174    * @param keystoreFile Path to keystore file
175    * @param keyPass Password to access to keystore
176    *
177    * @return keystore Information of file if KeyStore class format
178    * @throws KernelException If error
179    */
180   private KeyStore initKeyStore(File keystoreFile, String keyPass)
181     throws KernelException {
182 
183     String path = keystoreFile.getAbsolutePath();
184     try {
185       final String defaultKeystoreType = "JKS";
186       KeyStore kstore = KeyStore.getInstance(defaultKeystoreType);
187       InputStream istream = new FileInputStream(keystoreFile);
188       kstore.load(istream, keyPass.toCharArray());
189       return kstore;
190     } catch (FileNotFoundException fnfe) {
191       fnfe.printStackTrace();
192       // CLT032=Can not read keystore file ({0})
193       throw new CKernelException(fnfe, "CLT032", path);
194     } catch (IOException ioe) {
195       ioe.printStackTrace();
196       // CLT033=Keystore file is not valid ({0}) or incorrect password
197       throw new CKernelException(ioe, "CLT033", path);
198     } catch (KeyStoreException e) {
199       e.printStackTrace();
200       // CLT031=Certificate verify failed
201       throw new CKernelException(e, "CLT031");
202     } catch (NoSuchAlgorithmException e) {
203       e.printStackTrace();
204       // CLT031=Certificate verify failed
205       throw new CKernelException(e, "CLT031");
206     } catch (CertificateException e) {
207       e.printStackTrace();
208       // CLT031=Certificate verify failed
209       throw new CKernelException(e, "CLT031");
210     }
211   }
212 }