1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 package org.apache.http.conn.ssl;
29
30 import java.io.IOException;
31 import java.net.InetAddress;
32 import java.net.InetSocketAddress;
33 import java.net.Socket;
34 import java.net.SocketTimeoutException;
35 import java.net.UnknownHostException;
36 import java.security.KeyManagementException;
37 import java.security.KeyStore;
38 import java.security.KeyStoreException;
39 import java.security.NoSuchAlgorithmException;
40 import java.security.SecureRandom;
41 import java.security.UnrecoverableKeyException;
42
43 import javax.net.ssl.KeyManager;
44 import javax.net.ssl.KeyManagerFactory;
45 import javax.net.ssl.SSLContext;
46 import javax.net.ssl.SSLSocket;
47 import javax.net.ssl.TrustManager;
48 import javax.net.ssl.TrustManagerFactory;
49 import javax.net.ssl.X509TrustManager;
50
51 import org.apache.http.HttpHost;
52 import org.apache.http.annotation.ThreadSafe;
53 import org.apache.http.conn.ConnectTimeoutException;
54 import org.apache.http.conn.HttpInetSocketAddress;
55 import org.apache.http.conn.scheme.HostNameResolver;
56 import org.apache.http.conn.scheme.LayeredSchemeSocketFactory;
57 import org.apache.http.conn.scheme.LayeredSocketFactory;
58 import org.apache.http.conn.scheme.SchemeLayeredSocketFactory;
59 import org.apache.http.conn.socket.LayeredConnectionSocketFactory;
60 import org.apache.http.params.HttpConnectionParams;
61 import org.apache.http.params.HttpParams;
62 import org.apache.http.protocol.HttpContext;
63 import org.apache.http.util.Args;
64 import org.apache.http.util.Asserts;
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139 @SuppressWarnings("deprecation")
140 @ThreadSafe
141 public class SSLSocketFactory implements LayeredConnectionSocketFactory, SchemeLayeredSocketFactory,
142 LayeredSchemeSocketFactory, LayeredSocketFactory {
143
144 public static final String TLS = "TLS";
145 public static final String SSL = "SSL";
146 public static final String SSLV2 = "SSLv2";
147
148 public static final X509HostnameVerifier ALLOW_ALL_HOSTNAME_VERIFIER
149 = new AllowAllHostnameVerifier();
150
151 public static final X509HostnameVerifier BROWSER_COMPATIBLE_HOSTNAME_VERIFIER
152 = new BrowserCompatHostnameVerifier();
153
154 public static final X509HostnameVerifier STRICT_HOSTNAME_VERIFIER
155 = new StrictHostnameVerifier();
156
157
158
159
160
161
162
163
164 public static SSLSocketFactory getSocketFactory() throws SSLInitializationException {
165 return new SSLSocketFactory(
166 SSLContexts.createDefault(),
167 BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
168 }
169
170
171
172
173
174
175
176
177
178
179 public static SSLSocketFactory getSystemSocketFactory() throws SSLInitializationException {
180 return new SSLSocketFactory(
181 (javax.net.ssl.SSLSocketFactory) javax.net.ssl.SSLSocketFactory.getDefault(),
182 BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
183 }
184
185 private final javax.net.ssl.SSLSocketFactory socketfactory;
186 private final HostNameResolver nameResolver;
187
188 private volatile X509HostnameVerifier hostnameVerifier;
189
190 private static SSLContext createSSLContext(
191 String algorithm,
192 final KeyStore keystore,
193 final char[] keystorePassword,
194 final KeyStore truststore,
195 final SecureRandom random,
196 final TrustStrategy trustStrategy)
197 throws NoSuchAlgorithmException, KeyStoreException, UnrecoverableKeyException, KeyManagementException {
198 if (algorithm == null) {
199 algorithm = TLS;
200 }
201 final KeyManagerFactory kmfactory = KeyManagerFactory.getInstance(
202 KeyManagerFactory.getDefaultAlgorithm());
203 kmfactory.init(keystore, keystorePassword);
204 final KeyManager[] keymanagers = kmfactory.getKeyManagers();
205 final TrustManagerFactory tmfactory = TrustManagerFactory.getInstance(
206 TrustManagerFactory.getDefaultAlgorithm());
207 tmfactory.init(truststore);
208 final TrustManager[] trustmanagers = tmfactory.getTrustManagers();
209 if (trustmanagers != null && trustStrategy != null) {
210 for (int i = 0; i < trustmanagers.length; i++) {
211 final TrustManager tm = trustmanagers[i];
212 if (tm instanceof X509TrustManager) {
213 trustmanagers[i] = new TrustManagerDecorator(
214 (X509TrustManager) tm, trustStrategy);
215 }
216 }
217 }
218
219 final SSLContext sslcontext = SSLContext.getInstance(algorithm);
220 sslcontext.init(keymanagers, trustmanagers, random);
221 return sslcontext;
222 }
223
224
225
226
227 public SSLSocketFactory(
228 final String algorithm,
229 final KeyStore keystore,
230 final char[] keystorePassword,
231 final KeyStore truststore,
232 final SecureRandom random,
233 final TrustStrategy trustStrategy,
234 final X509HostnameVerifier hostnameVerifier)
235 throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
236 this(createSSLContext(algorithm, keystore, keystorePassword, truststore, random, trustStrategy),
237 hostnameVerifier);
238 }
239
240
241
242
243
244 @Deprecated
245 public SSLSocketFactory(
246 final String algorithm,
247 final KeyStore keystore,
248 final String keystorePassword,
249 final KeyStore truststore,
250 final SecureRandom random,
251 final HostNameResolver nameResolver)
252 throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
253 this(createSSLContext(
254 algorithm, keystore, keystorePassword != null ? keystorePassword.toCharArray() : null,
255 truststore, random, null), nameResolver);
256 }
257
258
259
260
261
262
263
264 @Deprecated
265 public SSLSocketFactory(
266 final String algorithm,
267 final KeyStore keystore,
268 final String keystorePassword,
269 final KeyStore truststore,
270 final SecureRandom random,
271 final TrustStrategy trustStrategy,
272 final X509HostnameVerifier hostnameVerifier)
273 throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
274 this(createSSLContext(
275 algorithm, keystore, keystorePassword != null ? keystorePassword.toCharArray() : null,
276 truststore, random, trustStrategy), hostnameVerifier);
277 }
278
279
280
281
282
283
284
285 @Deprecated
286 public SSLSocketFactory(
287 final String algorithm,
288 final KeyStore keystore,
289 final String keystorePassword,
290 final KeyStore truststore,
291 final SecureRandom random,
292 final X509HostnameVerifier hostnameVerifier)
293 throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
294 this(createSSLContext(
295 algorithm, keystore, keystorePassword != null ? keystorePassword.toCharArray() : null,
296 truststore, random, null), hostnameVerifier);
297 }
298
299
300
301
302 public SSLSocketFactory(
303 final String algorithm,
304 final KeyStore keystore,
305 final char[] keystorePassword,
306 final KeyStore truststore,
307 final SecureRandom random,
308 final X509HostnameVerifier hostnameVerifier)
309 throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
310 this(createSSLContext(algorithm, keystore, keystorePassword, truststore, random, null),
311 hostnameVerifier);
312 }
313
314
315
316
317 @Deprecated
318 public SSLSocketFactory(
319 final KeyStore keystore,
320 final String keystorePassword,
321 final KeyStore truststore)
322 throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
323 this(TLS, keystore, keystorePassword, truststore, null, null, BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
324 }
325
326
327
328
329 public SSLSocketFactory(
330 final KeyStore keystore,
331 final char[] keystorePassword,
332 final KeyStore truststore)
333 throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException{
334 this(createSSLContext(TLS, keystore, keystorePassword, truststore, null, null),
335 BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
336 }
337
338
339
340
341 @Deprecated
342 public SSLSocketFactory(
343 final KeyStore keystore,
344 final String keystorePassword)
345 throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException{
346 this(createSSLContext(TLS, keystore, keystorePassword != null ? keystorePassword.toCharArray() : null,
347 null, null, null),
348 BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
349 }
350
351
352
353
354 public SSLSocketFactory(
355 final KeyStore keystore,
356 final char[] keystorePassword)
357 throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException{
358 this(createSSLContext(TLS, keystore, keystorePassword, null, null, null),
359 BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
360 }
361
362 public SSLSocketFactory(
363 final KeyStore truststore)
364 throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
365 this(createSSLContext(TLS, null, null, truststore, null, null),
366 BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
367 }
368
369
370
371
372 public SSLSocketFactory(
373 final TrustStrategy trustStrategy,
374 final X509HostnameVerifier hostnameVerifier)
375 throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
376 this(createSSLContext(TLS, null, null, null, null, trustStrategy), hostnameVerifier);
377 }
378
379
380
381
382 public SSLSocketFactory(
383 final TrustStrategy trustStrategy)
384 throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
385 this(createSSLContext(TLS, null, null, null, null, trustStrategy), BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
386 }
387
388 public SSLSocketFactory(final SSLContext sslContext) {
389 this(sslContext, BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
390 }
391
392
393
394
395 @Deprecated
396 public SSLSocketFactory(
397 final SSLContext sslContext, final HostNameResolver nameResolver) {
398 super();
399 this.socketfactory = sslContext.getSocketFactory();
400 this.hostnameVerifier = BROWSER_COMPATIBLE_HOSTNAME_VERIFIER;
401 this.nameResolver = nameResolver;
402 }
403
404
405
406
407 public SSLSocketFactory(
408 final SSLContext sslContext, final X509HostnameVerifier hostnameVerifier) {
409 super();
410 Args.notNull(sslContext, "SSL context");
411 this.socketfactory = sslContext.getSocketFactory();
412 this.hostnameVerifier = hostnameVerifier;
413 this.nameResolver = null;
414 }
415
416
417
418
419 public SSLSocketFactory(
420 final javax.net.ssl.SSLSocketFactory socketfactory,
421 final X509HostnameVerifier hostnameVerifier) {
422 Args.notNull(socketfactory, "SSL socket factory");
423 this.socketfactory = socketfactory;
424 this.hostnameVerifier = hostnameVerifier;
425 this.nameResolver = null;
426 }
427
428
429
430
431
432
433
434
435 @Deprecated
436 public Socket createSocket(final HttpParams params) throws IOException {
437 return createSocket((HttpContext) null);
438 }
439
440
441
442
443 @Deprecated
444 public Socket createSocket() throws IOException {
445 return createSocket((HttpContext) null);
446 }
447
448
449
450
451
452
453
454 @Deprecated
455 public Socket connectSocket(
456 final Socket socket,
457 final InetSocketAddress remoteAddress,
458 final InetSocketAddress localAddress,
459 final HttpParams params) throws IOException, UnknownHostException, ConnectTimeoutException {
460 Args.notNull(remoteAddress, "Remote address");
461 Args.notNull(params, "HTTP parameters");
462 HttpHost host;
463 if (remoteAddress instanceof HttpInetSocketAddress) {
464 host = ((HttpInetSocketAddress) remoteAddress).getHttpHost();
465 } else {
466 host = new HttpHost(remoteAddress.getHostName(), remoteAddress.getPort(), "https");
467 }
468 final int connectTimeout = HttpConnectionParams.getConnectionTimeout(params);
469 return connectSocket(connectTimeout, socket, host, remoteAddress, localAddress, null);
470 }
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488 @Deprecated
489 public boolean isSecure(final Socket sock) throws IllegalArgumentException {
490 Args.notNull(sock, "Socket");
491 Asserts.check(sock instanceof SSLSocket, "Socket not created by this factory");
492 Asserts.check(!sock.isClosed(), "Socket is closed");
493 return true;
494 }
495
496
497
498
499
500
501 @Deprecated
502 public Socket createLayeredSocket(
503 final Socket socket,
504 final String host,
505 final int port,
506 final HttpParams params) throws IOException, UnknownHostException {
507 return createLayeredSocket(socket, host, port, (HttpContext) null);
508 }
509
510
511
512
513 @Deprecated
514 public Socket createLayeredSocket(
515 final Socket socket,
516 final String host,
517 final int port,
518 final boolean autoClose) throws IOException, UnknownHostException {
519 return createLayeredSocket(socket, host, port, (HttpContext) null);
520 }
521
522
523
524
525 @Deprecated
526 public void setHostnameVerifier(final X509HostnameVerifier hostnameVerifier) {
527 Args.notNull(hostnameVerifier, "Hostname verifier");
528 this.hostnameVerifier = hostnameVerifier;
529 }
530
531 public X509HostnameVerifier getHostnameVerifier() {
532 return this.hostnameVerifier;
533 }
534
535
536
537
538
539 @Deprecated
540 public Socket connectSocket(
541 final Socket socket,
542 final String host, final int port,
543 final InetAddress local, int localPort,
544 final HttpParams params) throws IOException, UnknownHostException, ConnectTimeoutException {
545 InetAddress remote;
546 if (this.nameResolver != null) {
547 remote = this.nameResolver.resolve(host);
548 } else {
549 remote = InetAddress.getByName(host);
550 }
551 InetSocketAddress localAddress = null;
552 if (local != null || localPort > 0) {
553
554 if (localPort < 0) {
555 localPort = 0;
556 }
557 localAddress = new InetSocketAddress(local, localPort);
558 }
559 final InetSocketAddress remoteAddress = new HttpInetSocketAddress(
560 new HttpHost(host, port), remote, port);
561 return connectSocket(socket, remoteAddress, localAddress, params);
562 }
563
564
565
566
567 @Deprecated
568 public Socket createSocket(
569 final Socket socket,
570 final String host, final int port,
571 final boolean autoClose) throws IOException, UnknownHostException {
572 return createLayeredSocket(socket, host, port, autoClose);
573 }
574
575
576
577
578
579
580
581
582
583
584 protected void prepareSocket(final SSLSocket socket) throws IOException {
585 }
586
587
588
589
590
591
592 public Socket createSocket(final HttpContext context) throws IOException {
593 final SSLSocket sock = (SSLSocket) this.socketfactory.createSocket();
594 prepareSocket(sock);
595 return sock;
596 }
597
598
599
600
601
602
603 public Socket connectSocket(
604 final int connectTimeout,
605 final Socket socket,
606 final HttpHost host,
607 final InetSocketAddress remoteAddress,
608 final InetSocketAddress localAddress,
609 final HttpContext context) throws IOException, ConnectTimeoutException {
610 Args.notNull(host, "HTTP host");
611 Args.notNull(remoteAddress, "Remote address");
612 Socket sock = socket != null ? socket : createSocket(context);
613 if (localAddress != null) {
614 sock.bind(localAddress);
615 }
616 try {
617 sock.connect(remoteAddress, connectTimeout);
618 } catch (final SocketTimeoutException ex) {
619 throw new ConnectTimeoutException(host, remoteAddress);
620 }
621
622 if (sock instanceof SSLSocket) {
623 verifyHostname((SSLSocket) sock, host.getHostName());
624 } else {
625 sock = createLayeredSocket(sock, host.getHostName(), remoteAddress.getPort(), context);
626 }
627 return sock;
628 }
629
630 public Socket createLayeredSocket(
631 final Socket socket,
632 final String target,
633 final int port,
634 final HttpContext context) throws IOException, UnknownHostException {
635 final SSLSocket sslSocket = (SSLSocket) this.socketfactory.createSocket(
636 socket,
637 target,
638 port,
639 true);
640 prepareSocket(sslSocket);
641 verifyHostname(sslSocket, target);
642 return sslSocket;
643 }
644
645 private void verifyHostname(final SSLSocket sslsock, final String hostname) throws IOException {
646 if (this.hostnameVerifier != null) {
647 try {
648 this.hostnameVerifier.verify(hostname, sslsock);
649
650 } catch (final IOException iox) {
651
652 try { sslsock.close(); } catch (final Exception x) {
653 throw iox;
654 }
655 }
656 }
657
658 }