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  import static org.junit.Assert.fail;
19  
20  import java.io.ByteArrayInputStream;
21  import java.io.InputStream;
22  import java.net.URL;
23  
24  import javax.net.ssl.SSLHandshakeException;
25  
26  import org.eclipse.jetty.server.SslConnectionFactory;
27  import org.eclipse.jetty.util.ssl.SslContextFactory;
28  import org.eclipse.jetty.util.ssl.SslContextFactory.Server;
29  import org.htmlunit.junit.BrowserRunner;
30  import org.junit.Test;
31  import org.junit.runner.RunWith;
32  
33  /**
34   * Tests for insecure SSL, with client certificate.
35   *
36   * @author Martin Huber
37   * @author Ahmed Ashour
38   * @author Ronald Brill
39   */
40  @RunWith(BrowserRunner.class)
41  public class HttpWebConnectionInsecureSSLWithClientCertificateTest extends WebServerTestCase {
42  
43      /**
44       * @throws Exception if an error occurs
45       */
46      @Test(expected = SSLHandshakeException.class)
47      public void insecureSSL_clientCertificates_fail() throws Exception {
48          final URL https = new URL("https://localhost:" + PORT2 + "/");
49          loadPage("<div>test</div>", https);
50          fail("SSLHandshakeException expected");
51      }
52  
53      /**
54       * @throws Exception if an error occurs
55       */
56      @Test
57      public void insecureSSL_clientCertificates() throws Exception {
58          final WebClient webClient = getWebClient();
59          webClient.getOptions().setSSLClientCertificateKeyStore(
60                  getClass().getClassLoader().getResource("insecureSSL.pfx"),
61                  "nopassword", "PKCS12");
62          webClient.getOptions().setUseInsecureSSL(true);
63  
64          final URL https = new URL("https://localhost:" + PORT2 + "/");
65          loadPage("<div>test</div>", https);
66      }
67  
68      /**
69       * Test if a certificate/keystore can be load from an input stream.
70       *
71       * @throws Exception if an error occurs
72       */
73      @Test(expected = SSLHandshakeException.class)
74      public void insecureSSL_clientCertificatesInputStream_fail() throws Exception {
75          final URL https = new URL("https://localhost:" + PORT2 + "/");
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 }