6477 |
12 Jun 14 |
nicklas |
1 |
/** |
6477 |
12 Jun 14 |
nicklas |
$Id: SSLUtil.java 5870 2011-11-11 09:55:23Z nicklas $ |
6477 |
12 Jun 14 |
nicklas |
3 |
|
6477 |
12 Jun 14 |
nicklas |
Copyright (C) 2010 Nicklas Nordborg |
6477 |
12 Jun 14 |
nicklas |
5 |
|
6477 |
12 Jun 14 |
nicklas |
This file is part of BASE - BioArray Software Environment. |
6477 |
12 Jun 14 |
nicklas |
Available at http://base.thep.lu.se/ |
6477 |
12 Jun 14 |
nicklas |
8 |
|
6477 |
12 Jun 14 |
nicklas |
BASE is free software; you can redistribute it and/or |
6477 |
12 Jun 14 |
nicklas |
modify it under the terms of the GNU General Public License |
6477 |
12 Jun 14 |
nicklas |
as published by the Free Software Foundation; either version 3 |
6477 |
12 Jun 14 |
nicklas |
of the License, or (at your option) any later version. |
6477 |
12 Jun 14 |
nicklas |
13 |
|
6477 |
12 Jun 14 |
nicklas |
BASE is distributed in the hope that it will be useful, |
6477 |
12 Jun 14 |
nicklas |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
6477 |
12 Jun 14 |
nicklas |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
6477 |
12 Jun 14 |
nicklas |
GNU General Public License for more details. |
6477 |
12 Jun 14 |
nicklas |
18 |
|
6477 |
12 Jun 14 |
nicklas |
You should have received a copy of the GNU General Public License |
6477 |
12 Jun 14 |
nicklas |
along with BASE. If not, see <http://www.gnu.org/licenses/>. |
6477 |
12 Jun 14 |
nicklas |
21 |
*/ |
6477 |
12 Jun 14 |
nicklas |
22 |
package net.sf.basedb.util.ssl; |
6477 |
12 Jun 14 |
nicklas |
23 |
|
6477 |
12 Jun 14 |
nicklas |
24 |
import java.io.ByteArrayInputStream; |
6477 |
12 Jun 14 |
nicklas |
25 |
import java.io.FileInputStream; |
6477 |
12 Jun 14 |
nicklas |
26 |
import java.io.IOException; |
6477 |
12 Jun 14 |
nicklas |
27 |
import java.io.InputStream; |
6601 |
17 Nov 14 |
nicklas |
28 |
import java.net.Socket; |
6477 |
12 Jun 14 |
nicklas |
29 |
import java.security.KeyStore; |
6477 |
12 Jun 14 |
nicklas |
30 |
import java.security.KeyStoreException; |
6477 |
12 Jun 14 |
nicklas |
31 |
import java.security.NoSuchAlgorithmException; |
6477 |
12 Jun 14 |
nicklas |
32 |
import java.security.NoSuchProviderException; |
6477 |
12 Jun 14 |
nicklas |
33 |
import java.security.UnrecoverableKeyException; |
6477 |
12 Jun 14 |
nicklas |
34 |
import java.security.cert.Certificate; |
6477 |
12 Jun 14 |
nicklas |
35 |
import java.security.cert.CertificateException; |
6477 |
12 Jun 14 |
nicklas |
36 |
import java.security.cert.CertificateFactory; |
6477 |
12 Jun 14 |
nicklas |
37 |
import java.security.cert.X509Certificate; |
6477 |
12 Jun 14 |
nicklas |
38 |
|
6477 |
12 Jun 14 |
nicklas |
39 |
import javax.net.ssl.KeyManager; |
6477 |
12 Jun 14 |
nicklas |
40 |
import javax.net.ssl.KeyManagerFactory; |
6477 |
12 Jun 14 |
nicklas |
41 |
import javax.net.ssl.SSLContext; |
6477 |
12 Jun 14 |
nicklas |
42 |
import javax.net.ssl.TrustManager; |
6477 |
12 Jun 14 |
nicklas |
43 |
import javax.net.ssl.TrustManagerFactory; |
6477 |
12 Jun 14 |
nicklas |
44 |
|
6477 |
12 Jun 14 |
nicklas |
45 |
import org.apache.http.conn.ssl.SSLConnectionSocketFactory; |
6601 |
17 Nov 14 |
nicklas |
46 |
import org.apache.http.protocol.HttpContext; |
6477 |
12 Jun 14 |
nicklas |
47 |
|
6477 |
12 Jun 14 |
nicklas |
48 |
import net.sf.basedb.core.BaseException; |
6477 |
12 Jun 14 |
nicklas |
49 |
import net.sf.basedb.core.Config; |
6477 |
12 Jun 14 |
nicklas |
50 |
|
6477 |
12 Jun 14 |
nicklas |
51 |
/** |
6477 |
12 Jun 14 |
nicklas |
Utility class for working with SSL connections. |
6477 |
12 Jun 14 |
nicklas |
53 |
|
6477 |
12 Jun 14 |
nicklas |
@author Nicklas |
6477 |
12 Jun 14 |
nicklas |
@since 3.4 |
6477 |
12 Jun 14 |
nicklas |
56 |
*/ |
6477 |
12 Jun 14 |
nicklas |
57 |
public class SSLUtil2 |
6477 |
12 Jun 14 |
nicklas |
58 |
{ |
6477 |
12 Jun 14 |
nicklas |
59 |
|
6477 |
12 Jun 14 |
nicklas |
60 |
private static KeyManager[] defaultKeyManagers; |
6477 |
12 Jun 14 |
nicklas |
61 |
private static TrustManager[] defaultTrustManagers; |
6477 |
12 Jun 14 |
nicklas |
62 |
private static SSLConnectionSocketFactory defaultSocketFactory; |
6477 |
12 Jun 14 |
nicklas |
63 |
|
6477 |
12 Jun 14 |
nicklas |
64 |
/** |
6477 |
12 Jun 14 |
nicklas |
Get a SSL Socket Factory object that is used to create SSL sockets. |
6477 |
12 Jun 14 |
nicklas |
66 |
|
6477 |
12 Jun 14 |
nicklas |
Unless a key-store and/or trust-store has been configured this method returns a |
6477 |
12 Jun 14 |
nicklas |
default socket factory provided by {@link SSLConnectionSocketFactory}. |
6477 |
12 Jun 14 |
nicklas |
<p> |
6477 |
12 Jun 14 |
nicklas |
A key-store is used to store personal certificates that are used for |
6477 |
12 Jun 14 |
nicklas |
authentication with the server. A key-store can be setup with the |
6477 |
12 Jun 14 |
nicklas |
following configuration options in base.config. |
6477 |
12 Jun 14 |
nicklas |
73 |
|
6477 |
12 Jun 14 |
nicklas |
<ul> |
6477 |
12 Jun 14 |
nicklas |
<li>ssl.keystore.file: The full path to a file containing certificate keys. |
6477 |
12 Jun 14 |
nicklas |
<li>ssl.keystore.password: The password that is required to unlock the certificates. |
6477 |
12 Jun 14 |
nicklas |
All certificates must use the same password. |
6477 |
12 Jun 14 |
nicklas |
<li>ssl.keystore.type (optional): The type of the keystore. The default value is 'JKS'. |
6477 |
12 Jun 14 |
nicklas |
<li>ssl.keystore.provider (optional): The cryptographic provider implementation to use. |
6477 |
12 Jun 14 |
nicklas |
If not specified the list of registered providers is searched. |
6477 |
12 Jun 14 |
nicklas |
<li>ssl.keystore.algorithm (optional): The encryption algorithm used in the keystore. |
6477 |
12 Jun 14 |
nicklas |
If not specified, 'SunX509' is used. |
6477 |
12 Jun 14 |
nicklas |
</ul> |
6477 |
12 Jun 14 |
nicklas |
84 |
|
6477 |
12 Jun 14 |
nicklas |
<p> |
6477 |
12 Jun 14 |
nicklas |
A trust-store is used to store public certificates of of servers that are trusted. |
6477 |
12 Jun 14 |
nicklas |
The default trust-store uses the certificates that are shipped with the java runtime |
6477 |
12 Jun 14 |
nicklas |
in $JAVA_HOME/jre/lib/security/cacerts. A trust-store can be setup with the following |
6477 |
12 Jun 14 |
nicklas |
configuration options in base.config. |
6477 |
12 Jun 14 |
nicklas |
90 |
|
6477 |
12 Jun 14 |
nicklas |
<ul> |
6477 |
12 Jun 14 |
nicklas |
<li>ssl.truststore.file: The full path to a file containing the certificates. |
6477 |
12 Jun 14 |
nicklas |
<li>ssl.truststore.password: The password that is required to unlock the certificates. |
6477 |
12 Jun 14 |
nicklas |
All certificates must use the same password. |
6477 |
12 Jun 14 |
nicklas |
<li>ssl.truststore.type (optional): The type of the keystore. The default value is 'JKS'. |
6477 |
12 Jun 14 |
nicklas |
<li>ssl.truststore.provider (optional): The cryptographic provider implementation to use. |
6477 |
12 Jun 14 |
nicklas |
If not specified the list of registered providers is searched. |
6477 |
12 Jun 14 |
nicklas |
<li>ssl.truststore.algorithm (optional): The encryption algorithm used in the keystore. |
6477 |
12 Jun 14 |
nicklas |
If not specified, 'PKIX' is used. |
6477 |
12 Jun 14 |
nicklas |
</ul> |
6477 |
12 Jun 14 |
nicklas |
101 |
|
6477 |
12 Jun 14 |
nicklas |
For more information about algorithms, keystore types, etc. see |
6477 |
12 Jun 14 |
nicklas |
<a href="http://java.sun.com/javase/6/docs/technotes/guides/security/jsse/JSSERefGuide.html"> |
6477 |
12 Jun 14 |
nicklas |
Java Secure Socket Extension Reference Guide</a> |
6477 |
12 Jun 14 |
nicklas |
105 |
|
6477 |
12 Jun 14 |
nicklas |
@return A SSL socket factory |
6477 |
12 Jun 14 |
nicklas |
107 |
*/ |
6477 |
12 Jun 14 |
nicklas |
108 |
public static SSLConnectionSocketFactory getSSLSocketFactory() |
6477 |
12 Jun 14 |
nicklas |
109 |
{ |
6477 |
12 Jun 14 |
nicklas |
110 |
if (defaultSocketFactory == null) |
6477 |
12 Jun 14 |
nicklas |
111 |
{ |
6477 |
12 Jun 14 |
nicklas |
112 |
String sslProtocol = Config.getString("ssl.context.protocol", "TLS"); |
6477 |
12 Jun 14 |
nicklas |
113 |
String sslProvider = Config.getString("ssl.context.provider"); |
6477 |
12 Jun 14 |
nicklas |
114 |
|
6477 |
12 Jun 14 |
nicklas |
115 |
try |
6477 |
12 Jun 14 |
nicklas |
116 |
{ |
6477 |
12 Jun 14 |
nicklas |
117 |
KeyManager[] keyManagers = getDefaultKeyManagers(); |
6477 |
12 Jun 14 |
nicklas |
118 |
TrustManager[] trustManagers = getDefaultTrustManagers(); |
6477 |
12 Jun 14 |
nicklas |
119 |
|
6477 |
12 Jun 14 |
nicklas |
120 |
if (keyManagers != null || trustManagers != null) |
6477 |
12 Jun 14 |
nicklas |
121 |
{ |
6477 |
12 Jun 14 |
nicklas |
122 |
SSLContext context = sslProvider == null ? |
6477 |
12 Jun 14 |
nicklas |
123 |
SSLContext.getInstance(sslProtocol) : |
6477 |
12 Jun 14 |
nicklas |
124 |
SSLContext.getInstance(sslProtocol, sslProvider); |
6477 |
12 Jun 14 |
nicklas |
125 |
context.init(keyManagers, trustManagers, null); |
6477 |
12 Jun 14 |
nicklas |
126 |
defaultSocketFactory = new SSLConnectionSocketFactory(context); |
6477 |
12 Jun 14 |
nicklas |
127 |
} |
6477 |
12 Jun 14 |
nicklas |
128 |
else |
6477 |
12 Jun 14 |
nicklas |
129 |
{ |
6477 |
12 Jun 14 |
nicklas |
130 |
defaultSocketFactory = new SSLConnectionSocketFactory(SSLContext.getDefault()); |
6477 |
12 Jun 14 |
nicklas |
131 |
} |
6477 |
12 Jun 14 |
nicklas |
132 |
} |
6477 |
12 Jun 14 |
nicklas |
133 |
catch (Exception ex) |
6477 |
12 Jun 14 |
nicklas |
134 |
{ |
6477 |
12 Jun 14 |
nicklas |
135 |
throw new BaseException(ex); |
6477 |
12 Jun 14 |
nicklas |
136 |
} |
6477 |
12 Jun 14 |
nicklas |
137 |
} |
6477 |
12 Jun 14 |
nicklas |
138 |
return defaultSocketFactory; |
6477 |
12 Jun 14 |
nicklas |
139 |
} |
6477 |
12 Jun 14 |
nicklas |
140 |
|
6497 |
26 Jun 14 |
nicklas |
141 |
|
6477 |
12 Jun 14 |
nicklas |
142 |
/** |
6497 |
26 Jun 14 |
nicklas |
Create a SSL context that optionally uses the given trusted server certificate |
6497 |
26 Jun 14 |
nicklas |
and client certificate. |
6477 |
12 Jun 14 |
nicklas |
145 |
|
6477 |
12 Jun 14 |
nicklas |
@param serverCertificate The trusted server certificate data or null to use |
6477 |
12 Jun 14 |
nicklas |
the default trusted certificates (see {@link #getSSLSocketFactory()}. The |
6477 |
12 Jun 14 |
nicklas |
data must represent a X.509 certificate in binary or base64-encoded DER |
6477 |
12 Jun 14 |
nicklas |
format |
6477 |
12 Jun 14 |
nicklas |
@param clientCertificate The client certificate to use for authorization with |
6477 |
12 Jun 14 |
nicklas |
the server or null to use the default certificates. The data must represent |
6477 |
12 Jun 14 |
nicklas |
a PKCS #12 cretificate in binary form |
6477 |
12 Jun 14 |
nicklas |
@param clientCertificatePassword A password used to unlock the client |
6477 |
12 Jun 14 |
nicklas |
certificate |
6497 |
26 Jun 14 |
nicklas |
@return A SSL context |
6477 |
12 Jun 14 |
nicklas |
156 |
*/ |
6497 |
26 Jun 14 |
nicklas |
157 |
public static SSLContext getSSLContext(byte[] serverCertificate, |
6497 |
26 Jun 14 |
nicklas |
158 |
byte[] clientCertificate, String clientCertificatePassword) |
6477 |
12 Jun 14 |
nicklas |
159 |
{ |
6477 |
12 Jun 14 |
nicklas |
160 |
String sslProtocol = Config.getString("ssl.context.protocol", "TLS"); |
6477 |
12 Jun 14 |
nicklas |
161 |
String sslProvider = Config.getString("ssl.context.provider"); |
6497 |
26 Jun 14 |
nicklas |
162 |
SSLContext context = null; |
6477 |
12 Jun 14 |
nicklas |
163 |
try |
6477 |
12 Jun 14 |
nicklas |
164 |
{ |
6477 |
12 Jun 14 |
nicklas |
165 |
KeyManager[] keyManagers = null; |
6477 |
12 Jun 14 |
nicklas |
166 |
if (clientCertificate != null) |
6477 |
12 Jun 14 |
nicklas |
167 |
{ |
6477 |
12 Jun 14 |
nicklas |
168 |
String provider = Config.getString("ssl.keystore.provider"); |
6477 |
12 Jun 14 |
nicklas |
169 |
String algorithm = Config.getString("ssl.keystore.algorithm", "SunX509"); |
6477 |
12 Jun 14 |
nicklas |
170 |
KeyStore keyStore = createKeyStore(new ByteArrayInputStream(clientCertificate), clientCertificatePassword, |
6477 |
12 Jun 14 |
nicklas |
171 |
"PKCS12", provider); |
6477 |
12 Jun 14 |
nicklas |
172 |
keyManagers = new KeyManager[] { |
6477 |
12 Jun 14 |
nicklas |
173 |
new StaticKeyManager(keyStore, null, clientCertificatePassword) |
6477 |
12 Jun 14 |
nicklas |
174 |
}; |
6477 |
12 Jun 14 |
nicklas |
175 |
} |
6477 |
12 Jun 14 |
nicklas |
176 |
else |
6477 |
12 Jun 14 |
nicklas |
177 |
{ |
6477 |
12 Jun 14 |
nicklas |
178 |
keyManagers = getDefaultKeyManagers(); |
6477 |
12 Jun 14 |
nicklas |
179 |
} |
6477 |
12 Jun 14 |
nicklas |
180 |
TrustManager[] trustManagers = null; |
6477 |
12 Jun 14 |
nicklas |
181 |
if (serverCertificate != null) |
6477 |
12 Jun 14 |
nicklas |
182 |
{ |
6477 |
12 Jun 14 |
nicklas |
183 |
String trustStoreType = Config.getString("ssl.truststore.type", "JKS"); |
6477 |
12 Jun 14 |
nicklas |
184 |
String trustStoreProvider = Config.getString("ssl.truststore.provider"); |
6477 |
12 Jun 14 |
nicklas |
185 |
String trustStoreAlgorithm = Config.getString("ssl.truststore.algorithm", "PKIX"); |
6477 |
12 Jun 14 |
nicklas |
186 |
Certificate cert = getCertificate(new ByteArrayInputStream(serverCertificate), "X.509", trustStoreProvider); |
6477 |
12 Jun 14 |
nicklas |
187 |
KeyStore keyStore = createKeyStore(null, null, trustStoreType, trustStoreProvider); |
6477 |
12 Jun 14 |
nicklas |
188 |
keyStore.setCertificateEntry("tmp", cert); |
6477 |
12 Jun 14 |
nicklas |
189 |
trustManagers = createTrustManagers(keyStore, trustStoreProvider, trustStoreAlgorithm); |
6477 |
12 Jun 14 |
nicklas |
190 |
} |
6477 |
12 Jun 14 |
nicklas |
191 |
else |
6477 |
12 Jun 14 |
nicklas |
192 |
{ |
6477 |
12 Jun 14 |
nicklas |
193 |
trustManagers = getDefaultTrustManagers(); |
6477 |
12 Jun 14 |
nicklas |
194 |
} |
6477 |
12 Jun 14 |
nicklas |
195 |
|
6477 |
12 Jun 14 |
nicklas |
196 |
if (keyManagers != null || trustManagers != null) |
6477 |
12 Jun 14 |
nicklas |
197 |
{ |
6497 |
26 Jun 14 |
nicklas |
198 |
context = sslProvider == null ? |
6477 |
12 Jun 14 |
nicklas |
199 |
SSLContext.getInstance(sslProtocol) : |
6477 |
12 Jun 14 |
nicklas |
200 |
SSLContext.getInstance(sslProtocol, sslProvider); |
6477 |
12 Jun 14 |
nicklas |
201 |
context.init(keyManagers, trustManagers, null); |
6477 |
12 Jun 14 |
nicklas |
202 |
} |
6477 |
12 Jun 14 |
nicklas |
203 |
else |
6477 |
12 Jun 14 |
nicklas |
204 |
{ |
6497 |
26 Jun 14 |
nicklas |
205 |
context = SSLContext.getDefault(); |
6477 |
12 Jun 14 |
nicklas |
206 |
} |
6477 |
12 Jun 14 |
nicklas |
207 |
} |
6477 |
12 Jun 14 |
nicklas |
208 |
catch (Exception ex) |
6477 |
12 Jun 14 |
nicklas |
209 |
{ |
6477 |
12 Jun 14 |
nicklas |
210 |
throw new BaseException(ex); |
6477 |
12 Jun 14 |
nicklas |
211 |
} |
6497 |
26 Jun 14 |
nicklas |
212 |
return context; |
6497 |
26 Jun 14 |
nicklas |
213 |
} |
6477 |
12 Jun 14 |
nicklas |
214 |
|
6497 |
26 Jun 14 |
nicklas |
215 |
|
6497 |
26 Jun 14 |
nicklas |
216 |
/** |
6497 |
26 Jun 14 |
nicklas |
Create a SSL socket factory that optionally uses the given trusted server certificate |
6497 |
26 Jun 14 |
nicklas |
and client certificate. If both parameters are null then the socket factory from |
6497 |
26 Jun 14 |
nicklas |
{@link #getSSLSocketFactory()} is returned. |
6497 |
26 Jun 14 |
nicklas |
220 |
|
6497 |
26 Jun 14 |
nicklas |
@param serverCertificate The trusted server certificate data or null to use |
6497 |
26 Jun 14 |
nicklas |
the default trusted certificates (see {@link #getSSLSocketFactory()}. The |
6497 |
26 Jun 14 |
nicklas |
data must represent a X.509 certificate in binary or base64-encoded DER |
6497 |
26 Jun 14 |
nicklas |
format |
6497 |
26 Jun 14 |
nicklas |
@param clientCertificate The client certificate to use for authorization with |
6497 |
26 Jun 14 |
nicklas |
the server or null to use the default certificates. The data must represent |
6497 |
26 Jun 14 |
nicklas |
a PKCS #12 cretificate in binary form |
6497 |
26 Jun 14 |
nicklas |
@param clientCertificatePassword A password used to unlock the client |
6497 |
26 Jun 14 |
nicklas |
certificate |
6497 |
26 Jun 14 |
nicklas |
@return A socket factory |
6497 |
26 Jun 14 |
nicklas |
231 |
*/ |
6497 |
26 Jun 14 |
nicklas |
232 |
public static SSLConnectionSocketFactory getSSLSocketFactory(byte[] serverCertificate, |
6497 |
26 Jun 14 |
nicklas |
233 |
byte[] clientCertificate, String clientCertificatePassword) |
6497 |
26 Jun 14 |
nicklas |
234 |
{ |
6497 |
26 Jun 14 |
nicklas |
235 |
if (serverCertificate == null && clientCertificate == null) |
6497 |
26 Jun 14 |
nicklas |
236 |
{ |
6497 |
26 Jun 14 |
nicklas |
237 |
return getSSLSocketFactory(); |
6497 |
26 Jun 14 |
nicklas |
238 |
} |
6497 |
26 Jun 14 |
nicklas |
239 |
SSLContext context = getSSLContext(serverCertificate, clientCertificate, clientCertificatePassword); |
6601 |
17 Nov 14 |
nicklas |
240 |
SSLConnectionSocketFactory factory = new SSLConnectionSocketFactory(context, new AllowAnyHostNameVerifyer()) |
6601 |
17 Nov 14 |
nicklas |
241 |
{ |
6601 |
17 Nov 14 |
nicklas |
242 |
/** |
6601 |
17 Nov 14 |
nicklas |
Override default socket creation since we want to null out the host name |
6601 |
17 Nov 14 |
nicklas |
in order to be able to connect to some "mis-configured" servers. This change |
6601 |
17 Nov 14 |
nicklas |
should effectively cause the same behaviour as if jsse.enableSNIExtension=false |
6601 |
17 Nov 14 |
nicklas |
has been set. |
6601 |
17 Nov 14 |
nicklas |
See http://stackoverflow.com/questions/7615645/ssl-handshake-alert-unrecognized-name-error-since-upgrade-to-java-1-7-0 |
6601 |
17 Nov 14 |
nicklas |
248 |
*/ |
6601 |
17 Nov 14 |
nicklas |
249 |
@Override |
6601 |
17 Nov 14 |
nicklas |
250 |
public Socket createLayeredSocket(Socket socket, String target, int port, HttpContext context) |
6601 |
17 Nov 14 |
nicklas |
251 |
throws IOException |
6601 |
17 Nov 14 |
nicklas |
252 |
{ |
6601 |
17 Nov 14 |
nicklas |
// 'null' instead of 'target' |
6601 |
17 Nov 14 |
nicklas |
254 |
return super.createLayeredSocket(socket, null, port, context); |
6601 |
17 Nov 14 |
nicklas |
255 |
} |
6601 |
17 Nov 14 |
nicklas |
256 |
|
6601 |
17 Nov 14 |
nicklas |
257 |
}; |
6477 |
12 Jun 14 |
nicklas |
258 |
return factory; |
6477 |
12 Jun 14 |
nicklas |
259 |
} |
6477 |
12 Jun 14 |
nicklas |
260 |
|
6477 |
12 Jun 14 |
nicklas |
261 |
/** |
6477 |
12 Jun 14 |
nicklas |
Get the default trust manages as configured in the base.config file by |
6477 |
12 Jun 14 |
nicklas |
ssl.truststore.* settings. |
6477 |
12 Jun 14 |
nicklas |
@return An array with trust managers or null if no trust-store file has been |
6477 |
12 Jun 14 |
nicklas |
configured |
6477 |
12 Jun 14 |
nicklas |
266 |
*/ |
6477 |
12 Jun 14 |
nicklas |
267 |
private static TrustManager[] getDefaultTrustManagers() |
6477 |
12 Jun 14 |
nicklas |
268 |
throws KeyStoreException, NoSuchAlgorithmException, CertificateException, |
6477 |
12 Jun 14 |
nicklas |
269 |
NoSuchProviderException, IOException |
6477 |
12 Jun 14 |
nicklas |
270 |
{ |
6477 |
12 Jun 14 |
nicklas |
271 |
if (defaultTrustManagers == null) |
6477 |
12 Jun 14 |
nicklas |
272 |
{ |
6477 |
12 Jun 14 |
nicklas |
273 |
String file = Config.getString("ssl.truststore.file"); |
6477 |
12 Jun 14 |
nicklas |
274 |
String password = Config.getString("ssl.truststore.password"); |
6477 |
12 Jun 14 |
nicklas |
275 |
String type = Config.getString("ssl.truststore.type", "JKS"); |
6477 |
12 Jun 14 |
nicklas |
276 |
String provider = Config.getString("ssl.truststore.provider"); |
6477 |
12 Jun 14 |
nicklas |
277 |
String algorithm = Config.getString("ssl.truststore.algorithm", "PKIX"); |
6477 |
12 Jun 14 |
nicklas |
278 |
|
6477 |
12 Jun 14 |
nicklas |
279 |
if (file == null) |
6477 |
12 Jun 14 |
nicklas |
280 |
{ |
6477 |
12 Jun 14 |
nicklas |
281 |
defaultTrustManagers = new TrustManager[0]; |
6477 |
12 Jun 14 |
nicklas |
282 |
} |
6477 |
12 Jun 14 |
nicklas |
283 |
else |
6477 |
12 Jun 14 |
nicklas |
284 |
{ |
6477 |
12 Jun 14 |
nicklas |
285 |
KeyStore keyStore = createKeyStore(new FileInputStream(file), password, type, provider); |
6477 |
12 Jun 14 |
nicklas |
286 |
createTrustManagers(keyStore, provider, algorithm); |
6477 |
12 Jun 14 |
nicklas |
287 |
} |
6477 |
12 Jun 14 |
nicklas |
288 |
|
6477 |
12 Jun 14 |
nicklas |
289 |
} |
6477 |
12 Jun 14 |
nicklas |
290 |
return defaultTrustManagers.length == 0 ? null : defaultTrustManagers; |
6477 |
12 Jun 14 |
nicklas |
291 |
} |
6477 |
12 Jun 14 |
nicklas |
292 |
|
6477 |
12 Jun 14 |
nicklas |
293 |
/** |
6477 |
12 Jun 14 |
nicklas |
Get the default keys manages as configured in the base.config file by |
6477 |
12 Jun 14 |
nicklas |
ssl.keystore.* settings. |
6477 |
12 Jun 14 |
nicklas |
@return An array with key managers or null if no key-store file has been |
6477 |
12 Jun 14 |
nicklas |
configured |
6477 |
12 Jun 14 |
nicklas |
298 |
*/ |
6477 |
12 Jun 14 |
nicklas |
299 |
private static KeyManager[] getDefaultKeyManagers() |
6477 |
12 Jun 14 |
nicklas |
300 |
throws UnrecoverableKeyException, KeyStoreException, NoSuchAlgorithmException, |
6477 |
12 Jun 14 |
nicklas |
301 |
CertificateException, NoSuchProviderException, IOException |
6477 |
12 Jun 14 |
nicklas |
302 |
{ |
6477 |
12 Jun 14 |
nicklas |
303 |
if (defaultKeyManagers == null) |
6477 |
12 Jun 14 |
nicklas |
304 |
{ |
6477 |
12 Jun 14 |
nicklas |
305 |
String file = Config.getString("ssl.keystore.file"); |
6477 |
12 Jun 14 |
nicklas |
306 |
String password = Config.getString("ssl.keystore.password"); |
6477 |
12 Jun 14 |
nicklas |
307 |
String type = Config.getString("ssl.keystore.type", "JKS"); |
6477 |
12 Jun 14 |
nicklas |
308 |
String provider = Config.getString("ssl.keystore.provider"); |
6477 |
12 Jun 14 |
nicklas |
309 |
String algorithm = Config.getString("ssl.keystore.algorithm", "SunX509"); |
6477 |
12 Jun 14 |
nicklas |
310 |
|
6477 |
12 Jun 14 |
nicklas |
311 |
if (file == null) |
6477 |
12 Jun 14 |
nicklas |
312 |
{ |
6477 |
12 Jun 14 |
nicklas |
313 |
defaultKeyManagers = new KeyManager[0]; |
6477 |
12 Jun 14 |
nicklas |
314 |
} |
6477 |
12 Jun 14 |
nicklas |
315 |
else |
6477 |
12 Jun 14 |
nicklas |
316 |
{ |
6477 |
12 Jun 14 |
nicklas |
317 |
KeyStore keyStore = createKeyStore(new FileInputStream(file), password, type, provider); |
6477 |
12 Jun 14 |
nicklas |
318 |
defaultKeyManagers = createKeyManagers(keyStore, password, provider, algorithm); |
6477 |
12 Jun 14 |
nicklas |
319 |
} |
6477 |
12 Jun 14 |
nicklas |
320 |
} |
6477 |
12 Jun 14 |
nicklas |
321 |
return defaultKeyManagers.length == 0 ? null : defaultKeyManagers; |
6477 |
12 Jun 14 |
nicklas |
322 |
} |
6477 |
12 Jun 14 |
nicklas |
323 |
|
6477 |
12 Jun 14 |
nicklas |
324 |
/** |
6477 |
12 Jun 14 |
nicklas |
Create a key-store from the given input stream |
6477 |
12 Jun 14 |
nicklas |
@param store The stream with key-store data |
6477 |
12 Jun 14 |
nicklas |
@param password The password to unlock the keystore |
6477 |
12 Jun 14 |
nicklas |
@return A KeyStore object |
6477 |
12 Jun 14 |
nicklas |
329 |
*/ |
6477 |
12 Jun 14 |
nicklas |
330 |
public static KeyStore createKeyStore(InputStream store, String password, String type, String provider) |
6477 |
12 Jun 14 |
nicklas |
331 |
throws KeyStoreException, NoSuchProviderException, NoSuchAlgorithmException, CertificateException, IOException |
6477 |
12 Jun 14 |
nicklas |
332 |
{ |
6477 |
12 Jun 14 |
nicklas |
333 |
char[] pw = password == null ? null : password.toCharArray(); |
6477 |
12 Jun 14 |
nicklas |
334 |
KeyStore keyStore = provider == null ? |
6477 |
12 Jun 14 |
nicklas |
335 |
KeyStore.getInstance(type) : |
6477 |
12 Jun 14 |
nicklas |
336 |
KeyStore.getInstance(type, provider); |
6477 |
12 Jun 14 |
nicklas |
337 |
keyStore.load(store, pw); |
6477 |
12 Jun 14 |
nicklas |
338 |
return keyStore; |
6477 |
12 Jun 14 |
nicklas |
339 |
} |
6477 |
12 Jun 14 |
nicklas |
340 |
|
6477 |
12 Jun 14 |
nicklas |
341 |
/** |
6477 |
12 Jun 14 |
nicklas |
Get the certificate that is found in the given input stream. |
6477 |
12 Jun 14 |
nicklas |
343 |
|
6477 |
12 Jun 14 |
nicklas |
@param cert The stream with the certificate information |
6477 |
12 Jun 14 |
nicklas |
@param type The type of the certificate, usually "X.509" |
6477 |
12 Jun 14 |
nicklas |
@return A Certificate object (can usually be subclassed to {@link X509Certificate} |
6477 |
12 Jun 14 |
nicklas |
347 |
*/ |
6477 |
12 Jun 14 |
nicklas |
348 |
public static Certificate getCertificate(InputStream cert, String type, String provider) |
6477 |
12 Jun 14 |
nicklas |
349 |
throws CertificateException, NoSuchProviderException |
6477 |
12 Jun 14 |
nicklas |
350 |
{ |
6477 |
12 Jun 14 |
nicklas |
351 |
CertificateFactory factory = provider == null ? |
6477 |
12 Jun 14 |
nicklas |
352 |
CertificateFactory.getInstance(type) : |
6477 |
12 Jun 14 |
nicklas |
353 |
CertificateFactory.getInstance(type, provider); |
6477 |
12 Jun 14 |
nicklas |
354 |
return factory.generateCertificate(cert); |
6477 |
12 Jun 14 |
nicklas |
355 |
} |
6477 |
12 Jun 14 |
nicklas |
356 |
|
6477 |
12 Jun 14 |
nicklas |
357 |
private static KeyManager[] createKeyManagers(KeyStore keyStore, String password, String provider, String algorithm) |
6477 |
12 Jun 14 |
nicklas |
358 |
throws KeyStoreException, NoSuchAlgorithmException, CertificateException, |
6477 |
12 Jun 14 |
nicklas |
359 |
IOException, UnrecoverableKeyException, NoSuchProviderException |
6477 |
12 Jun 14 |
nicklas |
360 |
{ |
6477 |
12 Jun 14 |
nicklas |
361 |
char[] pw = password == null ? null : password.toCharArray(); |
6477 |
12 Jun 14 |
nicklas |
362 |
|
6477 |
12 Jun 14 |
nicklas |
// Create key manager factory |
6477 |
12 Jun 14 |
nicklas |
364 |
KeyManagerFactory keyManagerFactory = provider == null ? |
6477 |
12 Jun 14 |
nicklas |
365 |
KeyManagerFactory.getInstance(algorithm) : |
6477 |
12 Jun 14 |
nicklas |
366 |
KeyManagerFactory.getInstance(algorithm, provider); |
6477 |
12 Jun 14 |
nicklas |
367 |
keyManagerFactory.init(keyStore, pw); |
6477 |
12 Jun 14 |
nicklas |
368 |
return keyManagerFactory.getKeyManagers(); |
6477 |
12 Jun 14 |
nicklas |
369 |
} |
6477 |
12 Jun 14 |
nicklas |
370 |
|
6477 |
12 Jun 14 |
nicklas |
371 |
private static TrustManager[] createTrustManagers(KeyStore keyStore, String provider, String algorithm) |
6477 |
12 Jun 14 |
nicklas |
372 |
throws KeyStoreException, NoSuchAlgorithmException, CertificateException, |
6477 |
12 Jun 14 |
nicklas |
373 |
IOException, NoSuchProviderException |
6477 |
12 Jun 14 |
nicklas |
374 |
{ |
6477 |
12 Jun 14 |
nicklas |
// Create trust manager factory |
6477 |
12 Jun 14 |
nicklas |
376 |
TrustManagerFactory trustManagerFactory = provider == null ? |
6477 |
12 Jun 14 |
nicklas |
377 |
TrustManagerFactory.getInstance(algorithm) : |
6477 |
12 Jun 14 |
nicklas |
378 |
TrustManagerFactory.getInstance(algorithm, provider); |
6477 |
12 Jun 14 |
nicklas |
379 |
trustManagerFactory.init(keyStore); |
6477 |
12 Jun 14 |
nicklas |
380 |
return trustManagerFactory.getTrustManagers(); |
6477 |
12 Jun 14 |
nicklas |
381 |
} |
6477 |
12 Jun 14 |
nicklas |
382 |
|
6477 |
12 Jun 14 |
nicklas |
383 |
|
6477 |
12 Jun 14 |
nicklas |
384 |
} |