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.util.KeyManagerUtils;
20  import nl.altindag.ssl.util.KeyStoreUtils;
21  import org.junit.jupiter.api.Test;
22  import org.junit.jupiter.api.extension.ExtendWith;
23  import org.mockito.junit.jupiter.MockitoExtension;
24  
25  import javax.net.ssl.SSLEngine;
26  import javax.net.ssl.X509ExtendedKeyManager;
27  import java.net.InetSocketAddress;
28  import java.net.Socket;
29  import java.net.SocketAddress;
30  import java.net.URI;
31  import java.security.KeyStore;
32  import java.security.KeyStoreException;
33  import java.security.Principal;
34  import java.security.cert.X509Certificate;
35  import java.util.Arrays;
36  import java.util.Collections;
37  
38  import static org.assertj.core.api.Assertions.assertThat;
39  import static org.mockito.ArgumentMatchers.anyString;
40  import static org.mockito.Mockito.mock;
41  import static org.mockito.Mockito.when;
42  
43  /**
44   * @author Hakan Altindag
45   */
46  @ExtendWith(MockitoExtension.class)
47  class CompositeX509ExtendedKeyManagerShould {
48  
49      private static final String IDENTITY_FILE_NAME = "identity.jks";
50      private static final String IDENTITY_TWO_FILE_NAME = "identity-two.jks";
51      private static final char[] IDENTITY_PASSWORD = new char[] {'s', 'e', 'c', 'r', 'e', 't'};
52      private static final String KEYSTORE_LOCATION = "keystores-for-unit-tests/";
53  
54      @Test
55      void returnPrivateKeyForAlias() throws KeyStoreException {
56          KeyStore identityOne = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_FILE_NAME, IDENTITY_PASSWORD);
57          KeyStore identityTwo = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_TWO_FILE_NAME, IDENTITY_PASSWORD);
58  
59          X509ExtendedKeyManager keyManagerOne = KeyManagerUtils.createKeyManager(identityOne, IDENTITY_PASSWORD);
60          X509ExtendedKeyManager keyManagerTwo = KeyManagerUtils.createKeyManager(identityTwo, IDENTITY_PASSWORD);
61  
62          CompositeX509ExtendedKeyManager keyManager = new CompositeX509ExtendedKeyManager(
63                  Arrays.asList(keyManagerOne, keyManagerTwo)
64          );
65  
66          assertThat(keyManager).isNotNull();
67  
68          assertThat(identityOne.size()).isEqualTo(1);
69          assertThat(identityTwo.size()).isEqualTo(1);
70          assertThat(keyManager.size()).isEqualTo(2);
71          assertThat(keyManager.getPrivateKey("dummy-client")).isNotNull();
72          assertThat(keyManager.getPrivateKey("another-server")).isNotNull();
73      }
74  
75      @Test
76      void returnNullForUnknownAlias() throws KeyStoreException {
77          KeyStore identityOne = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_FILE_NAME, IDENTITY_PASSWORD);
78          KeyStore identityTwo = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_TWO_FILE_NAME, IDENTITY_PASSWORD);
79  
80          X509ExtendedKeyManager keyManagerOne = KeyManagerUtils.createKeyManager(identityOne, IDENTITY_PASSWORD);
81          X509ExtendedKeyManager keyManagerTwo = KeyManagerUtils.createKeyManager(identityTwo, IDENTITY_PASSWORD);
82  
83          CompositeX509ExtendedKeyManager keyManager = new CompositeX509ExtendedKeyManager(
84                  Arrays.asList(keyManagerOne, keyManagerTwo)
85          );
86  
87          assertThat(keyManager).isNotNull();
88          assertThat(keyManager.size()).isEqualTo(2);
89  
90          assertThat(identityOne.size()).isEqualTo(1);
91          assertThat(identityTwo.size()).isEqualTo(1);
92          assertThat(keyManager.getPrivateKey("TOGG")).isNull();
93      }
94  
95      @Test
96      void returnCertificateChain() throws KeyStoreException {
97          KeyStore identityOne = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_FILE_NAME, IDENTITY_PASSWORD);
98          KeyStore identityTwo = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_TWO_FILE_NAME, IDENTITY_PASSWORD);
99  
100         X509ExtendedKeyManager keyManagerOne = KeyManagerUtils.createKeyManager(identityOne, IDENTITY_PASSWORD);
101         X509ExtendedKeyManager keyManagerTwo = KeyManagerUtils.createKeyManager(identityTwo, IDENTITY_PASSWORD);
102 
103         CompositeX509ExtendedKeyManager keyManager = new CompositeX509ExtendedKeyManager(
104                 Arrays.asList(keyManagerOne, keyManagerTwo)
105         );
106 
107         assertThat(keyManager).isNotNull();
108         assertThat(keyManager.size()).isEqualTo(2);
109 
110         assertThat(identityOne.size()).isEqualTo(1);
111         assertThat(identityTwo.size()).isEqualTo(1);
112 
113         assertThat(keyManager.getCertificateChain("dummy-client"))
114                 .isNotNull()
115                 .isNotEmpty();
116 
117         assertThat(keyManager.getCertificateChain("another-server"))
118                 .isNotNull()
119                 .isNotEmpty();
120     }
121 
122     @Test
123     void returnNullForUnknownAliasWhenGettingCertificateChain() throws KeyStoreException {
124         KeyStore identityOne = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_FILE_NAME, IDENTITY_PASSWORD);
125         KeyStore identityTwo = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_TWO_FILE_NAME, IDENTITY_PASSWORD);
126 
127         X509ExtendedKeyManager keyManagerOne = KeyManagerUtils.createKeyManager(identityOne, IDENTITY_PASSWORD);
128         X509ExtendedKeyManager keyManagerTwo = KeyManagerUtils.createKeyManager(identityTwo, IDENTITY_PASSWORD);
129 
130         CompositeX509ExtendedKeyManager keyManager = new CompositeX509ExtendedKeyManager(
131                 Arrays.asList(keyManagerOne, keyManagerTwo)
132         );
133 
134         assertThat(keyManager).isNotNull();
135         assertThat(keyManager.size()).isEqualTo(2);
136 
137         assertThat(identityOne.size()).isEqualTo(1);
138         assertThat(identityTwo.size()).isEqualTo(1);
139         assertThat(keyManager.getCertificateChain("TOGG")).isNull();
140     }
141 
142     @Test
143     void returnNullWhenCertificateChainLengthIsZeroWhenGettingCertificateChain() {
144         X509ExtendedKeyManager mockedInnerKeyManager = mock(X509ExtendedKeyManager.class);
145         when(mockedInnerKeyManager.getCertificateChain(anyString())).thenReturn(new X509Certificate[] {});
146 
147         CompositeX509ExtendedKeyManager keyManager = new CompositeX509ExtendedKeyManager(Collections.singletonList(mockedInnerKeyManager));
148         X509Certificate[] certificateChain = keyManager.getCertificateChain("dummy-client");
149 
150         assertThat(certificateChain).isNull();
151     }
152 
153 
154     @Test
155     void getServerAliases() throws KeyStoreException {
156         KeyStore identityOne = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_FILE_NAME, IDENTITY_PASSWORD);
157         KeyStore identityTwo = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_TWO_FILE_NAME, IDENTITY_PASSWORD);
158 
159         X509ExtendedKeyManager keyManagerOne = KeyManagerUtils.createKeyManager(identityOne, IDENTITY_PASSWORD);
160         X509ExtendedKeyManager keyManagerTwo = KeyManagerUtils.createKeyManager(identityTwo, IDENTITY_PASSWORD);
161 
162         CompositeX509ExtendedKeyManager keyManager = new CompositeX509ExtendedKeyManager(
163                 Arrays.asList(keyManagerOne, keyManagerTwo)
164         );
165 
166         String[] aliases = keyManager.getServerAliases("RSA", null);
167 
168         assertThat(keyManager).isNotNull();
169         assertThat(keyManager.size()).isEqualTo(2);
170         assertThat(identityOne.size()).isEqualTo(1);
171         assertThat(identityTwo.size()).isEqualTo(1);
172         assertThat(aliases).containsExactlyInAnyOrder("dummy-client", "another-server");
173     }
174 
175     @Test
176     void getServerAliasesReturnsNullWhenThereIsNoMatchingIssuer() {
177         X509ExtendedKeyManager mockedInnerKeyManager = mock(X509ExtendedKeyManager.class);
178         Principal mockedIssuer = mock(Principal.class);
179         Principal[] mockedIssuers = new Principal[]{ mockedIssuer };
180         when(mockedInnerKeyManager.getServerAliases("RSA", mockedIssuers)).thenReturn(null);
181 
182         CompositeX509ExtendedKeyManager keyManager = new CompositeX509ExtendedKeyManager(Collections.singletonList(mockedInnerKeyManager));
183         String[] serverAliases = keyManager.getServerAliases("RSA", mockedIssuers);
184 
185         assertThat(serverAliases).isNull();
186     }
187 
188     @Test
189     void getClientAliases() throws KeyStoreException {
190         KeyStore identityOne = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_FILE_NAME, IDENTITY_PASSWORD);
191         KeyStore identityTwo = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_TWO_FILE_NAME, IDENTITY_PASSWORD);
192 
193         X509ExtendedKeyManager keyManagerOne = KeyManagerUtils.createKeyManager(identityOne, IDENTITY_PASSWORD);
194         X509ExtendedKeyManager keyManagerTwo = KeyManagerUtils.createKeyManager(identityTwo, IDENTITY_PASSWORD);
195 
196         CompositeX509ExtendedKeyManager keyManager = new CompositeX509ExtendedKeyManager(
197                 Arrays.asList(keyManagerOne, keyManagerTwo)
198         );
199 
200         String[] aliases = keyManager.getClientAliases("RSA", null);
201 
202         assertThat(keyManager).isNotNull();
203         assertThat(keyManager.size()).isEqualTo(2);
204         assertThat(identityOne.size()).isEqualTo(1);
205         assertThat(identityTwo.size()).isEqualTo(1);
206         assertThat(aliases).containsExactlyInAnyOrder("dummy-client", "another-server");
207     }
208 
209     @Test
210     void chooseFirstServerAliasWithMatchingKeyType() throws KeyStoreException {
211         KeyStore identityOne = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_FILE_NAME, IDENTITY_PASSWORD);
212         KeyStore identityTwo = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_TWO_FILE_NAME, IDENTITY_PASSWORD);
213 
214         X509ExtendedKeyManager keyManagerOne = KeyManagerUtils.createKeyManager(identityOne, IDENTITY_PASSWORD);
215         X509ExtendedKeyManager keyManagerTwo = KeyManagerUtils.createKeyManager(identityTwo, IDENTITY_PASSWORD);
216 
217         CompositeX509ExtendedKeyManager keyManager = new CompositeX509ExtendedKeyManager(
218                 Arrays.asList(keyManagerOne, keyManagerTwo)
219         );
220 
221         String alias = keyManager.chooseServerAlias("RSA", null, null);
222 
223         assertThat(keyManager).isNotNull();
224         assertThat(keyManager.size()).isEqualTo(2);
225         assertThat(identityOne.size()).isEqualTo(1);
226         assertThat(identityTwo.size()).isEqualTo(1);
227         assertThat(alias).isEqualTo("dummy-client");
228     }
229 
230     @Test
231     void chooseFirstEngineServerAliasWithMatchingKeyType() throws KeyStoreException {
232         KeyStore identityOne = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_FILE_NAME, IDENTITY_PASSWORD);
233         KeyStore identityTwo = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_TWO_FILE_NAME, IDENTITY_PASSWORD);
234 
235         X509ExtendedKeyManager keyManagerOne = KeyManagerUtils.createKeyManager(identityOne, IDENTITY_PASSWORD);
236         X509ExtendedKeyManager keyManagerTwo = KeyManagerUtils.createKeyManager(identityTwo, IDENTITY_PASSWORD);
237 
238         CompositeX509ExtendedKeyManager keyManager = new CompositeX509ExtendedKeyManager(
239                 Arrays.asList(keyManagerOne, keyManagerTwo)
240         );
241 
242         String alias = keyManager.chooseEngineServerAlias("RSA", null, null);
243 
244         assertThat(keyManager).isNotNull();
245         assertThat(keyManager.size()).isEqualTo(2);
246         assertThat(identityOne.size()).isEqualTo(1);
247         assertThat(identityTwo.size()).isEqualTo(1);
248         assertThat(alias).isEqualTo("dummy-client");
249     }
250 
251     @Test
252     void chooseFirstServerAliasWithMatchingKeyTypeWithDifferentOrderOfInitializationOfTheKeyManager() throws KeyStoreException {
253         KeyStore identityOne = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_FILE_NAME, IDENTITY_PASSWORD);
254         KeyStore identityTwo = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_TWO_FILE_NAME, IDENTITY_PASSWORD);
255 
256         X509ExtendedKeyManager keyManagerOne = KeyManagerUtils.createKeyManager(identityOne, IDENTITY_PASSWORD);
257         X509ExtendedKeyManager keyManagerTwo = KeyManagerUtils.createKeyManager(identityTwo, IDENTITY_PASSWORD);
258 
259         CompositeX509ExtendedKeyManager keyManager = new CompositeX509ExtendedKeyManager(
260                 Arrays.asList(keyManagerTwo, keyManagerOne)
261         );
262 
263         String alias = keyManager.chooseServerAlias("RSA", null, null);
264 
265         assertThat(keyManager).isNotNull();
266         assertThat(keyManager.size()).isEqualTo(2);
267         assertThat(identityOne.size()).isEqualTo(1);
268         assertThat(identityTwo.size()).isEqualTo(1);
269         assertThat(alias).isEqualTo("another-server");
270     }
271 
272     @Test
273     void chooseFirstEngineServerAliasWithMatchingKeyTypeWithDifferentOrderOfInitializationOfTheKeyManager() throws KeyStoreException {
274         KeyStore identityOne = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_FILE_NAME, IDENTITY_PASSWORD);
275         KeyStore identityTwo = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_TWO_FILE_NAME, IDENTITY_PASSWORD);
276 
277         X509ExtendedKeyManager keyManagerOne = KeyManagerUtils.createKeyManager(identityOne, IDENTITY_PASSWORD);
278         X509ExtendedKeyManager keyManagerTwo = KeyManagerUtils.createKeyManager(identityTwo, IDENTITY_PASSWORD);
279 
280         CompositeX509ExtendedKeyManager keyManager = new CompositeX509ExtendedKeyManager(
281                 Arrays.asList(keyManagerTwo, keyManagerOne)
282         );
283 
284         String alias = keyManager.chooseServerAlias("RSA", null, null);
285 
286         assertThat(keyManager).isNotNull();
287         assertThat(keyManager.size()).isEqualTo(2);
288         assertThat(identityOne.size()).isEqualTo(1);
289         assertThat(identityTwo.size()).isEqualTo(1);
290         assertThat(alias).isEqualTo("another-server");
291     }
292 
293     @Test
294     void returnNullWhenThereIsNoMatchOfKeyTypeForKeyManagersWhileChoosingServerAlias() throws KeyStoreException {
295         KeyStore identityOne = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_FILE_NAME, IDENTITY_PASSWORD);
296         KeyStore identityTwo = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_TWO_FILE_NAME, IDENTITY_PASSWORD);
297 
298         X509ExtendedKeyManager keyManagerOne = KeyManagerUtils.createKeyManager(identityOne, IDENTITY_PASSWORD);
299         X509ExtendedKeyManager keyManagerTwo = KeyManagerUtils.createKeyManager(identityTwo, IDENTITY_PASSWORD);
300 
301         CompositeX509ExtendedKeyManager keyManager = new CompositeX509ExtendedKeyManager(
302                 Arrays.asList(keyManagerOne, keyManagerTwo)
303         );
304 
305         String alias = keyManager.chooseServerAlias("ECDSA", null, null);
306 
307         assertThat(keyManager).isNotNull();
308         assertThat(keyManager.size()).isEqualTo(2);
309         assertThat(identityOne.size()).isEqualTo(1);
310         assertThat(identityTwo.size()).isEqualTo(1);
311         assertThat(alias).isNull();
312     }
313 
314     @Test
315     void returnNullWhenThereIsNoMatchOfKeyTypeForKeyManagersWhileChoosingEngineServerAlias() throws KeyStoreException {
316         KeyStore identityOne = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_FILE_NAME, IDENTITY_PASSWORD);
317         KeyStore identityTwo = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_TWO_FILE_NAME, IDENTITY_PASSWORD);
318 
319         X509ExtendedKeyManager keyManagerOne = KeyManagerUtils.createKeyManager(identityOne, IDENTITY_PASSWORD);
320         X509ExtendedKeyManager keyManagerTwo = KeyManagerUtils.createKeyManager(identityTwo, IDENTITY_PASSWORD);
321 
322         CompositeX509ExtendedKeyManager keyManager = new CompositeX509ExtendedKeyManager(
323                 Arrays.asList(keyManagerOne, keyManagerTwo)
324         );
325 
326         String alias = keyManager.chooseEngineServerAlias("ECDSA", null, null);
327 
328         assertThat(keyManager).isNotNull();
329         assertThat(keyManager.size()).isEqualTo(2);
330         assertThat(identityOne.size()).isEqualTo(1);
331         assertThat(identityTwo.size()).isEqualTo(1);
332         assertThat(alias).isNull();
333     }
334 
335     @Test
336     void chooseFirstClientAliasWithMatchingKeyType() throws KeyStoreException {
337         KeyStore identityOne = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_FILE_NAME, IDENTITY_PASSWORD);
338         KeyStore identityTwo = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_TWO_FILE_NAME, IDENTITY_PASSWORD);
339 
340         X509ExtendedKeyManager keyManagerOne = KeyManagerUtils.createKeyManager(identityOne, IDENTITY_PASSWORD);
341         X509ExtendedKeyManager keyManagerTwo = KeyManagerUtils.createKeyManager(identityTwo, IDENTITY_PASSWORD);
342 
343         CompositeX509ExtendedKeyManager keyManager = new CompositeX509ExtendedKeyManager(
344                 Arrays.asList(keyManagerOne, keyManagerTwo)
345         );
346 
347         String alias = keyManager.chooseClientAlias(new String[]{"RSA"}, null, null);
348 
349         assertThat(keyManager).isNotNull();
350         assertThat(keyManager.size()).isEqualTo(2);
351         assertThat(identityOne.size()).isEqualTo(1);
352         assertThat(identityTwo.size()).isEqualTo(1);
353         assertThat(alias).isEqualTo("dummy-client");
354     }
355 
356     @Test
357     void chooseFirstClientAliasWithMatchingKeyTypeWithPreferredAlias() throws KeyStoreException {
358         KeyStore identityOne = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_FILE_NAME, IDENTITY_PASSWORD);
359         KeyStore identityTwo = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_TWO_FILE_NAME, IDENTITY_PASSWORD);
360 
361         X509ExtendedKeyManager keyManagerOne = KeyManagerUtils.createKeyManager(identityOne, IDENTITY_PASSWORD);
362         X509ExtendedKeyManager keyManagerTwo = KeyManagerUtils.createKeyManager(identityTwo, IDENTITY_PASSWORD);
363 
364         CompositeX509ExtendedKeyManager keyManager = new CompositeX509ExtendedKeyManager(
365                 Arrays.asList(keyManagerOne, keyManagerTwo),
366                 Collections.singletonMap("another-server", Collections.singletonList(URI.create("https://localhost:8443/")))
367         );
368 
369         Socket socket = mock(Socket.class);
370         InetSocketAddress socketAddress = mock(InetSocketAddress.class);
371 
372         when(socket.getRemoteSocketAddress()).thenReturn(socketAddress);
373         when(socketAddress.getPort()).thenReturn(8443);
374         when(socketAddress.getHostName()).thenReturn("localhost");
375 
376         String alias = keyManager.chooseClientAlias(new String[]{"RSA"}, null, socket);
377 
378         assertThat(keyManager).isNotNull();
379         assertThat(keyManager.size()).isEqualTo(2);
380         assertThat(identityOne.size()).isEqualTo(1);
381         assertThat(identityTwo.size()).isEqualTo(1);
382         assertThat(alias).isEqualTo("another-server");
383     }
384 
385     @Test
386     void chooseFirstClientAliasWithMatchingKeyTypWhilePreferredAliasIsIgnoredBecauseRemoteSocketAddressIsNotAnInstanceOfInetSocketAddress() throws KeyStoreException {
387         KeyStore identityOne = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_FILE_NAME, IDENTITY_PASSWORD);
388         KeyStore identityTwo = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_TWO_FILE_NAME, IDENTITY_PASSWORD);
389 
390         X509ExtendedKeyManager keyManagerOne = KeyManagerUtils.createKeyManager(identityOne, IDENTITY_PASSWORD);
391         X509ExtendedKeyManager keyManagerTwo = KeyManagerUtils.createKeyManager(identityTwo, IDENTITY_PASSWORD);
392 
393         CompositeX509ExtendedKeyManager keyManager = new CompositeX509ExtendedKeyManager(
394                 Arrays.asList(keyManagerOne, keyManagerTwo),
395                 Collections.singletonMap("another-server", Collections.singletonList(URI.create("https://localhost:8443/")))
396         );
397 
398         Socket socket = mock(Socket.class);
399         SocketAddress socketAddress = mock(SocketAddress.class);
400         when(socket.getRemoteSocketAddress()).thenReturn(socketAddress);
401 
402         String alias = keyManager.chooseClientAlias(new String[]{"RSA"}, null, socket);
403 
404         assertThat(keyManager).isNotNull();
405         assertThat(keyManager.size()).isEqualTo(2);
406         assertThat(identityOne.size()).isEqualTo(1);
407         assertThat(identityTwo.size()).isEqualTo(1);
408         assertThat(alias).isEqualTo("dummy-client");
409     }
410 
411     @Test
412     void chooseFirstClientAliasWithMatchingKeyTypeWhilePreferredAliasIsIgnoredBecauseSocketIsNull() throws KeyStoreException {
413         KeyStore identityOne = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_FILE_NAME, IDENTITY_PASSWORD);
414         KeyStore identityTwo = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_TWO_FILE_NAME, IDENTITY_PASSWORD);
415 
416         X509ExtendedKeyManager keyManagerOne = KeyManagerUtils.createKeyManager(identityOne, IDENTITY_PASSWORD);
417         X509ExtendedKeyManager keyManagerTwo = KeyManagerUtils.createKeyManager(identityTwo, IDENTITY_PASSWORD);
418 
419         CompositeX509ExtendedKeyManager keyManager = new CompositeX509ExtendedKeyManager(
420                 Arrays.asList(keyManagerOne, keyManagerTwo),
421                 Collections.singletonMap("another-server", Collections.singletonList(URI.create("https://localhost:8443/")))
422         );
423 
424         String alias = keyManager.chooseClientAlias(new String[]{"RSA"}, null, null);
425 
426         assertThat(keyManager).isNotNull();
427         assertThat(keyManager.size()).isEqualTo(2);
428         assertThat(identityOne.size()).isEqualTo(1);
429         assertThat(identityTwo.size()).isEqualTo(1);
430         assertThat(alias).isEqualTo("dummy-client");
431     }
432 
433     @Test
434     void chooseFirstEngineClientAliasWithMatchingKeyType() throws KeyStoreException {
435         KeyStore identityOne = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_FILE_NAME, IDENTITY_PASSWORD);
436         KeyStore identityTwo = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_TWO_FILE_NAME, IDENTITY_PASSWORD);
437 
438         X509ExtendedKeyManager keyManagerOne = KeyManagerUtils.createKeyManager(identityOne, IDENTITY_PASSWORD);
439         X509ExtendedKeyManager keyManagerTwo = KeyManagerUtils.createKeyManager(identityTwo, IDENTITY_PASSWORD);
440 
441         CompositeX509ExtendedKeyManager keyManager = new CompositeX509ExtendedKeyManager(
442                 Arrays.asList(keyManagerOne, keyManagerTwo)
443         );
444 
445         String alias = keyManager.chooseEngineClientAlias(new String[]{"RSA"}, null, null);
446 
447         assertThat(keyManager).isNotNull();
448         assertThat(keyManager.size()).isEqualTo(2);
449         assertThat(identityOne.size()).isEqualTo(1);
450         assertThat(identityTwo.size()).isEqualTo(1);
451         assertThat(alias).isEqualTo("dummy-client");
452     }
453 
454     @Test
455     void chooseFirstEngineClientAliasWithMatchingKeyTypeWithPreferredAlias() throws KeyStoreException {
456         KeyStore identityOne = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_FILE_NAME, IDENTITY_PASSWORD);
457         KeyStore identityTwo = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_TWO_FILE_NAME, IDENTITY_PASSWORD);
458 
459         X509ExtendedKeyManager keyManagerOne = KeyManagerUtils.createKeyManager(identityOne, IDENTITY_PASSWORD);
460         X509ExtendedKeyManager keyManagerTwo = KeyManagerUtils.createKeyManager(identityTwo, IDENTITY_PASSWORD);
461 
462         CompositeX509ExtendedKeyManager keyManager = new CompositeX509ExtendedKeyManager(
463                 Arrays.asList(keyManagerOne, keyManagerTwo),
464                 Collections.singletonMap("another-server", Collections.singletonList(URI.create("https://localhost:8443/")))
465         );
466 
467         SSLEngine sslEngine = mock(SSLEngine.class);
468         when(sslEngine.getPeerPort()).thenReturn(8443);
469         when(sslEngine.getPeerHost()).thenReturn("localhost");
470 
471         String alias = keyManager.chooseEngineClientAlias(new String[]{"RSA"}, null, sslEngine);
472 
473         assertThat(keyManager).isNotNull();
474         assertThat(keyManager.size()).isEqualTo(2);
475         assertThat(identityOne.size()).isEqualTo(1);
476         assertThat(identityTwo.size()).isEqualTo(1);
477         assertThat(alias).isEqualTo("another-server");
478     }
479 
480     @Test
481     void chooseFirstEngineClientAliasWithMatchingKeyTypeWhilePreferredAliasIsIgnoredBecauseSslEngineIsNull() throws KeyStoreException {
482         KeyStore identityOne = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_FILE_NAME, IDENTITY_PASSWORD);
483         KeyStore identityTwo = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_TWO_FILE_NAME, IDENTITY_PASSWORD);
484 
485         X509ExtendedKeyManager keyManagerOne = KeyManagerUtils.createKeyManager(identityOne, IDENTITY_PASSWORD);
486         X509ExtendedKeyManager keyManagerTwo = KeyManagerUtils.createKeyManager(identityTwo, IDENTITY_PASSWORD);
487 
488         CompositeX509ExtendedKeyManager keyManager = new CompositeX509ExtendedKeyManager(
489                 Arrays.asList(keyManagerOne, keyManagerTwo),
490                 Collections.singletonMap("another-server", Collections.singletonList(URI.create("https://localhost:8443/")))
491         );
492 
493         String alias = keyManager.chooseEngineClientAlias(new String[]{"RSA"}, null, null);
494 
495         assertThat(keyManager).isNotNull();
496         assertThat(keyManager.size()).isEqualTo(2);
497         assertThat(identityOne.size()).isEqualTo(1);
498         assertThat(identityTwo.size()).isEqualTo(1);
499         assertThat(alias).isEqualTo("dummy-client");
500     }
501 
502     @Test
503     void returnNullWhenThereIsNoMatchOfKeyTypeForKeyManagersWhileChoosingClientAlias() throws KeyStoreException {
504         KeyStore identityOne = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_FILE_NAME, IDENTITY_PASSWORD);
505         KeyStore identityTwo = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_TWO_FILE_NAME, IDENTITY_PASSWORD);
506 
507         X509ExtendedKeyManager keyManagerOne = KeyManagerUtils.createKeyManager(identityOne, IDENTITY_PASSWORD);
508         X509ExtendedKeyManager keyManagerTwo = KeyManagerUtils.createKeyManager(identityTwo, IDENTITY_PASSWORD);
509 
510         CompositeX509ExtendedKeyManager keyManager = new CompositeX509ExtendedKeyManager(
511                 Arrays.asList(keyManagerOne, keyManagerTwo)
512         );
513 
514         String alias = keyManager.chooseClientAlias(new String[]{"ECDSA"}, null, null);
515 
516         assertThat(keyManager).isNotNull();
517         assertThat(keyManager.size()).isEqualTo(2);
518         assertThat(identityOne.size()).isEqualTo(1);
519         assertThat(identityTwo.size()).isEqualTo(1);
520         assertThat(alias).isNull();
521     }
522 
523     @Test
524     void returnNullWhenThereIsNoMatchOfKeyTypeForKeyManagersWhileChoosingEngineClientAlias() throws KeyStoreException {
525         KeyStore identityOne = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_FILE_NAME, IDENTITY_PASSWORD);
526         KeyStore identityTwo = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_TWO_FILE_NAME, IDENTITY_PASSWORD);
527 
528         X509ExtendedKeyManager keyManagerOne = KeyManagerUtils.createKeyManager(identityOne, IDENTITY_PASSWORD);
529         X509ExtendedKeyManager keyManagerTwo = KeyManagerUtils.createKeyManager(identityTwo, IDENTITY_PASSWORD);
530 
531         CompositeX509ExtendedKeyManager keyManager = new CompositeX509ExtendedKeyManager(
532                 Arrays.asList(keyManagerOne, keyManagerTwo)
533         );
534 
535         String alias = keyManager.chooseEngineClientAlias(new String[]{"ECDSA"}, null, null);
536 
537         assertThat(keyManager).isNotNull();
538         assertThat(keyManager.size()).isEqualTo(2);
539         assertThat(identityOne.size()).isEqualTo(1);
540         assertThat(identityTwo.size()).isEqualTo(1);
541         assertThat(alias).isNull();
542     }
543 
544 }