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.params.HttpConnectionParams;
60 import org.apache.http.params.HttpParams;
61
62
63
64
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
140
141
142
143 @SuppressWarnings("deprecation")
144 @ThreadSafe
145 public class SSLSocketFactory implements SchemeLayeredSocketFactory,
146 LayeredSchemeSocketFactory, LayeredSocketFactory {
147
148 public static final String TLS = "TLS";
149 public static final String SSL = "SSL";
150 public static final String SSLV2 = "SSLv2";
151
152 public static final X509HostnameVerifier ALLOW_ALL_HOSTNAME_VERIFIER
153 = new AllowAllHostnameVerifier();
154
155 public static final X509HostnameVerifier BROWSER_COMPATIBLE_HOSTNAME_VERIFIER
156 = new BrowserCompatHostnameVerifier();
157
158 public static final X509HostnameVerifier STRICT_HOSTNAME_VERIFIER
159 = new StrictHostnameVerifier();
160
161
162
163
164
165
166
167
168 public static SSLSocketFactory getSocketFactory() throws SSLInitializationException {
169 SSLContext sslcontext;
170 try {
171 sslcontext = SSLContext.getInstance("TLS");
172 sslcontext.init(null, null, null);
173 return new SSLSocketFactory(
174 sslcontext,
175 BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
176 } catch (NoSuchAlgorithmException ex) {
177 throw new SSLInitializationException(ex.getMessage(), ex);
178 } catch (KeyManagementException ex) {
179 throw new SSLInitializationException(ex.getMessage(), ex);
180 }
181 }
182
183
184
185
186
187
188
189
190
191
192 public static SSLSocketFactory getSystemSocketFactory() throws SSLInitializationException {
193 return new SSLSocketFactory(
194 (javax.net.ssl.SSLSocketFactory) javax.net.ssl.SSLSocketFactory.getDefault(),
195 BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
196 }
197
198 private final javax.net.ssl.SSLSocketFactory socketfactory;
199 private final HostNameResolver nameResolver;
200
201 private volatile X509HostnameVerifier hostnameVerifier;
202
203 private static SSLContext createSSLContext(
204 String algorithm,
205 final KeyStore keystore,
206 final String keystorePassword,
207 final KeyStore truststore,
208 final SecureRandom random,
209 final TrustStrategy trustStrategy)
210 throws NoSuchAlgorithmException, KeyStoreException, UnrecoverableKeyException, KeyManagementException {
211 if (algorithm == null) {
212 algorithm = TLS;
213 }
214 KeyManagerFactory kmfactory = KeyManagerFactory.getInstance(
215 KeyManagerFactory.getDefaultAlgorithm());
216 kmfactory.init(keystore, keystorePassword != null ? keystorePassword.toCharArray(): null);
217 KeyManager[] keymanagers = kmfactory.getKeyManagers();
218 TrustManagerFactory tmfactory = TrustManagerFactory.getInstance(
219 TrustManagerFactory.getDefaultAlgorithm());
220 tmfactory.init(truststore);
221 TrustManager[] trustmanagers = tmfactory.getTrustManagers();
222 if (trustmanagers != null && trustStrategy != null) {
223 for (int i = 0; i < trustmanagers.length; i++) {
224 TrustManager tm = trustmanagers[i];
225 if (tm instanceof X509TrustManager) {
226 trustmanagers[i] = new TrustManagerDecorator(
227 (X509TrustManager) tm, trustStrategy);
228 }
229 }
230 }
231
232 SSLContext sslcontext = SSLContext.getInstance(algorithm);
233 sslcontext.init(keymanagers, trustmanagers, random);
234 return sslcontext;
235 }
236
237
238
239
240 @Deprecated
241 public SSLSocketFactory(
242 final String algorithm,
243 final KeyStore keystore,
244 final String keystorePassword,
245 final KeyStore truststore,
246 final SecureRandom random,
247 final HostNameResolver nameResolver)
248 throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
249 this(createSSLContext(
250 algorithm, keystore, keystorePassword, truststore, random, null),
251 nameResolver);
252 }
253
254
255
256
257 public SSLSocketFactory(
258 String algorithm,
259 final KeyStore keystore,
260 final String keystorePassword,
261 final KeyStore truststore,
262 final SecureRandom random,
263 final X509HostnameVerifier hostnameVerifier)
264 throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
265 this(createSSLContext(
266 algorithm, keystore, keystorePassword, truststore, random, null),
267 hostnameVerifier);
268 }
269
270
271
272
273 public SSLSocketFactory(
274 String algorithm,
275 final KeyStore keystore,
276 final String keystorePassword,
277 final KeyStore truststore,
278 final SecureRandom random,
279 final TrustStrategy trustStrategy,
280 final X509HostnameVerifier hostnameVerifier)
281 throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
282 this(createSSLContext(
283 algorithm, keystore, keystorePassword, truststore, random, trustStrategy),
284 hostnameVerifier);
285 }
286
287 public SSLSocketFactory(
288 final KeyStore keystore,
289 final String keystorePassword,
290 final KeyStore truststore)
291 throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
292 this(TLS, keystore, keystorePassword, truststore, null, null, BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
293 }
294
295 public SSLSocketFactory(
296 final KeyStore keystore,
297 final String keystorePassword)
298 throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException{
299 this(TLS, keystore, keystorePassword, null, null, null, BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
300 }
301
302 public SSLSocketFactory(
303 final KeyStore truststore)
304 throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
305 this(TLS, null, null, truststore, null, null, BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
306 }
307
308
309
310
311 public SSLSocketFactory(
312 final TrustStrategy trustStrategy,
313 final X509HostnameVerifier hostnameVerifier)
314 throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
315 this(TLS, null, null, null, null, trustStrategy, hostnameVerifier);
316 }
317
318
319
320
321 public SSLSocketFactory(
322 final TrustStrategy trustStrategy)
323 throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
324 this(TLS, null, null, null, null, trustStrategy, BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
325 }
326
327 public SSLSocketFactory(final SSLContext sslContext) {
328 this(sslContext, BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
329 }
330
331
332
333
334 @Deprecated
335 public SSLSocketFactory(
336 final SSLContext sslContext, final HostNameResolver nameResolver) {
337 super();
338 this.socketfactory = sslContext.getSocketFactory();
339 this.hostnameVerifier = BROWSER_COMPATIBLE_HOSTNAME_VERIFIER;
340 this.nameResolver = nameResolver;
341 }
342
343
344
345
346 public SSLSocketFactory(
347 final SSLContext sslContext, final X509HostnameVerifier hostnameVerifier) {
348 super();
349 if (sslContext == null) {
350 throw new IllegalArgumentException("SSL context may not be null");
351 }
352 this.socketfactory = sslContext.getSocketFactory();
353 this.hostnameVerifier = hostnameVerifier;
354 this.nameResolver = null;
355 }
356
357
358
359
360 public SSLSocketFactory(
361 final javax.net.ssl.SSLSocketFactory socketfactory,
362 final X509HostnameVerifier hostnameVerifier) {
363 if (socketfactory == null) {
364 throw new IllegalArgumentException("SSL socket factory may not be null");
365 }
366 this.socketfactory = socketfactory;
367 this.hostnameVerifier = hostnameVerifier;
368 this.nameResolver = null;
369 }
370
371
372
373
374
375
376 public Socket createSocket(final HttpParams params) throws IOException {
377 SSLSocket sock = (SSLSocket) this.socketfactory.createSocket();
378 prepareSocket(sock);
379 return sock;
380 }
381
382 @Deprecated
383 public Socket createSocket() throws IOException {
384 SSLSocket sock = (SSLSocket) this.socketfactory.createSocket();
385 prepareSocket(sock);
386 return sock;
387 }
388
389
390
391
392 public Socket connectSocket(
393 final Socket socket,
394 final InetSocketAddress remoteAddress,
395 final InetSocketAddress localAddress,
396 final HttpParams params) throws IOException, UnknownHostException, ConnectTimeoutException {
397 if (remoteAddress == null) {
398 throw new IllegalArgumentException("Remote address may not be null");
399 }
400 if (params == null) {
401 throw new IllegalArgumentException("HTTP parameters may not be null");
402 }
403 Socket sock = socket != null ? socket : this.socketfactory.createSocket();
404 if (localAddress != null) {
405 sock.setReuseAddress(HttpConnectionParams.getSoReuseaddr(params));
406 sock.bind(localAddress);
407 }
408
409 int connTimeout = HttpConnectionParams.getConnectionTimeout(params);
410 int soTimeout = HttpConnectionParams.getSoTimeout(params);
411
412 try {
413 sock.setSoTimeout(soTimeout);
414 sock.connect(remoteAddress, connTimeout);
415 } catch (SocketTimeoutException ex) {
416 throw new ConnectTimeoutException("Connect to " + remoteAddress + " timed out");
417 }
418
419 String hostname;
420 if (remoteAddress instanceof HttpInetSocketAddress) {
421 hostname = ((HttpInetSocketAddress) remoteAddress).getHttpHost().getHostName();
422 } else {
423 hostname = remoteAddress.getHostName();
424 }
425
426 SSLSocket sslsock;
427
428 if (sock instanceof SSLSocket) {
429 sslsock = (SSLSocket) sock;
430 } else {
431 int port = remoteAddress.getPort();
432 sslsock = (SSLSocket) this.socketfactory.createSocket(sock, hostname, port, true);
433 prepareSocket(sslsock);
434 }
435 if (this.hostnameVerifier != null) {
436 try {
437 this.hostnameVerifier.verify(hostname, sslsock);
438
439 } catch (IOException iox) {
440
441 try { sslsock.close(); } catch (Exception x) {
442 throw iox;
443 }
444 }
445 return sslsock;
446 }
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463 public boolean isSecure(final Socket sock) throws IllegalArgumentException {
464 if (sock == null) {
465 throw new IllegalArgumentException("Socket may not be null");
466 }
467
468 if (!(sock instanceof SSLSocket)) {
469 throw new IllegalArgumentException("Socket not created by this factory");
470 }
471
472 if (sock.isClosed()) {
473 throw new IllegalArgumentException("Socket is closed");
474 }
475 return true;
476 }
477
478
479
480
481 public Socket createLayeredSocket(
482 final Socket socket,
483 final String host,
484 final int port,
485 final HttpParams params) throws IOException, UnknownHostException {
486 SSLSocket sslSocket = (SSLSocket) this.socketfactory.createSocket(
487 socket,
488 host,
489 port,
490 true);
491 prepareSocket(sslSocket);
492 if (this.hostnameVerifier != null) {
493 this.hostnameVerifier.verify(host, sslSocket);
494 }
495
496 return sslSocket;
497 }
498
499
500
501
502 public Socket createLayeredSocket(
503 final Socket socket,
504 final String host,
505 final int port,
506 final boolean autoClose) throws IOException, UnknownHostException {
507 SSLSocket sslSocket = (SSLSocket) this.socketfactory.createSocket(
508 socket,
509 host,
510 port,
511 autoClose
512 );
513 prepareSocket(sslSocket);
514 if (this.hostnameVerifier != null) {
515 this.hostnameVerifier.verify(host, sslSocket);
516 }
517
518 return sslSocket;
519 }
520
521 @Deprecated
522 public void setHostnameVerifier(X509HostnameVerifier hostnameVerifier) {
523 if ( hostnameVerifier == null ) {
524 throw new IllegalArgumentException("Hostname verifier may not be null");
525 }
526 this.hostnameVerifier = hostnameVerifier;
527 }
528
529 public X509HostnameVerifier getHostnameVerifier() {
530 return this.hostnameVerifier;
531 }
532
533
534
535
536 @Deprecated
537 public Socket connectSocket(
538 final Socket socket,
539 final String host, int port,
540 final InetAddress localAddress, int localPort,
541 final HttpParams params) throws IOException, UnknownHostException, ConnectTimeoutException {
542 InetSocketAddress local = null;
543 if (localAddress != null || localPort > 0) {
544
545 if (localPort < 0) {
546 localPort = 0;
547 }
548 local = new InetSocketAddress(localAddress, localPort);
549 }
550 InetAddress remoteAddress;
551 if (this.nameResolver != null) {
552 remoteAddress = this.nameResolver.resolve(host);
553 } else {
554 remoteAddress = InetAddress.getByName(host);
555 }
556 InetSocketAddress remote = new HttpInetSocketAddress(new HttpHost(host, port), remoteAddress, port);
557 return connectSocket(socket, remote, local, params);
558 }
559
560
561
562
563 @Deprecated
564 public Socket createSocket(
565 final Socket socket,
566 final String host, int port,
567 boolean autoClose) throws IOException, UnknownHostException {
568 return createLayeredSocket(socket, host, port, autoClose);
569 }
570
571
572
573
574
575
576
577
578
579
580 protected void prepareSocket(final SSLSocket socket) throws IOException {
581 }
582 }