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.util;
18  
19  import nl.altindag.ssl.exception.GenericKeyManagerException;
20  import nl.altindag.ssl.keymanager.CompositeX509ExtendedKeyManager;
21  import nl.altindag.ssl.keymanager.X509KeyManagerWrapper;
22  import nl.altindag.ssl.model.KeyStoreHolder;
23  import org.junit.jupiter.api.Test;
24  import org.junit.jupiter.api.extension.ExtendWith;
25  import org.mockito.junit.jupiter.MockitoExtension;
26  
27  import javax.net.ssl.KeyManagerFactory;
28  import javax.net.ssl.X509ExtendedKeyManager;
29  import javax.net.ssl.X509KeyManager;
30  import java.security.KeyStore;
31  import java.security.KeyStoreException;
32  import java.security.Provider;
33  import java.security.Security;
34  import java.util.Arrays;
35  import java.util.HashMap;
36  import java.util.List;
37  import java.util.Map;
38  
39  import static org.assertj.core.api.Assertions.assertThat;
40  import static org.assertj.core.api.Assertions.assertThatThrownBy;
41  import static org.mockito.Mockito.mock;
42  
43  /**
44   * @author Hakan Altindag
45   */
46  @ExtendWith(MockitoExtension.class)
47  class KeyManagerUtilsShould {
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 createKeyManagerWithKeyStoreAndCustomAlgorithm() {
56          KeyStore identity = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_FILE_NAME, IDENTITY_PASSWORD);
57          X509ExtendedKeyManager keyManager = KeyManagerUtils.createKeyManager(identity, IDENTITY_PASSWORD, KeyManagerFactory.getDefaultAlgorithm());
58  
59          assertThat(keyManager).isNotNull();
60      }
61  
62      @Test
63      void createKeyManagerWithKeyStoreHolders() {
64          KeyStore identityOne = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_FILE_NAME, IDENTITY_PASSWORD);
65          KeyStore identityTwo = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_TWO_FILE_NAME, IDENTITY_PASSWORD);
66  
67          KeyStoreHolder keyStoreHolderOne = new KeyStoreHolder(identityOne, IDENTITY_PASSWORD, IDENTITY_PASSWORD);
68          KeyStoreHolder keyStoreHolderTwo = new KeyStoreHolder(identityTwo, IDENTITY_PASSWORD, IDENTITY_PASSWORD);
69  
70          X509ExtendedKeyManager keyManager = KeyManagerUtils.createKeyManager(keyStoreHolderOne, keyStoreHolderTwo);
71  
72          assertThat(keyManager).isInstanceOf(CompositeX509ExtendedKeyManager.class);
73      }
74  
75      @Test
76      void createKeyManagerWithCustomSecurityProviderName() {
77          KeyStore identity = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_FILE_NAME, IDENTITY_PASSWORD);
78  
79          X509ExtendedKeyManager keyManager = KeyManagerUtils.createKeyManager(identity, IDENTITY_PASSWORD, KeyManagerFactory.getDefaultAlgorithm(), "SunJSSE");
80  
81          assertThat(keyManager).isNotNull();
82      }
83  
84      @Test
85      void createKeyManagerWithCustomSecurityProvider() {
86          KeyStore identity = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_FILE_NAME, IDENTITY_PASSWORD);
87          Provider sunJsseSecurityProvider = Security.getProvider("SunJSSE");
88  
89          X509ExtendedKeyManager keyManager = KeyManagerUtils.createKeyManager(identity, IDENTITY_PASSWORD, KeyManagerFactory.getDefaultAlgorithm(), sunJsseSecurityProvider);
90  
91          assertThat(keyManager).isNotNull();
92      }
93  
94      @Test
95      void wrapIfNeeded() {
96          X509KeyManager keyManager = mock(X509KeyManager.class);
97          X509ExtendedKeyManager extendedKeyManager = KeyManagerUtils.wrapIfNeeded(keyManager);
98  
99          assertThat(extendedKeyManager).isInstanceOf(X509KeyManagerWrapper.class);
100     }
101 
102     @Test
103     void doNotWrapWhenInstanceIsX509ExtendedKeyManager() {
104         X509ExtendedKeyManager keyManager = mock(X509ExtendedKeyManager.class);
105         X509ExtendedKeyManager extendedKeyManager = KeyManagerUtils.wrapIfNeeded(keyManager);
106 
107         assertThat(extendedKeyManager)
108                 .isEqualTo(keyManager)
109                 .isNotInstanceOf(X509KeyManagerWrapper.class);
110     }
111 
112     @Test
113     void combineMultipleKeyManagersIntoOne() {
114         KeyStore identityOne = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_FILE_NAME, IDENTITY_PASSWORD);
115         KeyStore identityTwo = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_TWO_FILE_NAME, IDENTITY_PASSWORD);
116 
117         X509ExtendedKeyManager keyManagerOne = KeyManagerUtils.createKeyManager(identityOne, IDENTITY_PASSWORD);
118         X509ExtendedKeyManager keyManagerTwo = KeyManagerUtils.createKeyManager(identityTwo, IDENTITY_PASSWORD);
119 
120         X509ExtendedKeyManager combinedKeyManager = KeyManagerUtils.combine(keyManagerOne, keyManagerTwo);
121 
122         assertThat(combinedKeyManager).isInstanceOf(CompositeX509ExtendedKeyManager.class);
123     }
124 
125     @Test
126     void unwrapCombinedKeyManagersAndRecombineIntoSingleBaseKeyManager() {
127         KeyStore identityOne = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_FILE_NAME, IDENTITY_PASSWORD);
128         KeyStore identityTwo = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_TWO_FILE_NAME, IDENTITY_PASSWORD);
129 
130         X509ExtendedKeyManager keyManagerOne = KeyManagerUtils.createKeyManager(identityOne, IDENTITY_PASSWORD);
131         X509ExtendedKeyManager keyManagerTwo = KeyManagerUtils.createKeyManager(identityTwo, IDENTITY_PASSWORD);
132 
133         X509ExtendedKeyManager combinedKeyManager = KeyManagerUtils.combine(keyManagerOne, keyManagerTwo);
134         X509ExtendedKeyManager combinedCombinedKeyManager = KeyManagerUtils.combine(combinedKeyManager, keyManagerOne, keyManagerTwo);
135 
136         assertThat(combinedKeyManager).isInstanceOf(CompositeX509ExtendedKeyManager.class);
137         assertThat(combinedCombinedKeyManager).isInstanceOf(CompositeX509ExtendedKeyManager.class);
138         assertThat(((CompositeX509ExtendedKeyManager) combinedKeyManager).size()).isEqualTo(2);
139         assertThat(((CompositeX509ExtendedKeyManager) combinedCombinedKeyManager).size()).isEqualTo(4);
140     }
141 
142     @Test
143     void createKeyManagerFactory() {
144         X509ExtendedKeyManager keyManager = mock(X509ExtendedKeyManager.class);
145         KeyManagerFactory keyManagerFactory = KeyManagerUtils.createKeyManagerFactory(keyManager);
146 
147         assertThat(keyManagerFactory).isNotNull();
148         assertThat(keyManagerFactory.getKeyManagers()).containsExactly(keyManager);
149     }
150 
151     @Test
152     void createKeyManagerFromMultipleKeyManagers() {
153         KeyStore identityOne = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_FILE_NAME, IDENTITY_PASSWORD);
154         KeyStore identityTwo = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_TWO_FILE_NAME, IDENTITY_PASSWORD);
155 
156         X509ExtendedKeyManager keyManagerOne = KeyManagerUtils.createKeyManager(identityOne, IDENTITY_PASSWORD);
157         X509ExtendedKeyManager keyManagerTwo = KeyManagerUtils.createKeyManager(identityTwo, IDENTITY_PASSWORD);
158 
159         X509ExtendedKeyManager keyManager = KeyManagerUtils.keyManagerBuilder()
160                 .withKeyManager(keyManagerOne)
161                 .withKeyManager(keyManagerTwo)
162                 .build();
163 
164         assertThat(keyManager).isNotNull();
165     }
166 
167     @Test
168     void createKeyManagerFromMultipleKeyManagersUsingVarArgs() {
169         KeyStore identityOne = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_FILE_NAME, IDENTITY_PASSWORD);
170         KeyStore identityTwo = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_TWO_FILE_NAME, IDENTITY_PASSWORD);
171 
172         X509ExtendedKeyManager keyManagerOne = KeyManagerUtils.createKeyManager(identityOne, IDENTITY_PASSWORD);
173         X509ExtendedKeyManager keyManagerTwo = KeyManagerUtils.createKeyManager(identityTwo, IDENTITY_PASSWORD);
174 
175         X509ExtendedKeyManager keyManager = KeyManagerUtils.keyManagerBuilder()
176                 .withKeyManagers(keyManagerOne, keyManagerTwo)
177                 .build();
178 
179         assertThat(keyManager).isNotNull();
180     }
181 
182     @Test
183     void createKeyManagerFromMultipleKeyManagersUsingList() {
184         KeyStore identityOne = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_FILE_NAME, IDENTITY_PASSWORD);
185         KeyStore identityTwo = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_TWO_FILE_NAME, IDENTITY_PASSWORD);
186 
187         X509ExtendedKeyManager keyManagerOne = KeyManagerUtils.createKeyManager(identityOne, IDENTITY_PASSWORD);
188         X509ExtendedKeyManager keyManagerTwo = KeyManagerUtils.createKeyManager(identityTwo, IDENTITY_PASSWORD);
189 
190         X509ExtendedKeyManager keyManager = KeyManagerUtils.keyManagerBuilder()
191                 .withKeyManagers(Arrays.asList(keyManagerOne, keyManagerTwo))
192                 .build();
193 
194         assertThat(keyManager).isNotNull();
195     }
196 
197     @Test
198     void createKeyManagerFromMultipleKeyStoreHoldersAsVarArgs() {
199         KeyStore identityOne = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_FILE_NAME, IDENTITY_PASSWORD);
200         KeyStore identityTwo = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_TWO_FILE_NAME, IDENTITY_PASSWORD);
201 
202         KeyStoreHolder keyStoreHolderOne = new KeyStoreHolder(identityOne, IDENTITY_PASSWORD, IDENTITY_PASSWORD);
203         KeyStoreHolder keyStoreHolderTwo = new KeyStoreHolder(identityTwo, IDENTITY_PASSWORD, IDENTITY_PASSWORD);
204 
205         X509ExtendedKeyManager keyManager = KeyManagerUtils.keyManagerBuilder()
206                 .withIdentities(keyStoreHolderOne, keyStoreHolderTwo)
207                 .build();
208 
209         assertThat(keyManager).isNotNull();
210     }
211 
212     @Test
213     void createKeyManagerFromMultipleKeyStoreHoldersAsList() {
214         KeyStore identityOne = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_FILE_NAME, IDENTITY_PASSWORD);
215         KeyStore identityTwo = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_TWO_FILE_NAME, IDENTITY_PASSWORD);
216 
217         KeyStoreHolder keyStoreHolderOne = new KeyStoreHolder(identityOne, IDENTITY_PASSWORD, IDENTITY_PASSWORD);
218         KeyStoreHolder keyStoreHolderTwo = new KeyStoreHolder(identityTwo, IDENTITY_PASSWORD, IDENTITY_PASSWORD);
219 
220         X509ExtendedKeyManager keyManager = KeyManagerUtils.keyManagerBuilder()
221                 .withIdentities(Arrays.asList(keyStoreHolderOne, keyStoreHolderTwo))
222                 .build();
223 
224         assertThat(keyManager).isNotNull();
225     }
226 
227     @Test
228     void createKeyManagerFromAMultipleKeyStores() {
229         KeyStore identityOne = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_FILE_NAME, IDENTITY_PASSWORD);
230         KeyStore identityTwo = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_TWO_FILE_NAME, IDENTITY_PASSWORD);
231 
232         X509ExtendedKeyManager keyManager = KeyManagerUtils.keyManagerBuilder()
233                 .withIdentity(identityOne, IDENTITY_PASSWORD, KeyManagerFactory.getDefaultAlgorithm())
234                 .withIdentity(identityTwo, IDENTITY_PASSWORD, KeyManagerFactory.getDefaultAlgorithm())
235                 .build();
236 
237         assertThat(keyManager).isNotNull();
238     }
239 
240     @Test
241     void createKeyManagerFromKeyStoreContainingMultipleKeysWithDifferentPasswords() throws KeyStoreException {
242         KeyStore identity = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + "identity-with-multiple-keys.jks", IDENTITY_PASSWORD);
243 
244         assertThat(identity.size()).isEqualTo(2);
245 
246         assertThat(identity.containsAlias("kaiba")).isTrue();
247         assertThat(identity.isKeyEntry("kaiba")).isTrue();
248 
249         assertThat(identity.containsAlias("yugioh")).isTrue();
250         assertThat(identity.isKeyEntry("yugioh")).isTrue();
251 
252 
253         Map<String, char[]> aliasToPassword = new HashMap<>();
254         aliasToPassword.put("kaiba", "kazuki".toCharArray());
255         aliasToPassword.put("yugioh", "takahashi".toCharArray());
256 
257         X509ExtendedKeyManager keyManager = KeyManagerUtils.createKeyManager(identity, aliasToPassword);
258 
259         assertThat(keyManager).isNotNull();
260     }
261 
262     @Test
263     void toArray() {
264         KeyStore identity = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_FILE_NAME, IDENTITY_PASSWORD);
265         X509ExtendedKeyManager keyManager = KeyManagerUtils.createKeyManager(identity, IDENTITY_PASSWORD);
266 
267         X509ExtendedKeyManager[] keyManagers = KeyManagerUtils.toArray(keyManager);
268         assertThat(keyManagers)
269                 .hasSize(1)
270                 .contains(keyManager);
271     }
272 
273     @Test
274     void addMultipleClientIdentityRoutes() {
275         KeyStore identityOne = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_FILE_NAME, IDENTITY_PASSWORD);
276         KeyStore identityTwo = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_TWO_FILE_NAME, IDENTITY_PASSWORD);
277 
278         X509ExtendedKeyManager keyManagerOne = KeyManagerUtils.createKeyManager(identityOne, IDENTITY_PASSWORD);
279         X509ExtendedKeyManager keyManagerTwo = KeyManagerUtils.createKeyManager(identityTwo, IDENTITY_PASSWORD);
280 
281         X509ExtendedKeyManager keyManager = KeyManagerUtils.combine(keyManagerOne, keyManagerTwo);
282         KeyManagerUtils.addClientIdentityRoute(keyManager, "client","https://localhost:8443/");
283         KeyManagerUtils.addClientIdentityRoute(keyManager, "client","https://localhost:8453/");
284         Map<String, List<String>> clientIdentityRoute = KeyManagerUtils.getClientIdentityRoute(keyManager);
285 
286         assertThat(clientIdentityRoute)
287                 .containsKey("client")
288                 .containsValue(Arrays.asList("https://localhost:8443/", "https://localhost:8453/"));
289     }
290 
291     @Test
292     void overrideClientIdentityRoutes() {
293         KeyStore identityOne = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_FILE_NAME, IDENTITY_PASSWORD);
294         KeyStore identityTwo = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_TWO_FILE_NAME, IDENTITY_PASSWORD);
295 
296         X509ExtendedKeyManager keyManagerOne = KeyManagerUtils.createKeyManager(identityOne, IDENTITY_PASSWORD);
297         X509ExtendedKeyManager keyManagerTwo = KeyManagerUtils.createKeyManager(identityTwo, IDENTITY_PASSWORD);
298 
299         X509ExtendedKeyManager keyManager = KeyManagerUtils.combine(keyManagerOne, keyManagerTwo);
300         KeyManagerUtils.addClientIdentityRoute(keyManager, "client","https://localhost:8443/", "https://localhost:8453/");
301         Map<String, List<String>> clientIdentityRoute = KeyManagerUtils.getClientIdentityRoute(keyManager);
302 
303         assertThat(clientIdentityRoute)
304                 .containsKey("client")
305                 .containsValue(Arrays.asList("https://localhost:8443/", "https://localhost:8453/"));
306 
307         KeyManagerUtils.overrideClientIdentityRoute(keyManager, "client", "https://localhost:9443/", "https://localhost:9453/");
308         clientIdentityRoute = KeyManagerUtils.getClientIdentityRoute(keyManager);
309 
310         assertThat(clientIdentityRoute)
311                 .containsKey("client")
312                 .doesNotContainValue(Arrays.asList("https://localhost:8443/", "https://localhost:8453/"))
313                 .containsValue(Arrays.asList("https://localhost:9443/", "https://localhost:9453/"));
314     }
315 
316     @Test
317     void addClientIdentityRoutesWhenTryingToOverrideANonExistingRoute() {
318         KeyStore identityOne = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_FILE_NAME, IDENTITY_PASSWORD);
319         KeyStore identityTwo = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_TWO_FILE_NAME, IDENTITY_PASSWORD);
320 
321         X509ExtendedKeyManager keyManagerOne = KeyManagerUtils.createKeyManager(identityOne, IDENTITY_PASSWORD);
322         X509ExtendedKeyManager keyManagerTwo = KeyManagerUtils.createKeyManager(identityTwo, IDENTITY_PASSWORD);
323 
324         X509ExtendedKeyManager keyManager = KeyManagerUtils.combine(keyManagerOne, keyManagerTwo);
325         KeyManagerUtils.overrideClientIdentityRoute(keyManager, "client","https://localhost:8443/", "https://localhost:8453/");
326         Map<String, List<String>> clientIdentityRoute = KeyManagerUtils.getClientIdentityRoute(keyManager);
327 
328         assertThat(clientIdentityRoute)
329                 .containsKey("client")
330                 .containsValue(Arrays.asList("https://localhost:8443/", "https://localhost:8453/"));
331     }
332 
333     @Test
334     void throwExceptionWhenCreatingKeyManagerFromKeyStoreWhichDoesNotHaveMatchingAlias() throws KeyStoreException {
335         KeyStore identity = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + "identity-with-multiple-keys.jks", IDENTITY_PASSWORD);
336 
337         assertThat(identity.size()).isEqualTo(2);
338 
339         assertThat(identity.containsAlias("Jessie")).isFalse();
340         assertThat(identity.containsAlias("James")).isFalse();
341 
342 
343         Map<String, char[]> aliasToPassword = new HashMap<>();
344         aliasToPassword.put("Jessie", "team-rocket".toCharArray());
345         aliasToPassword.put("James", "team-rocket".toCharArray());
346 
347         assertThatThrownBy(() -> KeyManagerUtils.createKeyManager(identity, aliasToPassword))
348                 .isInstanceOf(GenericKeyManagerException.class)
349                 .hasMessage("Could not create any KeyManager from the given KeyStore, Alias and Password");
350     }
351 
352     @Test
353     void throwExceptionWhenCreatingKeyManagerFromKeyStoreWithIncorrectKeyPassword() throws KeyStoreException {
354         KeyStore identity = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + "identity-with-multiple-keys.jks", IDENTITY_PASSWORD);
355 
356         assertThat(identity.size()).isEqualTo(2);
357 
358         assertThat(identity.containsAlias("kaiba")).isTrue();
359         assertThat(identity.isKeyEntry("kaiba")).isTrue();
360 
361         assertThat(identity.containsAlias("yugioh")).isTrue();
362         assertThat(identity.isKeyEntry("yugioh")).isTrue();
363 
364 
365         Map<String, char[]> aliasToPassword = new HashMap<>();
366         aliasToPassword.put("kaiba", "team-rocket".toCharArray());
367         aliasToPassword.put("yugioh", "team-rocket".toCharArray());
368 
369         assertThatThrownBy(() -> KeyManagerUtils.createKeyManager(identity, aliasToPassword))
370                 .isInstanceOf(GenericKeyManagerException.class);
371     }
372 
373     @Test
374     void throwExceptionWhenCreatingKeyManagerWithIncorrectKeyPassword() {
375         KeyStore identity = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_FILE_NAME, IDENTITY_PASSWORD);
376         char[] keyPassword = "no-password".toCharArray();
377         String keyManagerFactoryAlgorithm = KeyManagerFactory.getDefaultAlgorithm();
378 
379         assertThatThrownBy(() -> KeyManagerUtils.createKeyManager(identity, keyPassword, keyManagerFactoryAlgorithm))
380                 .isInstanceOf(GenericKeyManagerException.class);
381     }
382 
383     @Test
384     void throwExceptionWhenCreatingKeyManagerWithInvalidAlgorithm() {
385         KeyStore identity = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_FILE_NAME, IDENTITY_PASSWORD);
386 
387         assertThatThrownBy(() -> KeyManagerUtils.createKeyManager(identity, IDENTITY_PASSWORD, "NONE"))
388                 .isInstanceOf(GenericKeyManagerException.class)
389                 .hasMessage("java.security.NoSuchAlgorithmException: NONE KeyManagerFactory not available");
390     }
391 
392     @Test
393     void throwExceptionWhenCreatingKeyManagerWithInvalidSecurityProviderName() {
394         KeyStore identity = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_FILE_NAME, IDENTITY_PASSWORD);
395         String keyManagerFactoryAlgorithm = KeyManagerFactory.getDefaultAlgorithm();
396 
397         assertThatThrownBy(() -> KeyManagerUtils.createKeyManager(identity, IDENTITY_PASSWORD, keyManagerFactoryAlgorithm, "test"))
398                 .isInstanceOf(GenericKeyManagerException.class)
399                 .hasMessage("java.security.NoSuchProviderException: no such provider: test");
400     }
401 
402     @Test
403     void throwExceptionWhenInvalidSecurityProviderIsProvidedForTheKeyManagerFactoryAlgorithm() {
404         KeyStore identity = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_FILE_NAME, IDENTITY_PASSWORD);
405         String keyManagerFactoryAlgorithm = KeyManagerFactory.getDefaultAlgorithm();
406         Provider sunSecurityProvider = Security.getProvider("SUN");
407 
408         assertThatThrownBy(() -> KeyManagerUtils.createKeyManager(identity, IDENTITY_PASSWORD, keyManagerFactoryAlgorithm, sunSecurityProvider))
409                 .isInstanceOf(GenericKeyManagerException.class)
410                 .hasMessage("java.security.NoSuchAlgorithmException: no such algorithm: SunX509 for provider SUN");
411     }
412 
413     @Test
414     void throwExceptionWhenUnsupportedKeyManagerIsProvidedWhenSwappingKeyManager() {
415         KeyStore identityOne = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_FILE_NAME, IDENTITY_PASSWORD);
416         KeyStore identityTwo = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_TWO_FILE_NAME, IDENTITY_PASSWORD);
417 
418         X509ExtendedKeyManager keyManagerOne = KeyManagerUtils.createKeyManager(identityOne, IDENTITY_PASSWORD);
419         X509ExtendedKeyManager keyManagerTwo = KeyManagerUtils.createKeyManager(identityTwo, IDENTITY_PASSWORD);
420 
421         assertThatThrownBy(() -> KeyManagerUtils.swapKeyManager(keyManagerOne, keyManagerTwo))
422                 .isInstanceOf(GenericKeyManagerException.class)
423                 .hasMessage("The baseKeyManager is from the instance of [sun.security.ssl.SunX509KeyManagerImpl] " +
424                         "and should be an instance of [nl.altindag.ssl.keymanager.HotSwappableX509ExtendedKeyManager].");
425     }
426 
427     @Test
428     void throwExceptionWhenUnsupportedKeyManagerIsProvidedWhenSwappingKeyManagerWithANewKeyManager() {
429         KeyStore identityOne = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_FILE_NAME, IDENTITY_PASSWORD);
430         KeyStore identityTwo = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_TWO_FILE_NAME, IDENTITY_PASSWORD);
431 
432         X509ExtendedKeyManager baseKeyManager = KeyManagerUtils.createSwappableKeyManager(KeyManagerUtils.createKeyManager(identityOne, IDENTITY_PASSWORD));
433         X509ExtendedKeyManager newKeyManager = KeyManagerUtils.createSwappableKeyManager(KeyManagerUtils.createKeyManager(identityTwo, IDENTITY_PASSWORD));
434 
435         assertThatThrownBy(() -> KeyManagerUtils.swapKeyManager(baseKeyManager, newKeyManager))
436                 .isInstanceOf(GenericKeyManagerException.class)
437                 .hasMessage("The newKeyManager should not be an instance of [nl.altindag.ssl.keymanager.HotSwappableX509ExtendedKeyManager]");
438     }
439 
440     @Test
441     void throwExceptionWhenUnsupportedKeyManagerIsProvidedWhenAddingNewClientIdentityRoute() {
442         KeyStore identity = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_FILE_NAME, IDENTITY_PASSWORD);
443         X509ExtendedKeyManager keyManager = KeyManagerUtils.createKeyManager(identity, IDENTITY_PASSWORD);
444 
445         assertThatThrownBy(() -> KeyManagerUtils.addClientIdentityRoute(keyManager, "another-server", "https://localhost:8443/"))
446                 .isInstanceOf(GenericKeyManagerException.class)
447                 .hasMessage("KeyManager should be an instance of: [nl.altindag.ssl.keymanager.CompositeX509ExtendedKeyManager], " +
448                             "but received: [sun.security.ssl.SunX509KeyManagerImpl]");
449     }
450 
451     @Test
452     void throwExceptionWhenUnsupportedKeyManagerIsProvidedWhenGettingClientIdentityRoute() {
453         KeyStore identity = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_FILE_NAME, IDENTITY_PASSWORD);
454         X509ExtendedKeyManager keyManager = KeyManagerUtils.createKeyManager(identity, IDENTITY_PASSWORD);
455 
456         assertThatThrownBy(() -> KeyManagerUtils.getClientIdentityRoute(keyManager))
457                 .isInstanceOf(GenericKeyManagerException.class)
458                 .hasMessage("KeyManager should be an instance of: [nl.altindag.ssl.keymanager.CompositeX509ExtendedKeyManager], " +
459                         "but received: [sun.security.ssl.SunX509KeyManagerImpl]");
460     }
461 
462 }