001/* 002 * Copyright 2008-2024 Ping Identity Corporation 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright 2008-2024 Ping Identity Corporation 007 * 008 * Licensed under the Apache License, Version 2.0 (the "License"); 009 * you may not use this file except in compliance with the License. 010 * You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, software 015 * distributed under the License is distributed on an "AS IS" BASIS, 016 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 017 * See the License for the specific language governing permissions and 018 * limitations under the License. 019 */ 020/* 021 * Copyright (C) 2008-2024 Ping Identity Corporation 022 * 023 * This program is free software; you can redistribute it and/or modify 024 * it under the terms of the GNU General Public License (GPLv2 only) 025 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only) 026 * as published by the Free Software Foundation. 027 * 028 * This program is distributed in the hope that it will be useful, 029 * but WITHOUT ANY WARRANTY; without even the implied warranty of 030 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 031 * GNU General Public License for more details. 032 * 033 * You should have received a copy of the GNU General Public License 034 * along with this program; if not, see <http://www.gnu.org/licenses>. 035 */ 036package com.unboundid.util.ssl; 037 038 039 040import java.io.IOException; 041import java.net.ServerSocket; 042import java.net.Socket; 043import java.security.GeneralSecurityException; 044import java.security.Provider; 045import java.security.cert.X509Certificate; 046import java.util.ArrayList; 047import java.util.Arrays; 048import java.util.Collection; 049import java.util.Collections; 050import java.util.Iterator; 051import java.util.LinkedHashSet; 052import java.util.Set; 053import java.util.StringTokenizer; 054import java.util.concurrent.atomic.AtomicReference; 055import javax.net.ssl.KeyManager; 056import javax.net.ssl.SSLContext; 057import javax.net.ssl.SSLServerSocket; 058import javax.net.ssl.SSLSocket; 059import javax.net.ssl.SSLSocketFactory; 060import javax.net.ssl.SSLServerSocketFactory; 061import javax.net.ssl.TrustManager; 062import javax.security.auth.x500.X500Principal; 063 064import com.unboundid.ldap.sdk.LDAPException; 065import com.unboundid.ldap.sdk.ResultCode; 066import com.unboundid.util.CryptoHelper; 067import com.unboundid.util.Debug; 068import com.unboundid.util.NotNull; 069import com.unboundid.util.Nullable; 070import com.unboundid.util.PropertyManager; 071import com.unboundid.util.StaticUtils; 072import com.unboundid.util.ThreadLocalSecureRandom; 073import com.unboundid.util.ThreadSafety; 074import com.unboundid.util.ThreadSafetyLevel; 075import com.unboundid.util.Validator; 076 077import static com.unboundid.util.ssl.SSLMessages.*; 078 079 080 081/** 082 * This class provides a relatively simple interface for helping to configure 083 * secure communication using TLS (formerly known as SSL) and StartTLS (which 084 * uses an LDAP extended operation to convert an already-established non-secure 085 * connection to one that uses TLS security). When establishing secure 086 * connections, there are five main concepts to be aware of: 087 * <UL> 088 * <LI>The allowed set of TLS protocol versions</LI> 089 * <LI>The allowed set of TLS cipher suites</LI> 090 * <LI>The key manager (if any) to use for obtaining local certificates</LI> 091 * <LI>The trust manager to use for determining whether to trust peer 092 * certificates</LI> 093 * <LI>The logic used to validate certificate hostnames</LI> 094 * </UL> 095 * Each of these is covered in more detail below. 096 * <BR><BR> 097 * <H2>TLS Protocol Versions</H2> 098 * The TLS protocol has evolved over time to improve both security and 099 * efficiency, and each update to the protocol has been assigned a version 100 * number. At present, only TLSv1.3 and TLSv1.2 are considered secure, and only 101 * those versions will be enabled by default, with TLSv1.3 preferred over 102 * TLSv1.2. Note that some older JVMs do not support TLSv1.3, and only TLSv1.2 103 * will be enabled by default in that case. In the very unlikely event that the 104 * JVM does not support either TLSv1.3 or TLSv1.2, the LDAP SDK may fall back to 105 * enabling support for TLSv1.1 or TLSv1. 106 * <BR><BR> 107 * If you want or need to explicitly specify the TLS protocol versions to use 108 * for secure communication, then you may use the 109 * {@link #setEnabledSSLProtocols} method to indicate which protocol versions 110 * are allowed, and the {@link #setDefaultSSLProtocol} method to indicate which 111 * is the preferred protocol version. You can use any TLS protocol version that 112 * the underlying JVM supports. 113 * <BR><BR> 114 * It is also possible to specify the set of enabled and default TLS protocol 115 * versions using Java system properties. The 116 * {@code com.unboundid.util.SSLUtil.enabledSSLProtocols} property may be set 117 * with a comma-delimited list of the TLS protocol versions that should be 118 * enabled by default, and the 119 * {@code com.unboundid.util.SSLUtil.defaultSSLProtocol} property may be set 120 * with the protocol version that should be preferred. If set, these properties 121 * will override the logic that the LDAP SDK automatically uses to select 122 * default values, but those defaults may be explicitly overridden by calls to 123 * the {@code setEnabledSSLProtocols} and {@code setDefaultSSLProtocol} methods. 124 * <BR><BR> 125 * <H2>TLS Cipher Suites</H2> 126 * A cipher suite encapsulates a number of settings that will be used to 127 * actually secure TLS communication between two systems, including which 128 * algorithm to use for key exchange, which algorithm to use for bulk 129 * encryption, and which algorithm to use for integrity protection. The JVM 130 * supports a fixed set of TLS cipher suites, although it may only enable 131 * support for a subset of those by default, and the LDAP SDK may further 132 * disable support for some of those suites by default for security reasons. 133 * The logic that the LDAP SDK uses to select a good default set of TLS cipher 134 * suites is encapsulated in the {@link TLSCipherSuiteSelector} class, and the 135 * class-level documentation for that class describes the criteria that it uses 136 * to make its selection. 137 * <BR><BR> 138 * If you wish to override the LDAP SDK's default selection, you may use the 139 * {@link #setEnabledSSLCipherSuites} method to explicitly specify the set of 140 * cipher suites that should be enabled. Alternatively, the 141 * {@code com.unboundid.util.SSLUtil.enabledSSLCipherSuites} system property may 142 * be set with a comma-delimited list of the cipher suites that should be 143 * enabled. 144 * <BR><BR> 145 * <H2>Key Managers</H2> 146 * A key manager is used to obtain access to a certificate chain and private key 147 * that should be presented to the peer during TLS negotiation. In the most 148 * common use cases, in which the LDAP SDK is used only to establish outbound 149 * connections and does not need to use a certificate to authenticate itself to 150 * the LDAP server, there won't be any need to present a certificate chain, and 151 * there won't be any need to configure a key manager. However, if you are 152 * using the LDAP SDK to accept TLS-secured connections from LDAP clients (for 153 * example, using the 154 * {@link com.unboundid.ldap.listener.InMemoryDirectoryServer} or 155 * another type of {@link com.unboundid.ldap.listener.LDAPListener}), if the 156 * server requires clients to present their own certificate for mutual TLS 157 * authentication, or if you want to use the SASL EXTERNAL mechanism to use a 158 * client certificate to authenticate to the server at the LDAP layer, then you 159 * will need to specify a key manager to provide access to that certificate 160 * chain. The key manager to use for that purpose should be provided in the 161 * {@code SSLUtil} constructor. 162 * <BR><BR> 163 * While any {@code javax.net.ssl.KeyManager} instance can be used, the LDAP SDK 164 * provides three options that will be sufficient for most use cases: 165 * <UL> 166 * <LI>{@link KeyStoreKeyManager} -- Allows the certificate chain and private 167 * key to be obtained from a key store file, which will typically be in 168 * the JKS or PKCS #12 format (or in the Bouncy Castle BCFKS format when 169 * using the LDAP SDK in FIPS-compliant mode).</LI> 170 * <LI>{@link PEMFileKeyManager} -- Allows the certificate chain and private 171 * key to be obtained from text files that contain the PEM-encoded 172 * representation of X.509 certificates and a PKCS #8 private key.</LI> 173 * <LI>{@link PKCS11KeyManager} -- Allows the certificate chain and private 174 * key to be accessed from a PKCS #11 token, like a hardware security 175 * module (HSM).</LI> 176 * </UL> 177 * <BR><BR> 178 * <H2>Trust Managers</H2> 179 * A trust manager is used to determine whether to trust a certificate chain 180 * presented by a peer during TLS negotiation. Trust is a very important aspect 181 * of TLS because it's important to make sure that the peer you're communicating 182 * with is actually who you intend it to be and not someone else who has managed 183 * to hijack the negotiation process. 184 * <BR><BR> 185 * You will generally always want to provide a trust manager, regardless of 186 * whether you're using the LDAP SDK to act as a client or a server, and this 187 * trust manager should be provided in the {@code SSLUtil} constructor. The 188 * LDAP SDK offers several trust manager implementations, including: 189 * <UL> 190 * <LI>{@link JVMDefaultTrustManager} -- Uses the JVM's default 191 * {@code cacerts} trust store to obtain access to a set of trusted, 192 * well-known issuer certificates, including those from commercial 193 * certification authorities like Verisign or DigiCert, and from trusted 194 * free providers like Let's Encrypt. This trust manager will only accept 195 * valid certificates that have been signed by one of those trusted 196 * authorities.</LI> 197 * <LI>{@link TrustStoreTrustManager} -- Uses the information in a trust store 198 * file (typically in a format like JKS, PKCS #12 or BCFKS) as a set of 199 * trusted certificates and issuers.</LI> 200 * <LI>{@link PEMFileTrustManager} -- Uses the information one or more files 201 * containing the PEM representations of X.509 certificates as a set of 202 * trusted certificates and issuers.</LI> 203 * <LI>{@link com.unboundid.ldap.sdk.unboundidds.TopologyRegistryTrustManager} 204 * -- Uses the topology registry information in the configuration of a 205 * Ping Identity Directory Server (or related server product) to obtain a 206 * set of trusted certificates and issuers.</LI> 207 * <LI>{@link PromptTrustManager} -- Interactively prompts the user (via the 208 * terminal) to determine whether the presented certificate chain should 209 * be trusted.</LI> 210 * <LI>{@link TrustAllTrustManager} -- Blindly trusts all certificate chains 211 * that are presented to it. This may be convenient in some cases for 212 * testing purposes, but it is strongly discouraged for production use 213 * because it does not actually perform any real trust processing and will 214 * allow connecting to unintended or malicious peers.</LI> 215 * <LI>{@link AggregateTrustManager} -- Allows you to combine multiple other 216 * trust managers in the course of determining whether to trust a 217 * presented certificate chain. For example, you may use this to 218 * automatically trust certificates signed by an issuer in the JVM's 219 * {@code cacerts} file or in an explicitly specified alternative trust 220 * store file, but to fall back to interactively prompting the user for 221 * certificates not trusted by one of the previous two methods.</LI> 222 * </UL> 223 * <BR><BR> 224 * <H2>Certificate Hostname Validation</H2> 225 * Trust managers can be used to ensure that a certificate chain presented by a 226 * peer originally came from a trusted source, but that doesn't necessarily mean 227 * that the peer system is the one you intend it to be. It's not at all 228 * difficult for malicious users and applications to obtain a certificate that 229 * is signed by a CA in the JVM's default set of trusted issuers. However, any 230 * certificate signed by one of those trusted issuers will include information 231 * in a subject alternative name extension that specifies the hostnames (or at 232 * least domain names) and IP addresses for systems with which that certificate 233 * is allowed to be used, and those issues are careful to verify that they only 234 * issue certificates to systems that are legitimately associated with those 235 * systems. So while a malicious user may be able to easily get a certificate 236 * from a trusted issuer, it should not be possible for them to get a 237 * certificate with a subject alternative name extension containing addresses 238 * they don't legitimately have the right to use. 239 * <BR><BR> 240 * Because of this, it's very important that clients not only verify that the 241 * server's certificate comes from a trusted source, but also that it's allowed 242 * to be used by that server system. This additional level of validation can 243 * help thwart attacks that rely on DNS hijacking or other methods of diverting 244 * communication away from the intended recipient to one that an attacker 245 * controls instead. The LDAP SDK does not perform this validation by default 246 * because there are unfortunately too many cases in which clients (especially 247 * those used in testing and development environments) might need to interact 248 * with a server whose certificate may not have an appropriate subject 249 * alternative name extension. However, in production environments with a 250 * properly configured TLS certificate, hostname verification can be enabled by 251 * calling the 252 * {@link com.unboundid.ldap.sdk.LDAPConnectionOptions#setSSLSocketVerifier} 253 * method with an instance of the {@link HostNameSSLSocketVerifier}. 254 * Alternatively, you can set the {@code com.unboundid.ldap.sdk. 255 * LDAPConnectionOptions.defaultVerifyCertificateHostnames} system property with 256 * a value of "{@code true}" to enable this validation by default. 257 * <BR><BR> 258 * <H2>Examples</H2> 259 * The following example demonstrates the process for establish a secure client 260 * connection. It relies on the LDAP SDK's default configuration for selecting 261 * TLS protocols and cipher suites, and does not use a key manager. It uses an 262 * aggregate trust manager to automatically trust any certificates signed by one 263 * of the JVM's default trusted issuers or an issuer in an explicitly specified 264 * key store file, and it enables host name validation. 265 * <BR><BR> 266 * <PRE> 267 * AggregateTrustManager trustManager = new AggregateTrustManager(false, 268 * JVMDefaultTrustManager.getInstance(), 269 * new TrustStoreTrustManager(trustStorePath, trustStorePIN, 270 * "PKCS12", true)); 271 * SSLUtil sslUtil = new SSLUtil(trustManager); 272 * 273 * LDAPConnectionOptions connectionOptions = new LDAPConnectionOptions(); 274 * connectionOptions.setSSLSocketVerifier( 275 * new HostNameSSLSocketVerifier(true)); 276 * 277 * try (LDAPConnection connection = new LDAPConnection( 278 * sslUtil.createSSLSocketFactory(), connectionOptions, 279 * serverAddress, serverLDAPSPort)) 280 * { 281 * // Use the connection here. 282 * RootDSE rootDSE = connection.getRootDSE(); 283 * } 284 * </PRE> 285 * <BR><BR> 286 * The above example establishes an LDAPS connection that is secured by TLS as 287 * soon as it is created. The following example shows the process needed to use 288 * the StartTLS extended operation to secure an already-established non-secure 289 * connection: 290 * <BR><BR> 291 * <PRE> 292 * AggregateTrustManager trustManager = new AggregateTrustManager(false, 293 * JVMDefaultTrustManager.getInstance(), 294 * new TrustStoreTrustManager(trustStorePath, trustStorePIN, 295 * "PKCS12", true)); 296 * SSLUtil sslUtil = new SSLUtil(trustManager); 297 * 298 * LDAPConnectionOptions connectionOptions = new LDAPConnectionOptions(); 299 * connectionOptions.setSSLSocketVerifier( 300 * new HostNameSSLSocketVerifier(true)); 301 * 302 * try (LDAPConnection connection = new LDAPConnection( 303 * connectionOptions, serverAddress, serverLDAPPort)) 304 * { 305 * // Use the StartTLS extended operation to secure the connection. 306 * ExtendedResult startTLSResult; 307 * try 308 * { 309 * startTLSResult = connection.processExtendedOperation( 310 * new StartTLSExtendedRequest( 311 * sslUtil.createSSLSocketFactory())); 312 * } 313 * catch (LDAPException e) 314 * { 315 * Debug.debugException(e); 316 * startTLSResult = new ExtendedResult(e); 317 * } 318 * LDAPTestUtils.assertResultCodeEquals(startTLSResult, 319 * ResultCode.SUCCESS); 320 * 321 * // Use the connection here. 322 * RootDSE rootDSE = connection.getRootDSE(); 323 * } 324 * </PRE> 325 */ 326@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE) 327public final class SSLUtil 328{ 329 /** 330 * The name of a system property 331 * (com.unboundid.util.SSLUtil.defaultSSLProtocol) that can be used to specify 332 * the initial value for the default SSL protocol that should be used. If 333 * this is not set, then the default SSL protocol will be dynamically 334 * determined. This can be overridden via the 335 * {@link #setDefaultSSLProtocol(String)} method. 336 */ 337 @NotNull public static final String PROPERTY_DEFAULT_SSL_PROTOCOL = 338 "com.unboundid.util.SSLUtil.defaultSSLProtocol"; 339 340 341 342 /** 343 * The name of a system property 344 * (com.unboundid.util.SSLUtil.enabledSSLProtocols) that can be used to 345 * provide the initial set of enabled SSL protocols that should be used, as a 346 * comma-delimited list. If this is not set, then the enabled SSL protocols 347 * will be dynamically determined. This can be overridden via the 348 * {@link #setEnabledSSLProtocols(Collection)} method. 349 */ 350 @NotNull public static final String PROPERTY_ENABLED_SSL_PROTOCOLS = 351 "com.unboundid.util.SSLUtil.enabledSSLProtocols"; 352 353 354 355 /** 356 * The name of a system property 357 * (com.unboundid.util.SSLUtil.enabledSSLCipherSuites) that can be used to 358 * provide the initial set of enabled SSL cipher suites that should be used, 359 * as a comma-delimited list. If this is not set, then the enabled SSL cipher 360 * suites will be dynamically determined using the 361 * {@link TLSCipherSuiteSelector}. This can be overridden via the 362 * {@link #setEnabledSSLCipherSuites(Collection)} method. 363 */ 364 @NotNull public static final String PROPERTY_ENABLED_SSL_CIPHER_SUITES = 365 "com.unboundid.util.SSLUtil.enabledSSLCipherSuites"; 366 367 368 369 /** 370 * The name of the SSL protocol that can be used to request TLSv1.3. 371 */ 372 @NotNull public static final String SSL_PROTOCOL_TLS_1_3 = "TLSv1.3"; 373 374 375 376 /** 377 * The name of the SSL protocol that can be used to request TLSv1.2. 378 */ 379 @NotNull public static final String SSL_PROTOCOL_TLS_1_2 = "TLSv1.2"; 380 381 382 383 /** 384 * The name of the SSL protocol that can be used to request TLSv1.1. 385 */ 386 @NotNull public static final String SSL_PROTOCOL_TLS_1_1 = "TLSv1.1"; 387 388 389 390 /** 391 * The name of the SSL protocol that can be used to request TLSv1. 392 */ 393 @NotNull public static final String SSL_PROTOCOL_TLS_1 = "TLSv1"; 394 395 396 397 /** 398 * The name of the SSL protocol that can be used to request SSLv3. 399 */ 400 @NotNull public static final String SSL_PROTOCOL_SSL_3 = "SSLv3"; 401 402 403 404 /** 405 * The name of the SSL protocol that can be used to request SSLv2Hello. 406 */ 407 @NotNull public static final String SSL_PROTOCOL_SSL_2_HELLO = "SSLv2Hello"; 408 409 410 411 /** 412 * The default protocol string that will be used to create SSL contexts when 413 * no explicit protocol is specified. 414 */ 415 @NotNull private static final AtomicReference<String> DEFAULT_SSL_PROTOCOL = 416 new AtomicReference<>(SSL_PROTOCOL_TLS_1_2); 417 418 419 420 /** 421 * The default set of SSL cipher suites that will be enabled for use if 422 * available for SSL sockets created within the LDAP SDK. 423 */ 424 @NotNull private static final AtomicReference<Set<String>> 425 ENABLED_SSL_CIPHER_SUITES = new AtomicReference<>( 426 (Set<String>) new LinkedHashSet<>( 427 TLSCipherSuiteSelector.getRecommendedCipherSuites())); 428 429 430 431 /** 432 * The default set of SSL protocols that will be enabled for use if available 433 * for SSL sockets created within the LDAP SDK. 434 */ 435 @NotNull private static final AtomicReference<Set<String>> 436 ENABLED_SSL_PROTOCOLS = new AtomicReference<>( 437 StaticUtils.setOf(SSL_PROTOCOL_TLS_1_2)); 438 439 440 441 /** 442 * The name of the service type that providers use to indicate the 443 * {@code SSLContext} algorithms that they support. 444 */ 445 @NotNull static final String PROVIDER_SERVICE_TYPE_SSL_CONTEXT = 446 "SSLContext"; 447 448 449 450 /** 451 * Indicates whether SSL/TLS debugging is expected to be enabled, based on 452 * the javax.net.debug system property. 453 */ 454 private static final boolean JVM_SSL_DEBUGGING_ENABLED = 455 TLSCipherSuiteSelector.jvmSSLDebuggingEnabled(); 456 457 458 459 static 460 { 461 configureSSLDefaults(); 462 } 463 464 465 466 // Indicates whether any of the provided key managers is a PKCS #11 key 467 // manager. 468 private final boolean usingPKCS11KeyManager; 469 470 // The set of key managers to be used. 471 @Nullable private final KeyManager[] keyManagers; 472 473 // The set of trust managers to be used. 474 @Nullable private final TrustManager[] trustManagers; 475 476 477 478 /** 479 * Creates a new SSLUtil instance that will not have a custom key manager or 480 * trust manager. It will not be able to provide a certificate to the server 481 * if one is requested, and it will only trust certificates signed by a 482 * predefined set of authorities. 483 */ 484 public SSLUtil() 485 { 486 keyManagers = null; 487 trustManagers = null; 488 usingPKCS11KeyManager = false; 489 } 490 491 492 493 /** 494 * Creates a new SSLUtil instance that will use the provided trust manager to 495 * determine whether to trust server certificates presented to the client. 496 * It will not be able to provide a certificate to the server if one is 497 * requested. 498 * 499 * @param trustManager The trust manager to use to determine whether to 500 * trust server certificates presented to the client. 501 * It may be {@code null} if the default set of trust 502 * managers should be used. 503 */ 504 public SSLUtil(@Nullable final TrustManager trustManager) 505 { 506 keyManagers = null; 507 usingPKCS11KeyManager = false; 508 509 if (trustManager == null) 510 { 511 trustManagers = null; 512 } 513 else 514 { 515 trustManagers = new TrustManager[] { trustManager }; 516 } 517 } 518 519 520 521 /** 522 * Creates a new SSLUtil instance that will use the provided trust managers 523 * to determine whether to trust server certificates presented to the client. 524 * It will not be able to provide a certificate to the server if one is 525 * requested. 526 * 527 * @param trustManagers The set of trust managers to use to determine 528 * whether to trust server certificates presented to 529 * the client. It may be {@code null} or empty if the 530 * default set of trust managers should be used. 531 */ 532 public SSLUtil(@Nullable final TrustManager[] trustManagers) 533 { 534 keyManagers = null; 535 usingPKCS11KeyManager = false; 536 537 if ((trustManagers == null) || (trustManagers.length == 0)) 538 { 539 this.trustManagers = null; 540 } 541 else 542 { 543 this.trustManagers = trustManagers; 544 } 545 } 546 547 548 549 /** 550 * Creates a new SSLUtil instance that will use the provided key manager to 551 * obtain certificates to present to the server, and the provided trust 552 * manager to determine whether to trust server certificates presented to the 553 * client. 554 * 555 * @param keyManager The key manager to use to obtain certificates to 556 * present to the server if requested. It may be 557 * {@code null} if no client certificates will be 558 * required or should be provided. 559 * @param trustManager The trust manager to use to determine whether to 560 * trust server certificates presented to the client. 561 * It may be {@code null} if the default set of trust 562 * managers should be used. 563 */ 564 public SSLUtil(@Nullable final KeyManager keyManager, 565 @Nullable final TrustManager trustManager) 566 { 567 if (keyManager == null) 568 { 569 keyManagers = null; 570 usingPKCS11KeyManager = false; 571 } 572 else 573 { 574 keyManagers = new KeyManager[] { keyManager }; 575 usingPKCS11KeyManager = (keyManager instanceof PKCS11KeyManager); 576 } 577 578 if (trustManager == null) 579 { 580 trustManagers = null; 581 } 582 else 583 { 584 trustManagers = new TrustManager[] { trustManager }; 585 } 586 } 587 588 589 590 /** 591 * Creates a new SSLUtil instance that will use the provided key managers to 592 * obtain certificates to present to the server, and the provided trust 593 * managers to determine whether to trust server certificates presented to the 594 * client. 595 * 596 * @param keyManagers The set of key managers to use to obtain 597 * certificates to present to the server if requested. 598 * It may be {@code null} or empty if no client 599 * certificates will be required or should be provided. 600 * @param trustManagers The set of trust managers to use to determine 601 * whether to trust server certificates presented to 602 * the client. It may be {@code null} or empty if the 603 * default set of trust managers should be used. 604 */ 605 public SSLUtil(@Nullable final KeyManager[] keyManagers, 606 @Nullable final TrustManager[] trustManagers) 607 { 608 if ((keyManagers == null) || (keyManagers.length == 0)) 609 { 610 this.keyManagers = null; 611 usingPKCS11KeyManager = false; 612 } 613 else 614 { 615 this.keyManagers = keyManagers; 616 617 boolean usingPKCS11 = false; 618 for (final KeyManager km : keyManagers) 619 { 620 if (km instanceof PKCS11KeyManager) 621 { 622 usingPKCS11 = true; 623 break; 624 } 625 } 626 627 usingPKCS11KeyManager = usingPKCS11; 628 } 629 630 if ((trustManagers == null) || (trustManagers.length == 0)) 631 { 632 this.trustManagers = null; 633 } 634 else 635 { 636 this.trustManagers = trustManagers; 637 } 638 } 639 640 641 642 /** 643 * Retrieves the set of key managers configured for use by this class, if any. 644 * 645 * @return The set of key managers configured for use by this class, or 646 * {@code null} if none were provided. 647 */ 648 @Nullable() 649 public KeyManager[] getKeyManagers() 650 { 651 return keyManagers; 652 } 653 654 655 656 /** 657 * Retrieves the set of trust managers configured for use by this class, if 658 * any. 659 * 660 * @return The set of trust managers configured for use by this class, or 661 * {@code null} if none were provided. 662 */ 663 @Nullable() 664 public TrustManager[] getTrustManagers() 665 { 666 return trustManagers; 667 } 668 669 670 671 /** 672 * Creates an initialized SSL context created with the configured key and 673 * trust managers. It will use the protocol returned by the 674 * {@link #getDefaultSSLProtocol} method and the JVM-default provider. 675 * 676 * @return The created SSL context. 677 * 678 * @throws GeneralSecurityException If a problem occurs while creating or 679 * initializing the SSL context. 680 */ 681 @NotNull() 682 public SSLContext createSSLContext() 683 throws GeneralSecurityException 684 { 685 return createSSLContext(DEFAULT_SSL_PROTOCOL.get()); 686 } 687 688 689 690 /** 691 * Creates an initialized SSL context created with the configured key and 692 * trust managers. It will use a default provider. 693 * 694 * @param protocol The SSL protocol to use. The Java Secure Socket 695 * Extension (JSSE) Reference Guide provides a list of the 696 * supported protocols, but commonly used values are 697 * "TLSv1.3", "TLSv1.2", "TLSv1.1", and "TLSv1". This must 698 * not be {@code null}. 699 * 700 * 701 * @return The created SSL context. 702 * 703 * @throws GeneralSecurityException If a problem occurs while creating or 704 * initializing the SSL context. 705 */ 706 @NotNull() 707 public SSLContext createSSLContext(@NotNull final String protocol) 708 throws GeneralSecurityException 709 { 710 Validator.ensureNotNull(protocol); 711 712 SSLContext sslContext = null; 713 if (usingPKCS11KeyManager) 714 { 715 final Provider pkcs11JSSEProvider = 716 PKCS11KeyManager.getPKCS11JSSESProvider(); 717 if ((pkcs11JSSEProvider != null) && (pkcs11JSSEProvider.getService( 718 PROVIDER_SERVICE_TYPE_SSL_CONTEXT, protocol) != null)) 719 { 720 if (JVM_SSL_DEBUGGING_ENABLED) 721 { 722 System.err.println("SSLUtil.createSSLContext creating a PKCS #11 " + 723 "SSLContext for protocol " + protocol); 724 } 725 726 sslContext = CryptoHelper.getSSLContext(protocol, pkcs11JSSEProvider); 727 } 728 } 729 730 if (sslContext == null) 731 { 732 if (JVM_SSL_DEBUGGING_ENABLED) 733 { 734 System.err.println("SSLUtil.createSSLContext creating an SSLContext " + 735 "for protocol " + protocol); 736 } 737 738 sslContext = CryptoHelper.getSSLContext(protocol); 739 } 740 741 sslContext.init(keyManagers, trustManagers, ThreadLocalSecureRandom.get()); 742 return sslContext; 743 } 744 745 746 747 /** 748 * Creates an initialized SSL context created with the configured key and 749 * trust managers. 750 * 751 * @param protocol The SSL protocol to use. The Java Secure Socket 752 * Extension (JSSE) Reference Guide provides a list of the 753 * supported protocols, but commonly used values are 754 * "TLSv1.3", "TLSv1.2", "TLSv1.1", and "TLSv1". This must 755 * not be {@code null}. 756 * @param provider The name of the provider to use for cryptographic 757 * operations. It must not be {@code null}. 758 * 759 * @return The created SSL context. 760 * 761 * @throws GeneralSecurityException If a problem occurs while creating or 762 * initializing the SSL context. 763 */ 764 @NotNull() 765 public SSLContext createSSLContext(@NotNull final String protocol, 766 @NotNull final String provider) 767 throws GeneralSecurityException 768 { 769 Validator.ensureNotNull(protocol, provider); 770 771 if (JVM_SSL_DEBUGGING_ENABLED) 772 { 773 System.err.println("SSLUtil.createSSLContext creating an SSLContext " + 774 "for protocol " + protocol + " and provider " + provider); 775 } 776 777 final SSLContext sslContext = 778 CryptoHelper.getSSLContext(protocol, provider); 779 sslContext.init(keyManagers, trustManagers, null); 780 return sslContext; 781 } 782 783 784 785 /** 786 * Creates an SSL socket factory using the configured key and trust manager 787 * providers. It will use the protocol returned by the 788 * {@link #getDefaultSSLProtocol} method and the JVM-default provider. 789 * 790 * @return The created SSL socket factory. 791 * 792 * @throws GeneralSecurityException If a problem occurs while creating or 793 * initializing the SSL socket factory. 794 */ 795 @NotNull() 796 public SSLSocketFactory createSSLSocketFactory() 797 throws GeneralSecurityException 798 { 799 if (JVM_SSL_DEBUGGING_ENABLED) 800 { 801 System.err.println("SSLUtil.createSSLSocketFactory creating a " + 802 "SetEnabledProtocolsAndCipherSuitesSSLSocketFactory with enabled " + 803 "protocols " + ENABLED_SSL_PROTOCOLS.get() + 804 " and enabled cipher suites " + ENABLED_SSL_CIPHER_SUITES.get()); 805 } 806 807 return new SetEnabledProtocolsAndCipherSuitesSSLSocketFactory( 808 createSSLContext().getSocketFactory(), 809 ENABLED_SSL_PROTOCOLS.get(), ENABLED_SSL_CIPHER_SUITES.get()); 810 } 811 812 813 814 /** 815 * Creates an SSL socket factory with the configured key and trust managers. 816 * It will use the default provider. 817 * 818 * @param protocol The SSL protocol to use. The Java Secure Socket 819 * Extension (JSSE) Reference Guide provides a list of the 820 * supported protocols, but commonly used values are 821 * "TLSv1.3", "TLSv1.2", "TLSv1.1", and "TLSv1". This must 822 * not be {@code null}. 823 * 824 * @return The created SSL socket factory. 825 * 826 * @throws GeneralSecurityException If a problem occurs while creating or 827 * initializing the SSL socket factory. 828 */ 829 @NotNull() 830 public SSLSocketFactory createSSLSocketFactory( 831 @NotNull final String protocol) 832 throws GeneralSecurityException 833 { 834 if (JVM_SSL_DEBUGGING_ENABLED) 835 { 836 System.err.println("SSLUtil.createSSLSocketFactory creating a " + 837 "SetEnabledProtocolsAndCipherSuitesSSLSocketFactory with protocol " + 838 protocol + " and enabled cipher suites " + 839 ENABLED_SSL_CIPHER_SUITES.get()); 840 } 841 842 return new SetEnabledProtocolsAndCipherSuitesSSLSocketFactory( 843 createSSLContext(protocol).getSocketFactory(), protocol, 844 ENABLED_SSL_CIPHER_SUITES.get()); 845 } 846 847 848 849 /** 850 * Creates an SSL socket factory with the configured key and trust managers. 851 * 852 * @param protocol The SSL protocol to use. The Java Secure Socket 853 * Extension (JSSE) Reference Guide provides a list of the 854 * supported protocols, but commonly used values are 855 * "TLSv1.3", "TLSv1.2", "TLSv1.1", and "TLSv1". This must 856 * not be {@code null}. 857 * @param provider The name of the provider to use for cryptographic 858 * operations. It must not be {@code null}. 859 * 860 * @return The created SSL socket factory. 861 * 862 * @throws GeneralSecurityException If a problem occurs while creating or 863 * initializing the SSL socket factory. 864 */ 865 @NotNull() 866 public SSLSocketFactory createSSLSocketFactory(@NotNull final String protocol, 867 @NotNull final String provider) 868 throws GeneralSecurityException 869 { 870 if (JVM_SSL_DEBUGGING_ENABLED) 871 { 872 System.err.println("SSLUtil.createSSLSocketFactory creating an " + 873 874 "SetEnabledProtocolsAndCipherSuitesSSLSocketFactory with protocol " + 875 protocol + ", provider " + provider + 876 ", and enabled cipher suites " + ENABLED_SSL_CIPHER_SUITES.get()); 877 } 878 879 return new SetEnabledProtocolsAndCipherSuitesSSLSocketFactory( 880 createSSLContext(protocol, provider).getSocketFactory(), protocol, 881 ENABLED_SSL_CIPHER_SUITES.get()); 882 } 883 884 885 886 /** 887 * Creates an SSL server socket factory using the configured key and trust 888 * manager providers. It will use the protocol returned by the 889 * {@link #getDefaultSSLProtocol} method and the JVM-default provider. 890 * 891 * @return The created SSL server socket factory. 892 * 893 * @throws GeneralSecurityException If a problem occurs while creating or 894 * initializing the SSL server socket 895 * factory. 896 */ 897 @NotNull() 898 public SSLServerSocketFactory createSSLServerSocketFactory() 899 throws GeneralSecurityException 900 { 901 if (JVM_SSL_DEBUGGING_ENABLED) 902 { 903 System.err.println("SSLUtil.createSSLServerSocketFactory creating a " + 904 "SetEnabledProtocolsAndCipherSuitesSSLServerSocketFactory with " + 905 "enabled protocols " + ENABLED_SSL_PROTOCOLS.get() + 906 " and enabled cipher suites " + ENABLED_SSL_CIPHER_SUITES.get()); 907 } 908 909 return new SetEnabledProtocolsAndCipherSuitesSSLServerSocketFactory( 910 createSSLContext().getServerSocketFactory(), 911 ENABLED_SSL_PROTOCOLS.get(), ENABLED_SSL_CIPHER_SUITES.get()); 912 } 913 914 915 916 /** 917 * Creates an SSL server socket factory using the configured key and trust 918 * manager providers. It will use the JVM-default provider. 919 * 920 * @param protocol The SSL protocol to use. The Java Secure Socket 921 * Extension (JSSE) Reference Guide provides a list of the 922 * supported protocols, but commonly used values are 923 * "TLSv1.3", "TLSv1.2", "TLSv1.1", and "TLSv1". This must 924 * not be {@code null}. 925 * 926 * @return The created SSL server socket factory. 927 * 928 * @throws GeneralSecurityException If a problem occurs while creating or 929 * initializing the SSL server socket 930 * factory. 931 */ 932 @NotNull() 933 public SSLServerSocketFactory createSSLServerSocketFactory( 934 @NotNull final String protocol) 935 throws GeneralSecurityException 936 { 937 if (JVM_SSL_DEBUGGING_ENABLED) 938 { 939 System.err.println("SSLUtil.createSSLServerSocketFactory creating a " + 940 "SetEnabledProtocolsAndCipherSuitesSSLServerSocketFactory with " + 941 "protocol " + protocol + " and enabled cipher suites " + 942 ENABLED_SSL_CIPHER_SUITES.get()); 943 } 944 945 return new SetEnabledProtocolsAndCipherSuitesSSLServerSocketFactory( 946 createSSLContext(protocol).getServerSocketFactory(), protocol, 947 ENABLED_SSL_CIPHER_SUITES.get()); 948 } 949 950 951 952 /** 953 * Creates an SSL server socket factory using the configured key and trust 954 * manager providers. 955 * 956 * @param protocol The SSL protocol to use. The Java Secure Socket 957 * Extension (JSSE) Reference Guide provides a list of the 958 * supported protocols, but commonly used values are 959 * "TLSv1.3", "TLSv1.2", "TLSv1.1", and "TLSv1". This must 960 * not be {@code null}. 961 * @param provider The name of the provider to use for cryptographic 962 * operations. It must not be {@code null}. 963 * 964 * @return The created SSL server socket factory. 965 * 966 * @throws GeneralSecurityException If a problem occurs while creating or 967 * initializing the SSL server socket 968 * factory. 969 */ 970 @NotNull() 971 public SSLServerSocketFactory createSSLServerSocketFactory( 972 @NotNull final String protocol, 973 @NotNull final String provider) 974 throws GeneralSecurityException 975 { 976 if (JVM_SSL_DEBUGGING_ENABLED) 977 { 978 System.err.println("SSLUtil.createSSLServerSocketFactory creating a " + 979 "SetEnabledProtocolsAndCipherSuitesSSLServerSocketFactory with " + 980 "protocol " + protocol + ", provider " + provider + 981 ", and enabled cipher suites " + ENABLED_SSL_CIPHER_SUITES.get()); 982 } 983 984 return new SetEnabledProtocolsAndCipherSuitesSSLServerSocketFactory( 985 createSSLContext(protocol, provider).getServerSocketFactory(), 986 protocol, ENABLED_SSL_CIPHER_SUITES.get()); 987 } 988 989 990 991 /** 992 * Retrieves the SSL protocol string that will be used by calls to 993 * {@link #createSSLContext()} that do not explicitly specify which protocol 994 * to use. 995 * 996 * @return The SSL protocol string that will be used by calls to create an 997 * SSL context that do not explicitly specify which protocol to use. 998 */ 999 @NotNull() 1000 public static String getDefaultSSLProtocol() 1001 { 1002 return DEFAULT_SSL_PROTOCOL.get(); 1003 } 1004 1005 1006 1007 /** 1008 * Specifies the SSL protocol string that will be used by calls to 1009 * {@link #createSSLContext()} that do not explicitly specify which protocol 1010 * to use. 1011 * 1012 * @param defaultSSLProtocol The SSL protocol string that will be used by 1013 * calls to create an SSL context that do not 1014 * explicitly specify which protocol to use. It 1015 * must not be {@code null}. 1016 */ 1017 public static void setDefaultSSLProtocol( 1018 @NotNull final String defaultSSLProtocol) 1019 { 1020 Validator.ensureNotNull(defaultSSLProtocol); 1021 1022 if (JVM_SSL_DEBUGGING_ENABLED) 1023 { 1024 System.err.println("SSLUtil.setDefaultSSLProtocol setting the " + 1025 "default SSL protocol to " + defaultSSLProtocol); 1026 } 1027 1028 DEFAULT_SSL_PROTOCOL.set(defaultSSLProtocol); 1029 } 1030 1031 1032 1033 /** 1034 * Retrieves the set of SSL protocols that will be enabled for use, if 1035 * available, for SSL sockets created within the LDAP SDK. 1036 * 1037 * @return The set of SSL protocols that will be enabled for use, if 1038 * available, for SSL sockets created within the LDAP SDK. 1039 */ 1040 @NotNull() 1041 public static Set<String> getEnabledSSLProtocols() 1042 { 1043 return ENABLED_SSL_PROTOCOLS.get(); 1044 } 1045 1046 1047 1048 /** 1049 * Specifies the set of SSL protocols that will be enabled for use for SSL 1050 * sockets created within the LDAP SDK. When creating an SSL socket, the 1051 * {@code SSLSocket.getSupportedProtocols} method will be used to determine 1052 * which protocols are supported for that socket, and then the 1053 * {@code SSLSocket.setEnabledProtocols} method will be used to enable those 1054 * protocols which are listed as both supported by the socket and included in 1055 * this set. If the provided set is {@code null} or empty, then the default 1056 * set of enabled protocols will be used. 1057 * 1058 * @param enabledSSLProtocols The set of SSL protocols that will be enabled 1059 * for use for SSL sockets created within the 1060 * LDAP SDK. It may be {@code null} or empty to 1061 * indicate that the JDK-default set of enabled 1062 * protocols should be used for the socket. 1063 */ 1064 public static void setEnabledSSLProtocols( 1065 @Nullable final Collection<String> enabledSSLProtocols) 1066 { 1067 if (enabledSSLProtocols == null) 1068 { 1069 if (JVM_SSL_DEBUGGING_ENABLED) 1070 { 1071 System.err.println("SSLUtil.setEnabledSSLProtocols setting the " + 1072 "enabled SSL protocols to an empty set"); 1073 } 1074 1075 ENABLED_SSL_PROTOCOLS.set(Collections.<String>emptySet()); 1076 } 1077 else 1078 { 1079 if (JVM_SSL_DEBUGGING_ENABLED) 1080 { 1081 System.err.println("SSLUtil.setEnabledSSLProtocols setting the " + 1082 "enabled SSL protocols to " + enabledSSLProtocols); 1083 } 1084 1085 ENABLED_SSL_PROTOCOLS.set(Collections.unmodifiableSet( 1086 new LinkedHashSet<>(enabledSSLProtocols))); 1087 } 1088 } 1089 1090 1091 1092 /** 1093 * Updates the provided socket to apply the appropriate set of enabled SSL 1094 * protocols. This will only have any effect for sockets that are instances 1095 * of {@code javax.net.ssl.SSLSocket}, but it is safe to call for any kind of 1096 * {@code java.net.Socket}. This should be called before attempting any 1097 * communication over the socket. 1098 * 1099 * @param socket The socket on which to apply the configured set of enabled 1100 * SSL protocols. 1101 * 1102 * @throws LDAPException If {@link #getEnabledSSLProtocols} returns a 1103 * non-empty set but none of the values in that set 1104 * are supported by the socket. 1105 */ 1106 public static void applyEnabledSSLProtocols(@NotNull final Socket socket) 1107 throws LDAPException 1108 { 1109 try 1110 { 1111 applyEnabledSSLProtocols(socket, ENABLED_SSL_PROTOCOLS.get()); 1112 } 1113 catch (final IOException ioe) 1114 { 1115 Debug.debugException(ioe); 1116 throw new LDAPException(ResultCode.CONNECT_ERROR, ioe.getMessage(), ioe); 1117 } 1118 } 1119 1120 1121 1122 /** 1123 * Updates the provided socket to apply the appropriate set of enabled SSL 1124 * protocols. This will only have any effect for sockets that are instances 1125 * of {@code javax.net.ssl.SSLSocket}, but it is safe to call for any kind of 1126 * {@code java.net.Socket}. This should be called before attempting any 1127 * communication over the socket. 1128 * 1129 * @param socket The socket on which to apply the configured set of 1130 * enabled SSL protocols. 1131 * @param protocols The set of protocols that should be enabled for the 1132 * socket, if available. 1133 * 1134 * @throws IOException If a problem is encountered while applying the 1135 * desired set of enabled protocols to the given socket. 1136 */ 1137 static void applyEnabledSSLProtocols(@Nullable final Socket socket, 1138 @NotNull final Set<String> protocols) 1139 throws IOException 1140 { 1141 if ((socket == null) || (!(socket instanceof SSLSocket)) || 1142 protocols.isEmpty()) 1143 { 1144 return; 1145 } 1146 1147 final SSLSocket sslSocket = (SSLSocket) socket; 1148 final String[] protocolsToEnable = 1149 getSSLProtocolsToEnable(protocols, sslSocket.getSupportedProtocols()); 1150 1151 try 1152 { 1153 if (JVM_SSL_DEBUGGING_ENABLED) 1154 { 1155 System.err.println("SSLUtil.applyEnabledSSLProtocols applying " + 1156 "protocolsToEnable " + Arrays.toString(protocolsToEnable) + 1157 " to SSLSocket " + sslSocket); 1158 } 1159 1160 sslSocket.setEnabledProtocols(protocolsToEnable); 1161 } 1162 catch (final Exception e) 1163 { 1164 Debug.debugException(e); 1165 } 1166 } 1167 1168 1169 1170 /** 1171 * Updates the provided server socket to apply the appropriate set of enabled 1172 * SSL protocols. This will only have any effect for server sockets that are 1173 * instances of {@code javax.net.ssl.SSLServerSocket}, but it is safe to call 1174 * for any kind of {@code java.net.ServerSocket}. This should be called 1175 * before attempting any communication over the socket. 1176 * 1177 * @param serverSocket The server socket on which to apply the configured 1178 * set of enabled SSL protocols. 1179 * @param protocols The set of protocols that should be enabled for the 1180 * server socket, if available. 1181 * 1182 * @throws IOException If a problem is encountered while applying the 1183 * desired set of enabled protocols to the given server 1184 * socket. 1185 */ 1186 static void applyEnabledSSLProtocols( 1187 @Nullable final ServerSocket serverSocket, 1188 @NotNull final Set<String> protocols) 1189 throws IOException 1190 { 1191 if ((serverSocket == null) || 1192 (!(serverSocket instanceof SSLServerSocket)) || 1193 protocols.isEmpty()) 1194 { 1195 return; 1196 } 1197 1198 final SSLServerSocket sslServerSocket = (SSLServerSocket) serverSocket; 1199 final String[] protocolsToEnable = getSSLProtocolsToEnable(protocols, 1200 sslServerSocket.getSupportedProtocols()); 1201 1202 try 1203 { 1204 if (JVM_SSL_DEBUGGING_ENABLED) 1205 { 1206 System.err.println("SSLUtil.applyEnabledSSLProtocols applying " + 1207 "protocolsToEnable " + Arrays.toString(protocolsToEnable) + 1208 " to SSLServerSocket " + sslServerSocket); 1209 } 1210 1211 sslServerSocket.setEnabledProtocols(protocolsToEnable); 1212 } 1213 catch (final Exception e) 1214 { 1215 Debug.debugException(e); 1216 } 1217 } 1218 1219 1220 1221 /** 1222 * Retrieves the names of the SSL protocols that should be enabled given the 1223 * provided information. 1224 * 1225 * @param desiredProtocols The set of protocols that are desired to be 1226 * enabled. 1227 * @param supportedProtocols The set of all protocols that are supported. 1228 * 1229 * @return The names of the SSL protocols that should be enabled. 1230 * 1231 * @throws IOException If none of the desired values are included in the 1232 * supported set. 1233 */ 1234 @NotNull() 1235 private static String[] getSSLProtocolsToEnable( 1236 @NotNull final Set<String> desiredProtocols, 1237 @NotNull final String[] supportedProtocols) 1238 throws IOException 1239 { 1240 final Set<String> lowerProtocols = new LinkedHashSet<>( 1241 StaticUtils.computeMapCapacity(desiredProtocols.size())); 1242 for (final String s : desiredProtocols) 1243 { 1244 lowerProtocols.add(StaticUtils.toLowerCase(s)); 1245 } 1246 1247 final ArrayList<String> enabledList = 1248 new ArrayList<>(supportedProtocols.length); 1249 for (final String supportedProtocol : supportedProtocols) 1250 { 1251 if (lowerProtocols.contains(StaticUtils.toLowerCase(supportedProtocol))) 1252 { 1253 enabledList.add(supportedProtocol); 1254 } 1255 } 1256 1257 if (enabledList.isEmpty()) 1258 { 1259 final StringBuilder enabledBuffer = new StringBuilder(); 1260 final Iterator<String> enabledIterator = desiredProtocols.iterator(); 1261 while (enabledIterator.hasNext()) 1262 { 1263 enabledBuffer.append('\''); 1264 enabledBuffer.append(enabledIterator.next()); 1265 enabledBuffer.append('\''); 1266 1267 if (enabledIterator.hasNext()) 1268 { 1269 enabledBuffer.append(", "); 1270 } 1271 } 1272 1273 final StringBuilder supportedBuffer = new StringBuilder(); 1274 for (int i=0; i < supportedProtocols.length; i++) 1275 { 1276 if (i > 0) 1277 { 1278 supportedBuffer.append(", "); 1279 } 1280 1281 supportedBuffer.append('\''); 1282 supportedBuffer.append(supportedProtocols[i]); 1283 supportedBuffer.append('\''); 1284 } 1285 1286 throw new IOException( 1287 ERR_NO_ENABLED_SSL_PROTOCOLS_AVAILABLE_FOR_SOCKET.get( 1288 enabledBuffer.toString(), supportedBuffer.toString(), 1289 PROPERTY_ENABLED_SSL_PROTOCOLS, 1290 SSLUtil.class.getName() + ".setEnabledSSLProtocols")); 1291 } 1292 else 1293 { 1294 return enabledList.toArray(StaticUtils.NO_STRINGS); 1295 } 1296 } 1297 1298 1299 1300 /** 1301 * Retrieves the set of SSL cipher suites that will be enabled for use, if 1302 * available, for SSL sockets created within the LDAP SDK. 1303 * 1304 * @return The set of SSL cipher suites that will be enabled for use, if 1305 * available, for SSL sockets created within the LDAP SDK. 1306 */ 1307 @NotNull() 1308 public static Set<String> getEnabledSSLCipherSuites() 1309 { 1310 return ENABLED_SSL_CIPHER_SUITES.get(); 1311 } 1312 1313 1314 1315 /** 1316 * Specifies the set of SSL cipher suites that will be enabled for SSL sockets 1317 * created within the LDAP SDK. When creating an SSL socket, the 1318 * {@code SSLSocket.getSupportedCipherSuites} method will be used to determine 1319 * which cipher suites are supported for that socket, and then the 1320 * {@code SSLSocket.setEnabledCipherSuites} method will be used to enable 1321 * those suites which are listed as both supported by the socket and included 1322 * in this set. If the provided set is {@code null} or empty, then the 1323 * default set of enabled cipher suites will be used. 1324 * 1325 * @param enabledSSLCipherSuites The set of SSL cipher suites that will be 1326 * enabled for use for SSL sockets created 1327 * within the LDAP SDK. It may be 1328 * {@code null} or empty to indicate that the 1329 * JDK-default set of enabled cipher suites 1330 * should be used for the socket. 1331 */ 1332 public static void setEnabledSSLCipherSuites( 1333 @Nullable final Collection<String> enabledSSLCipherSuites) 1334 { 1335 if (enabledSSLCipherSuites == null) 1336 { 1337 if (JVM_SSL_DEBUGGING_ENABLED) 1338 { 1339 System.err.println("SSLUtil.setEnabledSSLCipherSuites setting the " + 1340 "enabled SSL cipher suites to an empty set"); 1341 } 1342 1343 ENABLED_SSL_CIPHER_SUITES.set(Collections.<String>emptySet()); 1344 } 1345 else 1346 { 1347 if (JVM_SSL_DEBUGGING_ENABLED) 1348 { 1349 System.err.println("SSLUtil.setEnabledSSLCipherSuites setting the " + 1350 "enabled SSL cipher suites to " + enabledSSLCipherSuites); 1351 } 1352 1353 ENABLED_SSL_CIPHER_SUITES.set(Collections.unmodifiableSet( 1354 new LinkedHashSet<>(enabledSSLCipherSuites))); 1355 } 1356 } 1357 1358 1359 1360 /** 1361 * Updates the provided socket to apply the appropriate set of enabled SSL 1362 * cipher suites. This will only have any effect for sockets that are 1363 * instances of {@code javax.net.ssl.SSLSocket}, but it is safe to call for 1364 * any kind of {@code java.net.Socket}. This should be called before 1365 * attempting any communication over the socket. 1366 * 1367 * @param socket The socket on which to apply the configured set of enabled 1368 * SSL cipher suites. 1369 * 1370 * @throws LDAPException If {@link #getEnabledSSLCipherSuites} returns a 1371 * non-empty set but none of the values in that set 1372 * are supported by the socket. 1373 */ 1374 public static void applyEnabledSSLCipherSuites(@NotNull final Socket socket) 1375 throws LDAPException 1376 { 1377 try 1378 { 1379 applyEnabledSSLCipherSuites(socket, ENABLED_SSL_CIPHER_SUITES.get()); 1380 } 1381 catch (final IOException ioe) 1382 { 1383 Debug.debugException(ioe); 1384 throw new LDAPException(ResultCode.CONNECT_ERROR, ioe.getMessage(), ioe); 1385 } 1386 } 1387 1388 1389 1390 /** 1391 * Updates the provided socket to apply the appropriate set of enabled SSL 1392 * cipher suites. This will only have any effect for sockets that are 1393 * instances of {@code javax.net.ssl.SSLSocket}, but it is safe to call for 1394 * any kind of {@code java.net.Socket}. This should be called before 1395 * attempting any communication over the socket. 1396 * 1397 * @param socket The socket on which to apply the configured set of 1398 * enabled SSL cipher suites. 1399 * @param cipherSuites The set of cipher suites that should be enabled for 1400 * the socket, if available. 1401 * 1402 * @throws IOException If a problem is encountered while applying the 1403 * desired set of enabled cipher suites to the given 1404 * socket. 1405 */ 1406 static void applyEnabledSSLCipherSuites(@Nullable final Socket socket, 1407 @NotNull final Set<String> cipherSuites) 1408 throws IOException 1409 { 1410 if ((socket == null) || (!(socket instanceof SSLSocket)) || 1411 cipherSuites.isEmpty()) 1412 { 1413 return; 1414 } 1415 1416 final SSLSocket sslSocket = (SSLSocket) socket; 1417 final String[] cipherSuitesToEnable = 1418 getSSLCipherSuitesToEnable(cipherSuites, 1419 sslSocket.getSupportedCipherSuites()); 1420 try 1421 { 1422 if (JVM_SSL_DEBUGGING_ENABLED) 1423 { 1424 System.err.println("SSLUtil.applyEnabledSSLCipherSuites applying " + 1425 "cinpherSuitesToEnable " + Arrays.toString(cipherSuitesToEnable) + 1426 " to SSLSocket " + sslSocket); 1427 } 1428 1429 sslSocket.setEnabledCipherSuites(cipherSuitesToEnable); 1430 } 1431 catch (final Exception e) 1432 { 1433 Debug.debugException(e); 1434 } 1435 } 1436 1437 1438 1439 /** 1440 * Updates the provided server socket to apply the appropriate set of enabled 1441 * SSL cipher suites. This will only have any effect for server sockets that 1442 * are instances of {@code javax.net.ssl.SSLServerSocket}, but it is safe to 1443 * call for any kind of {@code java.net.ServerSocket}. This should be called 1444 * before attempting any communication over the socket. 1445 * 1446 * @param serverSocket The server socket on which to apply the configured 1447 * set of enabled SSL cipher suites. 1448 * @param cipherSuites The set of cipher suites that should be enabled 1449 * for the server socket, if available. 1450 * 1451 * @throws IOException If a problem is encountered while applying the 1452 * desired set of enabled cipher suites to the given 1453 * server socket. 1454 */ 1455 static void applyEnabledSSLCipherSuites( 1456 @Nullable final ServerSocket serverSocket, 1457 @NotNull final Set<String> cipherSuites) 1458 throws IOException 1459 { 1460 if ((serverSocket == null) || 1461 (! (serverSocket instanceof SSLServerSocket)) || 1462 cipherSuites.isEmpty()) 1463 { 1464 return; 1465 } 1466 1467 final SSLServerSocket sslServerSocket = (SSLServerSocket) serverSocket; 1468 final String[] cipherSuitesToEnable = 1469 getSSLCipherSuitesToEnable(cipherSuites, 1470 sslServerSocket.getSupportedCipherSuites()); 1471 1472 try 1473 { 1474 if (JVM_SSL_DEBUGGING_ENABLED) 1475 { 1476 System.err.println("SSLUtil.applyEnabledSSLCipherSuites applying " + 1477 "cinpherSuitesToEnable " + Arrays.toString(cipherSuitesToEnable) + 1478 " to SSLServerSocket " + sslServerSocket); 1479 } 1480 1481 sslServerSocket.setEnabledCipherSuites(cipherSuitesToEnable); 1482 } 1483 catch (final Exception e) 1484 { 1485 Debug.debugException(e); 1486 } 1487 } 1488 1489 1490 1491 /** 1492 * Retrieves the names of the SSL cipher suites that should be enabled given 1493 * the provided information. 1494 * 1495 * @param desiredCipherSuites The set of cipher suites that are desired to 1496 * be enabled. 1497 * @param supportedCipherSuites The set of all cipher suites that are 1498 * supported. 1499 * 1500 * @return The names of the SSL cipher suites that should be enabled. 1501 * 1502 * @throws IOException If none of the desired values are included in the 1503 * supported set. 1504 */ 1505 @NotNull() 1506 private static String[] getSSLCipherSuitesToEnable( 1507 @NotNull final Set<String> desiredCipherSuites, 1508 @NotNull final String[] supportedCipherSuites) 1509 throws IOException 1510 { 1511 final Set<String> upperCipherSuites = new LinkedHashSet<>( 1512 StaticUtils.computeMapCapacity(desiredCipherSuites.size())); 1513 for (final String s : desiredCipherSuites) 1514 { 1515 upperCipherSuites.add(StaticUtils.toUpperCase(s)); 1516 } 1517 1518 final ArrayList<String> enabledList = 1519 new ArrayList<>(supportedCipherSuites.length); 1520 for (final String supportedCipherSuite : supportedCipherSuites) 1521 { 1522 if (upperCipherSuites.contains(StaticUtils.toUpperCase( 1523 supportedCipherSuite))) 1524 { 1525 enabledList.add(supportedCipherSuite); 1526 } 1527 } 1528 1529 if (enabledList.isEmpty()) 1530 { 1531 final StringBuilder enabledBuffer = new StringBuilder(); 1532 final Iterator<String> enabledIterator = desiredCipherSuites.iterator(); 1533 while (enabledIterator.hasNext()) 1534 { 1535 enabledBuffer.append('\''); 1536 enabledBuffer.append(enabledIterator.next()); 1537 enabledBuffer.append('\''); 1538 1539 if (enabledIterator.hasNext()) 1540 { 1541 enabledBuffer.append(", "); 1542 } 1543 } 1544 1545 final StringBuilder supportedBuffer = new StringBuilder(); 1546 for (int i=0; i < supportedCipherSuites.length; i++) 1547 { 1548 if (i > 0) 1549 { 1550 supportedBuffer.append(", "); 1551 } 1552 1553 supportedBuffer.append('\''); 1554 supportedBuffer.append(supportedCipherSuites[i]); 1555 supportedBuffer.append('\''); 1556 } 1557 1558 throw new IOException( 1559 ERR_NO_ENABLED_SSL_CIPHER_SUITES_AVAILABLE_FOR_SOCKET.get( 1560 enabledBuffer.toString(), supportedBuffer.toString(), 1561 PROPERTY_ENABLED_SSL_CIPHER_SUITES, 1562 SSLUtil.class.getName() + ".setEnabledSSLCipherSuites")); 1563 } 1564 else 1565 { 1566 return enabledList.toArray(StaticUtils.NO_STRINGS); 1567 } 1568 } 1569 1570 1571 1572 /** 1573 * Configures SSL default settings for the LDAP SDK. This method is 1574 * non-private for purposes of easier test coverage. 1575 */ 1576 static void configureSSLDefaults() 1577 { 1578 // Determine the set of TLS protocols that the JVM supports. 1579 String tls13Protocol = null; 1580 String tls12Protocol = null; 1581 String tls11Protocol = null; 1582 String tls1Protocol = null; 1583 try 1584 { 1585 final SSLContext defaultContext = CryptoHelper.getDefaultSSLContext(); 1586 for (final String supportedProtocol : 1587 defaultContext.getSupportedSSLParameters().getProtocols()) 1588 { 1589 if (supportedProtocol.equalsIgnoreCase(SSL_PROTOCOL_TLS_1_3)) 1590 { 1591 tls13Protocol = supportedProtocol; 1592 } 1593 else if (supportedProtocol.equalsIgnoreCase(SSL_PROTOCOL_TLS_1_2)) 1594 { 1595 tls12Protocol = supportedProtocol; 1596 } 1597 else if (supportedProtocol.equalsIgnoreCase(SSL_PROTOCOL_TLS_1_1)) 1598 { 1599 tls11Protocol = supportedProtocol; 1600 } 1601 else if (supportedProtocol.equalsIgnoreCase(SSL_PROTOCOL_TLS_1)) 1602 { 1603 tls1Protocol = supportedProtocol; 1604 } 1605 } 1606 } 1607 catch (final Exception e) 1608 { 1609 Debug.debugException(e); 1610 } 1611 1612 1613 // Determine the set of TLS protocols that should be enabled. 1614 final String enabledProtocolsPropertyValue = 1615 PropertyManager.get(PROPERTY_ENABLED_SSL_PROTOCOLS); 1616 final Set<String> enabledProtocols = new LinkedHashSet<>(); 1617 if (enabledProtocolsPropertyValue != null) 1618 { 1619 final StringTokenizer tokenizer = 1620 new StringTokenizer(enabledProtocolsPropertyValue, ", ", false); 1621 while (tokenizer.hasMoreTokens()) 1622 { 1623 final String enabledProtocol = tokenizer.nextToken().trim(); 1624 if (! enabledProtocol.isEmpty()) 1625 { 1626 enabledProtocols.add(enabledProtocol); 1627 } 1628 } 1629 } 1630 else 1631 { 1632 if (tls13Protocol != null) 1633 { 1634 enabledProtocols.add(tls13Protocol); 1635 if (tls12Protocol != null) 1636 { 1637 enabledProtocols.add(tls12Protocol); 1638 } 1639 } 1640 else if (tls12Protocol != null) 1641 { 1642 enabledProtocols.add(tls12Protocol); 1643 } 1644 else if (tls11Protocol != null) 1645 { 1646 enabledProtocols.add(tls11Protocol); 1647 } 1648 else if (tls1Protocol != null) 1649 { 1650 enabledProtocols.add(tls1Protocol); 1651 } 1652 } 1653 1654 ENABLED_SSL_PROTOCOLS.set(Collections.unmodifiableSet(enabledProtocols)); 1655 1656 1657 // Determine the default TLS protocol. 1658 final String defaultProtocol; 1659 final String defaultProtocolPropertyValue = 1660 PropertyManager.get(PROPERTY_DEFAULT_SSL_PROTOCOL); 1661 if (defaultProtocolPropertyValue != null) 1662 { 1663 defaultProtocol = defaultProtocolPropertyValue; 1664 } 1665 else 1666 { 1667 defaultProtocol = enabledProtocols.iterator().next(); 1668 } 1669 1670 DEFAULT_SSL_PROTOCOL.set(defaultProtocol); 1671 1672 1673 // Determine the set of TLS cipher suites to enable by default. 1674 TLSCipherSuiteSelector.recompute(); 1675 final String enabledSuitesPropertyValue = 1676 PropertyManager.get(PROPERTY_ENABLED_SSL_CIPHER_SUITES); 1677 final LinkedHashSet<String> enabledCipherSuites = new LinkedHashSet<>(); 1678 if ((enabledSuitesPropertyValue != null) && 1679 (! enabledSuitesPropertyValue.isEmpty())) 1680 { 1681 final StringTokenizer tokenizer = 1682 new StringTokenizer(enabledSuitesPropertyValue, ", ", false); 1683 while (tokenizer.hasMoreTokens()) 1684 { 1685 final String token = tokenizer.nextToken().trim(); 1686 if (! token.isEmpty()) 1687 { 1688 enabledCipherSuites.add(token); 1689 } 1690 } 1691 } 1692 else 1693 { 1694 enabledCipherSuites.addAll( 1695 TLSCipherSuiteSelector.getRecommendedCipherSuites()); 1696 } 1697 1698 ENABLED_SSL_CIPHER_SUITES.set(enabledCipherSuites); 1699 } 1700 1701 1702 1703 /** 1704 * Creates a string representation of the provided certificate. 1705 * 1706 * @param certificate The certificate for which to generate the string 1707 * representation. It must not be {@code null}. 1708 * 1709 * @return A string representation of the provided certificate. 1710 */ 1711 @NotNull() 1712 public static String certificateToString( 1713 @NotNull final X509Certificate certificate) 1714 { 1715 final StringBuilder buffer = new StringBuilder(); 1716 certificateToString(certificate, buffer); 1717 return buffer.toString(); 1718 } 1719 1720 1721 1722 /** 1723 * Appends a string representation of the provided certificate to the given 1724 * buffer. 1725 * 1726 * @param certificate The certificate for which to generate the string 1727 * representation. It must not be {@code null}. 1728 * @param buffer The buffer to which to append the string 1729 * representation. 1730 */ 1731 public static void certificateToString( 1732 @NotNull final X509Certificate certificate, 1733 @NotNull final StringBuilder buffer) 1734 { 1735 buffer.append("Certificate(subject='"); 1736 buffer.append( 1737 certificate.getSubjectX500Principal().getName(X500Principal.RFC2253)); 1738 buffer.append("', serialNumber="); 1739 buffer.append(certificate.getSerialNumber()); 1740 buffer.append(", notBefore="); 1741 buffer.append( 1742 StaticUtils.encodeGeneralizedTime(certificate.getNotBefore())); 1743 buffer.append(", notAfter="); 1744 buffer.append( 1745 StaticUtils.encodeGeneralizedTime(certificate.getNotAfter())); 1746 buffer.append(", signatureAlgorithm='"); 1747 buffer.append(certificate.getSigAlgName()); 1748 buffer.append("', signatureBytes='"); 1749 StaticUtils.toHex(certificate.getSignature(), buffer); 1750 buffer.append("', issuerSubject='"); 1751 buffer.append( 1752 certificate.getIssuerX500Principal().getName(X500Principal.RFC2253)); 1753 buffer.append("')"); 1754 } 1755}