1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package nl.altindag.ssl;
18
19 import nl.altindag.ssl.exception.GenericKeyStoreException;
20 import nl.altindag.ssl.exception.GenericSecurityException;
21 import nl.altindag.ssl.model.IdentityMaterial;
22 import nl.altindag.ssl.model.KeyStoreHolder;
23 import nl.altindag.ssl.model.SSLMaterial;
24 import nl.altindag.ssl.model.TrustMaterial;
25 import nl.altindag.ssl.util.KeyManagerUtils;
26 import nl.altindag.ssl.util.KeyStoreUtils;
27 import nl.altindag.ssl.util.SSLContextUtils;
28 import nl.altindag.ssl.util.SSLParametersUtils;
29 import nl.altindag.ssl.util.SSLSessionUtils;
30 import nl.altindag.ssl.util.SSLSocketUtils;
31 import nl.altindag.ssl.util.StringUtils;
32 import nl.altindag.ssl.util.TrustManagerUtils;
33 import nl.altindag.ssl.util.UriUtils;
34 import org.slf4j.Logger;
35 import org.slf4j.LoggerFactory;
36
37 import javax.net.ssl.HostnameVerifier;
38 import javax.net.ssl.KeyManagerFactory;
39 import javax.net.ssl.SSLContext;
40 import javax.net.ssl.SSLEngine;
41 import javax.net.ssl.SSLParameters;
42 import javax.net.ssl.SSLServerSocketFactory;
43 import javax.net.ssl.SSLSocketFactory;
44 import javax.net.ssl.TrustManagerFactory;
45 import javax.net.ssl.X509ExtendedKeyManager;
46 import javax.net.ssl.X509ExtendedTrustManager;
47 import javax.net.ssl.X509KeyManager;
48 import javax.net.ssl.X509TrustManager;
49 import java.io.InputStream;
50 import java.net.URI;
51 import java.nio.file.Path;
52 import java.security.Key;
53 import java.security.KeyStore;
54 import java.security.Provider;
55 import java.security.SecureRandom;
56 import java.security.cert.Certificate;
57 import java.security.cert.X509Certificate;
58 import java.util.AbstractMap;
59 import java.util.ArrayList;
60 import java.util.Arrays;
61 import java.util.Collections;
62 import java.util.HashMap;
63 import java.util.List;
64 import java.util.Map;
65 import java.util.Optional;
66 import java.util.stream.Collectors;
67
68 import static java.util.Objects.isNull;
69 import static java.util.Objects.nonNull;
70
71
72
73
74 public final class SSLFactory {
75
76 private static final Logger LOGGER = LoggerFactory.getLogger(SSLFactory.class);
77
78 private final SSLMaterial sslMaterial;
79
80 private SSLFactory(SSLMaterial sslMaterial) {
81 this.sslMaterial = sslMaterial;
82 }
83
84 public List<KeyStoreHolder> getIdentities() {
85 return sslMaterial.getIdentityMaterial().getIdentities();
86 }
87
88 public List<KeyStoreHolder> getTrustStores() {
89 return sslMaterial.getTrustMaterial().getTrustStores();
90 }
91
92 public SSLContext getSslContext() {
93 return sslMaterial.getSslContext();
94 }
95
96 public SSLSocketFactory getSslSocketFactory() {
97 return SSLSocketUtils.createSslSocketFactory(sslMaterial.getSslContext(), getSslParameters());
98 }
99
100 public SSLServerSocketFactory getSslServerSocketFactory() {
101 return SSLSocketUtils.createSslServerSocketFactory(sslMaterial.getSslContext(), getSslParameters());
102 }
103
104 public Optional<X509ExtendedKeyManager> getKeyManager() {
105 return Optional.ofNullable(sslMaterial.getIdentityMaterial().getKeyManager());
106 }
107
108 public Optional<KeyManagerFactory> getKeyManagerFactory() {
109 return getKeyManager().map(KeyManagerUtils::createKeyManagerFactory);
110 }
111
112 public Optional<X509ExtendedTrustManager> getTrustManager() {
113 return Optional.ofNullable(sslMaterial.getTrustMaterial().getTrustManager());
114 }
115
116 public Optional<TrustManagerFactory> getTrustManagerFactory() {
117 return getTrustManager().map(TrustManagerUtils::createTrustManagerFactory);
118 }
119
120 public List<X509Certificate> getTrustedCertificates() {
121 return getTrustManager()
122 .map(X509ExtendedTrustManager::getAcceptedIssuers)
123 .flatMap(x509Certificates -> Optional.of(Arrays.asList(x509Certificates)))
124 .map(Collections::unmodifiableList)
125 .orElse(Collections.emptyList());
126 }
127
128 public HostnameVerifier getHostnameVerifier() {
129 return sslMaterial.getHostnameVerifier();
130 }
131
132 public List<String> getCiphers() {
133 return sslMaterial.getCiphers();
134 }
135
136 public List<String> getProtocols() {
137 return sslMaterial.getProtocols();
138 }
139
140 public SSLParameters getSslParameters() {
141 return SSLParametersUtils.copy(sslMaterial.getSslParameters());
142 }
143
144 public SSLEngine getSSLEngine() {
145 return getSSLEngine(null, null);
146 }
147
148 public SSLEngine getSSLEngine(String peerHost, Integer peerPort) {
149 SSLEngine sslEngine;
150 if (nonNull(peerHost) && nonNull(peerPort)) {
151 sslEngine = sslMaterial.getSslContext().createSSLEngine(peerHost, peerPort);
152 } else {
153 sslEngine = sslMaterial.getSslContext().createSSLEngine();
154 }
155
156 sslEngine.setSSLParameters(getSslParameters());
157 return sslEngine;
158 }
159
160 public static Builder builder() {
161 return new Builder();
162 }
163
164 public static class Builder {
165
166 private static final String TRUST_STORE_VALIDATION_EXCEPTION_MESSAGE = "TrustStore details are empty, which are required to be present when SSL/TLS is enabled";
167 private static final String IDENTITY_VALIDATION_EXCEPTION_MESSAGE = "Identity details are empty, which are required to be present when SSL/TLS is enabled";
168 private static final String IDENTITY_AND_TRUST_MATERIAL_VALIDATION_EXCEPTION_MESSAGE = "Could not create instance of SSLFactory because Identity " +
169 "and Trust material are not present. Please provide at least a Trust material.";
170
171 private static final char[] EMPTY_PASSWORD = {};
172
173 private String sslContextAlgorithm = "TLS";
174 private Provider securityProvider = null;
175 private String securityProviderName = null;
176 private SecureRandom secureRandom = null;
177 private HostnameVerifier hostnameVerifier = (host, sslSession) -> host.equalsIgnoreCase(sslSession.getPeerHost());
178
179 private final List<KeyStoreHolder> identities = new ArrayList<>();
180 private final List<KeyStoreHolder> trustStores = new ArrayList<>();
181 private final List<X509ExtendedKeyManager> identityManagers = new ArrayList<>();
182 private final List<X509ExtendedTrustManager> trustManagers = new ArrayList<>();
183 private final SSLParameters sslParameters = new SSLParameters();
184 private final Map<String, List<URI>> preferredClientAliasToHost = new HashMap<>();
185
186 private boolean passwordCachingEnabled = false;
187 private boolean swappableKeyManagerEnabled = false;
188 private boolean swappableTrustManagerEnabled = false;
189
190 private int sessionTimeoutInSeconds = -1;
191 private int sessionCacheSizeInBytes = -1;
192
193 private Builder() {}
194
195 public Builder withSystemTrustMaterial() {
196 TrustManagerUtils.createTrustManagerWithSystemTrustedCertificates().ifPresent(trustManagers::add);
197 return this;
198 }
199
200 public Builder withDefaultTrustMaterial() {
201 trustManagers.add(TrustManagerUtils.createTrustManagerWithJdkTrustedCertificates());
202 return this;
203 }
204
205
206
207
208
209
210
211
212 public Builder withSwappableTrustMaterial() {
213 swappableTrustManagerEnabled = true;
214 return this;
215 }
216
217 public <T extends X509TrustManager> Builder withTrustMaterial(T trustManager) {
218 trustManagers.add(TrustManagerUtils.wrapIfNeeded(trustManager));
219 return this;
220 }
221
222 public <T extends TrustManagerFactory> Builder withTrustMaterial(T trustManagerFactory) {
223 X509ExtendedTrustManager trustManager = TrustManagerUtils.getTrustManager(trustManagerFactory);
224 this.trustManagers.add(trustManager);
225 return this;
226 }
227
228 public Builder withTrustMaterial(String trustStorePath, char[] trustStorePassword) {
229 return withTrustMaterial(trustStorePath, trustStorePassword, KeyStore.getDefaultType());
230 }
231
232 public Builder withTrustMaterial(String trustStorePath, char[] trustStorePassword, String trustStoreType) {
233 if (StringUtils.isBlank(trustStorePath)) {
234 throw new GenericKeyStoreException(TRUST_STORE_VALIDATION_EXCEPTION_MESSAGE);
235 }
236
237 KeyStore trustStore = KeyStoreUtils.loadKeyStore(trustStorePath, trustStorePassword, trustStoreType);
238 KeyStoreHolder trustStoreHolder = new KeyStoreHolder(trustStore, trustStorePassword);
239 trustStores.add(trustStoreHolder);
240
241 return this;
242 }
243
244 public Builder withTrustMaterial(Path trustStorePath, char[] trustStorePassword) {
245 return withTrustMaterial(trustStorePath, trustStorePassword, KeyStore.getDefaultType());
246 }
247
248 public Builder withTrustMaterial(Path trustStorePath, char[] trustStorePassword, String trustStoreType) {
249 if (isNull(trustStorePath) || StringUtils.isBlank(trustStoreType)) {
250 throw new GenericKeyStoreException(TRUST_STORE_VALIDATION_EXCEPTION_MESSAGE);
251 }
252
253 KeyStore trustStore = KeyStoreUtils.loadKeyStore(trustStorePath, trustStorePassword, trustStoreType);
254 KeyStoreHolder trustStoreHolder = new KeyStoreHolder(trustStore, trustStorePassword);
255 trustStores.add(trustStoreHolder);
256
257 return this;
258 }
259
260 public Builder withTrustMaterial(InputStream trustStoreStream, char[] trustStorePassword) {
261 return withTrustMaterial(trustStoreStream, trustStorePassword, KeyStore.getDefaultType());
262 }
263
264 public Builder withTrustMaterial(InputStream trustStoreStream, char[] trustStorePassword, String trustStoreType) {
265 KeyStore trustStore = KeyStoreUtils.loadKeyStore(trustStoreStream, trustStorePassword, trustStoreType);
266 KeyStoreHolder trustStoreHolder = new KeyStoreHolder(trustStore, trustStorePassword);
267 trustStores.add(trustStoreHolder);
268 return this;
269 }
270
271 public Builder withTrustMaterial(KeyStore trustStore) {
272 withTrustMaterial(trustStore, EMPTY_PASSWORD);
273 return this;
274 }
275
276 public Builder withTrustMaterial(KeyStore trustStore, char[] trustStorePassword) {
277 validateKeyStore(trustStore, TRUST_STORE_VALIDATION_EXCEPTION_MESSAGE);
278 KeyStoreHolder trustStoreHolder = new KeyStoreHolder(trustStore, trustStorePassword);
279 trustStores.add(trustStoreHolder);
280
281 return this;
282 }
283
284 @SafeVarargs
285 public final <T extends Certificate> Builder withTrustMaterial(T... certificates) {
286 return withTrustMaterial(Arrays.asList(certificates));
287 }
288
289 public <T extends Certificate> Builder withTrustMaterial(List<T> certificates) {
290 KeyStore trustStore = KeyStoreUtils.createTrustStore(certificates);
291 KeyStoreHolder trustStoreHolder = new KeyStoreHolder(trustStore, KeyStoreUtils.DUMMY_PASSWORD.toCharArray());
292 trustStores.add(trustStoreHolder);
293 return this;
294 }
295
296 public Builder withIdentityMaterial(String identityStorePath, char[] identityStorePassword) {
297 return withIdentityMaterial(identityStorePath, identityStorePassword, identityStorePassword, KeyStore.getDefaultType());
298 }
299
300 public Builder withIdentityMaterial(String identityStorePath, char[] identityStorePassword, char[] identityPassword) {
301 return withIdentityMaterial(identityStorePath, identityStorePassword, identityPassword, KeyStore.getDefaultType());
302 }
303
304 public Builder withIdentityMaterial(String identityStorePath, char[] identityStorePassword, String identityStoreType) {
305 return withIdentityMaterial(identityStorePath, identityStorePassword, identityStorePassword, identityStoreType);
306 }
307
308 public Builder withIdentityMaterial(String identityStorePath, char[] identityStorePassword, char[] identityPassword, String identityStoreType) {
309 if (StringUtils.isBlank(identityStorePath) || StringUtils.isBlank(identityStoreType)) {
310 throw new GenericKeyStoreException(IDENTITY_VALIDATION_EXCEPTION_MESSAGE);
311 }
312
313 KeyStore identity = KeyStoreUtils.loadKeyStore(identityStorePath, identityStorePassword, identityStoreType);
314 KeyStoreHolder identityHolder = new KeyStoreHolder(identity, identityStorePassword, identityPassword);
315 identities.add(identityHolder);
316 return this;
317 }
318
319 public Builder withIdentityMaterial(Path identityStorePath, char[] identityStorePassword) {
320 return withIdentityMaterial(identityStorePath, identityStorePassword, identityStorePassword, KeyStore.getDefaultType());
321 }
322
323 public Builder withIdentityMaterial(Path identityStorePath, char[] identityStorePassword, char[] identityPassword) {
324 return withIdentityMaterial(identityStorePath, identityStorePassword, identityPassword, KeyStore.getDefaultType());
325 }
326
327 public Builder withIdentityMaterial(Path identityStorePath, char[] identityStorePassword, String identityStoreType) {
328 return withIdentityMaterial(identityStorePath, identityStorePassword, identityStorePassword, identityStoreType);
329 }
330
331 public Builder withIdentityMaterial(Path identityStorePath, char[] identityStorePassword, char[] identityPassword, String identityStoreType) {
332 if (isNull(identityStorePath) || StringUtils.isBlank(identityStoreType)) {
333 throw new GenericKeyStoreException(IDENTITY_VALIDATION_EXCEPTION_MESSAGE);
334 }
335
336 KeyStore identity = KeyStoreUtils.loadKeyStore(identityStorePath, identityStorePassword, identityStoreType);
337 KeyStoreHolder identityHolder = new KeyStoreHolder(identity, identityStorePassword, identityPassword);
338 identities.add(identityHolder);
339 return this;
340 }
341
342 public Builder withIdentityMaterial(InputStream identityStream, char[] identityStorePassword) {
343 return withIdentityMaterial(identityStream, identityStorePassword, identityStorePassword);
344 }
345
346 public Builder withIdentityMaterial(InputStream identityStream, char[] identityStorePassword, char[] identityPassword) {
347 return withIdentityMaterial(identityStream, identityStorePassword, identityPassword, KeyStore.getDefaultType());
348 }
349
350 public Builder withIdentityMaterial(InputStream identityStream, char[] identityStorePassword, String identityStoreType) {
351 return withIdentityMaterial(identityStream, identityStorePassword, identityStorePassword, identityStoreType);
352 }
353
354 public Builder withIdentityMaterial(InputStream identityStream, char[] identityStorePassword, char[] identityPassword, String identityStoreType) {
355 if (isNull(identityStream) || StringUtils.isBlank(identityStoreType)) {
356 throw new GenericKeyStoreException(IDENTITY_VALIDATION_EXCEPTION_MESSAGE);
357 }
358
359 KeyStore identity = KeyStoreUtils.loadKeyStore(identityStream, identityStorePassword, identityStoreType);
360 KeyStoreHolder identityHolder = new KeyStoreHolder(identity, identityStorePassword, identityPassword);
361 identities.add(identityHolder);
362 return this;
363 }
364
365 public Builder withIdentityMaterial(KeyStore identityStore, char[] identityStorePassword) {
366 return withIdentityMaterial(identityStore, identityStorePassword, identityStorePassword);
367 }
368
369 public Builder withIdentityMaterial(KeyStore identityStore, char[] identityStorePassword, char[] identityPassword) {
370 validateKeyStore(identityStore, IDENTITY_VALIDATION_EXCEPTION_MESSAGE);
371 KeyStoreHolder identityHolder = new KeyStoreHolder(identityStore, identityStorePassword, identityPassword);
372 identities.add(identityHolder);
373 return this;
374 }
375
376 public Builder withIdentityMaterial(Key privateKey, char[] privateKeyPassword, Certificate... certificateChain) {
377 return withIdentityMaterial(privateKey, privateKeyPassword, null, certificateChain);
378 }
379
380 public Builder withIdentityMaterial(Key privateKey, char[] privateKeyPassword, String alias, Certificate... certificateChain) {
381 KeyStore identityStore = KeyStoreUtils.createIdentityStore(privateKey, privateKeyPassword, alias, certificateChain);
382 identities.add(new KeyStoreHolder(identityStore, KeyStoreUtils.DUMMY_PASSWORD.toCharArray(), privateKeyPassword));
383 return this;
384 }
385
386 public <T extends X509KeyManager> Builder withIdentityMaterial(T keyManager) {
387 identityManagers.add(KeyManagerUtils.wrapIfNeeded(keyManager));
388 return this;
389 }
390
391 public <T extends KeyManagerFactory> Builder withIdentityMaterial(T keyManagerFactory) {
392 X509ExtendedKeyManager keyManager = KeyManagerUtils.getKeyManager(keyManagerFactory);
393 this.identityManagers.add(keyManager);
394 return this;
395 }
396
397
398
399
400
401
402
403
404 public Builder withSwappableIdentityMaterial() {
405 swappableKeyManagerEnabled = true;
406 return this;
407 }
408
409 private void validateKeyStore(KeyStore keyStore, String exceptionMessage) {
410 if (isNull(keyStore)) {
411 throw new GenericKeyStoreException(exceptionMessage);
412 }
413 }
414
415 public Builder withClientIdentityRoute(String clientAlias, String... hosts) {
416 return withClientIdentityRoute(
417 clientAlias,
418 Arrays.stream(hosts)
419 .map(URI::create)
420 .collect(Collectors.toList())
421 );
422 }
423
424 public Builder withClientIdentityRoute(Map<String, List<String>> clientAliasesToHosts) {
425 clientAliasesToHosts.entrySet().stream()
426 .map(clientAliasToHosts -> new AbstractMap.SimpleEntry<>(
427 clientAliasToHosts.getKey(),
428 clientAliasToHosts.getValue().stream()
429 .map(URI::create)
430 .collect(Collectors.toList())))
431 .forEach(clientAliasToHosts -> withClientIdentityRoute(clientAliasToHosts.getKey(), clientAliasToHosts.getValue()));
432 return this;
433 }
434
435 private Builder withClientIdentityRoute(String clientAlias, List<URI> hosts) {
436 if (StringUtils.isBlank(clientAlias)) {
437 throw new IllegalArgumentException("clientAlias should be present");
438 }
439
440 if (hosts.isEmpty()) {
441 throw new IllegalArgumentException(String.format("At least one host should be present. No host(s) found for the given alias: [%s]", clientAlias));
442 }
443
444 for (URI host : hosts) {
445 UriUtils.validate(host);
446
447 if (preferredClientAliasToHost.containsKey(clientAlias)) {
448 preferredClientAliasToHost.get(clientAlias).add(host);
449 } else {
450 preferredClientAliasToHost.put(clientAlias, new ArrayList<>(Collections.singletonList(host)));
451 }
452 }
453 return this;
454 }
455
456 public <T extends HostnameVerifier> Builder withHostnameVerifier(T hostnameVerifier) {
457 this.hostnameVerifier = hostnameVerifier;
458 return this;
459 }
460
461 public Builder withCiphers(String... ciphers) {
462 sslParameters.setCipherSuites(ciphers);
463 return this;
464 }
465
466 public Builder withProtocols(String... protocols) {
467 sslParameters.setProtocols(protocols);
468 return this;
469 }
470
471 public Builder withNeedClientAuthentication() {
472 return withNeedClientAuthentication(true);
473 }
474
475 public Builder withNeedClientAuthentication(boolean needClientAuthentication) {
476 sslParameters.setNeedClientAuth(needClientAuthentication);
477 return this;
478 }
479
480 public Builder withWantClientAuthentication() {
481 return withWantClientAuthentication(true);
482 }
483
484 public Builder withWantClientAuthentication(boolean wantClientAuthentication) {
485 sslParameters.setWantClientAuth(wantClientAuthentication);
486 return this;
487 }
488
489 public Builder withSessionTimeout(int timeoutInSeconds) {
490 this.sessionTimeoutInSeconds = timeoutInSeconds;
491 return this;
492 }
493
494 public Builder withSessionCacheSize(int cacheSizeInBytes) {
495 this.sessionCacheSizeInBytes = cacheSizeInBytes;
496 return this;
497 }
498
499 public Builder withSslContextAlgorithm(String sslContextAlgorithm) {
500 this.sslContextAlgorithm = sslContextAlgorithm;
501 return this;
502 }
503
504 public <T extends Provider> Builder withSecurityProvider(T securityProvider) {
505 this.securityProvider = securityProvider;
506 return this;
507 }
508
509 public Builder withSecurityProvider(String securityProviderName) {
510 this.securityProviderName = securityProviderName;
511 return this;
512 }
513
514 public <T extends SecureRandom> Builder withSecureRandom(T secureRandom) {
515 this.secureRandom = secureRandom;
516 return this;
517 }
518
519 public Builder withTrustingAllCertificatesWithoutValidation() {
520 LOGGER.warn("UnsafeTrustManager is being used. Client/Server certificates will be accepted without validation.");
521 trustManagers.add(TrustManagerUtils.createUnsafeTrustManager());
522 return this;
523 }
524
525 public Builder withPasswordCaching() {
526 passwordCachingEnabled = true;
527 return this;
528 }
529
530 public SSLFactory build() {
531 if (!isIdentityMaterialPresent() && !isTrustMaterialPresent()) {
532 throw new GenericSecurityException(IDENTITY_AND_TRUST_MATERIAL_VALIDATION_EXCEPTION_MESSAGE);
533 }
534
535 X509ExtendedKeyManager keyManager = isIdentityMaterialPresent() ? createKeyManager() : null;
536 X509ExtendedTrustManager trustManager = isTrustMaterialPresent() ? createTrustManagers() : null;
537 SSLContext sslContext = SSLContextUtils.createSslContext(
538 keyManager,
539 trustManager,
540 secureRandom,
541 sslContextAlgorithm,
542 securityProviderName,
543 securityProvider
544 );
545
546 if (sessionTimeoutInSeconds >= 0) {
547 SSLSessionUtils.updateSessionTimeout(sslContext, sessionTimeoutInSeconds);
548 }
549
550 if (sessionCacheSizeInBytes >= 0) {
551 SSLSessionUtils.updateSessionCacheSize(sslContext, sessionCacheSizeInBytes);
552 }
553
554 SSLParameters baseSslParameters = SSLParametersUtils.merge(sslParameters, sslContext.getDefaultSSLParameters());
555
556 if (!passwordCachingEnabled && !identities.isEmpty()) {
557 KeyStoreUtils.sanitizeKeyStores(identities);
558 }
559
560 if (!passwordCachingEnabled && !trustStores.isEmpty()) {
561 KeyStoreUtils.sanitizeKeyStores(trustStores);
562 }
563
564 IdentityMaterial identityMaterial = new IdentityMaterial.Builder()
565 .withKeyManager(keyManager)
566 .withIdentities(Collections.unmodifiableList(identities))
567 .build();
568
569 TrustMaterial trustMaterial = new TrustMaterial.Builder()
570 .withTrustManager(trustManager)
571 .withTrustStores(Collections.unmodifiableList(trustStores))
572 .build();
573
574 SSLMaterial sslMaterial = new SSLMaterial.Builder()
575 .withSslContext(sslContext)
576 .withIdentityMaterial(identityMaterial)
577 .withTrustMaterial(trustMaterial)
578 .withSslParameters(baseSslParameters)
579 .withHostnameVerifier(hostnameVerifier)
580 .withCiphers(Collections.unmodifiableList(Arrays.asList(baseSslParameters.getCipherSuites())))
581 .withProtocols(Collections.unmodifiableList(Arrays.asList(baseSslParameters.getProtocols())))
582 .build();
583
584 return new SSLFactory(sslMaterial);
585 }
586
587 private boolean isTrustMaterialPresent() {
588 return !trustStores.isEmpty()
589 || !trustManagers.isEmpty();
590 }
591
592 private boolean isIdentityMaterialPresent() {
593 return !identities.isEmpty()
594 || !identityManagers.isEmpty();
595 }
596
597 private X509ExtendedKeyManager createKeyManager() {
598 return KeyManagerUtils.keyManagerBuilder()
599 .withKeyManagers(identityManagers)
600 .withIdentities(identities)
601 .withSwappableKeyManager(swappableKeyManagerEnabled)
602 .withClientAliasToHost(preferredClientAliasToHost)
603 .build();
604 }
605
606 private X509ExtendedTrustManager createTrustManagers() {
607 return TrustManagerUtils.trustManagerBuilder()
608 .withTrustManagers(trustManagers)
609 .withTrustStores(trustStores.stream()
610 .map(KeyStoreHolder::getKeyStore)
611 .collect(Collectors.toList()))
612 .withSwappableTrustManager(swappableTrustManagerEnabled)
613 .build();
614 }
615
616 }
617 }