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.trustmanager;
18  
19  import nl.altindag.log.LogCaptor;
20  import nl.altindag.ssl.util.KeyStoreUtils;
21  import nl.altindag.ssl.util.TrustManagerUtils;
22  import org.junit.jupiter.api.Test;
23  
24  import javax.net.ssl.SSLEngine;
25  import javax.net.ssl.SSLEngineResult;
26  import javax.net.ssl.SSLException;
27  import javax.net.ssl.SSLPeerUnverifiedException;
28  import javax.net.ssl.SSLSession;
29  import javax.net.ssl.SSLSessionContext;
30  import javax.net.ssl.X509ExtendedTrustManager;
31  import java.io.IOException;
32  import java.net.Socket;
33  import java.nio.ByteBuffer;
34  import java.security.KeyStore;
35  import java.security.KeyStoreException;
36  import java.security.NoSuchAlgorithmException;
37  import java.security.Principal;
38  import java.security.cert.Certificate;
39  import java.security.cert.CertificateException;
40  import java.security.cert.X509Certificate;
41  import java.util.Arrays;
42  import java.util.Collections;
43  
44  import static org.assertj.core.api.Assertions.assertThat;
45  import static org.assertj.core.api.Assertions.assertThatCode;
46  import static org.assertj.core.api.Assertions.assertThatThrownBy;
47  
48  /**
49   * @author Hakan Altindag
50   */
51  class CompositeX509ExtendedTrustManagerShould {
52  
53      private static final String TRUSTSTORE_FILE_NAME = "truststore.jks";
54      private static final char[] TRUSTSTORE_PASSWORD = new char[]{'s', 'e', 'c', 'r', 'e', 't'};
55      private static final String KEYSTORE_FILE_NAME = "identity.jks";
56      private static final char[] KEYSTORE_PASSWORD = new char[]{'s', 'e', 'c', 'r', 'e', 't'};
57      private static final String KEYSTORE_LOCATION = "keystores-for-unit-tests/";
58  
59      private static final Socket SOCKET = new Socket();
60      private static final SSLEngine SSL_ENGINE = new MockedSSLEngine();
61  
62      @Test
63      void checkClientTrusted() throws KeyStoreException {
64          KeyStore trustStore = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + TRUSTSTORE_FILE_NAME, TRUSTSTORE_PASSWORD);
65          X509ExtendedTrustManager trustManager = TrustManagerUtils.createTrustManager(trustStore);
66          X509Certificate[] trustedCerts = KeyStoreTestUtils.getTrustedX509Certificates(trustStore);
67  
68          LogCaptor logCaptor = LogCaptor.forClass(CompositeX509ExtendedTrustManager.class);
69          logCaptor.setLogLevelToInfo();
70  
71          CompositeX509ExtendedTrustManager compositeX509ExtendedTrustManager = new CompositeX509ExtendedTrustManager(Collections.singletonList(trustManager));
72          assertThat(trustManager).isNotNull();
73          assertThat(trustManager.getAcceptedIssuers()).hasSize(1);
74          assertThat(trustedCerts).hasSize(1);
75          assertThat(compositeX509ExtendedTrustManager.size()).isEqualTo(1);
76  
77          assertThatCode(() -> compositeX509ExtendedTrustManager.checkClientTrusted(trustedCerts, "RSA"))
78                  .doesNotThrowAnyException();
79  
80          assertThat(logCaptor.getLogs()).isEmpty();
81          logCaptor.resetLogLevel();
82      }
83  
84      @Test
85      void checkClientTrustedWithSslEngine() throws KeyStoreException {
86          KeyStore trustStore = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + TRUSTSTORE_FILE_NAME, TRUSTSTORE_PASSWORD);
87          X509ExtendedTrustManager trustManager = TrustManagerUtils.createTrustManager(trustStore);
88          X509Certificate[] trustedCerts = KeyStoreTestUtils.getTrustedX509Certificates(trustStore);
89  
90          LogCaptor logCaptor = LogCaptor.forClass(CompositeX509ExtendedTrustManager.class);
91          logCaptor.setLogLevelToInfo();
92  
93          CompositeX509ExtendedTrustManager compositeX509ExtendedTrustManager = new CompositeX509ExtendedTrustManager(Collections.singletonList(trustManager));
94          assertThat(trustManager).isNotNull();
95          assertThat(trustManager.getAcceptedIssuers()).hasSize(1);
96          assertThat(trustedCerts).hasSize(1);
97  
98          assertThatCode(() -> compositeX509ExtendedTrustManager.checkClientTrusted(trustedCerts, "RSA", SSL_ENGINE))
99                  .doesNotThrowAnyException();
100 
101         assertThat(logCaptor.getLogs()).isEmpty();
102         logCaptor.resetLogLevel();
103     }
104 
105     @Test
106     void checkClientTrustedWithSocket() throws KeyStoreException {
107         KeyStore trustStore = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + TRUSTSTORE_FILE_NAME, TRUSTSTORE_PASSWORD);
108         X509ExtendedTrustManager trustManager = TrustManagerUtils.createTrustManager(trustStore);
109         X509Certificate[] trustedCerts = KeyStoreTestUtils.getTrustedX509Certificates(trustStore);
110 
111         LogCaptor logCaptor = LogCaptor.forClass(CompositeX509ExtendedTrustManager.class);
112         logCaptor.setLogLevelToInfo();
113 
114         CompositeX509ExtendedTrustManager compositeX509ExtendedTrustManager = new CompositeX509ExtendedTrustManager(Collections.singletonList(trustManager));
115         assertThat(trustManager).isNotNull();
116         assertThat(trustManager.getAcceptedIssuers()).hasSize(1);
117         assertThat(trustedCerts).hasSize(1);
118 
119         assertThatCode(() -> compositeX509ExtendedTrustManager.checkClientTrusted(trustedCerts, "RSA", SOCKET))
120                 .doesNotThrowAnyException();
121 
122         assertThat(logCaptor.getLogs()).isEmpty();
123         logCaptor.resetLogLevel();
124     }
125 
126     @Test
127     void checkClientTrustedLogsCertificateChainIfDebugIsEnabled() throws KeyStoreException {
128         KeyStore trustStore = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + TRUSTSTORE_FILE_NAME, TRUSTSTORE_PASSWORD);
129         X509ExtendedTrustManager trustManager = TrustManagerUtils.createTrustManager(trustStore);
130         X509Certificate[] trustedCerts = KeyStoreTestUtils.getTrustedX509Certificates(trustStore);
131 
132         LogCaptor logCaptor = LogCaptor.forClass(CompositeX509ExtendedTrustManager.class);
133 
134         CompositeX509ExtendedTrustManager compositeX509ExtendedTrustManager = new CompositeX509ExtendedTrustManager(Collections.singletonList(trustManager));
135         assertThat(trustManager).isNotNull();
136         assertThat(trustManager.getAcceptedIssuers()).hasSize(1);
137         assertThat(trustedCerts).hasSize(1);
138 
139         assertThatCode(() -> compositeX509ExtendedTrustManager.checkClientTrusted(trustedCerts, "RSA"))
140                 .doesNotThrowAnyException();
141 
142         assertThat(logCaptor.getDebugLogs())
143                 .hasSize(1)
144                 .contains("Received the following client certificate: [CN=*.google.com, O=Google LLC, L=Mountain View, ST=California, C=US]");
145     }
146 
147     @Test
148     void checkClientTrustedWithSslEngineLogsCertificateChainIfDebugIsEnabled() throws KeyStoreException {
149         KeyStore trustStore = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + TRUSTSTORE_FILE_NAME, TRUSTSTORE_PASSWORD);
150         X509ExtendedTrustManager trustManager = TrustManagerUtils.createTrustManager(trustStore);
151         X509Certificate[] trustedCerts = KeyStoreTestUtils.getTrustedX509Certificates(trustStore);
152 
153         LogCaptor logCaptor = LogCaptor.forClass(CompositeX509ExtendedTrustManager.class);
154 
155         CompositeX509ExtendedTrustManager compositeX509ExtendedTrustManager = new CompositeX509ExtendedTrustManager(Collections.singletonList(trustManager));
156         assertThat(trustManager).isNotNull();
157         assertThat(trustManager.getAcceptedIssuers()).hasSize(1);
158         assertThat(trustedCerts).hasSize(1);
159 
160         assertThatCode(() -> compositeX509ExtendedTrustManager.checkClientTrusted(trustedCerts, "RSA", SSL_ENGINE))
161                 .doesNotThrowAnyException();
162 
163         assertThat(logCaptor.getDebugLogs())
164                 .hasSize(1)
165                 .contains("Received the following client certificate: [CN=*.google.com, O=Google LLC, L=Mountain View, ST=California, C=US]");
166     }
167 
168     @Test
169     void checkClientTrustedWithSocketLogsCertificateChainIfDebugIsEnabled() throws KeyStoreException {
170         KeyStore trustStore = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + TRUSTSTORE_FILE_NAME, TRUSTSTORE_PASSWORD);
171         X509ExtendedTrustManager trustManager = TrustManagerUtils.createTrustManager(trustStore);
172         X509Certificate[] trustedCerts = KeyStoreTestUtils.getTrustedX509Certificates(trustStore);
173 
174         LogCaptor logCaptor = LogCaptor.forClass(CompositeX509ExtendedTrustManager.class);
175 
176         CompositeX509ExtendedTrustManager compositeX509ExtendedTrustManager = new CompositeX509ExtendedTrustManager(Collections.singletonList(trustManager));
177         assertThat(trustManager).isNotNull();
178         assertThat(trustManager.getAcceptedIssuers()).hasSize(1);
179         assertThat(trustedCerts).hasSize(1);
180 
181         assertThatCode(() -> compositeX509ExtendedTrustManager.checkClientTrusted(trustedCerts, "RSA", SOCKET))
182                 .doesNotThrowAnyException();
183 
184         assertThat(logCaptor.getDebugLogs())
185                 .hasSize(1)
186                 .contains("Received the following client certificate: [CN=*.google.com, O=Google LLC, L=Mountain View, ST=California, C=US]");
187     }
188 
189     @Test
190     void checkServerTrusted() throws KeyStoreException {
191         KeyStore trustStore = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + "truststore-containing-dummy-client.jks", TRUSTSTORE_PASSWORD);
192         X509Certificate[] trustedCerts = KeyStoreTestUtils.getTrustedX509Certificates(KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + KEYSTORE_FILE_NAME, KEYSTORE_PASSWORD));
193 
194         LogCaptor logCaptor = LogCaptor.forClass(CompositeX509ExtendedTrustManager.class);
195         logCaptor.setLogLevelToInfo();
196 
197         CompositeX509ExtendedTrustManager trustManager = new CompositeX509ExtendedTrustManager(Collections.singletonList(TrustManagerUtils.createTrustManager(trustStore)));
198         assertThat(trustedCerts).hasSize(1);
199         assertThat(trustManager.getAcceptedIssuers()).hasSize(1);
200 
201         assertThatCode(() -> trustManager.checkServerTrusted(trustedCerts, "RSA"))
202                 .doesNotThrowAnyException();
203 
204         assertThat(logCaptor.getLogs()).isEmpty();
205         logCaptor.resetLogLevel();
206     }
207 
208     @Test
209     void checkServerTrustedWithSslEngine() throws KeyStoreException {
210         KeyStore trustStore = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + "truststore-containing-dummy-client.jks", TRUSTSTORE_PASSWORD);
211         X509Certificate[] trustedCerts = KeyStoreTestUtils.getTrustedX509Certificates(KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + KEYSTORE_FILE_NAME, KEYSTORE_PASSWORD));
212 
213         LogCaptor logCaptor = LogCaptor.forClass(CompositeX509ExtendedTrustManager.class);
214         logCaptor.setLogLevelToInfo();
215 
216         CompositeX509ExtendedTrustManager trustManager = new CompositeX509ExtendedTrustManager(Collections.singletonList(TrustManagerUtils.createTrustManager(trustStore)));
217         assertThat(trustedCerts).hasSize(1);
218         assertThat(trustManager.getAcceptedIssuers()).hasSize(1);
219 
220         assertThatCode(() -> trustManager.checkServerTrusted(trustedCerts, "RSA", SSL_ENGINE))
221                 .doesNotThrowAnyException();
222 
223         assertThat(logCaptor.getLogs()).isEmpty();
224         logCaptor.resetLogLevel();
225     }
226 
227     @Test
228     void checkServerTrustedWithSocket() throws KeyStoreException {
229         KeyStore trustStore = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + "truststore-containing-dummy-client.jks", TRUSTSTORE_PASSWORD);
230         X509Certificate[] trustedCerts = KeyStoreTestUtils.getTrustedX509Certificates(KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + KEYSTORE_FILE_NAME, KEYSTORE_PASSWORD));
231 
232         LogCaptor logCaptor = LogCaptor.forClass(CompositeX509ExtendedTrustManager.class);
233         logCaptor.setLogLevelToInfo();
234 
235         CompositeX509ExtendedTrustManager trustManager = new CompositeX509ExtendedTrustManager(Collections.singletonList(TrustManagerUtils.createTrustManager(trustStore)));
236         assertThat(trustedCerts).hasSize(1);
237         assertThat(trustManager.getAcceptedIssuers()).hasSize(1);
238 
239         assertThatCode(() -> trustManager.checkServerTrusted(trustedCerts, "RSA", SOCKET))
240                 .doesNotThrowAnyException();
241 
242         assertThat(logCaptor.getLogs()).isEmpty();
243         logCaptor.resetLogLevel();
244     }
245 
246     @Test
247     void checkServerTrustedLogsCertificateChainIfDebugIsEnabled() throws KeyStoreException {
248         KeyStore trustStore = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + "truststore-containing-dummy-client.jks", TRUSTSTORE_PASSWORD);
249         X509Certificate[] trustedCerts = KeyStoreTestUtils.getTrustedX509Certificates(KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + KEYSTORE_FILE_NAME, KEYSTORE_PASSWORD));
250 
251         LogCaptor logCaptor = LogCaptor.forClass(CompositeX509ExtendedTrustManager.class);
252 
253         CompositeX509ExtendedTrustManager trustManager = new CompositeX509ExtendedTrustManager(Collections.singletonList(TrustManagerUtils.createTrustManager(trustStore)));
254         assertThat(trustedCerts).hasSize(1);
255         assertThat(trustManager.getAcceptedIssuers()).hasSize(1);
256 
257         assertThatCode(() -> trustManager.checkServerTrusted(trustedCerts, "RSA"))
258                 .doesNotThrowAnyException();
259 
260         assertThat(logCaptor.getDebugLogs())
261                 .hasSize(1)
262                 .contains("Received the following server certificate: [CN=Prof Oak, OU=Oak Pokémon Research Lab, O=Oak Pokémon Research Lab, C=Pallet Town]");
263     }
264 
265     @Test
266     void checkServerTrustedWithSslEngineLogsCertificateChainIfDebugIsEnabled() throws KeyStoreException {
267         KeyStore trustStore = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + "truststore-containing-dummy-client.jks", TRUSTSTORE_PASSWORD);
268         X509Certificate[] trustedCerts = KeyStoreTestUtils.getTrustedX509Certificates(KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + KEYSTORE_FILE_NAME, KEYSTORE_PASSWORD));
269 
270         LogCaptor logCaptor = LogCaptor.forClass(CompositeX509ExtendedTrustManager.class);
271 
272         CompositeX509ExtendedTrustManager trustManager = new CompositeX509ExtendedTrustManager(Collections.singletonList(TrustManagerUtils.createTrustManager(trustStore)));
273         assertThat(trustedCerts).hasSize(1);
274         assertThat(trustManager.getAcceptedIssuers()).hasSize(1);
275 
276         assertThatCode(() -> trustManager.checkServerTrusted(trustedCerts, "RSA", SSL_ENGINE))
277                 .doesNotThrowAnyException();
278 
279         assertThat(logCaptor.getDebugLogs())
280                 .hasSize(1)
281                 .contains("Received the following server certificate: [CN=Prof Oak, OU=Oak Pokémon Research Lab, O=Oak Pokémon Research Lab, C=Pallet Town]");
282     }
283 
284     @Test
285     void checkServerTrustedWithSocketLogsCertificateChainIfDebugIsEnabled() throws KeyStoreException {
286         KeyStore trustStore = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + "truststore-containing-dummy-client.jks", TRUSTSTORE_PASSWORD);
287         X509Certificate[] trustedCerts = KeyStoreTestUtils.getTrustedX509Certificates(KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + KEYSTORE_FILE_NAME, KEYSTORE_PASSWORD));
288 
289         LogCaptor logCaptor = LogCaptor.forClass(CompositeX509ExtendedTrustManager.class);
290 
291         CompositeX509ExtendedTrustManager trustManager = new CompositeX509ExtendedTrustManager(Collections.singletonList(TrustManagerUtils.createTrustManager(trustStore)));
292         assertThat(trustedCerts).hasSize(1);
293         assertThat(trustManager.getAcceptedIssuers()).hasSize(1);
294 
295         assertThatCode(() -> trustManager.checkServerTrusted(trustedCerts, "RSA", SOCKET))
296                 .doesNotThrowAnyException();
297 
298         assertThat(logCaptor.getDebugLogs())
299                 .hasSize(1)
300                 .contains("Received the following server certificate: [CN=Prof Oak, OU=Oak Pokémon Research Lab, O=Oak Pokémon Research Lab, C=Pallet Town]");
301     }
302 
303     @Test
304     void throwsExceptionWhenCheckServerTrustedDoesNotTrustTheSuppliedCertificate() throws KeyStoreException {
305         KeyStore trustStore = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + TRUSTSTORE_FILE_NAME, TRUSTSTORE_PASSWORD);
306         X509Certificate[] trustedCerts = KeyStoreTestUtils.getTrustedX509Certificates(KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + KEYSTORE_FILE_NAME, KEYSTORE_PASSWORD));
307 
308         CompositeX509ExtendedTrustManager trustManager = new CompositeX509ExtendedTrustManager(Collections.singletonList(TrustManagerUtils.createTrustManager(trustStore)));
309         assertThat(trustedCerts).hasSize(1);
310         assertThat(trustManager.getAcceptedIssuers()).hasSize(1);
311 
312         assertThatThrownBy(() -> trustManager.checkServerTrusted(trustedCerts, "RSA"))
313                 .isInstanceOf(CertificateException.class)
314                 .hasMessage("None of the TrustManagers trust this certificate chain");
315     }
316 
317     @Test
318     void throwsExceptionWhenCheckServerTrustedWithSslEngineDoesNotTrustTheSuppliedCertificate() throws KeyStoreException {
319         KeyStore trustStore = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + TRUSTSTORE_FILE_NAME, TRUSTSTORE_PASSWORD);
320         X509Certificate[] trustedCerts = KeyStoreTestUtils.getTrustedX509Certificates(KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + KEYSTORE_FILE_NAME, KEYSTORE_PASSWORD));
321 
322         CompositeX509ExtendedTrustManager trustManager = new CompositeX509ExtendedTrustManager(Collections.singletonList(TrustManagerUtils.createTrustManager(trustStore)));
323         assertThat(trustedCerts).hasSize(1);
324         assertThat(trustManager.getAcceptedIssuers()).hasSize(1);
325 
326         assertThatThrownBy(() -> trustManager.checkServerTrusted(trustedCerts, "RSA", SSL_ENGINE))
327                 .isInstanceOf(CertificateException.class)
328                 .hasMessage("None of the TrustManagers trust this certificate chain");
329     }
330 
331     @Test
332     void throwsExceptionWhenCheckServerTrustedWithSocketDoesNotTrustTheSuppliedCertificate() throws KeyStoreException {
333         KeyStore trustStore = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + TRUSTSTORE_FILE_NAME, TRUSTSTORE_PASSWORD);
334         X509Certificate[] trustedCerts = KeyStoreTestUtils.getTrustedX509Certificates(KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + KEYSTORE_FILE_NAME, KEYSTORE_PASSWORD));
335 
336         CompositeX509ExtendedTrustManager trustManager = new CompositeX509ExtendedTrustManager(Collections.singletonList(TrustManagerUtils.createTrustManager(trustStore)));
337         assertThat(trustedCerts).hasSize(1);
338         assertThat(trustManager.getAcceptedIssuers()).hasSize(1);
339 
340         assertThatThrownBy(() -> trustManager.checkServerTrusted(trustedCerts, "RSA", SOCKET))
341                 .isInstanceOf(CertificateException.class)
342                 .hasMessage("None of the TrustManagers trust this certificate chain");
343     }
344 
345     @Test
346     void combineTrustManagersWhileFilteringDuplicateCertificates() throws KeyStoreException {
347         KeyStore trustStore = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + TRUSTSTORE_FILE_NAME, TRUSTSTORE_PASSWORD);
348         X509ExtendedTrustManager trustManager = new CompositeX509ExtendedTrustManager(Arrays.asList(
349                 TrustManagerUtils.createTrustManager(trustStore), TrustManagerUtils.createTrustManager(trustStore)));
350 
351         assertThat(trustStore.size()).isEqualTo(1);
352         assertThat(trustManager.getAcceptedIssuers()).hasSize(1);
353     }
354 
355     @Test
356     void throwsExceptionWhenCheckClientTrustedDoesNotTrustTheSuppliedCertificate() throws KeyStoreException {
357         KeyStore trustStore = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + TRUSTSTORE_FILE_NAME, TRUSTSTORE_PASSWORD);
358         X509ExtendedTrustManager trustManager = TrustManagerUtils.createTrustManager(trustStore);
359         X509Certificate[] trustedCerts = KeyStoreTestUtils.getTrustedX509Certificates(KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + "truststore-containing-github.jks", TRUSTSTORE_PASSWORD));
360 
361         CompositeX509ExtendedTrustManager compositeX509ExtendedTrustManager = new CompositeX509ExtendedTrustManager(Collections.singletonList(trustManager));
362         assertThat(trustManager).isNotNull();
363         assertThat(trustManager.getAcceptedIssuers()).hasSize(1);
364         assertThat(trustedCerts).hasSize(1);
365 
366         assertThatThrownBy(() -> compositeX509ExtendedTrustManager.checkClientTrusted(trustedCerts, "RSA"))
367                 .isInstanceOf(CertificateException.class)
368                 .hasMessage("None of the TrustManagers trust this certificate chain");
369     }
370 
371     @Test
372     void throwsExceptionWhenCheckClientTrustedWithSslEngineDoesNotTrustTheSuppliedCertificate() throws KeyStoreException {
373         KeyStore trustStore = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + TRUSTSTORE_FILE_NAME, TRUSTSTORE_PASSWORD);
374         X509ExtendedTrustManager trustManager = TrustManagerUtils.createTrustManager(trustStore);
375         X509Certificate[] trustedCerts = KeyStoreTestUtils.getTrustedX509Certificates(KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + "truststore-containing-github.jks", TRUSTSTORE_PASSWORD));
376 
377         CompositeX509ExtendedTrustManager compositeX509ExtendedTrustManager = new CompositeX509ExtendedTrustManager(Collections.singletonList(trustManager));
378         assertThat(trustManager).isNotNull();
379         assertThat(trustManager.getAcceptedIssuers()).hasSize(1);
380         assertThat(trustedCerts).hasSize(1);
381 
382         assertThatThrownBy(() -> compositeX509ExtendedTrustManager.checkClientTrusted(trustedCerts, "RSA", SSL_ENGINE))
383                 .isInstanceOf(CertificateException.class)
384                 .hasMessage("None of the TrustManagers trust this certificate chain");
385     }
386 
387     @Test
388     void throwsExceptionWhenCheckClientTrustedWithSocketDoesNotTrustTheSuppliedCertificate() throws KeyStoreException {
389         KeyStore trustStore = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + TRUSTSTORE_FILE_NAME, TRUSTSTORE_PASSWORD);
390         X509ExtendedTrustManager trustManager = TrustManagerUtils.createTrustManager(trustStore);
391         X509Certificate[] trustedCerts = KeyStoreTestUtils.getTrustedX509Certificates(KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + "truststore-containing-github.jks", TRUSTSTORE_PASSWORD));
392 
393         CompositeX509ExtendedTrustManager compositeX509ExtendedTrustManager = new CompositeX509ExtendedTrustManager(Collections.singletonList(trustManager));
394         assertThat(trustManager).isNotNull();
395         assertThat(trustManager.getAcceptedIssuers()).hasSize(1);
396         assertThat(trustedCerts).hasSize(1);
397 
398         assertThatThrownBy(() -> compositeX509ExtendedTrustManager.checkClientTrusted(trustedCerts, "RSA", SOCKET))
399                 .isInstanceOf(CertificateException.class)
400                 .hasMessage("None of the TrustManagers trust this certificate chain");
401     }
402 
403     static class MockedSSLEngine extends SSLEngine {
404         @Override
405         public SSLEngineResult wrap(ByteBuffer[] byteBuffers, int i, int i1, ByteBuffer byteBuffer) {
406             return null;
407         }
408 
409         @Override
410         public SSLEngineResult unwrap(ByteBuffer byteBuffer, ByteBuffer[] byteBuffers, int i, int i1) {
411             return null;
412         }
413 
414         @Override
415         public Runnable getDelegatedTask() {
416             return null;
417         }
418 
419         @Override
420         public void closeInbound() {
421 
422         }
423 
424         @Override
425         public boolean isInboundDone() {
426             return false;
427         }
428 
429         @Override
430         public void closeOutbound() {
431 
432         }
433 
434         @Override
435         public boolean isOutboundDone() {
436             return false;
437         }
438 
439         @Override
440         public String[] getSupportedCipherSuites() {
441             return new String[0];
442         }
443 
444         @Override
445         public String[] getEnabledCipherSuites() {
446             return new String[0];
447         }
448 
449         @Override
450         public void setEnabledCipherSuites(String[] strings) {
451 
452         }
453 
454         @Override
455         public String[] getSupportedProtocols() {
456             return new String[0];
457         }
458 
459         @Override
460         public String[] getEnabledProtocols() {
461             return new String[0];
462         }
463 
464         @Override
465         public void setEnabledProtocols(String[] strings) {
466 
467         }
468 
469         @Override
470         public SSLSession getSession() {
471             return null;
472         }
473 
474         @Override
475         public void beginHandshake() {
476 
477         }
478 
479         @Override
480         public SSLEngineResult.HandshakeStatus getHandshakeStatus() {
481             return null;
482         }
483 
484         @Override
485         public SSLSession getHandshakeSession() {
486             return new SSLSession() {
487                 @Override
488                 public byte[] getId() {
489                     return new byte[0];
490                 }
491 
492                 @Override
493                 public SSLSessionContext getSessionContext() {
494                     return null;
495                 }
496 
497                 @Override
498                 public long getCreationTime() {
499                     return 0;
500                 }
501 
502                 @Override
503                 public long getLastAccessedTime() {
504                     return 0;
505                 }
506 
507                 @Override
508                 public void invalidate() {
509 
510                 }
511 
512                 @Override
513                 public boolean isValid() {
514                     return false;
515                 }
516 
517                 @Override
518                 public void putValue(String s, Object o) {
519 
520                 }
521 
522                 @Override
523                 public Object getValue(String s) {
524                     return null;
525                 }
526 
527                 @Override
528                 public void removeValue(String s) {
529 
530                 }
531 
532                 @Override
533                 public String[] getValueNames() {
534                     return new String[0];
535                 }
536 
537                 @Override
538                 public Certificate[] getPeerCertificates() {
539                     return new Certificate[0];
540                 }
541 
542                 @Override
543                 public Certificate[] getLocalCertificates() {
544                     return new Certificate[0];
545                 }
546 
547                 @Override
548                 public javax.security.cert.X509Certificate[] getPeerCertificateChain() {
549                     return new javax.security.cert.X509Certificate[0];
550                 }
551 
552                 @Override
553                 public Principal getPeerPrincipal() {
554                     return null;
555                 }
556 
557                 @Override
558                 public Principal getLocalPrincipal() {
559                     return null;
560                 }
561 
562                 @Override
563                 public String getCipherSuite() {
564                     return null;
565                 }
566 
567                 @Override
568                 public String getProtocol() {
569                     return "TLSv1.2";
570                 }
571 
572                 @Override
573                 public String getPeerHost() {
574                     return null;
575                 }
576 
577                 @Override
578                 public int getPeerPort() {
579                     return 0;
580                 }
581 
582                 @Override
583                 public int getPacketBufferSize() {
584                     return 0;
585                 }
586 
587                 @Override
588                 public int getApplicationBufferSize() {
589                     return 0;
590                 }
591             };
592         }
593 
594         @Override
595         public void setUseClientMode(boolean b) {
596 
597         }
598 
599         @Override
600         public boolean getUseClientMode() {
601             return false;
602         }
603 
604         @Override
605         public void setNeedClientAuth(boolean b) {
606 
607         }
608 
609         @Override
610         public boolean getNeedClientAuth() {
611             return false;
612         }
613 
614         @Override
615         public void setWantClientAuth(boolean b) {
616 
617         }
618 
619         @Override
620         public boolean getWantClientAuth() {
621             return false;
622         }
623 
624         @Override
625         public void setEnableSessionCreation(boolean b) {
626 
627         }
628 
629         @Override
630         public boolean getEnableSessionCreation() {
631             return false;
632         }
633     }
634 
635 }