1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package nl.altindag.ssl.trustmanager;
18
19 import nl.altindag.log.LogCaptor;
20 import nl.altindag.ssl.SSLFactory;
21 import nl.altindag.ssl.util.KeyStoreUtils;
22 import nl.altindag.ssl.util.TrustManagerUtils;
23 import org.junit.jupiter.api.BeforeAll;
24 import org.junit.jupiter.api.MethodOrderer;
25 import org.junit.jupiter.api.Order;
26 import org.junit.jupiter.api.Test;
27 import org.junit.jupiter.api.TestMethodOrder;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
30
31 import javax.net.ssl.HttpsURLConnection;
32 import javax.net.ssl.SSLSocketFactory;
33 import javax.net.ssl.X509ExtendedTrustManager;
34 import java.io.IOException;
35 import java.net.URL;
36 import java.security.KeyStore;
37
38 import static nl.altindag.ssl.TestConstants.KEYSTORE_LOCATION;
39 import static org.assertj.core.api.Assertions.assertThat;
40
41
42
43
44 @TestMethodOrder(MethodOrderer.OrderAnnotation.class)
45 class HotSwappableX509ExtendedTrustManagerIT {
46
47 private static final Logger LOGGER = LoggerFactory.getLogger(HotSwappableX509ExtendedTrustManagerIT.class);
48
49 private static SSLSocketFactory sslSocketFactory;
50 private static X509ExtendedTrustManager trustManager;
51
52 @BeforeAll
53 static void setUpSSLSocketFactory() {
54 KeyStore trustStoreWithBadSsl = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + "badssl-truststore.p12", "badssl.com".toCharArray());
55 X509ExtendedTrustManager trustManagerWithBadSsl = TrustManagerUtils.createTrustManager(trustStoreWithBadSsl);
56 trustManager = TrustManagerUtils.createSwappableTrustManager(trustManagerWithBadSsl);
57
58 SSLFactory sslFactory = SSLFactory.builder()
59 .withIdentityMaterial(KEYSTORE_LOCATION + "badssl-identity.p12", "badssl.com".toCharArray())
60 .withTrustMaterial(trustManager)
61 .build();
62
63 sslSocketFactory = sslFactory.getSslSocketFactory();
64 }
65
66 @Test
67 @Order(1)
68 void executeHttpsRequestWithSslSocketFactoryContainingBadSslTrustManager() throws IOException {
69 HttpsURLConnection connection = (HttpsURLConnection) new URL("https://client.badssl.com/").openConnection();
70 connection.setSSLSocketFactory(sslSocketFactory);
71 connection.setRequestMethod("GET");
72
73 int statusCode = connection.getResponseCode();
74
75 if (statusCode == 400) {
76 LOGGER.warn("Certificate may have expired and needs to be updated");
77 } else {
78 assertThat(statusCode).isEqualTo(200);
79 }
80 }
81
82 @Test
83 @Order(2)
84 void executeHttpsRequestWithExistingSslSocketFactoryContainingASwappedUnsafeTrustManager() throws IOException {
85 LogCaptor logCaptor = LogCaptor.forName("nl.altindag.ssl.trustmanager.UnsafeX509ExtendedTrustManager");
86
87 TrustManagerUtils.swapTrustManager(trustManager, TrustManagerUtils.createUnsafeTrustManager());
88
89 HttpsURLConnection connection = (HttpsURLConnection) new URL("https://client.badssl.com/").openConnection();
90 connection.setSSLSocketFactory(sslSocketFactory);
91 connection.setRequestMethod("GET");
92
93 int statusCode = connection.getResponseCode();
94
95 if (statusCode == 400) {
96 LOGGER.warn("Certificate may have expired and needs to be updated");
97 } else {
98 assertThat(statusCode).isEqualTo(200);
99 assertThat(logCaptor.getLogs()).containsExactly("Accepting the following server certificates without validating: [{CN=*.badssl.com, O=Lucas Garron Torres, L=Walnut Creek, ST=California, C=US},{CN=DigiCert SHA2 Secure Server CA, O=DigiCert Inc, C=US}]");
100 }
101 }
102
103 }