View Javadoc
1   /*
2    * Copyright (c) 2002-2025 Gargoyle Software Inc.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * https://www.apache.org/licenses/LICENSE-2.0
8    *
9    * Unless required by applicable law or agreed to in writing, software
10   * distributed under the License is distributed on an "AS IS" BASIS,
11   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12   * See the License for the specific language governing permissions and
13   * limitations under the License.
14   */
15  package org.htmlunit;
16  
17  import static org.eclipse.jetty.http.HttpVersion.HTTP_1_1;
18  
19  import java.io.ByteArrayInputStream;
20  import java.io.InputStream;
21  import java.net.URL;
22  
23  import javax.net.ssl.SSLHandshakeException;
24  
25  import org.eclipse.jetty.server.SslConnectionFactory;
26  import org.eclipse.jetty.util.ssl.SslContextFactory;
27  import org.eclipse.jetty.util.ssl.SslContextFactory.Server;
28  import org.junit.jupiter.api.Assertions;
29  import org.junit.jupiter.api.Test;
30  
31  /**
32   * Tests for insecure SSL, with client certificate.
33   *
34   * @author Martin Huber
35   * @author Ahmed Ashour
36   * @author Ronald Brill
37   */
38  public class HttpWebConnectionInsecureSSLWithClientCertificateTest extends WebServerTestCase {
39  
40      /**
41       * @throws Exception if an error occurs
42       */
43      @Test
44      public void insecureSSL_clientCertificates_fail() throws Exception {
45          final URL https = new URL("https://localhost:" + PORT2 + "/");
46  
47          Assertions.assertThrows(SSLHandshakeException.class,
48                      () -> loadPage("<div>test</div>", https));
49      }
50  
51      /**
52       * @throws Exception if an error occurs
53       */
54      @Test
55      public void insecureSSL_clientCertificates() throws Exception {
56          final WebClient webClient = getWebClient();
57          webClient.getOptions().setSSLClientCertificateKeyStore(
58                  getClass().getClassLoader().getResource("insecureSSL.pfx"),
59                  "nopassword", "PKCS12");
60          webClient.getOptions().setUseInsecureSSL(true);
61  
62          final URL https = new URL("https://localhost:" + PORT2 + "/");
63          loadPage("<div>test</div>", https);
64      }
65  
66      /**
67       * Test if a certificate/keystore can be load from an input stream.
68       *
69       * @throws Exception if an error occurs
70       */
71      @Test
72      public void insecureSSL_clientCertificatesInputStream_fail() throws Exception {
73          final URL https = new URL("https://localhost:" + PORT2 + "/");
74  
75          Assertions.assertThrows(SSLHandshakeException.class,
76                  () -> loadPage("<div>test</div>", https));
77      }
78  
79      /**
80       * Test if a certificate/keystore can be load from an input stream.
81       *
82       * @throws Exception if an error occurs
83       */
84      @Test
85      public void insecureSSL_clientCertificatesInputStream() throws Exception {
86          final WebClient webClient = getWebClient();
87          try (InputStream certificateInputStream = getClass().getClassLoader()
88                  .getResourceAsStream("insecureSSL.pfx")) {
89              final byte[] certificateBytes = new byte[4096];
90              certificateInputStream.read(certificateBytes);
91  
92              try (InputStream is = new ByteArrayInputStream(certificateBytes)) {
93                  webClient.getOptions().setSSLClientCertificateKeyStore(is, "nopassword", "PKCS12");
94                  webClient.getOptions().setUseInsecureSSL(true);
95  
96                  final URL https = new URL("https://localhost:" + PORT2 + "/");
97                  loadPage("<div>test</div>", https);
98              }
99          }
100     }
101 
102     @Override
103     protected boolean isHttps() {
104         return true;
105     }
106 
107     @Override
108     public SslConnectionFactory getSslConnectionFactory() {
109         final URL url = HttpWebConnectionInsecureSSLWithClientCertificateTest.class
110                 .getClassLoader().getResource("insecureSSL.pfx");
111 
112         final SslContextFactory contextFactory = new Server.Server();
113         contextFactory.setKeyStorePath(url.toExternalForm());
114         contextFactory.setKeyStorePassword("nopassword");
115         return new SslConnectionFactory(contextFactory, HTTP_1_1.toString());
116     }
117 }