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.ssl;
29
30 import java.io.IOException;
31 import java.io.InputStream;
32 import java.io.OutputStream;
33 import java.net.InetSocketAddress;
34 import java.net.ServerSocket;
35 import java.net.Socket;
36 import java.net.URL;
37 import java.security.KeyStore;
38 import java.security.KeyStoreException;
39 import java.security.NoSuchAlgorithmException;
40 import java.security.Principal;
41 import java.security.Security;
42 import java.security.UnrecoverableKeyException;
43 import java.security.cert.CertificateException;
44 import java.security.cert.X509Certificate;
45 import java.util.Arrays;
46 import java.util.LinkedHashSet;
47 import java.util.Map;
48 import java.util.Set;
49 import java.util.concurrent.Callable;
50 import java.util.concurrent.ExecutorService;
51 import java.util.concurrent.Executors;
52 import java.util.concurrent.Future;
53 import java.util.concurrent.TimeUnit;
54 import java.util.concurrent.atomic.AtomicReference;
55
56 import javax.net.ssl.KeyManagerFactory;
57 import javax.net.ssl.SSLContext;
58 import javax.net.ssl.SSLException;
59 import javax.net.ssl.SSLHandshakeException;
60 import javax.net.ssl.SSLPeerUnverifiedException;
61 import javax.net.ssl.SSLServerSocket;
62 import javax.net.ssl.SSLSession;
63 import javax.net.ssl.SSLSocket;
64 import javax.net.ssl.SSLSocketFactory;
65 import javax.net.ssl.TrustManagerFactory;
66
67 import org.junit.After;
68 import org.junit.Assert;
69 import org.junit.Rule;
70 import org.junit.Test;
71 import org.junit.rules.ExpectedException;
72
73
74
75
76 public class TestSSLContextBuilder {
77
78 private static final String PROVIDER_SUN_JSSE = "SunJSSE";
79
80 private static boolean isWindows() {
81 return System.getProperty("os.name").contains("Windows");
82 }
83
84 @Rule
85 public ExpectedException thrown = ExpectedException.none();
86
87 private static final int TIMEOUT = 5000;
88 private ExecutorService executorService;
89
90 @After
91 public void cleanup() throws Exception {
92 if (this.executorService != null) {
93 this.executorService.shutdown();
94 this.executorService.awaitTermination(5, TimeUnit.SECONDS);
95 }
96 }
97
98 private URL getResource(final String name) {
99 return getClass().getResource(name);
100 }
101
102 @Test
103 public void testBuildDefault() throws Exception {
104 new SSLContextBuilder().build();
105 }
106
107 @Test
108 public void testBuildAllNull() throws Exception {
109 final SSLContext sslContext = SSLContextBuilder.create()
110 .setKeyStoreType(null)
111 .setKeyManagerFactoryAlgorithm(null)
112 .setTrustManagerFactoryAlgorithm(null)
113 .setProtocol(null)
114 .setProvider((String) null)
115 .setSecureRandom(null)
116 .loadTrustMaterial((KeyStore) null, null)
117 .loadKeyMaterial((KeyStore) null, null, null)
118 .build();
119 Assert.assertNotNull(sslContext);
120 Assert.assertEquals("TLS", sslContext.getProtocol());
121 Assert.assertEquals(PROVIDER_SUN_JSSE, sslContext.getProvider().getName());
122 }
123
124 @Test
125 public void testBuildAllDefaults() throws Exception {
126 final SSLContext sslContext = SSLContextBuilder.create()
127 .setKeyStoreType(KeyStore.getDefaultType())
128 .setKeyManagerFactoryAlgorithm(KeyManagerFactory.getDefaultAlgorithm())
129 .setTrustManagerFactoryAlgorithm(TrustManagerFactory.getDefaultAlgorithm())
130 .setProvider(PROVIDER_SUN_JSSE)
131 .setProtocol("TLS")
132 .setSecureRandom(null)
133 .loadTrustMaterial((KeyStore) null, null)
134 .loadKeyMaterial((KeyStore) null, null, null)
135 .build();
136 Assert.assertNotNull(sslContext);
137 Assert.assertEquals("TLS", sslContext.getProtocol());
138 Assert.assertEquals(PROVIDER_SUN_JSSE, sslContext.getProvider().getName());
139 }
140
141 @Test
142 public void testBuildNoSuchKeyStoreType() throws Exception {
143 thrown.expect(KeyStoreException.class);
144
145 final URL resource1 = getResource("/test-keypasswd.keystore");
146 final String storePassword = "nopassword";
147 final String keyPassword = "password";
148 SSLContextBuilder.create()
149 .setKeyStoreType(" BAD ")
150 .loadKeyMaterial(resource1, storePassword.toCharArray(), keyPassword.toCharArray())
151 .build();
152 }
153
154 @Test
155 public void testBuildNoSuchKeyManagerFactoryAlgorithm() throws Exception {
156 thrown.expect(NoSuchAlgorithmException.class);
157
158 final URL resource1 = getResource("/test-keypasswd.keystore");
159 final String storePassword = "nopassword";
160 final String keyPassword = "password";
161 SSLContextBuilder.create()
162 .setKeyManagerFactoryAlgorithm(" BAD ")
163 .loadKeyMaterial(resource1, storePassword.toCharArray(), keyPassword.toCharArray())
164 .build();
165 }
166
167 @Test
168 public void testBuildNoSuchTrustManagerFactoryAlgorithm() throws Exception {
169 thrown.expect(NoSuchAlgorithmException.class);
170
171 final URL resource1 = getResource("/test-keypasswd.keystore");
172 final String storePassword = "nopassword";
173 SSLContextBuilder.create()
174 .setTrustManagerFactoryAlgorithm(" BAD ")
175 .loadTrustMaterial(resource1, storePassword.toCharArray())
176 .build();
177 }
178
179 @Test
180 public void testBuildAllNull_deprecated() throws Exception {
181 final SSLContext sslContext = SSLContextBuilder.create()
182 .useProtocol(null)
183 .setSecureRandom(null)
184 .loadTrustMaterial((KeyStore) null, null)
185 .loadKeyMaterial((KeyStore) null, null, null)
186 .build();
187 Assert.assertNotNull(sslContext);
188 Assert.assertEquals("TLS", sslContext.getProtocol());
189 }
190
191 @Test
192 public void testKeyWithAlternatePassword() throws Exception {
193 final URL resource1 = getResource("/test-keypasswd.keystore");
194 final String storePassword = "nopassword";
195 final String keyPassword = "password";
196 final SSLContext sslContext = SSLContextBuilder.create()
197 .loadKeyMaterial(resource1, storePassword.toCharArray(), keyPassword.toCharArray())
198 .loadTrustMaterial(resource1, storePassword.toCharArray())
199 .build();
200 Assert.assertNotNull(sslContext);
201 final SSLSocketFactory socketFactory = sslContext.getSocketFactory();
202 Assert.assertNotNull(socketFactory);
203 }
204
205 @Test
206 public void testKeyWithAlternatePasswordInvalid() throws Exception {
207 thrown.expect(UnrecoverableKeyException.class);
208
209 final URL resource1 = getResource("/test-keypasswd.keystore");
210 final String storePassword = "nopassword";
211 final String keyPassword = "!password";
212 SSLContextBuilder.create()
213 .loadKeyMaterial(resource1, storePassword.toCharArray(), keyPassword.toCharArray())
214 .loadTrustMaterial(resource1, storePassword.toCharArray())
215 .build();
216 }
217
218 @Test
219 public void testSSLHandshakeServerTrusted() throws Exception {
220 final URL resource1 = getResource("/test.keystore");
221 final String storePassword = "nopassword";
222 final String keyPassword = "nopassword";
223 final SSLContext serverSslContext = SSLContextBuilder.create()
224 .loadKeyMaterial(resource1, storePassword.toCharArray(), keyPassword.toCharArray())
225 .build();
226 Assert.assertNotNull(serverSslContext);
227 final SSLContext clientSslContext = SSLContextBuilder.create()
228 .loadTrustMaterial(resource1, storePassword.toCharArray())
229 .build();
230 Assert.assertNotNull(clientSslContext);
231 final ServerSocket serverSocket = serverSslContext.getServerSocketFactory().createServerSocket();
232 serverSocket.bind(new InetSocketAddress(0));
233
234 this.executorService = Executors.newSingleThreadExecutor();
235 final Future<Boolean> future = this.executorService.submit(new Callable<Boolean>() {
236 @Override
237 public Boolean call() throws Exception {
238 final Socket socket = serverSocket.accept();
239 try {
240 final OutputStream outputStream = socket.getOutputStream();
241 outputStream.write(new byte[]{'H', 'i'});
242 outputStream.flush();
243 } finally {
244 socket.close();
245 }
246 return Boolean.TRUE;
247 }
248 });
249
250 final int localPort = serverSocket.getLocalPort();
251 final Socket clientSocket = clientSslContext.getSocketFactory().createSocket();
252 try {
253 clientSocket.connect(new InetSocketAddress("localhost", localPort), TIMEOUT);
254 final InputStream inputStream = clientSocket.getInputStream();
255 Assert.assertEquals('H', inputStream.read());
256 Assert.assertEquals('i', inputStream.read());
257 Assert.assertEquals(-1, inputStream.read());
258 } finally {
259 clientSocket.close();
260 }
261
262 final Boolean result = future.get(5, TimeUnit.SECONDS);
263 Assert.assertNotNull(result);
264 }
265
266 @Test
267 public void testSSLHandshakeServerNotTrusted() throws Exception {
268 thrown.expect(IOException.class);
269
270 final URL resource1 = getResource("/test-server.keystore");
271 final String storePassword = "nopassword";
272 final String keyPassword = "nopassword";
273 final SSLContext serverSslContext = SSLContextBuilder.create()
274 .loadKeyMaterial(resource1, storePassword.toCharArray(), keyPassword.toCharArray())
275 .build();
276 Assert.assertNotNull(serverSslContext);
277 final URL resource2 = getResource("/test.keystore");
278 final SSLContext clientSslContext = SSLContextBuilder.create()
279 .loadTrustMaterial(resource2, storePassword.toCharArray())
280 .build();
281 Assert.assertNotNull(clientSslContext);
282 final ServerSocket serverSocket = serverSslContext.getServerSocketFactory().createServerSocket();
283 serverSocket.bind(new InetSocketAddress(0));
284
285 this.executorService = Executors.newSingleThreadExecutor();
286 this.executorService.submit(new Callable<Boolean>() {
287 @Override
288 public Boolean call() throws Exception {
289 final SSLSocket socket = (SSLSocket) serverSocket.accept();
290 try {
291 socket.getSession();
292 } finally {
293 socket.close();
294 }
295 return Boolean.FALSE;
296 }
297 });
298 final int localPort = serverSocket.getLocalPort();
299 final SSLSocket clientSocket = (SSLSocket) clientSslContext.getSocketFactory().createSocket();
300 try {
301 clientSocket.connect(new InetSocketAddress("localhost", localPort), TIMEOUT);
302 clientSocket.setSoTimeout(TIMEOUT);
303 clientSocket.startHandshake();
304 } finally {
305 clientSocket.close();
306 }
307 }
308
309 @Test
310 public void testSSLHandshakeServerCustomTrustStrategy() throws Exception {
311 final URL resource1 = getResource("/test-server.keystore");
312 final String storePassword = "nopassword";
313 final String keyPassword = "nopassword";
314 final SSLContext serverSslContext = SSLContextBuilder.create()
315 .loadKeyMaterial(resource1, storePassword.toCharArray(), keyPassword.toCharArray())
316 .build();
317 Assert.assertNotNull(serverSslContext);
318
319 final AtomicReference<X509Certificate[]> certChainRef = new AtomicReference<X509Certificate[]>();
320
321 final TrustStrategy trustStrategy = new TrustStrategy() {
322
323 @Override
324 public boolean isTrusted(
325 final X509Certificate[] chain, final String authType) throws CertificateException {
326 certChainRef.set(chain);
327 return true;
328 }
329
330 };
331
332 final SSLContext clientSslContext = SSLContextBuilder.create()
333 .loadTrustMaterial(trustStrategy)
334 .build();
335
336 Assert.assertNotNull(clientSslContext);
337 final ServerSocket serverSocket = serverSslContext.getServerSocketFactory().createServerSocket();
338 serverSocket.bind(new InetSocketAddress(0));
339
340 this.executorService = Executors.newSingleThreadExecutor();
341 final Future<Boolean> future = this.executorService.submit(new Callable<Boolean>() {
342 @Override
343 public Boolean call() throws Exception {
344 final Socket socket = serverSocket.accept();
345 try {
346 final OutputStream outputStream = socket.getOutputStream();
347 outputStream.write(new byte[]{'H', 'i'});
348 outputStream.flush();
349 } finally {
350 socket.close();
351 }
352 return Boolean.TRUE;
353 }
354 });
355
356 final int localPort = serverSocket.getLocalPort();
357 final SSLSocket clientSocket = (SSLSocket) clientSslContext.getSocketFactory().createSocket();
358 try {
359 clientSocket.connect(new InetSocketAddress("localhost", localPort), TIMEOUT);
360 clientSocket.setSoTimeout(TIMEOUT);
361 final InputStream inputStream = clientSocket.getInputStream();
362 Assert.assertEquals('H', inputStream.read());
363 Assert.assertEquals('i', inputStream.read());
364 Assert.assertEquals(-1, inputStream.read());
365 } finally {
366 clientSocket.close();
367 }
368
369 final Boolean result = future.get(5, TimeUnit.SECONDS);
370 Assert.assertNotNull(result);
371
372 final X509Certificate[] certs = certChainRef.get();
373 Assert.assertNotNull(certs);
374 Assert.assertEquals(2, certs.length);
375 final X509Certificate cert1 = certs[0];
376 final Principal subjectDN1 = cert1.getSubjectDN();
377 Assert.assertNotNull(subjectDN1);
378 Assert.assertEquals("CN=Test Server, OU=HttpComponents Project, O=Apache Software Foundation", subjectDN1.getName());
379 final X509Certificate cert2 = certs[1];
380 final Principal subjectDN2 = cert2.getSubjectDN();
381 Assert.assertNotNull(subjectDN2);
382 Assert.assertEquals("EMAILADDRESS=dev@hc.apache.org, " +
383 "CN=Test CA, OU=HttpComponents Project, O=Apache Software Foundation", subjectDN2.getName());
384 final Principal issuerDN = cert2.getIssuerDN();
385 Assert.assertNotNull(issuerDN);
386 Assert.assertEquals("EMAILADDRESS=dev@hc.apache.org, " +
387 "CN=Test CA, OU=HttpComponents Project, O=Apache Software Foundation", issuerDN.getName());
388
389 }
390
391 @Test
392 public void testSSLHandshakeClientUnauthenticated() throws Exception {
393 final URL resource1 = getResource("/test-server.keystore");
394 final String storePassword = "nopassword";
395 final String keyPassword = "nopassword";
396 final SSLContext serverSslContext = SSLContextBuilder.create()
397 .loadKeyMaterial(resource1, storePassword.toCharArray(), keyPassword.toCharArray())
398 .build();
399 Assert.assertNotNull(serverSslContext);
400 final URL resource2 = getResource("/test-client.keystore");
401 final SSLContext clientSslContext = SSLContextBuilder.create()
402 .loadTrustMaterial(resource2, storePassword.toCharArray())
403 .build();
404 Assert.assertNotNull(clientSslContext);
405 final SSLServerSocket serverSocket = (SSLServerSocket) serverSslContext.getServerSocketFactory().createServerSocket();
406 serverSocket.setWantClientAuth(true);
407 serverSocket.bind(new InetSocketAddress(0));
408
409 this.executorService = Executors.newSingleThreadExecutor();
410 final Future<Principal> future = this.executorService.submit(new Callable<Principal>() {
411 @Override
412 public Principal call() throws Exception {
413 final SSLSocket socket = (SSLSocket) serverSocket.accept();
414 Principal clientPrincipal = null;
415 try {
416 final SSLSession session = socket.getSession();
417 try {
418 clientPrincipal = session.getPeerPrincipal();
419 } catch (final SSLPeerUnverifiedException ignore) {
420 }
421 final OutputStream outputStream = socket.getOutputStream();
422 outputStream.write(new byte [] {'H', 'i'});
423 outputStream.flush();
424 } finally {
425 socket.close();
426 }
427 return clientPrincipal;
428 }
429 });
430
431 final int localPort = serverSocket.getLocalPort();
432 final SSLSocket clientSocket = (SSLSocket) clientSslContext.getSocketFactory().createSocket();
433 try {
434 clientSocket.connect(new InetSocketAddress("localhost", localPort), TIMEOUT);
435 clientSocket.setSoTimeout(TIMEOUT);
436 clientSocket.startHandshake();
437 final InputStream inputStream = clientSocket.getInputStream();
438 Assert.assertEquals('H', inputStream.read());
439 Assert.assertEquals('i', inputStream.read());
440 Assert.assertEquals(-1, inputStream.read());
441 } finally {
442 clientSocket.close();
443 }
444
445 final Principal clientPrincipal = future.get(5, TimeUnit.SECONDS);
446 Assert.assertNull(clientPrincipal);
447 }
448
449 @Test
450 public void testSSLHandshakeClientUnauthenticatedError() throws Exception {
451 thrown.expect(IOException.class);
452
453 final URL resource1 = getResource("/test-server.keystore");
454 final String storePassword = "nopassword";
455 final String keyPassword = "nopassword";
456 final SSLContext serverSslContext = SSLContextBuilder.create()
457 .loadKeyMaterial(resource1, storePassword.toCharArray(), keyPassword.toCharArray())
458 .build();
459 Assert.assertNotNull(serverSslContext);
460 final URL resource2 = getResource("/test-client.keystore");
461 final SSLContext clientSslContext = SSLContextBuilder.create()
462 .loadTrustMaterial(resource2, storePassword.toCharArray())
463 .build();
464 Assert.assertNotNull(clientSslContext);
465 final SSLServerSocket serverSocket = (SSLServerSocket) serverSslContext.getServerSocketFactory().createServerSocket();
466 serverSocket.setNeedClientAuth(true);
467 serverSocket.bind(new InetSocketAddress(0));
468
469 this.executorService = Executors.newSingleThreadExecutor();
470 this.executorService.submit(new Callable<Boolean>() {
471 @Override
472 public Boolean call() throws Exception {
473 final SSLSocket socket = (SSLSocket) serverSocket.accept();
474 try {
475 socket.getSession();
476 } finally {
477 socket.close();
478 }
479 return Boolean.FALSE;
480 }
481 });
482
483 final int localPort = serverSocket.getLocalPort();
484 final SSLSocket clientSocket = (SSLSocket) clientSslContext.getSocketFactory().createSocket();
485 try {
486 clientSocket.connect(new InetSocketAddress("localhost", localPort), TIMEOUT);
487 clientSocket.setSoTimeout(TIMEOUT);
488 clientSocket.startHandshake();
489 final InputStream inputStream = clientSocket.getInputStream();
490 Assert.assertEquals(-1, inputStream.read());
491 } finally {
492 clientSocket.close();
493 }
494 }
495
496 @Test
497 public void testSSLHandshakeClientAuthenticated() throws Exception {
498 final URL resource1 = getResource("/test-server.keystore");
499 final String storePassword = "nopassword";
500 final String keyPassword = "nopassword";
501 final SSLContext serverSslContext = SSLContextBuilder.create()
502 .loadTrustMaterial(resource1, storePassword.toCharArray())
503 .loadKeyMaterial(resource1, storePassword.toCharArray(), keyPassword.toCharArray())
504 .build();
505 Assert.assertNotNull(serverSslContext);
506 final URL resource2 = getResource("/test-client.keystore");
507 final SSLContext clientSslContext = SSLContextBuilder.create()
508 .loadTrustMaterial(resource2, storePassword.toCharArray())
509 .loadKeyMaterial(resource2, storePassword.toCharArray(), storePassword.toCharArray())
510 .build();
511 Assert.assertNotNull(clientSslContext);
512 final SSLServerSocket serverSocket = (SSLServerSocket) serverSslContext.getServerSocketFactory().createServerSocket();
513 serverSocket.setNeedClientAuth(true);
514 serverSocket.bind(new InetSocketAddress(0));
515
516 this.executorService = Executors.newSingleThreadExecutor();
517 final Future<Principal> future = this.executorService.submit(new Callable<Principal>() {
518 @Override
519 public Principal call() throws Exception {
520 final SSLSocket socket = (SSLSocket) serverSocket.accept();
521 try {
522 final SSLSession session = socket.getSession();
523 final Principal clientPrincipal = session.getPeerPrincipal();
524 final OutputStream outputStream = socket.getOutputStream();
525 outputStream.write(new byte[]{'H', 'i'});
526 outputStream.flush();
527 return clientPrincipal;
528 } finally {
529 socket.close();
530 }
531 }
532 });
533 final int localPort = serverSocket.getLocalPort();
534 final SSLSocket clientSocket = (SSLSocket) clientSslContext.getSocketFactory().createSocket();
535 try {
536 clientSocket.connect(new InetSocketAddress("localhost", localPort), TIMEOUT);
537 clientSocket.setSoTimeout(TIMEOUT);
538 clientSocket.startHandshake();
539 final InputStream inputStream = clientSocket.getInputStream();
540 Assert.assertEquals('H', inputStream.read());
541 Assert.assertEquals('i', inputStream.read());
542 Assert.assertEquals(-1, inputStream.read());
543 } finally {
544 clientSocket.close();
545 }
546
547 final Principal clientPrincipal = future.get(5, TimeUnit.SECONDS);
548 Assert.assertNotNull(clientPrincipal);
549 }
550
551 @Test
552 public void testSSLHandshakeClientAuthenticatedPrivateKeyStrategy() throws Exception {
553 final URL resource1 = getResource("/test-server.keystore");
554 final String storePassword = "nopassword";
555 final String keyPassword = "nopassword";
556 final SSLContext serverSslContext = SSLContextBuilder.create()
557 .loadTrustMaterial(resource1, storePassword.toCharArray())
558 .loadKeyMaterial(resource1, storePassword.toCharArray(), keyPassword.toCharArray())
559 .build();
560 Assert.assertNotNull(serverSslContext);
561
562 final PrivateKeyStrategy privateKeyStrategy = new PrivateKeyStrategy() {
563 @Override
564 public String chooseAlias(final Map<String, PrivateKeyDetails> aliases, final Socket socket) {
565 return aliases.containsKey("client2") ? "client2" : null;
566 }
567 };
568
569 final URL resource2 = getResource("/test-client.keystore");
570 final SSLContext clientSslContext = SSLContextBuilder.create()
571 .loadTrustMaterial(resource2, storePassword.toCharArray())
572 .loadKeyMaterial(resource2, storePassword.toCharArray(), storePassword.toCharArray(), privateKeyStrategy)
573 .build();
574 Assert.assertNotNull(clientSslContext);
575 final SSLServerSocket serverSocket = (SSLServerSocket) serverSslContext.getServerSocketFactory().createServerSocket();
576 serverSocket.setNeedClientAuth(true);
577 serverSocket.bind(new InetSocketAddress(0));
578
579 this.executorService = Executors.newSingleThreadExecutor();
580 final Future<Principal> future = this.executorService.submit(new Callable<Principal>() {
581 @Override
582 public Principal call() throws Exception {
583 final SSLSocket socket = (SSLSocket) serverSocket.accept();
584 try {
585 final SSLSession session = socket.getSession();
586 final Principal clientPrincipal = session.getPeerPrincipal();
587 final OutputStream outputStream = socket.getOutputStream();
588 outputStream.write(new byte[]{'H', 'i'});
589 outputStream.flush();
590 return clientPrincipal;
591 } finally {
592 socket.close();
593 }
594 }
595 });
596 final int localPort = serverSocket.getLocalPort();
597 final SSLSocket clientSocket = (SSLSocket) clientSslContext.getSocketFactory().createSocket();
598 try {
599 clientSocket.connect(new InetSocketAddress("localhost", localPort), TIMEOUT);
600 clientSocket.setSoTimeout(TIMEOUT);
601 clientSocket.startHandshake();
602 final InputStream inputStream = clientSocket.getInputStream();
603 Assert.assertEquals('H', inputStream.read());
604 Assert.assertEquals('i', inputStream.read());
605 Assert.assertEquals(-1, inputStream.read());
606 } finally {
607 clientSocket.close();
608 }
609
610 final Principal clientPrincipal = future.get(5, TimeUnit.SECONDS);
611 Assert.assertNotNull(clientPrincipal);
612 Assert.assertEquals("CN=Test Client 2,OU=HttpComponents Project,O=Apache Software Foundation", clientPrincipal.getName());
613 }
614
615
616 @Test
617 public void testSSLHandshakeProtocolMismatch1() throws Exception {
618 if (isWindows()) {
619 thrown.expect(IOException.class);
620 } else {
621 thrown.expect(SSLHandshakeException.class);
622 }
623
624 final URL resource1 = getResource("/test-server.keystore");
625 final String storePassword = "nopassword";
626 final String keyPassword = "nopassword";
627 final SSLContext serverSslContext = SSLContextBuilder.create()
628 .loadKeyMaterial(resource1, storePassword.toCharArray(), keyPassword.toCharArray())
629 .build();
630 Assert.assertNotNull(serverSslContext);
631 final URL resource2 = getResource("/test-client.keystore");
632 final SSLContext clientSslContext = SSLContextBuilder.create()
633 .loadTrustMaterial(resource2, storePassword.toCharArray())
634 .build();
635 Assert.assertNotNull(clientSslContext);
636 final SSLServerSocket serverSocket = (SSLServerSocket) serverSslContext.getServerSocketFactory().createServerSocket();
637 final Set<String> supportedServerProtocols = new LinkedHashSet<String>(Arrays.asList(serverSocket.getSupportedProtocols()));
638 Assert.assertTrue(supportedServerProtocols.contains("TLSv1"));
639 serverSocket.setEnabledProtocols(new String[] {"TLSv1"});
640 serverSocket.bind(new InetSocketAddress(0));
641
642 this.executorService = Executors.newSingleThreadExecutor();
643 this.executorService.submit(new Callable<Boolean>() {
644 @Override
645 public Boolean call() throws Exception {
646 final SSLSocket socket = (SSLSocket) serverSocket.accept();
647 try {
648 socket.getSession();
649 } finally {
650 socket.close();
651 }
652 return Boolean.FALSE;
653 }
654 });
655
656 final int localPort = serverSocket.getLocalPort();
657 final SSLSocket clientSocket = (SSLSocket) clientSslContext.getSocketFactory().createSocket();
658 try {
659 final Set<String> supportedClientProtocols = new LinkedHashSet<String>(Arrays.asList(clientSocket.getSupportedProtocols()));
660 Assert.assertTrue(supportedClientProtocols.contains("SSLv3"));
661 clientSocket.setEnabledProtocols(new String[] {"SSLv3"} );
662 clientSocket.connect(new InetSocketAddress("localhost", localPort), TIMEOUT);
663 clientSocket.setSoTimeout(TIMEOUT);
664 clientSocket.startHandshake();
665 } finally {
666 clientSocket.close();
667 }
668 }
669
670 @Test
671 public void testSSLHandshakeProtocolMismatch2() throws Exception {
672 if (isWindows()) {
673 thrown.expect(IOException.class);
674 } else {
675 thrown.expect(SSLException.class);
676 }
677
678 final URL resource1 = getResource("/test-server.keystore");
679 final String storePassword = "nopassword";
680 final String keyPassword = "nopassword";
681 final SSLContext serverSslContext = SSLContextBuilder.create()
682 .loadKeyMaterial(resource1, storePassword.toCharArray(), keyPassword.toCharArray())
683 .build();
684 Assert.assertNotNull(serverSslContext);
685 final URL resource2 = getResource("/test-client.keystore");
686 final SSLContext clientSslContext = SSLContextBuilder.create()
687 .loadTrustMaterial(resource2, storePassword.toCharArray())
688 .build();
689 Assert.assertNotNull(clientSslContext);
690 final SSLServerSocket serverSocket = (SSLServerSocket) serverSslContext.getServerSocketFactory().createServerSocket();
691 final Set<String> supportedServerProtocols = new LinkedHashSet<String>(Arrays.asList(serverSocket.getSupportedProtocols()));
692 Assert.assertTrue(supportedServerProtocols.contains("SSLv3"));
693 serverSocket.setEnabledProtocols(new String[] {"SSLv3"});
694 serverSocket.bind(new InetSocketAddress("localhost", 0));
695
696 this.executorService = Executors.newSingleThreadExecutor();
697 this.executorService.submit(new Callable<Boolean>() {
698 @Override
699 public Boolean call() throws Exception {
700 final SSLSocket socket = (SSLSocket) serverSocket.accept();
701 try {
702 socket.getSession();
703 } finally {
704 socket.close();
705 }
706 return Boolean.FALSE;
707 }
708 });
709
710 final int localPort = serverSocket.getLocalPort();
711 final SSLSocket clientSocket = (SSLSocket) clientSslContext.getSocketFactory().createSocket();
712 try {
713 final Set<String> supportedClientProtocols = new LinkedHashSet<String>(
714 Arrays.asList(clientSocket.getSupportedProtocols()));
715 Assert.assertTrue(supportedClientProtocols.contains("TLSv1"));
716 clientSocket.setEnabledProtocols(new String[] { "TLSv1" });
717 clientSocket.connect(new InetSocketAddress("localhost", localPort), TIMEOUT);
718 clientSocket.setSoTimeout(TIMEOUT);
719 clientSocket.startHandshake();
720 } finally {
721 clientSocket.close();
722 }
723 }
724
725 @Test
726 public void testBuildWithProvider() throws Exception {
727 final URL resource1 = getResource("/test-server.keystore");
728 final String storePassword = "nopassword";
729 final String keyPassword = "nopassword";
730 final SSLContext sslContext=SSLContextBuilder.create()
731 .setProvider(Security.getProvider(PROVIDER_SUN_JSSE))
732 .loadKeyMaterial(resource1, storePassword.toCharArray(), keyPassword.toCharArray())
733 .build();
734 Assert.assertEquals(PROVIDER_SUN_JSSE, sslContext.getProvider().getName());
735 }
736
737 @Test
738 public void testBuildWithProviderName() throws Exception {
739 final URL resource1 = getResource("/test-server.keystore");
740 final String storePassword = "nopassword";
741 final String keyPassword = "nopassword";
742 final SSLContext sslContext=SSLContextBuilder.create()
743 .setProvider(PROVIDER_SUN_JSSE)
744 .loadKeyMaterial(resource1, storePassword.toCharArray(), keyPassword.toCharArray())
745 .build();
746 Assert.assertEquals(PROVIDER_SUN_JSSE, sslContext.getProvider().getName());
747 }
748
749 }