1 /* |
1 /* |
2 * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
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 |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. |
7 * published by the Free Software Foundation. |
104 * |
104 * |
105 * This gives a lot of low-level information about operations underway, |
105 * This gives a lot of low-level information about operations underway, |
106 * including specific handshake messages, and might be best examined |
106 * including specific handshake messages, and might be best examined |
107 * after gaining some familiarity with this application. |
107 * after gaining some familiarity with this application. |
108 */ |
108 */ |
109 private static final boolean debug = false; |
109 private static final boolean debug = true; |
110 |
110 |
111 private SSLEngine clientEngine; // client Engine |
111 private SSLEngine clientEngine; // client Engine |
112 private ByteBuffer clientOut; // write side of clientEngine |
112 private ByteBuffer clientOut; // write side of clientEngine |
113 private ByteBuffer clientIn; // read side of clientEngine |
113 private ByteBuffer clientIn; // read side of clientEngine |
114 |
114 |
140 static SimpleOCSPServer rootOcsp; // Root CA OCSP Responder |
140 static SimpleOCSPServer rootOcsp; // Root CA OCSP Responder |
141 static int rootOcspPort; // Port number for root OCSP |
141 static int rootOcspPort; // Port number for root OCSP |
142 static SimpleOCSPServer intOcsp; // Intermediate CA OCSP Responder |
142 static SimpleOCSPServer intOcsp; // Intermediate CA OCSP Responder |
143 static int intOcspPort; // Port number for intermed. OCSP |
143 static int intOcspPort; // Port number for intermed. OCSP |
144 |
144 |
|
145 // Extra configuration parameters and constants |
|
146 static final String[] TLS13ONLY = new String[] { "TLSv1.3" }; |
|
147 static final String[] TLS12MAX = |
|
148 new String[] { "TLSv1.2", "TLSv1.1", "TLSv1" }; |
|
149 |
145 /* |
150 /* |
146 * Main entry point for this test. |
151 * Main entry point for this test. |
147 */ |
152 */ |
148 public static void main(String args[]) throws Exception { |
153 public static void main(String args[]) throws Exception { |
149 if (debug) { |
154 if (debug) { |
150 System.setProperty("javax.net.debug", "ssl"); |
155 System.setProperty("javax.net.debug", "ssl:handshake"); |
151 } |
156 } |
152 |
157 |
153 // Create the PKI we will use for the test and start the OCSP servers |
158 // Create the PKI we will use for the test and start the OCSP servers |
154 createPKI(); |
159 createPKI(); |
155 |
160 |
164 SimpleOCSPServer.CertStatus.CERT_STATUS_REVOKED, |
169 SimpleOCSPServer.CertStatus.CERT_STATUS_REVOKED, |
165 new Date(System.currentTimeMillis() - |
170 new Date(System.currentTimeMillis() - |
166 TimeUnit.HOURS.toMillis(8)))); |
171 TimeUnit.HOURS.toMillis(8)))); |
167 intOcsp.updateStatusDb(revInfo); |
172 intOcsp.updateStatusDb(revInfo); |
168 |
173 |
169 SSLEngineWithStapling test = new SSLEngineWithStapling(); |
174 // Create a list of TLS protocol configurations we can use to |
170 try { |
175 // drive tests with different handshaking models. |
171 test.runTest(); |
176 List<String[]> allowedProtList = List.of(TLS12MAX, TLS13ONLY); |
172 throw new RuntimeException("Expected failure due to revocation " + |
177 |
173 "did not occur"); |
178 for (String[] protocols : allowedProtList) { |
174 } catch (Exception e) { |
179 SSLEngineWithStapling test = new SSLEngineWithStapling(); |
175 if (!checkClientValidationFailure(e, |
180 try { |
176 CertPathValidatorException.BasicReason.REVOKED)) { |
181 test.runTest(protocols); |
177 System.out.println("*** Didn't find the exception we wanted"); |
182 throw new RuntimeException("Expected failure due to " + |
178 throw e; |
183 "revocation did not occur"); |
|
184 } catch (Exception e) { |
|
185 if (!checkClientValidationFailure(e, |
|
186 CertPathValidatorException.BasicReason.REVOKED)) { |
|
187 System.out.println( |
|
188 "*** Didn't find the exception we wanted"); |
|
189 throw e; |
|
190 } |
179 } |
191 } |
180 } |
192 } |
181 |
193 |
182 System.out.println("Test Passed."); |
194 System.out.println("Test Passed."); |
183 } |
195 } |
216 * engine closing |
228 * engine closing |
217 * |
229 * |
218 * One could easily separate these phases into separate |
230 * One could easily separate these phases into separate |
219 * sections of code. |
231 * sections of code. |
220 */ |
232 */ |
221 private void runTest() throws Exception { |
233 private void runTest(String[] protocols) throws Exception { |
222 boolean dataDone = false; |
234 boolean dataDone = false; |
223 |
235 |
224 createSSLEngines(); |
236 createSSLEngines(protocols); |
225 createBuffers(); |
237 createBuffers(); |
226 |
238 |
227 SSLEngineResult clientResult; // results from client's last operation |
239 SSLEngineResult clientResult; // results from client's last operation |
228 SSLEngineResult serverResult; // results from server's last operation |
240 SSLEngineResult serverResult; // results from server's last operation |
229 |
241 |
288 |
300 |
289 /* |
301 /* |
290 * Using the SSLContext created during object creation, |
302 * Using the SSLContext created during object creation, |
291 * create/configure the SSLEngines we'll use for this test. |
303 * create/configure the SSLEngines we'll use for this test. |
292 */ |
304 */ |
293 private void createSSLEngines() throws Exception { |
305 private void createSSLEngines(String[] protocols) throws Exception { |
294 // Initialize the KeyManager and TrustManager for the server |
306 // Initialize the KeyManager and TrustManager for the server |
295 KeyManagerFactory servKmf = KeyManagerFactory.getInstance("PKIX"); |
307 KeyManagerFactory servKmf = KeyManagerFactory.getInstance("PKIX"); |
296 servKmf.init(serverKeystore, passwd.toCharArray()); |
308 servKmf.init(serverKeystore, passwd.toCharArray()); |
297 TrustManagerFactory servTmf = |
309 TrustManagerFactory servTmf = |
298 TrustManagerFactory.getInstance("PKIX"); |
310 TrustManagerFactory.getInstance("PKIX"); |
319 /* |
331 /* |
320 * Configure the serverEngine to act as a server in the SSL/TLS |
332 * Configure the serverEngine to act as a server in the SSL/TLS |
321 * handshake. |
333 * handshake. |
322 */ |
334 */ |
323 serverEngine = servCtx.createSSLEngine(); |
335 serverEngine = servCtx.createSSLEngine(); |
|
336 serverEngine.setEnabledProtocols(protocols); |
324 serverEngine.setUseClientMode(false); |
337 serverEngine.setUseClientMode(false); |
325 serverEngine.setNeedClientAuth(false); |
338 serverEngine.setNeedClientAuth(false); |
326 |
339 |
327 /* |
340 /* |
328 * Similar to above, but using client mode instead. |
341 * Similar to above, but using client mode instead. |
329 */ |
342 */ |
330 clientEngine = cliCtx.createSSLEngine("client", 80); |
343 clientEngine = cliCtx.createSSLEngine("client", 80); |
|
344 clientEngine.setEnabledProtocols(protocols); |
331 clientEngine.setUseClientMode(true); |
345 clientEngine.setUseClientMode(true); |
332 } |
346 } |
333 |
347 |
334 /* |
348 /* |
335 * Create and size the buffers appropriately. |
349 * Create and size the buffers appropriately. |
635 } |
649 } |
636 |
650 |
637 /** |
651 /** |
638 * Checks a validation failure to see if it failed for the reason we think |
652 * Checks a validation failure to see if it failed for the reason we think |
639 * it should. This comes in as an SSLException of some sort, but it |
653 * it should. This comes in as an SSLException of some sort, but it |
640 * encapsulates a ValidatorException which in turn encapsulates the |
654 * encapsulates a CertPathValidatorException at some point in the |
641 * CertPathValidatorException we are interested in. |
655 * exception stack. |
642 * |
656 * |
643 * @param e the exception thrown at the top level |
657 * @param e the exception thrown at the top level |
644 * @param reason the underlying CertPathValidatorException BasicReason |
658 * @param reason the underlying CertPathValidatorException BasicReason |
645 * we are expecting it to have. |
659 * we are expecting it to have. |
646 * |
660 * |
648 */ |
662 */ |
649 static boolean checkClientValidationFailure(Exception e, |
663 static boolean checkClientValidationFailure(Exception e, |
650 CertPathValidatorException.BasicReason reason) { |
664 CertPathValidatorException.BasicReason reason) { |
651 boolean result = false; |
665 boolean result = false; |
652 |
666 |
653 if (e instanceof SSLException) { |
667 // Locate the CertPathValidatorException. If one |
654 Throwable sslhe = e.getCause(); |
668 // Does not exist, then it's an automatic failure of |
655 if (sslhe instanceof SSLHandshakeException) { |
669 // the test. |
656 Throwable valExc = sslhe.getCause(); |
670 Throwable curExc = e; |
657 if (valExc instanceof sun.security.validator.ValidatorException) { |
671 CertPathValidatorException cpve = null; |
658 Throwable cause = valExc.getCause(); |
672 while (curExc != null) { |
659 if (cause instanceof CertPathValidatorException) { |
673 if (curExc instanceof CertPathValidatorException) { |
660 CertPathValidatorException cpve = |
674 cpve = (CertPathValidatorException)curExc; |
661 (CertPathValidatorException)cause; |
|
662 if (cpve.getReason() == reason) { |
|
663 result = true; |
|
664 } |
|
665 } |
|
666 } |
|
667 } |
675 } |
668 } |
676 curExc = curExc.getCause(); |
|
677 } |
|
678 |
|
679 // If we get through the loop and cpve is null then we |
|
680 // we didn't find CPVE and this is a failure |
|
681 if (cpve != null) { |
|
682 if (cpve.getReason() == reason) { |
|
683 result = true; |
|
684 } else { |
|
685 System.out.println("CPVE Reason Mismatch: Expected = " + |
|
686 reason + ", Actual = " + cpve.getReason()); |
|
687 } |
|
688 } else { |
|
689 System.out.println("Failed to find an expected CPVE"); |
|
690 } |
|
691 |
669 return result; |
692 return result; |
670 } |
693 } |
671 } |
694 } |