Version 5.1 by Pascal Robert on 2007/09/03 19:33

Hide last authors
Pascal Robert 4.1 1 == Francis Labrie ==
smmccraw 1.1 2
3 Sometimes, it's would be useful to relax the Java security manager to allow connection to secure HTTP server using self-signed certificate, especially during development phase. To avoid Java exception on HTTPS connection, it's possible to add self signed certificate to the Java trusted X509 certificate repository using Java keystore command line tool:
4
Francis Labrie 3.1 5 {{noformat}}
smmccraw 1.1 6
Francis Labrie 3.1 7 % cd /Library/Java/Home/lib/security
8 % sudo keytool -import -keystore cacerts -alias anAlias -file aCertificate
smmccraw 1.1 9
Francis Labrie 3.1 10 {{/noformat}}
smmccraw 1.1 11
12 (The default password for the "cacerts" keystore is "changeit")
13
14 But this can be painful, even more if the application must be tested with various servers using self-signed or bad defined certificate. And if a server is using a certificate with a hostname different from the one you use to test it, it will still fail.
15
Pascal Robert 5.1 16 It's also possible to change the {{code language="none"}}TrustManager{{/code}} and {{code language="none"}}HostnameVerifier{{/code}} in Java code, but the API did change from JDK 1.3 and 1.4. Unfortunately, the old deprecated {{code language="none"}}"com.sun.net.ssl"{{/code}} package is still available, making setting of a custom {{code language="none"}}TrustManager{{/code}} and {{code language="none"}}HostnameVerifier{{/code}} a bit difficult.
smmccraw 1.1 17
18 So I've created an utility class that allow relaxing of the SSL trust rules. Simply add it to a package, an application or a framework, and call:
19
Pascal Robert 5.1 20 * {{code language="none"}}SSLUtilities.trustAllHostnames(){{/code}} to turn off the default hostname verification on HTTPS connection;
21 * {{code language="none"}}SSLUtilities.trustAllHttpsCertificates(){{/code}} to turn off the default certificate validation on HTTPS connection.
smmccraw 1.1 22
Pascal Robert 5.1 23 {{code title="SSLUtilities.java" 0="java"}}
smmccraw 1.1 24
Francis Labrie 3.1 25 import java.security.GeneralSecurityException;
26 import java.security.SecureRandom;
27 import java.security.cert.X509Certificate;
28 import javax.net.ssl.HostnameVerifier;
29 import javax.net.ssl.HttpsURLConnection;
30 import javax.net.ssl.SSLContext;
31 import javax.net.ssl.TrustManager;
32 import javax.net.ssl.X509TrustManager;
33
34 /**
Pascal Robert 4.1 35 * This class provide various static methods that relax X509 certificate and
Francis Labrie 3.1 36 * hostname verification while using the SSL over the HTTP protocol.
37 *
38 * @author Francis Labrie
39 */
40 public final class SSLUtilities {
Pascal Robert 4.1 41
smmccraw 1.1 42 /**
Francis Labrie 3.1 43 * Hostname verifier for the Sun's deprecated API.
smmccraw 1.1 44 *
Francis Labrie 3.1 45 * @deprecated see {@link #_hostnameVerifier}.
smmccraw 1.1 46 */
Francis Labrie 3.1 47 private static com.sun.net.ssl.HostnameVerifier __hostnameVerifier;
48 /**
49 * Thrust managers for the Sun's deprecated API.
50 *
51 * @deprecated see {@link #_trustManagers}.
52 */
53 private static com.sun.net.ssl.TrustManager[] __trustManagers;
54 /**
55 * Hostname verifier.
56 */
57 private static HostnameVerifier _hostnameVerifier;
58 /**
59 * Thrust managers.
60 */
61 private static TrustManager[] _trustManagers;
62
63
64 /**
Pascal Robert 4.1 65 * Set the default Hostname Verifier to an instance of a fake class that
66 * trust all hostnames. This method uses the old deprecated API from the
Francis Labrie 3.1 67 * <code>com.sun.ssl</code> package.
68 *
69 * @deprecated see {@link #_trustAllHostnames()}.
70 */
71 private static void __trustAllHostnames() {
72 // Create a trust manager that does not validate certificate chains
73 if(__hostnameVerifier == null) {
74 __hostnameVerifier = new _FakeHostnameVerifier();
75 } // if
76 // Install the all-trusting host name verifier
77 com.sun.net.ssl.HttpsURLConnection.
78 setDefaultHostnameVerifier(__hostnameVerifier);
79 } // __trustAllHttpsCertificates
Pascal Robert 4.1 80
Francis Labrie 3.1 81 /**
Pascal Robert 4.1 82 * Set the default X509 Trust Manager to an instance of a fake class that
83 * trust all certificates, even the self-signed ones. This method uses the
Francis Labrie 3.1 84 * old deprecated API from the <code>com.sun.ssl</code> package.
85 *
86 * @deprecated see {@link #_trustAllHttpsCertificates()}.
87 */
88 private static void __trustAllHttpsCertificates() {
89 com.sun.net.ssl.SSLContext context;
Pascal Robert 4.1 90
Francis Labrie 3.1 91 // Create a trust manager that does not validate certificate chains
92 if(__trustManagers == null) {
Pascal Robert 4.1 93 __trustManagers = new com.sun.net.ssl.TrustManager[]
Francis Labrie 3.1 94 {new _FakeX509TrustManager()};
95 } // if
96 // Install the all-trusting trust manager
97 try {
98 context = com.sun.net.ssl.SSLContext.getInstance("SSL");
99 context.init(null, __trustManagers, new SecureRandom());
100 } catch(GeneralSecurityException gse) {
101 throw new IllegalStateException(gse.getMessage());
102 } // catch
103 com.sun.net.ssl.HttpsURLConnection.
104 setDefaultSSLSocketFactory(context.getSocketFactory());
105 } // __trustAllHttpsCertificates
106
107 /**
108 * Return <code>true</code> if the protocol handler property <code>java.
109 * protocol.handler.pkgs</code> is set to the Sun's <code>com.sun.net.ssl.
Pascal Robert 4.1 110 * internal.www.protocol</code> deprecated one, <code>false</code>
Francis Labrie 3.1 111 * otherwise.
112 *
Pascal Robert 4.1 113 * @return <code>true</code> if the protocol handler
114 * property is set to the Sun's deprecated one, <code>false</code>
Francis Labrie 3.1 115 * otherwise.
116 */
117 private static boolean isDeprecatedSSLProtocol() {
118 return("com.sun.net.ssl.internal.www.protocol".equals(System.
119 getProperty("java.protocol.handler.pkgs")));
120 } // isDeprecatedSSLProtocol
121
122 /**
Pascal Robert 4.1 123 * Set the default Hostname Verifier to an instance of a fake class that
Francis Labrie 3.1 124 * trust all hostnames.
125 */
126 private static void _trustAllHostnames() {
127 // Create a trust manager that does not validate certificate chains
128 if(_hostnameVerifier == null) {
129 _hostnameVerifier = new FakeHostnameVerifier();
130 } // if
131 // Install the all-trusting host name verifier:
132 HttpsURLConnection.setDefaultHostnameVerifier(_hostnameVerifier);
133 } // _trustAllHttpsCertificates
Pascal Robert 4.1 134
Francis Labrie 3.1 135 /**
Pascal Robert 4.1 136 * Set the default X509 Trust Manager to an instance of a fake class that
Francis Labrie 3.1 137 * trust all certificates, even the self-signed ones.
138 */
139 private static void _trustAllHttpsCertificates() {
140 SSLContext context;
Pascal Robert 4.1 141
Francis Labrie 3.1 142 // Create a trust manager that does not validate certificate chains
143 if(_trustManagers == null) {
144 _trustManagers = new TrustManager[] {new FakeX509TrustManager()};
145 } // if
146 // Install the all-trusting trust manager:
147 try {
148 context = SSLContext.getInstance("SSL");
149 context.init(null, _trustManagers, new SecureRandom());
150 } catch(GeneralSecurityException gse) {
151 throw new IllegalStateException(gse.getMessage());
152 } // catch
153 HttpsURLConnection.setDefaultSSLSocketFactory(context.
154 getSocketFactory());
155 } // _trustAllHttpsCertificates
156
157 /**
Pascal Robert 4.1 158 * Set the default Hostname Verifier to an instance of a fake class that
Francis Labrie 3.1 159 * trust all hostnames.
160 */
161 public static void trustAllHostnames() {
162 // Is the deprecated protocol setted?
163 if(isDeprecatedSSLProtocol()) {
164 __trustAllHostnames();
165 } else {
166 _trustAllHostnames();
167 } // else
168 } // trustAllHostnames
Pascal Robert 4.1 169
Francis Labrie 3.1 170 /**
Pascal Robert 4.1 171 * Set the default X509 Trust Manager to an instance of a fake class that
Francis Labrie 3.1 172 * trust all certificates, even the self-signed ones.
173 */
174 public static void trustAllHttpsCertificates() {
175 // Is the deprecated protocol setted?
176 if(isDeprecatedSSLProtocol()) {
177 __trustAllHttpsCertificates();
178 } else {
179 _trustAllHttpsCertificates();
180 } // else
181 } // trustAllHttpsCertificates
Pascal Robert 4.1 182
Francis Labrie 3.1 183 /**
Pascal Robert 4.1 184 * This class implements a fake hostname verificator, trusting any host
Francis Labrie 3.1 185 * name. This class uses the old deprecated API from the <code>com.sun.
186 * ssl</code> package.
187 *
188 * @author Francis Labrie
189 *
190 * @deprecated see {@link SSLUtilities.FakeHostnameVerifier}.
191 */
Pascal Robert 4.1 192 public static class _FakeHostnameVerifier
Francis Labrie 3.1 193 implements com.sun.net.ssl.HostnameVerifier {
Pascal Robert 4.1 194
Francis Labrie 3.1 195 /**
Pascal Robert 4.1 196 * Always return <code>true</code>, indicating that the host name is an
Francis Labrie 3.1 197 * acceptable match with the server's authentication scheme.
198 *
199 * @param hostname the host name.
Pascal Robert 4.1 200 * @param session the SSL session used on the connection to
Francis Labrie 3.1 201 * host.
Pascal Robert 4.1 202 * @return the <code>true</code> boolean value
Francis Labrie 3.1 203 * indicating the host name is trusted.
204 */
205 public boolean verify(String hostname, String session) {
206 return(true);
207 } // verify
208 } // _FakeHostnameVerifier
209
210
211 /**
Pascal Robert 4.1 212 * This class allow any X509 certificates to be used to authenticate the
213 * remote side of a secure socket, including self-signed certificates. This
214 * class uses the old deprecated API from the <code>com.sun.ssl</code>
Francis Labrie 3.1 215 * package.
216 *
217 * @author Francis Labrie
218 *
219 * @deprecated see {@link SSLUtilities.FakeX509TrustManager}.
220 */
Pascal Robert 4.1 221 public static class _FakeX509TrustManager
Francis Labrie 3.1 222 implements com.sun.net.ssl.X509TrustManager {
Pascal Robert 4.1 223
Francis Labrie 3.1 224 /**
225 * Empty array of certificate authority certificates.
226 */
Pascal Robert 4.1 227 private static final X509Certificate[] _AcceptedIssuers =
Francis Labrie 3.1 228 new X509Certificate[] {};
Pascal Robert 4.1 229
230
Francis Labrie 3.1 231 /**
Pascal Robert 4.1 232 * Always return <code>true</code>, trusting for client SSL
Francis Labrie 3.1 233 * <code>chain</code> peer certificate chain.
234 *
235 * @param chain the peer certificate chain.
Pascal Robert 4.1 236 * @return the <code>true</code> boolean value
Francis Labrie 3.1 237 * indicating the chain is trusted.
238 */
239 public boolean isClientTrusted(X509Certificate[] chain) {
240 return(true);
241 } // checkClientTrusted
Pascal Robert 4.1 242
Francis Labrie 3.1 243 /**
Pascal Robert 4.1 244 * Always return <code>true</code>, trusting for server SSL
Francis Labrie 3.1 245 * <code>chain</code> peer certificate chain.
246 *
247 * @param chain the peer certificate chain.
Pascal Robert 4.1 248 * @return the <code>true</code> boolean value
Francis Labrie 3.1 249 * indicating the chain is trusted.
250 */
251 public boolean isServerTrusted(X509Certificate[] chain) {
252 return(true);
253 } // checkServerTrusted
Pascal Robert 4.1 254
Francis Labrie 3.1 255 /**
Pascal Robert 4.1 256 * Return an empty array of certificate authority certificates which
Francis Labrie 3.1 257 * are trusted for authenticating peers.
258 *
259 * @return a empty array of issuer certificates.
260 */
261 public X509Certificate[] getAcceptedIssuers() {
262 return(_AcceptedIssuers);
263 } // getAcceptedIssuers
264 } // _FakeX509TrustManager
smmccraw 1.1 265
266
Francis Labrie 3.1 267 /**
Pascal Robert 4.1 268 * This class implements a fake hostname verificator, trusting any host
Francis Labrie 3.1 269 * name.
270 *
271 * @author Francis Labrie
272 */
273 public static class FakeHostnameVerifier implements HostnameVerifier {
Pascal Robert 4.1 274
Francis Labrie 3.1 275 /**
Pascal Robert 4.1 276 * Always return <code>true</code>, indicating that the host name is
Francis Labrie 3.1 277 * an acceptable match with the server's authentication scheme.
278 *
279 * @param hostname the host name.
Pascal Robert 4.1 280 * @param session the SSL session used on the connection to
Francis Labrie 3.1 281 * host.
Pascal Robert 4.1 282 * @return the <code>true</code> boolean value
Francis Labrie 3.1 283 * indicating the host name is trusted.
284 */
Pascal Robert 4.1 285 public boolean verify(String hostname,
Francis Labrie 3.1 286 javax.net.ssl.SSLSession session) {
287 return(true);
288 } // verify
289 } // FakeHostnameVerifier
290
291
292 /**
Pascal Robert 4.1 293 * This class allow any X509 certificates to be used to authenticate the
Francis Labrie 3.1 294 * remote side of a secure socket, including self-signed certificates.
295 *
296 * @author Francis Labrie
297 */
298 public static class FakeX509TrustManager implements X509TrustManager {
299
300 /**
301 * Empty array of certificate authority certificates.
302 */
Pascal Robert 4.1 303 private static final X509Certificate[] _AcceptedIssuers =
Francis Labrie 3.1 304 new X509Certificate[] {};
305
306
307 /**
Pascal Robert 4.1 308 * Always trust for client SSL <code>chain</code> peer certificate
Francis Labrie 3.1 309 * chain with any <code>authType</code> authentication types.
310 *
311 * @param chain the peer certificate chain.
Pascal Robert 4.1 312 * @param authType the authentication type based on the client
Francis Labrie 3.1 313 * certificate.
314 */
Pascal Robert 4.1 315 public void checkClientTrusted(X509Certificate[] chain,
Francis Labrie 3.1 316 String authType) {
317 } // checkClientTrusted
Pascal Robert 4.1 318
Francis Labrie 3.1 319 /**
Pascal Robert 4.1 320 * Always trust for server SSL <code>chain</code> peer certificate
Francis Labrie 3.1 321 * chain with any <code>authType</code> exchange algorithm types.
322 *
323 * @param chain the peer certificate chain.
324 * @param authType the key exchange algorithm used.
325 */
Pascal Robert 4.1 326 public void checkServerTrusted(X509Certificate[] chain,
Francis Labrie 3.1 327 String authType) {
328 } // checkServerTrusted
Pascal Robert 4.1 329
Francis Labrie 3.1 330 /**
Pascal Robert 4.1 331 * Return an empty array of certificate authority certificates which
Francis Labrie 3.1 332 * are trusted for authenticating peers.
333 *
334 * @return a empty array of issuer certificates.
335 */
336 public X509Certificate[] getAcceptedIssuers() {
337 return(_AcceptedIssuers);
338 } // getAcceptedIssuers
339 } // FakeX509TrustManager
340 } // SSLUtilities
341
342 {{/code}}
343
smmccraw 1.1 344 Category:WebObjects