1 /*
2  * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 // SunJSSE does not support dynamic system properties, no way to re-use
25 // system properties in samevm/agentvm mode.
26 
27 /*
28  * @test
29  * @bug 8046321 8153829
30  * @summary OCSP Stapling for TLS
31  * @library ../../../../java/security/testlibrary
32  * @build CertificateBuilder SimpleOCSPServer
33  * @run main/othervm SSLSocketWithStapling
34  */
35 
36 import java.io.*;
37 import java.math.BigInteger;
38 import java.net.InetAddress;
39 import java.net.Socket;
40 import java.net.ServerSocket;
41 import java.security.GeneralSecurityException;
42 import java.security.KeyPair;
43 import java.security.KeyPairGenerator;
44 import javax.net.ssl.*;
45 import java.security.KeyStore;
46 import java.security.PublicKey;
47 import java.security.Security;
48 import java.security.cert.CertPathValidator;
49 import java.security.cert.CertPathValidatorException;
50 import java.security.cert.CertPathValidatorException.BasicReason;
51 import java.security.cert.Certificate;
52 import java.security.cert.PKIXBuilderParameters;
53 import java.security.cert.X509CertSelector;
54 import java.security.cert.X509Certificate;
55 import java.security.cert.PKIXRevocationChecker;
56 import java.security.cert.PKIXRevocationChecker.Option;
57 import java.util.ArrayList;
58 import java.util.Collections;
59 import java.util.Date;
60 import java.util.EnumSet;
61 import java.util.List;
62 import java.util.Map;
63 import java.util.HashMap;
64 import java.util.concurrent.TimeUnit;
65 
66 import sun.security.testlibrary.SimpleOCSPServer;
67 import sun.security.testlibrary.CertificateBuilder;
68 
69 public class SSLSocketWithStapling {
70 
71     /*
72      * =============================================================
73      * Set the various variables needed for the tests, then
74      * specify what tests to run on each side.
75      */
76 
77     // Turn on TLS debugging
78     static final boolean debug = false;
79 
80     /*
81      * Should we run the client or server in a separate thread?
82      * Both sides can throw exceptions, but do you have a preference
83      * as to which side should be the main thread.
84      */
85     static boolean separateServerThread = true;
86     Thread clientThread = null;
87     Thread serverThread = null;
88 
89     static String passwd = "passphrase";
90     static String ROOT_ALIAS = "root";
91     static String INT_ALIAS = "intermediate";
92     static String SSL_ALIAS = "ssl";
93 
94     /*
95      * Is the server ready to serve?
96      */
97     volatile static boolean serverReady = false;
98     volatile int serverPort = 0;
99 
100     volatile Exception serverException = null;
101     volatile Exception clientException = null;
102 
103     // PKI components we will need for this test
104     static KeyStore rootKeystore;           // Root CA Keystore
105     static KeyStore intKeystore;            // Intermediate CA Keystore
106     static KeyStore serverKeystore;         // SSL Server Keystore
107     static KeyStore trustStore;             // SSL Client trust store
108     static SimpleOCSPServer rootOcsp;       // Root CA OCSP Responder
109     static int rootOcspPort;                // Port number for root OCSP
110     static SimpleOCSPServer intOcsp;        // Intermediate CA OCSP Responder
111     static int intOcspPort;                 // Port number for intermed. OCSP
112 
113     // Extra configuration parameters and constants
114     static final String[] TLS13ONLY = new String[] { "TLSv1.3" };
115     static final String[] TLS12MAX =
116             new String[] { "TLSv1.2", "TLSv1.1", "TLSv1" };
117 
118     /*
119      * If the client or server is doing some kind of object creation
120      * that the other side depends on, and that thread prematurely
121      * exits, you may experience a hang.  The test harness will
122      * terminate all hung threads after its timeout has expired,
123      * currently 3 minutes by default, but you might try to be
124      * smart about it....
125      */
main(String[] args)126     public static void main(String[] args) throws Exception {
127         if (debug) {
128             System.setProperty("javax.net.debug", "ssl:handshake");
129         }
130 
131         try {
132             // Create the PKI we will use for the test and start the OCSP servers
133             createPKI();
134 
135             testAllDefault(false);
136             testAllDefault(true);
137             testPKIXParametersRevEnabled(false);
138             testPKIXParametersRevEnabled(true);
139             testRevokedCertificate(false);
140             testRevokedCertificate(true);
141             testRevokedIntermediate(false);
142             testRevokedIntermediate(true);
143             testMissingIntermediate(false);
144             testMissingIntermediate(true);
145             testHardFailFallback(false);
146             testHardFailFallback(true);
147             testSoftFailFallback(false);
148             testSoftFailFallback(true);
149             testLatencyNoStaple(false, false);
150             testLatencyNoStaple(false, true);
151             testLatencyNoStaple(true, false);
152             testLatencyNoStaple(true, true);
153         } finally {
154             // shut down the OCSP responders before finishing the test
155             intOcsp.stop();
156             rootOcsp.stop();
157         }
158     }
159 
160     /**
161      * Default test using no externally-configured PKIXBuilderParameters
162      */
testAllDefault(boolean isTls13)163     static void testAllDefault(boolean isTls13) throws Exception {
164         ClientParameters cliParams = new ClientParameters();
165         ServerParameters servParams = new ServerParameters();
166         if (isTls13) {
167             cliParams.protocols = TLS13ONLY;
168             servParams.protocols = TLS13ONLY;
169         } else {
170             cliParams.protocols = TLS12MAX;
171             servParams.protocols = TLS12MAX;
172         }
173         serverReady = false;
174         Map<BigInteger, SimpleOCSPServer.CertStatusInfo> revInfo =
175                 new HashMap<>();
176 
177         // We will prove revocation checking is disabled by marking the SSL
178         // certificate as revoked.  The test would only pass if revocation
179         // checking did not happen.
180         X509Certificate sslCert =
181                 (X509Certificate)serverKeystore.getCertificate(SSL_ALIAS);
182         Date fiveMinsAgo = new Date(System.currentTimeMillis() -
183                 TimeUnit.MINUTES.toMillis(5));
184         revInfo.put(sslCert.getSerialNumber(),
185                 new SimpleOCSPServer.CertStatusInfo(
186                         SimpleOCSPServer.CertStatus.CERT_STATUS_REVOKED,
187                         fiveMinsAgo));
188         intOcsp.updateStatusDb(revInfo);
189 
190         System.out.println("=======================================");
191         System.out.println("Stapling enabled, default configuration");
192         System.out.println("=======================================");
193 
194         SSLSocketWithStapling sslTest = new SSLSocketWithStapling(cliParams,
195                 servParams);
196         TestResult tr = sslTest.getResult();
197         if (tr.clientExc != null) {
198             throw tr.clientExc;
199         } else if (tr.serverExc != null) {
200             throw tr.serverExc;
201         }
202 
203         // Return the ssl certificate to non-revoked status
204         revInfo.put(sslCert.getSerialNumber(),
205                 new SimpleOCSPServer.CertStatusInfo(
206                         SimpleOCSPServer.CertStatus.CERT_STATUS_GOOD));
207         intOcsp.updateStatusDb(revInfo);
208 
209         System.out.println("                PASS");
210         System.out.println("=======================================\n");
211     }
212 
213     /**
214      * Do a basic connection using PKIXParameters with revocation checking
215      * enabled and client-side OCSP disabled.  It will only pass if all
216      * stapled responses are present, valid and have a GOOD status.
217      */
testPKIXParametersRevEnabled(boolean isTls13)218     static void testPKIXParametersRevEnabled(boolean isTls13) throws Exception {
219         ClientParameters cliParams = new ClientParameters();
220         ServerParameters servParams = new ServerParameters();
221         if (isTls13) {
222             cliParams.protocols = TLS13ONLY;
223             servParams.protocols = TLS13ONLY;
224         } else {
225             cliParams.protocols = TLS12MAX;
226             servParams.protocols = TLS12MAX;
227         }
228         serverReady = false;
229 
230         System.out.println("=====================================");
231         System.out.println("Stapling enabled, PKIXParameters with");
232         System.out.println("Revocation checking enabled ");
233         System.out.println("=====================================");
234 
235         cliParams.pkixParams = new PKIXBuilderParameters(trustStore,
236                 new X509CertSelector());
237         cliParams.pkixParams.setRevocationEnabled(true);
238         Security.setProperty("ocsp.enable", "false");
239 
240         SSLSocketWithStapling sslTest = new SSLSocketWithStapling(cliParams,
241                 servParams);
242         TestResult tr = sslTest.getResult();
243         if (tr.clientExc != null) {
244             throw tr.clientExc;
245         } else if (tr.serverExc != null) {
246             throw tr.serverExc;
247         }
248 
249         System.out.println("                PASS");
250         System.out.println("=====================================\n");
251     }
252 
253     /**
254      * Perform a test where the certificate is revoked and placed in the
255      * TLS handshake.  Client-side OCSP is disabled, so this test will only
256      * pass if the OCSP response is found, since we will check the
257      * CertPathValidatorException reason for revoked status.
258      */
testRevokedCertificate(boolean isTls13)259     static void testRevokedCertificate(boolean isTls13) throws Exception {
260         ClientParameters cliParams = new ClientParameters();
261         ServerParameters servParams = new ServerParameters();
262         if (isTls13) {
263             cliParams.protocols = TLS13ONLY;
264             servParams.protocols = TLS13ONLY;
265         } else {
266             cliParams.protocols = TLS12MAX;
267             servParams.protocols = TLS12MAX;
268         }
269         serverReady = false;
270         Map<BigInteger, SimpleOCSPServer.CertStatusInfo> revInfo =
271                 new HashMap<>();
272 
273         // We will prove revocation checking is disabled by marking the SSL
274         // certificate as revoked.  The test would only pass if revocation
275         // checking did not happen.
276         X509Certificate sslCert =
277                 (X509Certificate)serverKeystore.getCertificate(SSL_ALIAS);
278         Date fiveMinsAgo = new Date(System.currentTimeMillis() -
279                 TimeUnit.MINUTES.toMillis(5));
280         revInfo.put(sslCert.getSerialNumber(),
281                 new SimpleOCSPServer.CertStatusInfo(
282                         SimpleOCSPServer.CertStatus.CERT_STATUS_REVOKED,
283                         fiveMinsAgo));
284         intOcsp.updateStatusDb(revInfo);
285 
286         System.out.println("============================================");
287         System.out.println("Stapling enabled, detect revoked certificate");
288         System.out.println("============================================");
289 
290         cliParams.pkixParams = new PKIXBuilderParameters(trustStore,
291                 new X509CertSelector());
292         cliParams.pkixParams.setRevocationEnabled(true);
293         Security.setProperty("ocsp.enable", "false");
294 
295         SSLSocketWithStapling sslTest = new SSLSocketWithStapling(cliParams,
296                 servParams);
297         TestResult tr = sslTest.getResult();
298         if (!checkClientValidationFailure(tr.clientExc, BasicReason.REVOKED)) {
299             if (tr.clientExc != null) {
300                 throw tr.clientExc;
301             } else {
302                 throw new RuntimeException(
303                         "Expected client failure, but the client succeeded");
304             }
305         }
306 
307         // Return the ssl certificate to non-revoked status
308         revInfo.put(sslCert.getSerialNumber(),
309                 new SimpleOCSPServer.CertStatusInfo(
310                         SimpleOCSPServer.CertStatus.CERT_STATUS_GOOD));
311         intOcsp.updateStatusDb(revInfo);
312 
313         System.out.println("                 PASS");
314         System.out.println("=======================================\n");
315     }
316 
317     /**
318      * Perform a test where the intermediate CA certificate is revoked and
319      * placed in the TLS handshake.  Client-side OCSP is disabled, so this
320      * test will only pass if the OCSP response for the intermediate CA is
321      * found and placed into the CertificateStatus or Certificate message
322      * (depending on the protocol version) since we will check
323      * the CertPathValidatorException reason for revoked status.
324      */
testRevokedIntermediate(boolean isTls13)325     static void testRevokedIntermediate(boolean isTls13) throws Exception {
326         ClientParameters cliParams = new ClientParameters();
327         ServerParameters servParams = new ServerParameters();
328         if (isTls13) {
329             cliParams.protocols = TLS13ONLY;
330             servParams.protocols = TLS13ONLY;
331         } else {
332             cliParams.protocols = TLS12MAX;
333             servParams.protocols = TLS12MAX;
334         }
335         serverReady = false;
336         Map<BigInteger, SimpleOCSPServer.CertStatusInfo> revInfo =
337                 new HashMap<>();
338 
339         // We will prove revocation checking is disabled by marking the SSL
340         // certificate as revoked.  The test would only pass if revocation
341         // checking did not happen.
342         X509Certificate intCACert =
343                 (X509Certificate)intKeystore.getCertificate(INT_ALIAS);
344         Date fiveMinsAgo = new Date(System.currentTimeMillis() -
345                 TimeUnit.MINUTES.toMillis(5));
346         revInfo.put(intCACert.getSerialNumber(),
347                 new SimpleOCSPServer.CertStatusInfo(
348                         SimpleOCSPServer.CertStatus.CERT_STATUS_REVOKED,
349                         fiveMinsAgo));
350         rootOcsp.updateStatusDb(revInfo);
351 
352         System.out.println("===============================================");
353         System.out.println("Stapling enabled, detect revoked CA certificate");
354         System.out.println("===============================================");
355 
356         cliParams.pkixParams = new PKIXBuilderParameters(trustStore,
357                 new X509CertSelector());
358         cliParams.pkixParams.setRevocationEnabled(true);
359         Security.setProperty("ocsp.enable", "false");
360 
361         SSLSocketWithStapling sslTest = new SSLSocketWithStapling(cliParams,
362                 servParams);
363         TestResult tr = sslTest.getResult();
364         if (!checkClientValidationFailure(tr.clientExc, BasicReason.REVOKED)) {
365             if (tr.clientExc != null) {
366                 throw tr.clientExc;
367             } else {
368                 throw new RuntimeException(
369                         "Expected client failure, but the client succeeded");
370             }
371         }
372 
373         // Return the ssl certificate to non-revoked status
374         revInfo.put(intCACert.getSerialNumber(),
375                 new SimpleOCSPServer.CertStatusInfo(
376                         SimpleOCSPServer.CertStatus.CERT_STATUS_GOOD));
377         rootOcsp.updateStatusDb(revInfo);
378 
379         System.out.println("                 PASS");
380         System.out.println("=======================================\n");
381     }
382 
383     /**
384      * Test a case where OCSP stapling is attempted, but partially occurs
385      * because the root OCSP responder is unreachable.  This should use a
386      * default hard-fail behavior.
387      */
testMissingIntermediate(boolean isTls13)388     static void testMissingIntermediate(boolean isTls13) throws Exception {
389         ClientParameters cliParams = new ClientParameters();
390         ServerParameters servParams = new ServerParameters();
391         if (isTls13) {
392             cliParams.protocols = TLS13ONLY;
393             servParams.protocols = TLS13ONLY;
394         } else {
395             cliParams.protocols = TLS12MAX;
396             servParams.protocols = TLS12MAX;
397         }
398         serverReady = false;
399 
400         // Make the OCSP responder reject connections
401         rootOcsp.rejectConnections();
402 
403         System.out.println("=======================================");
404         System.out.println("Stapling enbled in client and server,");
405         System.out.println("but root OCSP responder disabled.");
406         System.out.println("PKIXParameters with Revocation checking");
407         System.out.println("enabled.");
408         System.out.println("=======================================");
409 
410         Security.setProperty("ocsp.enable", "false");
411         cliParams.pkixParams = new PKIXBuilderParameters(trustStore,
412                 new X509CertSelector());
413         cliParams.pkixParams.setRevocationEnabled(true);
414 
415         SSLSocketWithStapling sslTest = new SSLSocketWithStapling(cliParams,
416                 servParams);
417         TestResult tr = sslTest.getResult();
418         if (!checkClientValidationFailure(tr.clientExc,
419                 BasicReason.UNDETERMINED_REVOCATION_STATUS)) {
420             if (tr.clientExc != null) {
421                 throw tr.clientExc;
422             } else {
423                 throw new RuntimeException(
424                         "Expected client failure, but the client succeeded");
425             }
426         }
427 
428         System.out.println("                 PASS");
429         System.out.println("=======================================\n");
430 
431         // Make root OCSP responder accept connections
432         rootOcsp.acceptConnections();
433 
434         // Wait 5 seconds for server ready
435         for (int i = 0; (i < 100 && !rootOcsp.isServerReady()); i++) {
436             Thread.sleep(50);
437         }
438         if (!rootOcsp.isServerReady()) {
439             throw new RuntimeException("Root OCSP responder not ready yet");
440         }
441     }
442 
443     /**
444      * Test a case where client-side stapling is attempted, but does not
445      * occur because OCSP responders are unreachable.  This should use a
446      * default hard-fail behavior.
447      */
testHardFailFallback(boolean isTls13)448     static void testHardFailFallback(boolean isTls13) throws Exception {
449         ClientParameters cliParams = new ClientParameters();
450         ServerParameters servParams = new ServerParameters();
451         if (isTls13) {
452             cliParams.protocols = TLS13ONLY;
453             servParams.protocols = TLS13ONLY;
454         } else {
455             cliParams.protocols = TLS12MAX;
456             servParams.protocols = TLS12MAX;
457         }
458         serverReady = false;
459 
460         // make OCSP responders reject connections
461         intOcsp.rejectConnections();
462         rootOcsp.rejectConnections();
463 
464         System.out.println("=======================================");
465         System.out.println("Stapling enbled in client and server,");
466         System.out.println("but OCSP responders disabled.");
467         System.out.println("PKIXParameters with Revocation checking");
468         System.out.println("enabled.");
469         System.out.println("=======================================");
470 
471         Security.setProperty("ocsp.enable", "true");
472         cliParams.pkixParams = new PKIXBuilderParameters(trustStore,
473                 new X509CertSelector());
474         cliParams.pkixParams.setRevocationEnabled(true);
475 
476         SSLSocketWithStapling sslTest = new SSLSocketWithStapling(cliParams,
477                 servParams);
478         TestResult tr = sslTest.getResult();
479         if (!checkClientValidationFailure(tr.clientExc,
480                 BasicReason.UNDETERMINED_REVOCATION_STATUS)) {
481             if (tr.clientExc != null) {
482                 throw tr.clientExc;
483             } else {
484                 throw new RuntimeException(
485                         "Expected client failure, but the client succeeded");
486             }
487         }
488 
489         System.out.println("                 PASS");
490         System.out.println("=======================================\n");
491 
492         // Make OCSP responders accept connections
493         intOcsp.acceptConnections();
494         rootOcsp.acceptConnections();
495 
496         // Wait 5 seconds for server ready
497         for (int i = 0; (i < 100 && (!intOcsp.isServerReady() ||
498                 !rootOcsp.isServerReady())); i++) {
499             Thread.sleep(50);
500         }
501         if (!intOcsp.isServerReady() || !rootOcsp.isServerReady()) {
502             throw new RuntimeException("Server not ready yet");
503         }
504     }
505 
506     /**
507      * Test a case where client-side stapling is attempted, but does not
508      * occur because OCSP responders are unreachable.  Client-side OCSP
509      * checking is enabled for this, with SOFT_FAIL.
510      */
testSoftFailFallback(boolean isTls13)511     static void testSoftFailFallback(boolean isTls13) throws Exception {
512         ClientParameters cliParams = new ClientParameters();
513         ServerParameters servParams = new ServerParameters();
514         if (isTls13) {
515             cliParams.protocols = TLS13ONLY;
516             servParams.protocols = TLS13ONLY;
517         } else {
518             cliParams.protocols = TLS12MAX;
519             servParams.protocols = TLS12MAX;
520         }
521         serverReady = false;
522 
523         // make OCSP responders reject connections
524         intOcsp.rejectConnections();
525         rootOcsp.rejectConnections();
526 
527         System.out.println("=======================================");
528         System.out.println("Stapling enbled in client and server,");
529         System.out.println("but OCSP responders disabled.");
530         System.out.println("PKIXParameters with Revocation checking");
531         System.out.println("enabled and SOFT_FAIL.");
532         System.out.println("=======================================");
533 
534         Security.setProperty("ocsp.enable", "true");
535         cliParams.pkixParams = new PKIXBuilderParameters(trustStore,
536                 new X509CertSelector());
537         cliParams.pkixParams.setRevocationEnabled(true);
538         CertPathValidator cpv = CertPathValidator.getInstance("PKIX");
539         cliParams.revChecker =
540                 (PKIXRevocationChecker)cpv.getRevocationChecker();
541         cliParams.revChecker.setOptions(EnumSet.of(Option.SOFT_FAIL));
542 
543         SSLSocketWithStapling sslTest = new SSLSocketWithStapling(cliParams,
544                 servParams);
545         TestResult tr = sslTest.getResult();
546         if (tr.clientExc != null) {
547             throw tr.clientExc;
548         } else if (tr.serverExc != null) {
549             throw tr.serverExc;
550         }
551 
552         // make sure getSoftFailExceptions is not empty
553         if (cliParams.revChecker.getSoftFailExceptions().isEmpty()) {
554             throw new Exception("No soft fail exceptions");
555         }
556 
557         System.out.println("                 PASS");
558         System.out.println("=======================================\n");
559 
560 
561         // Make OCSP responders accept connections
562         intOcsp.acceptConnections();
563         rootOcsp.acceptConnections();
564 
565         // Wait 5 seconds for server ready
566         for (int i = 0; (i < 100 && (!intOcsp.isServerReady() ||
567                         !rootOcsp.isServerReady())); i++) {
568             Thread.sleep(50);
569         }
570         if (!intOcsp.isServerReady() || !rootOcsp.isServerReady()) {
571             throw new RuntimeException("Server not ready yet");
572         }
573     }
574 
575     /**
576      * This test initiates stapling from the client, but the server does not
577      * support OCSP stapling for this connection.  In this case it happens
578      * because the latency of the OCSP responders is longer than the server
579      * is willing to wait.  To keep the test streamlined, we will set the server
580      * latency to a 1 second wait, and set the responder latency to 3 seconds.
581      *
582      * @param fallback if we allow client-side OCSP fallback, which
583      * will change the result from the client failing with CPVE (no fallback)
584      * to a pass (fallback active).
585      */
testLatencyNoStaple(Boolean fallback, boolean isTls13)586     static void testLatencyNoStaple(Boolean fallback, boolean isTls13)
587             throws Exception {
588         ClientParameters cliParams = new ClientParameters();
589         ServerParameters servParams = new ServerParameters();
590         if (isTls13) {
591             cliParams.protocols = TLS13ONLY;
592             servParams.protocols = TLS13ONLY;
593         } else {
594             cliParams.protocols = TLS12MAX;
595             servParams.protocols = TLS12MAX;
596         }
597         serverReady = false;
598 
599         // Give a 1 second delay before running the test.
600         intOcsp.setDelay(3000);
601         rootOcsp.setDelay(3000);
602         Thread.sleep(1000);
603 
604         // Wait 5 seconds for server ready
605         for (int i = 0; (i < 100 && (!intOcsp.isServerReady() ||
606                         !rootOcsp.isServerReady())); i++) {
607             Thread.sleep(50);
608         }
609         if (!intOcsp.isServerReady() || !rootOcsp.isServerReady()) {
610             throw new RuntimeException("Server not ready yet");
611         }
612 
613         System.out.println("========================================");
614         System.out.println("Stapling enbled in client.  Server does");
615         System.out.println("not support stapling due to OCSP latency.");
616         System.out.println("PKIXParameters with Revocation checking");
617         System.out.println("enabled, client-side OCSP checking is.");
618         System.out.println(fallback ? "enabled" : "disabled");
619         System.out.println("========================================");
620 
621         Security.setProperty("ocsp.enable", fallback.toString());
622         cliParams.pkixParams = new PKIXBuilderParameters(trustStore,
623                 new X509CertSelector());
624         cliParams.pkixParams.setRevocationEnabled(true);
625         servParams.respTimeout = 1000;
626 
627         SSLSocketWithStapling sslTest = new SSLSocketWithStapling(cliParams,
628                 servParams);
629         TestResult tr = sslTest.getResult();
630 
631         if (fallback) {
632             if (tr.clientExc != null) {
633                 throw tr.clientExc;
634             } else if (tr.serverExc != null) {
635                 throw tr.serverExc;
636             }
637         } else {
638             if (!checkClientValidationFailure(tr.clientExc,
639                     BasicReason.UNDETERMINED_REVOCATION_STATUS)) {
640                 if (tr.clientExc != null) {
641                     throw tr.clientExc;
642                 } else {
643                     throw new RuntimeException(
644                         "Expected client failure, but the client succeeded");
645                 }
646             }
647         }
648         System.out.println("                 PASS");
649         System.out.println("========================================\n");
650 
651         // Remove the OCSP responder latency
652         intOcsp.setDelay(0);
653         rootOcsp.setDelay(0);
654         Thread.sleep(1000);
655 
656         // Wait 5 seconds for server ready
657         for (int i = 0; (i < 100 && (!intOcsp.isServerReady() ||
658                 !rootOcsp.isServerReady())); i++) {
659             Thread.sleep(50);
660         }
661         if (!intOcsp.isServerReady() || !rootOcsp.isServerReady()) {
662             throw new RuntimeException("Server not ready yet");
663         }
664     }
665 
666     /*
667      * Define the server side of the test.
668      *
669      * If the server prematurely exits, serverReady will be set to true
670      * to avoid infinite hangs.
671      */
doServerSide(ServerParameters servParams)672     void doServerSide(ServerParameters servParams) throws Exception {
673 
674         // Selectively enable or disable the feature
675         System.setProperty("jdk.tls.server.enableStatusRequestExtension",
676                 Boolean.toString(servParams.enabled));
677 
678         // Set all the other operating parameters
679         System.setProperty("jdk.tls.stapling.cacheSize",
680                 Integer.toString(servParams.cacheSize));
681         System.setProperty("jdk.tls.stapling.cacheLifetime",
682                 Integer.toString(servParams.cacheLifetime));
683         System.setProperty("jdk.tls.stapling.responseTimeout",
684                 Integer.toString(servParams.respTimeout));
685         System.setProperty("jdk.tls.stapling.responderURI", servParams.respUri);
686         System.setProperty("jdk.tls.stapling.responderOverride",
687                 Boolean.toString(servParams.respOverride));
688         System.setProperty("jdk.tls.stapling.ignoreExtensions",
689                 Boolean.toString(servParams.ignoreExts));
690 
691         // Set keystores and trust stores for the server
692         KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
693         kmf.init(serverKeystore, passwd.toCharArray());
694         TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
695         tmf.init(trustStore);
696 
697         SSLContext sslc = SSLContext.getInstance("TLS");
698         sslc.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
699 
700         SSLServerSocketFactory sslssf = new CustomizedServerSocketFactory(sslc,
701                 servParams.protocols, servParams.ciphers);
702 
703         try (SSLServerSocket sslServerSocket =
704                 (SSLServerSocket) sslssf.createServerSocket(serverPort)) {
705 
706             serverPort = sslServerSocket.getLocalPort();
707 
708             /*
709              * Signal Client, we're ready for his connect.
710              */
711             serverReady = true;
712 
713             try (SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();
714                     InputStream sslIS = sslSocket.getInputStream();
715                     OutputStream sslOS = sslSocket.getOutputStream()) {
716                 int numberIn = sslIS.read();
717                 int numberSent = 85;
718                 log("Server received number: " + numberIn);
719                 sslOS.write(numberSent);
720                 sslOS.flush();
721                 log("Server sent number: " + numberSent);
722             }
723         }
724     }
725 
726     /*
727      * Define the client side of the test.
728      *
729      * If the server prematurely exits, serverReady will be set to true
730      * to avoid infinite hangs.
731      */
doClientSide(ClientParameters cliParams)732     void doClientSide(ClientParameters cliParams) throws Exception {
733 
734         // Wait 5 seconds for server ready
735         for (int i = 0; (i < 100 && !serverReady); i++) {
736             Thread.sleep(50);
737         }
738         if (!serverReady) {
739             throw new RuntimeException("Server not ready yet");
740         }
741 
742         // Selectively enable or disable the feature
743         System.setProperty("jdk.tls.client.enableStatusRequestExtension",
744                 Boolean.toString(cliParams.enabled));
745 
746         // Create the Trust Manager Factory using the PKIX variant
747         TrustManagerFactory tmf = TrustManagerFactory.getInstance("PKIX");
748 
749         // If we have a customized pkixParameters then use it
750         if (cliParams.pkixParams != null) {
751             // LIf we have a customized PKIXRevocationChecker, add
752             // it to the PKIXBuilderParameters.
753             if (cliParams.revChecker != null) {
754                 cliParams.pkixParams.addCertPathChecker(cliParams.revChecker);
755             }
756 
757             ManagerFactoryParameters trustParams =
758                     new CertPathTrustManagerParameters(cliParams.pkixParams);
759             tmf.init(trustParams);
760         } else {
761             tmf.init(trustStore);
762         }
763 
764         SSLContext sslc = SSLContext.getInstance("TLS");
765         sslc.init(null, tmf.getTrustManagers(), null);
766 
767         SSLSocketFactory sslsf = new CustomizedSocketFactory(sslc,
768                 cliParams.protocols, cliParams.ciphers);
769         try (SSLSocket sslSocket = (SSLSocket)sslsf.createSocket("localhost",
770                 serverPort);
771                 InputStream sslIS = sslSocket.getInputStream();
772                 OutputStream sslOS = sslSocket.getOutputStream()) {
773             int numberSent = 80;
774             sslOS.write(numberSent);
775             sslOS.flush();
776             log("Client sent number: " + numberSent);
777             int numberIn = sslIS.read();
778             log("Client received number:" + numberIn);
779         }
780     }
781 
782     /*
783      * Primary constructor, used to drive remainder of the test.
784      *
785      * Fork off the other side, then do your work.
786      */
SSLSocketWithStapling(ClientParameters cliParams, ServerParameters servParams)787     SSLSocketWithStapling(ClientParameters cliParams,
788             ServerParameters servParams) throws Exception {
789         Exception startException = null;
790         try {
791             if (separateServerThread) {
792                 startServer(servParams, true);
793                 startClient(cliParams, false);
794             } else {
795                 startClient(cliParams, true);
796                 startServer(servParams, false);
797             }
798         } catch (Exception e) {
799             startException = e;
800         }
801 
802         /*
803          * Wait for other side to close down.
804          */
805         if (separateServerThread) {
806             if (serverThread != null) {
807                 serverThread.join();
808             }
809         } else {
810             if (clientThread != null) {
811                 clientThread.join();
812             }
813         }
814     }
815 
816     /**
817      * Checks a validation failure to see if it failed for the reason we think
818      * it should.  This comes in as an SSLException of some sort, but it
819      * encapsulates a ValidatorException which in turn encapsulates the
820      * CertPathValidatorException we are interested in.
821      *
822      * @param e the exception thrown at the top level
823      * @param reason the underlying CertPathValidatorException BasicReason
824      * we are expecting it to have.
825      *
826      * @return true if the reason matches up, false otherwise.
827      */
checkClientValidationFailure(Exception e, BasicReason reason)828     static boolean checkClientValidationFailure(Exception e,
829             BasicReason reason) {
830         boolean result = false;
831 
832         if (e instanceof SSLException) {
833             Throwable valExc = e.getCause();
834             if (valExc instanceof sun.security.validator.ValidatorException) {
835                 Throwable cause = valExc.getCause();
836                 if (cause instanceof CertPathValidatorException) {
837                     CertPathValidatorException cpve =
838                             (CertPathValidatorException)cause;
839                     if (cpve.getReason() == reason) {
840                         result = true;
841                     }
842                 }
843             }
844         }
845         return result;
846     }
847 
getResult()848     TestResult getResult() {
849         TestResult tr = new TestResult();
850         tr.clientExc = clientException;
851         tr.serverExc = serverException;
852         return tr;
853     }
854 
startServer(ServerParameters servParams, boolean newThread)855     void startServer(ServerParameters servParams, boolean newThread)
856             throws Exception {
857         if (newThread) {
858             serverThread = new Thread() {
859                 public void run() {
860                     try {
861                         doServerSide(servParams);
862                     } catch (Exception e) {
863                         /*
864                          * Our server thread just died.
865                          *
866                          * Release the client, if not active already...
867                          */
868                         System.err.println("Server died...");
869                         e.printStackTrace(System.err);
870                         serverReady = true;
871                         serverException = e;
872                     }
873                 }
874             };
875             serverThread.start();
876         } else {
877             try {
878                 doServerSide(servParams);
879             } catch (Exception e) {
880                 serverException = e;
881             } finally {
882                 serverReady = true;
883             }
884         }
885     }
886 
startClient(ClientParameters cliParams, boolean newThread)887     void startClient(ClientParameters cliParams, boolean newThread)
888             throws Exception {
889         if (newThread) {
890             clientThread = new Thread() {
891                 public void run() {
892                     try {
893                         doClientSide(cliParams);
894                     } catch (Exception e) {
895                         /*
896                          * Our client thread just died.
897                          */
898                         System.err.println("Client died...");
899                         clientException = e;
900                     }
901                 }
902             };
903             clientThread.start();
904         } else {
905             try {
906                 doClientSide(cliParams);
907             } catch (Exception e) {
908                 clientException = e;
909             }
910         }
911     }
912 
913     /**
914      * Creates the PKI components necessary for this test, including
915      * Root CA, Intermediate CA and SSL server certificates, the keystores
916      * for each entity, a client trust store, and starts the OCSP responders.
917      */
createPKI()918     private static void createPKI() throws Exception {
919         CertificateBuilder cbld = new CertificateBuilder();
920         KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
921         keyGen.initialize(2048);
922         KeyStore.Builder keyStoreBuilder =
923                 KeyStore.Builder.newInstance("PKCS12", null,
924                         new KeyStore.PasswordProtection(passwd.toCharArray()));
925 
926         // Generate Root, IntCA, EE keys
927         KeyPair rootCaKP = keyGen.genKeyPair();
928         log("Generated Root CA KeyPair");
929         KeyPair intCaKP = keyGen.genKeyPair();
930         log("Generated Intermediate CA KeyPair");
931         KeyPair sslKP = keyGen.genKeyPair();
932         log("Generated SSL Cert KeyPair");
933 
934         // Set up the Root CA Cert
935         cbld.setSubjectName("CN=Root CA Cert, O=SomeCompany");
936         cbld.setPublicKey(rootCaKP.getPublic());
937         cbld.setSerialNumber(new BigInteger("1"));
938         // Make a 3 year validity starting from 60 days ago
939         long start = System.currentTimeMillis() - TimeUnit.DAYS.toMillis(60);
940         long end = start + TimeUnit.DAYS.toMillis(1085);
941         cbld.setValidity(new Date(start), new Date(end));
942         addCommonExts(cbld, rootCaKP.getPublic(), rootCaKP.getPublic());
943         addCommonCAExts(cbld);
944         // Make our Root CA Cert!
945         X509Certificate rootCert = cbld.build(null, rootCaKP.getPrivate(),
946                 "SHA256withRSA");
947         log("Root CA Created:\n" + certInfo(rootCert));
948 
949         // Now build a keystore and add the keys and cert
950         rootKeystore = keyStoreBuilder.getKeyStore();
951         Certificate[] rootChain = {rootCert};
952         rootKeystore.setKeyEntry(ROOT_ALIAS, rootCaKP.getPrivate(),
953                 passwd.toCharArray(), rootChain);
954 
955         // Now fire up the OCSP responder
956         rootOcsp = new SimpleOCSPServer(rootKeystore, passwd, ROOT_ALIAS, null);
957         rootOcsp.enableLog(debug);
958         rootOcsp.setNextUpdateInterval(3600);
959         rootOcsp.start();
960 
961         // Wait 5 seconds for server ready
962         for (int i = 0; (i < 100 && !rootOcsp.isServerReady()); i++) {
963             Thread.sleep(50);
964         }
965         if (!rootOcsp.isServerReady()) {
966             throw new RuntimeException("Server not ready yet");
967         }
968 
969         rootOcspPort = rootOcsp.getPort();
970         String rootRespURI = "http://localhost:" + rootOcspPort;
971         log("Root OCSP Responder URI is " + rootRespURI);
972 
973         // Now that we have the root keystore and OCSP responder we can
974         // create our intermediate CA.
975         cbld.reset();
976         cbld.setSubjectName("CN=Intermediate CA Cert, O=SomeCompany");
977         cbld.setPublicKey(intCaKP.getPublic());
978         cbld.setSerialNumber(new BigInteger("100"));
979         // Make a 2 year validity starting from 30 days ago
980         start = System.currentTimeMillis() - TimeUnit.DAYS.toMillis(30);
981         end = start + TimeUnit.DAYS.toMillis(730);
982         cbld.setValidity(new Date(start), new Date(end));
983         addCommonExts(cbld, intCaKP.getPublic(), rootCaKP.getPublic());
984         addCommonCAExts(cbld);
985         cbld.addAIAExt(Collections.singletonList(rootRespURI));
986         // Make our Intermediate CA Cert!
987         X509Certificate intCaCert = cbld.build(rootCert, rootCaKP.getPrivate(),
988                 "SHA256withRSA");
989         log("Intermediate CA Created:\n" + certInfo(intCaCert));
990 
991         // Provide intermediate CA cert revocation info to the Root CA
992         // OCSP responder.
993         Map<BigInteger, SimpleOCSPServer.CertStatusInfo> revInfo =
994             new HashMap<>();
995         revInfo.put(intCaCert.getSerialNumber(),
996                 new SimpleOCSPServer.CertStatusInfo(
997                         SimpleOCSPServer.CertStatus.CERT_STATUS_GOOD));
998         rootOcsp.updateStatusDb(revInfo);
999 
1000         // Now build a keystore and add the keys, chain and root cert as a TA
1001         intKeystore = keyStoreBuilder.getKeyStore();
1002         Certificate[] intChain = {intCaCert, rootCert};
1003         intKeystore.setKeyEntry(INT_ALIAS, intCaKP.getPrivate(),
1004                 passwd.toCharArray(), intChain);
1005         intKeystore.setCertificateEntry(ROOT_ALIAS, rootCert);
1006 
1007         // Now fire up the Intermediate CA OCSP responder
1008         intOcsp = new SimpleOCSPServer(intKeystore, passwd,
1009                 INT_ALIAS, null);
1010         intOcsp.enableLog(debug);
1011         intOcsp.setNextUpdateInterval(3600);
1012         intOcsp.start();
1013 
1014         // Wait 5 seconds for server ready
1015         for (int i = 0; (i < 100 && !intOcsp.isServerReady()); i++) {
1016             Thread.sleep(50);
1017         }
1018         if (!intOcsp.isServerReady()) {
1019             throw new RuntimeException("Server not ready yet");
1020         }
1021 
1022         intOcspPort = intOcsp.getPort();
1023         String intCaRespURI = "http://localhost:" + intOcspPort;
1024         log("Intermediate CA OCSP Responder URI is " + intCaRespURI);
1025 
1026         // Last but not least, let's make our SSLCert and add it to its own
1027         // Keystore
1028         cbld.reset();
1029         cbld.setSubjectName("CN=SSLCertificate, O=SomeCompany");
1030         cbld.setPublicKey(sslKP.getPublic());
1031         cbld.setSerialNumber(new BigInteger("4096"));
1032         // Make a 1 year validity starting from 7 days ago
1033         start = System.currentTimeMillis() - TimeUnit.DAYS.toMillis(7);
1034         end = start + TimeUnit.DAYS.toMillis(365);
1035         cbld.setValidity(new Date(start), new Date(end));
1036 
1037         // Add extensions
1038         addCommonExts(cbld, sslKP.getPublic(), intCaKP.getPublic());
1039         boolean[] kuBits = {true, false, true, false, false, false,
1040             false, false, false};
1041         cbld.addKeyUsageExt(kuBits);
1042         List<String> ekuOids = new ArrayList<>();
1043         ekuOids.add("1.3.6.1.5.5.7.3.1");
1044         ekuOids.add("1.3.6.1.5.5.7.3.2");
1045         cbld.addExtendedKeyUsageExt(ekuOids);
1046         cbld.addSubjectAltNameDNSExt(Collections.singletonList("localhost"));
1047         cbld.addAIAExt(Collections.singletonList(intCaRespURI));
1048         // Make our SSL Server Cert!
1049         X509Certificate sslCert = cbld.build(intCaCert, intCaKP.getPrivate(),
1050                 "SHA256withRSA");
1051         log("SSL Certificate Created:\n" + certInfo(sslCert));
1052 
1053         // Provide SSL server cert revocation info to the Intermeidate CA
1054         // OCSP responder.
1055         revInfo = new HashMap<>();
1056         revInfo.put(sslCert.getSerialNumber(),
1057                 new SimpleOCSPServer.CertStatusInfo(
1058                         SimpleOCSPServer.CertStatus.CERT_STATUS_GOOD));
1059         intOcsp.updateStatusDb(revInfo);
1060 
1061         // Now build a keystore and add the keys, chain and root cert as a TA
1062         serverKeystore = keyStoreBuilder.getKeyStore();
1063         Certificate[] sslChain = {sslCert, intCaCert, rootCert};
1064         serverKeystore.setKeyEntry(SSL_ALIAS, sslKP.getPrivate(),
1065                 passwd.toCharArray(), sslChain);
1066         serverKeystore.setCertificateEntry(ROOT_ALIAS, rootCert);
1067 
1068         // And finally a Trust Store for the client
1069         trustStore = keyStoreBuilder.getKeyStore();
1070         trustStore.setCertificateEntry(ROOT_ALIAS, rootCert);
1071     }
1072 
addCommonExts(CertificateBuilder cbld, PublicKey subjKey, PublicKey authKey)1073     private static void addCommonExts(CertificateBuilder cbld,
1074             PublicKey subjKey, PublicKey authKey) throws IOException {
1075         cbld.addSubjectKeyIdExt(subjKey);
1076         cbld.addAuthorityKeyIdExt(authKey);
1077     }
1078 
addCommonCAExts(CertificateBuilder cbld)1079     private static void addCommonCAExts(CertificateBuilder cbld)
1080             throws IOException {
1081         cbld.addBasicConstraintsExt(true, true, -1);
1082         // Set key usage bits for digitalSignature, keyCertSign and cRLSign
1083         boolean[] kuBitSettings = {true, false, false, false, false, true,
1084             true, false, false};
1085         cbld.addKeyUsageExt(kuBitSettings);
1086     }
1087 
1088     /**
1089      * Helper routine that dumps only a few cert fields rather than
1090      * the whole toString() output.
1091      *
1092      * @param cert an X509Certificate to be displayed
1093      *
1094      * @return the String output of the issuer, subject and
1095      * serial number
1096      */
certInfo(X509Certificate cert)1097     private static String certInfo(X509Certificate cert) {
1098         StringBuilder sb = new StringBuilder();
1099         sb.append("Issuer: ").append(cert.getIssuerX500Principal()).
1100                 append("\n");
1101         sb.append("Subject: ").append(cert.getSubjectX500Principal()).
1102                 append("\n");
1103         sb.append("Serial: ").append(cert.getSerialNumber()).append("\n");
1104         return sb.toString();
1105     }
1106 
1107     /**
1108      * Log a message on stdout
1109      *
1110      * @param message The message to log
1111      */
log(String message)1112     private static void log(String message) {
1113         if (debug) {
1114             System.out.println(message);
1115         }
1116     }
1117 
1118     // The following two classes are Simple nested class to group a handful
1119     // of configuration parameters used before starting a client or server.
1120     // We'll just access the data members directly for convenience.
1121     static class ClientParameters {
1122         boolean enabled = true;
1123         PKIXBuilderParameters pkixParams = null;
1124         PKIXRevocationChecker revChecker = null;
1125         String[] protocols = null;
1126         String[] ciphers = null;
1127 
ClientParameters()1128         ClientParameters() { }
1129     }
1130 
1131     static class ServerParameters {
1132         boolean enabled = true;
1133         int cacheSize = 256;
1134         int cacheLifetime = 3600;
1135         int respTimeout = 5000;
1136         String respUri = "";
1137         boolean respOverride = false;
1138         boolean ignoreExts = false;
1139         String[] protocols = null;
1140         String[] ciphers = null;
1141 
ServerParameters()1142         ServerParameters() { }
1143     }
1144 
1145     static class CustomizedSocketFactory extends SSLSocketFactory {
1146         final SSLContext sslc;
1147         final String[] protocols;
1148         final String[] cipherSuites;
1149 
CustomizedSocketFactory(SSLContext ctx, String[] prots, String[] suites)1150         CustomizedSocketFactory(SSLContext ctx, String[] prots, String[] suites)
1151                 throws GeneralSecurityException {
1152             super();
1153             sslc = (ctx != null) ? ctx : SSLContext.getDefault();
1154             protocols = prots;
1155             cipherSuites = suites;
1156 
1157             // Create the Trust Manager Factory using the PKIX variant
1158             TrustManagerFactory tmf = TrustManagerFactory.getInstance("PKIX");
1159         }
1160 
1161         @Override
createSocket(Socket s, String host, int port, boolean autoClose)1162         public Socket createSocket(Socket s, String host, int port,
1163                 boolean autoClose) throws IOException {
1164             Socket sock =  sslc.getSocketFactory().createSocket(s, host, port,
1165                     autoClose);
1166             customizeSocket(sock);
1167             return sock;
1168         }
1169 
1170         @Override
createSocket(InetAddress host, int port)1171         public Socket createSocket(InetAddress host, int port)
1172                 throws IOException {
1173             Socket sock = sslc.getSocketFactory().createSocket(host, port);
1174             customizeSocket(sock);
1175             return sock;
1176         }
1177 
1178         @Override
createSocket(InetAddress host, int port, InetAddress localAddress, int localPort)1179         public Socket createSocket(InetAddress host, int port,
1180                 InetAddress localAddress, int localPort) throws IOException {
1181             Socket sock = sslc.getSocketFactory().createSocket(host, port,
1182                     localAddress, localPort);
1183             customizeSocket(sock);
1184             return sock;
1185         }
1186 
1187         @Override
createSocket(String host, int port)1188         public Socket createSocket(String host, int port)
1189                 throws IOException {
1190             Socket sock =  sslc.getSocketFactory().createSocket(host, port);
1191             customizeSocket(sock);
1192             return sock;
1193         }
1194 
1195         @Override
createSocket(String host, int port, InetAddress localAddress, int localPort)1196         public Socket createSocket(String host, int port,
1197                 InetAddress localAddress, int localPort)
1198                 throws IOException {
1199             Socket sock =  sslc.getSocketFactory().createSocket(host, port,
1200                     localAddress, localPort);
1201             customizeSocket(sock);
1202             return sock;
1203         }
1204 
1205         @Override
getDefaultCipherSuites()1206         public String[] getDefaultCipherSuites() {
1207             return sslc.getDefaultSSLParameters().getCipherSuites();
1208         }
1209 
1210         @Override
getSupportedCipherSuites()1211         public String[] getSupportedCipherSuites() {
1212             return sslc.getSupportedSSLParameters().getCipherSuites();
1213         }
1214 
customizeSocket(Socket sock)1215         private void customizeSocket(Socket sock) {
1216             if (sock instanceof SSLSocket) {
1217                 if (protocols != null) {
1218                     ((SSLSocket)sock).setEnabledProtocols(protocols);
1219                 }
1220                 if (cipherSuites != null) {
1221                     ((SSLSocket)sock).setEnabledCipherSuites(cipherSuites);
1222                 }
1223             }
1224         }
1225     }
1226 
1227     static class CustomizedServerSocketFactory extends SSLServerSocketFactory {
1228         final SSLContext sslc;
1229         final String[] protocols;
1230         final String[] cipherSuites;
1231 
CustomizedServerSocketFactory(SSLContext ctx, String[] prots, String[] suites)1232         CustomizedServerSocketFactory(SSLContext ctx, String[] prots, String[] suites)
1233                 throws GeneralSecurityException {
1234             super();
1235             sslc = (ctx != null) ? ctx : SSLContext.getDefault();
1236             protocols = prots;
1237             cipherSuites = suites;
1238 
1239             // Create the Trust Manager Factory using the PKIX variant
1240             TrustManagerFactory tmf = TrustManagerFactory.getInstance("PKIX");
1241         }
1242 
1243         @Override
createServerSocket(int port)1244         public ServerSocket createServerSocket(int port) throws IOException {
1245             ServerSocket sock =
1246                     sslc.getServerSocketFactory().createServerSocket(port);
1247             customizeSocket(sock);
1248             return sock;
1249         }
1250 
1251         @Override
createServerSocket(int port, int backlog)1252         public ServerSocket createServerSocket(int port, int backlog)
1253                 throws IOException {
1254             ServerSocket sock =
1255                     sslc.getServerSocketFactory().createServerSocket(port,
1256                             backlog);
1257             customizeSocket(sock);
1258             return sock;
1259         }
1260 
1261         @Override
createServerSocket(int port, int backlog, InetAddress ifAddress)1262         public ServerSocket createServerSocket(int port, int backlog,
1263                 InetAddress ifAddress) throws IOException {
1264             ServerSocket sock =
1265                     sslc.getServerSocketFactory().createServerSocket(port,
1266                             backlog, ifAddress);
1267             customizeSocket(sock);
1268             return sock;
1269         }
1270 
1271         @Override
getDefaultCipherSuites()1272         public String[] getDefaultCipherSuites() {
1273             return sslc.getDefaultSSLParameters().getCipherSuites();
1274         }
1275 
1276         @Override
getSupportedCipherSuites()1277         public String[] getSupportedCipherSuites() {
1278             return sslc.getSupportedSSLParameters().getCipherSuites();
1279         }
1280 
customizeSocket(ServerSocket sock)1281         private void customizeSocket(ServerSocket sock) {
1282             if (sock instanceof SSLServerSocket) {
1283                 if (protocols != null) {
1284                     ((SSLServerSocket)sock).setEnabledProtocols(protocols);
1285                 }
1286                 if (cipherSuites != null) {
1287                     ((SSLServerSocket)sock).setEnabledCipherSuites(cipherSuites);
1288                 }
1289             }
1290         }
1291     }
1292 
1293 
1294     static class TestResult {
1295         Exception serverExc = null;
1296         Exception clientExc = null;
1297     }
1298 
1299 }
1300