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. |
107 static SimpleOCSPServer rootOcsp; // Root CA OCSP Responder |
107 static SimpleOCSPServer rootOcsp; // Root CA OCSP Responder |
108 static int rootOcspPort; // Port number for root OCSP |
108 static int rootOcspPort; // Port number for root OCSP |
109 static SimpleOCSPServer intOcsp; // Intermediate CA OCSP Responder |
109 static SimpleOCSPServer intOcsp; // Intermediate CA OCSP Responder |
110 static int intOcspPort; // Port number for intermed. OCSP |
110 static int intOcspPort; // Port number for intermed. OCSP |
111 |
111 |
|
112 // Extra configuration parameters and constants |
|
113 static final String[] TLS13ONLY = new String[] { "TLSv1.3" }; |
|
114 static final String[] TLS12MAX = |
|
115 new String[] { "TLSv1.2", "TLSv1.1", "TLSv1" }; |
|
116 |
112 private static final String SIMPLE_WEB_PAGE = "<HTML>\n" + |
117 private static final String SIMPLE_WEB_PAGE = "<HTML>\n" + |
113 "<HEAD><Title>Web Page!</Title></HEAD>\n" + |
118 "<HEAD><Title>Web Page!</Title></HEAD>\n" + |
114 "<BODY><H1>Web Page!</H1></BODY>\n</HTML>"; |
119 "<BODY><H1>Web Page!</H1></BODY>\n</HTML>"; |
115 private static final SimpleDateFormat utcDateFmt = |
120 private static final SimpleDateFormat utcDateFmt = |
116 new SimpleDateFormat("E, dd MMM yyyy HH:mm:ss z"); |
121 new SimpleDateFormat("E, dd MMM yyyy HH:mm:ss z"); |
122 * currently 3 minutes by default, but you might try to be |
127 * currently 3 minutes by default, but you might try to be |
123 * smart about it.... |
128 * smart about it.... |
124 */ |
129 */ |
125 public static void main(String[] args) throws Exception { |
130 public static void main(String[] args) throws Exception { |
126 if (debug) { |
131 if (debug) { |
127 System.setProperty("javax.net.debug", "ssl"); |
132 System.setProperty("javax.net.debug", "ssl:handshake"); |
128 } |
133 } |
129 |
134 |
130 System.setProperty("javax.net.ssl.keyStore", ""); |
135 System.setProperty("javax.net.ssl.keyStore", ""); |
131 System.setProperty("javax.net.ssl.keyStorePassword", ""); |
136 System.setProperty("javax.net.ssl.keyStorePassword", ""); |
132 System.setProperty("javax.net.ssl.trustStore", ""); |
137 System.setProperty("javax.net.ssl.trustStore", ""); |
146 /** |
152 /** |
147 * Do a basic connection using PKIXParameters with revocation checking |
153 * Do a basic connection using PKIXParameters with revocation checking |
148 * enabled and client-side OCSP disabled. It will only pass if all |
154 * enabled and client-side OCSP disabled. It will only pass if all |
149 * stapled responses are present, valid and have a GOOD status. |
155 * stapled responses are present, valid and have a GOOD status. |
150 */ |
156 */ |
151 static void testPKIXParametersRevEnabled() throws Exception { |
157 static void testPKIXParametersRevEnabled(String[] allowedProts) |
|
158 throws Exception { |
152 ClientParameters cliParams = new ClientParameters(); |
159 ClientParameters cliParams = new ClientParameters(); |
|
160 cliParams.protocols = allowedProts; |
153 ServerParameters servParams = new ServerParameters(); |
161 ServerParameters servParams = new ServerParameters(); |
154 serverReady = false; |
162 serverReady = false; |
155 |
163 |
156 System.out.println("====================================="); |
164 System.out.println("====================================="); |
157 System.out.println("Stapling enabled, PKIXParameters with"); |
165 System.out.println("Stapling enabled, PKIXParameters with"); |
331 |
339 |
332 int contentLength = tlsConn.getContentLength(); |
340 int contentLength = tlsConn.getContentLength(); |
333 if (contentLength == -1) { |
341 if (contentLength == -1) { |
334 contentLength = Integer.MAX_VALUE; |
342 contentLength = Integer.MAX_VALUE; |
335 } |
343 } |
336 byte[] response = new byte[contentLength > 2048 ? 2048 : contentLength]; |
344 byte[] response = new byte[contentLength > 2048 ? 2048 : |
|
345 contentLength]; |
337 int total = 0; |
346 int total = 0; |
338 while (total < contentLength) { |
347 while (total < contentLength) { |
339 int count = in.read(response, total, response.length - total); |
348 int count = in.read(response, total, response.length - total); |
340 if (count < 0) |
349 if (count < 0) |
341 break; |
350 break; |
389 } |
398 } |
390 |
399 |
391 /** |
400 /** |
392 * Checks a validation failure to see if it failed for the reason we think |
401 * Checks a validation failure to see if it failed for the reason we think |
393 * it should. This comes in as an SSLException of some sort, but it |
402 * it should. This comes in as an SSLException of some sort, but it |
394 * encapsulates a ValidatorException which in turn encapsulates the |
403 * encapsulates a CertPathValidatorException at some point in the |
395 * CertPathValidatorException we are interested in. |
404 * exception stack. |
396 * |
405 * |
397 * @param e the exception thrown at the top level |
406 * @param e the exception thrown at the top level |
398 * @param reason the underlying CertPathValidatorException BasicReason |
407 * @param reason the underlying CertPathValidatorException BasicReason |
399 * we are expecting it to have. |
408 * we are expecting it to have. |
400 * |
409 * |
402 */ |
411 */ |
403 static boolean checkClientValidationFailure(Exception e, |
412 static boolean checkClientValidationFailure(Exception e, |
404 BasicReason reason) { |
413 BasicReason reason) { |
405 boolean result = false; |
414 boolean result = false; |
406 |
415 |
407 if (e instanceof SSLException) { |
416 // Locate the CertPathValidatorException. If one |
408 Throwable valExc = e.getCause(); |
417 // Does not exist, then it's an automatic failure of |
409 if (valExc instanceof sun.security.validator.ValidatorException) { |
418 // the test. |
410 Throwable cause = valExc.getCause(); |
419 Throwable curExc = e; |
411 if (cause instanceof CertPathValidatorException) { |
420 CertPathValidatorException cpve = null; |
412 CertPathValidatorException cpve = |
421 while (curExc != null) { |
413 (CertPathValidatorException)cause; |
422 if (curExc instanceof CertPathValidatorException) { |
414 if (cpve.getReason() == reason) { |
423 cpve = (CertPathValidatorException)curExc; |
415 result = true; |
424 } |
416 } |
425 curExc = curExc.getCause(); |
417 } |
426 } |
418 } |
427 |
419 } |
428 // If we get through the loop and cpve is null then we |
|
429 // we didn't find CPVE and this is a failure |
|
430 if (cpve != null) { |
|
431 if (cpve.getReason() == reason) { |
|
432 result = true; |
|
433 } else { |
|
434 System.out.println("CPVE Reason Mismatch: Expected = " + |
|
435 reason + ", Actual = " + cpve.getReason()); |
|
436 } |
|
437 } else { |
|
438 System.out.println("Failed to find an expected CPVE"); |
|
439 } |
|
440 |
420 return result; |
441 return result; |
421 } |
442 } |
422 |
443 |
423 TestResult getResult() { |
444 TestResult getResult() { |
424 TestResult tr = new TestResult(); |
445 TestResult tr = new TestResult(); |
696 // We'll just access the data members directly for convenience. |
717 // We'll just access the data members directly for convenience. |
697 static class ClientParameters { |
718 static class ClientParameters { |
698 boolean enabled = true; |
719 boolean enabled = true; |
699 PKIXBuilderParameters pkixParams = null; |
720 PKIXBuilderParameters pkixParams = null; |
700 PKIXRevocationChecker revChecker = null; |
721 PKIXRevocationChecker revChecker = null; |
|
722 String[] protocols = null; |
|
723 String[] cipherSuites = null; |
701 |
724 |
702 ClientParameters() { } |
725 ClientParameters() { } |
703 } |
726 } |
704 |
727 |
705 static class ServerParameters { |
728 static class ServerParameters { |
715 } |
738 } |
716 |
739 |
717 static class TestResult { |
740 static class TestResult { |
718 Exception serverExc = null; |
741 Exception serverExc = null; |
719 Exception clientExc = null; |
742 Exception clientExc = null; |
|
743 |
|
744 @Override |
|
745 public String toString() { |
|
746 StringBuilder sb = new StringBuilder(); |
|
747 sb.append("Test Result:\n"). |
|
748 append("\tServer Exc = ").append(serverExc).append("\n"). |
|
749 append("\tClient Exc = ").append(clientExc).append("\n"); |
|
750 return sb.toString(); |
|
751 } |
720 } |
752 } |
721 |
753 |
722 static class HtucSSLSocketFactory extends SSLSocketFactory { |
754 static class HtucSSLSocketFactory extends SSLSocketFactory { |
|
755 ClientParameters params; |
723 SSLContext sslc = SSLContext.getInstance("TLS"); |
756 SSLContext sslc = SSLContext.getInstance("TLS"); |
724 |
757 |
725 HtucSSLSocketFactory(ClientParameters cliParams) |
758 HtucSSLSocketFactory(ClientParameters cliParams) |
726 throws GeneralSecurityException { |
759 throws GeneralSecurityException { |
727 super(); |
760 super(); |
745 } else { |
778 } else { |
746 tmf.init(trustStore); |
779 tmf.init(trustStore); |
747 } |
780 } |
748 |
781 |
749 sslc.init(null, tmf.getTrustManagers(), null); |
782 sslc.init(null, tmf.getTrustManagers(), null); |
|
783 params = cliParams; |
750 } |
784 } |
751 |
785 |
752 @Override |
786 @Override |
753 public Socket createSocket(Socket s, String host, int port, |
787 public Socket createSocket(Socket s, String host, int port, |
754 boolean autoClose) throws IOException { |
788 boolean autoClose) throws IOException { |
755 Socket sock = sslc.getSocketFactory().createSocket(s, host, port, |
789 Socket sock = sslc.getSocketFactory().createSocket(s, host, port, |
756 autoClose); |
790 autoClose); |
757 setCiphers(sock); |
791 customizeSocket(sock); |
758 return sock; |
792 return sock; |
759 } |
793 } |
760 |
794 |
761 @Override |
795 @Override |
762 public Socket createSocket(InetAddress host, int port) |
796 public Socket createSocket(InetAddress host, int port) |
763 throws IOException { |
797 throws IOException { |
764 Socket sock = sslc.getSocketFactory().createSocket(host, port); |
798 Socket sock = sslc.getSocketFactory().createSocket(host, port); |
765 setCiphers(sock); |
799 customizeSocket(sock); |
766 return sock; |
800 return sock; |
767 } |
801 } |
768 |
802 |
769 @Override |
803 @Override |
770 public Socket createSocket(InetAddress host, int port, |
804 public Socket createSocket(InetAddress host, int port, |
771 InetAddress localAddress, int localPort) throws IOException { |
805 InetAddress localAddress, int localPort) throws IOException { |
772 Socket sock = sslc.getSocketFactory().createSocket(host, port, |
806 Socket sock = sslc.getSocketFactory().createSocket(host, port, |
773 localAddress, localPort); |
807 localAddress, localPort); |
774 setCiphers(sock); |
808 customizeSocket(sock); |
775 return sock; |
809 return sock; |
776 } |
810 } |
777 |
811 |
778 @Override |
812 @Override |
779 public Socket createSocket(String host, int port) |
813 public Socket createSocket(String host, int port) |
780 throws IOException { |
814 throws IOException { |
781 Socket sock = sslc.getSocketFactory().createSocket(host, port); |
815 Socket sock = sslc.getSocketFactory().createSocket(host, port); |
782 setCiphers(sock); |
816 customizeSocket(sock); |
783 return sock; |
817 return sock; |
784 } |
818 } |
785 |
819 |
786 @Override |
820 @Override |
787 public Socket createSocket(String host, int port, |
821 public Socket createSocket(String host, int port, |
788 InetAddress localAddress, int localPort) |
822 InetAddress localAddress, int localPort) |
789 throws IOException { |
823 throws IOException { |
790 Socket sock = sslc.getSocketFactory().createSocket(host, port, |
824 Socket sock = sslc.getSocketFactory().createSocket(host, port, |
791 localAddress, localPort); |
825 localAddress, localPort); |
792 setCiphers(sock); |
826 customizeSocket(sock); |
793 return sock; |
827 return sock; |
794 } |
828 } |
795 |
829 |
796 @Override |
830 @Override |
797 public String[] getDefaultCipherSuites() { |
831 public String[] getDefaultCipherSuites() { |
801 @Override |
835 @Override |
802 public String[] getSupportedCipherSuites() { |
836 public String[] getSupportedCipherSuites() { |
803 return sslc.getSupportedSSLParameters().getCipherSuites(); |
837 return sslc.getSupportedSSLParameters().getCipherSuites(); |
804 } |
838 } |
805 |
839 |
806 private static void setCiphers(Socket sock) { |
840 private void customizeSocket(Socket sock) { |
807 if (sock instanceof SSLSocket) { |
841 if (sock instanceof SSLSocket) { |
808 String[] ciphers = { "TLS_RSA_WITH_AES_128_CBC_SHA" }; |
842 SSLSocket sslSock = (SSLSocket)sock; |
809 ((SSLSocket)sock).setEnabledCipherSuites(ciphers); |
843 if (params.protocols != null) { |
|
844 sslSock.setEnabledProtocols(params.protocols); |
|
845 } |
|
846 if (params.cipherSuites != null) { |
|
847 sslSock.setEnabledCipherSuites(params.cipherSuites); |
|
848 } |
810 } |
849 } |
811 } |
850 } |
812 } |
851 } |
813 |
852 |
814 } |
853 } |