View Javadoc
1   /*
2    * Copyright 2019-2021 the original author or authors.
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    *
8    *      https://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package nl.altindag.ssl.keymanager;
18  
19  import nl.altindag.ssl.SSLFactory;
20  import nl.altindag.ssl.util.KeyManagerUtils;
21  import nl.altindag.ssl.util.KeyStoreUtils;
22  import org.junit.jupiter.api.BeforeAll;
23  import org.junit.jupiter.api.MethodOrderer;
24  import org.junit.jupiter.api.Order;
25  import org.junit.jupiter.api.Test;
26  import org.junit.jupiter.api.TestMethodOrder;
27  import org.slf4j.Logger;
28  import org.slf4j.LoggerFactory;
29  
30  import javax.net.ssl.HttpsURLConnection;
31  import javax.net.ssl.SSLSocketFactory;
32  import javax.net.ssl.X509ExtendedKeyManager;
33  import java.io.IOException;
34  import java.net.URL;
35  import java.security.KeyStore;
36  
37  import static nl.altindag.ssl.TestConstants.KEYSTORE_LOCATION;
38  import static org.assertj.core.api.Assertions.assertThat;
39  
40  /**
41   * @author Hakan Altindag
42   */
43  @TestMethodOrder(MethodOrderer.OrderAnnotation.class)
44  class HotSwappableX509ExtendedKeyManagerIT {
45  
46      private static final Logger LOGGER = LoggerFactory.getLogger(HotSwappableX509ExtendedKeyManagerIT.class);
47  
48      private static SSLSocketFactory sslSocketFactory;
49      private static X509ExtendedKeyManager keyManager;
50  
51      @BeforeAll
52      static void setUpSSLSocketFactory() {
53          KeyStore identityStoreWithBadSsl = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + "badssl-identity.p12", "badssl.com".toCharArray());
54          X509ExtendedKeyManager keyManagerWithBadSsl = KeyManagerUtils.createKeyManager(identityStoreWithBadSsl, "badssl.com".toCharArray());
55          keyManager = KeyManagerUtils.createSwappableKeyManager(keyManagerWithBadSsl);
56  
57          SSLFactory sslFactory = SSLFactory.builder()
58                  .withIdentityMaterial(keyManager)
59                  .withTrustMaterial(KEYSTORE_LOCATION + "badssl-truststore.p12", "badssl.com".toCharArray())
60                  .build();
61  
62          sslSocketFactory = sslFactory.getSslSocketFactory();
63      }
64  
65      @Test
66      @Order(1)
67      void executeHttpsRequestWithSslSocketFactoryContainingBadSslKeyManager() throws IOException {
68          HttpsURLConnection connection = (HttpsURLConnection) new URL("https://client.badssl.com/").openConnection();
69          connection.setSSLSocketFactory(sslSocketFactory);
70          connection.setRequestMethod("GET");
71  
72          int statusCode = connection.getResponseCode();
73  
74          if (statusCode == 400) {
75              LOGGER.warn("Certificate may have expired and needs to be updated");
76          } else {
77              assertThat(statusCode).isEqualTo(200);
78          }
79      }
80  
81      @Test
82      @Order(2)
83      void executeHttpsRequestWithExistingSslSocketFactoryContainingASwappedKeyManager() throws IOException {
84          KeyStore identityStore = KeyStoreUtils.loadKeyStore("keystores-for-unit-tests/identity.jks", "secret".toCharArray());
85          X509ExtendedKeyManager anotherKeyManager = KeyManagerUtils.createKeyManager(identityStore, "secret".toCharArray());
86  
87          KeyManagerUtils.swapKeyManager(keyManager, anotherKeyManager);
88  
89          HttpsURLConnection connection = (HttpsURLConnection) new URL("https://client.badssl.com/").openConnection();
90          connection.setSSLSocketFactory(sslSocketFactory);
91          connection.setRequestMethod("GET");
92  
93          assertThat(connection.getResponseCode()).isEqualTo(400);
94      }
95  
96  }