001/* 002 * Copyright 2008-2022 Ping Identity Corporation 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright 2008-2022 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-2022 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.StaticUtils; 071import com.unboundid.util.ThreadLocalSecureRandom; 072import com.unboundid.util.ThreadSafety; 073import com.unboundid.util.ThreadSafetyLevel; 074import com.unboundid.util.Validator; 075 076import static com.unboundid.util.ssl.SSLMessages.*; 077 078 079 080/** 081 * This class provides a simple interface for creating {@code SSLContext} and 082 * {@code SSLSocketFactory} instances, which may be used to create SSL-based 083 * connections, or secure existing connections with StartTLS. By default, only 084 * the TLSv1.2 and TLSv1.3 (if supported by the JVM) will be enabled, with the 085 * higher protocol version being the default and preferred for use. The TLSv1.1 086 * or TLSv1 protocol will only be enabled if the JVM does not support either 087 * TLSv1.2 or TLSv1.3. 088 * <BR><BR> 089 * <H2>Example 1</H2> 090 * The following example demonstrates the use of the SSL helper to create an 091 * SSL-based LDAP connection that will blindly trust any certificate that the 092 * server presents. Using the {@code TrustAllTrustManager} is only recommended 093 * for testing purposes, since blindly trusting any certificate is not secure. 094 * <PRE> 095 * // Create an SSLUtil instance that is configured to trust any certificate, 096 * // and use it to create a socket factory. 097 * SSLUtil sslUtil = new SSLUtil(new TrustAllTrustManager()); 098 * SSLSocketFactory sslSocketFactory = sslUtil.createSSLSocketFactory(); 099 * 100 * // Establish a secure connection using the socket factory. 101 * LDAPConnection connection = new LDAPConnection(sslSocketFactory); 102 * connection.connect(serverAddress, serverSSLPort); 103 * 104 * // Process operations using the connection.... 105 * RootDSE rootDSE = connection.getRootDSE(); 106 * 107 * connection.close(); 108 * </PRE> 109 * <BR> 110 * <H2>Example 2</H2> 111 * The following example demonstrates the use of the SSL helper to create a 112 * non-secure LDAP connection and then use the StartTLS extended operation to 113 * secure it. It will use a trust store to determine whether to trust the 114 * server certificate. 115 * <PRE> 116 * // Establish a non-secure connection to the server. 117 * LDAPConnection connection = new LDAPConnection(serverAddress, serverPort); 118 * 119 * // Create an SSLUtil instance that is configured to trust certificates in 120 * // a specified trust store file, and use it to create an SSLContext that 121 * // will be used for StartTLS processing. 122 * SSLUtil sslUtil = new SSLUtil(new TrustStoreTrustManager(trustStorePath)); 123 * SSLContext sslContext = sslUtil.createSSLContext(); 124 * 125 * // Use the StartTLS extended operation to secure the connection. 126 * StartTLSExtendedRequest startTLSRequest = 127 * new StartTLSExtendedRequest(sslContext); 128 * ExtendedResult startTLSResult; 129 * try 130 * { 131 * startTLSResult = connection.processExtendedOperation(startTLSRequest); 132 * } 133 * catch (LDAPException le) 134 * { 135 * startTLSResult = new ExtendedResult(le); 136 * } 137 * LDAPTestUtils.assertResultCodeEquals(startTLSResult, ResultCode.SUCCESS); 138 * 139 * // Process operations using the connection.... 140 * RootDSE rootDSE = connection.getRootDSE(); 141 * 142 * connection.close(); 143 * </PRE> 144 */ 145@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE) 146public final class SSLUtil 147{ 148 /** 149 * The name of a system property 150 * (com.unboundid.util.SSLUtil.defaultSSLProtocol) that can be used to specify 151 * the initial value for the default SSL protocol that should be used. If 152 * this is not set, then the default SSL protocol will be dynamically 153 * determined. This can be overridden via the 154 * {@link #setDefaultSSLProtocol(String)} method. 155 */ 156 @NotNull public static final String PROPERTY_DEFAULT_SSL_PROTOCOL = 157 "com.unboundid.util.SSLUtil.defaultSSLProtocol"; 158 159 160 161 /** 162 * The name of a system property 163 * (com.unboundid.util.SSLUtil.enabledSSLProtocols) that can be used to 164 * provide the initial set of enabled SSL protocols that should be used, as a 165 * comma-delimited list. If this is not set, then the enabled SSL protocols 166 * will be dynamically determined. This can be overridden via the 167 * {@link #setEnabledSSLProtocols(Collection)} method. 168 */ 169 @NotNull public static final String PROPERTY_ENABLED_SSL_PROTOCOLS = 170 "com.unboundid.util.SSLUtil.enabledSSLProtocols"; 171 172 173 174 /** 175 * The name of a system property 176 * (com.unboundid.util.SSLUtil.enabledSSLCipherSuites) that can be used to 177 * provide the initial set of enabled SSL cipher suites that should be used, 178 * as a comma-delimited list. If this is not set, then the enabled SSL cipher 179 * suites will be dynamically determined using the 180 * {@link TLSCipherSuiteSelector}. This can be overridden via the 181 * {@link #setEnabledSSLCipherSuites(Collection)} method. 182 */ 183 @NotNull public static final String PROPERTY_ENABLED_SSL_CIPHER_SUITES = 184 "com.unboundid.util.SSLUtil.enabledSSLCipherSuites"; 185 186 187 188 /** 189 * The name of the SSL protocol that can be used to request TLSv1.3. 190 */ 191 @NotNull public static final String SSL_PROTOCOL_TLS_1_3 = "TLSv1.3"; 192 193 194 195 /** 196 * The name of the SSL protocol that can be used to request TLSv1.2. 197 */ 198 @NotNull public static final String SSL_PROTOCOL_TLS_1_2 = "TLSv1.2"; 199 200 201 202 /** 203 * The name of the SSL protocol that can be used to request TLSv1.1. 204 */ 205 @NotNull public static final String SSL_PROTOCOL_TLS_1_1 = "TLSv1.1"; 206 207 208 209 /** 210 * The name of the SSL protocol that can be used to request TLSv1. 211 */ 212 @NotNull public static final String SSL_PROTOCOL_TLS_1 = "TLSv1"; 213 214 215 216 /** 217 * The name of the SSL protocol that can be used to request SSLv3. 218 */ 219 @NotNull public static final String SSL_PROTOCOL_SSL_3 = "SSLv3"; 220 221 222 223 /** 224 * The name of the SSL protocol that can be used to request SSLv2Hello. 225 */ 226 @NotNull public static final String SSL_PROTOCOL_SSL_2_HELLO = "SSLv2Hello"; 227 228 229 230 /** 231 * The default protocol string that will be used to create SSL contexts when 232 * no explicit protocol is specified. 233 */ 234 @NotNull private static final AtomicReference<String> DEFAULT_SSL_PROTOCOL = 235 new AtomicReference<>(SSL_PROTOCOL_TLS_1_2); 236 237 238 239 /** 240 * The default set of SSL cipher suites that will be enabled for use if 241 * available for SSL sockets created within the LDAP SDK. 242 */ 243 @NotNull private static final AtomicReference<Set<String>> 244 ENABLED_SSL_CIPHER_SUITES = new AtomicReference<>( 245 (Set<String>) new LinkedHashSet<>( 246 TLSCipherSuiteSelector.getRecommendedCipherSuites())); 247 248 249 250 /** 251 * The default set of SSL protocols that will be enabled for use if available 252 * for SSL sockets created within the LDAP SDK. 253 */ 254 @NotNull private static final AtomicReference<Set<String>> 255 ENABLED_SSL_PROTOCOLS = new AtomicReference<>( 256 StaticUtils.setOf(SSL_PROTOCOL_TLS_1_2)); 257 258 259 260 /** 261 * The name of the service type that providers use to indicate the 262 * {@code SSLContext} algorithms that they support. 263 */ 264 @NotNull static final String PROVIDER_SERVICE_TYPE_SSL_CONTEXT = 265 "SSLContext"; 266 267 268 269 /** 270 * Indicates whether SSL/TLS debugging is expected to be enabled, based on 271 * the javax.net.debug system property. 272 */ 273 private static final boolean JVM_SSL_DEBUGGING_ENABLED = 274 TLSCipherSuiteSelector.jvmSSLDebuggingEnabled(); 275 276 277 278 static 279 { 280 configureSSLDefaults(); 281 } 282 283 284 285 // Indicates whether any of the provided key managers is a PKCS #11 key 286 // manager. 287 private final boolean usingPKCS11KeyManager; 288 289 // The set of key managers to be used. 290 @Nullable private final KeyManager[] keyManagers; 291 292 // The set of trust managers to be used. 293 @Nullable private final TrustManager[] trustManagers; 294 295 296 297 /** 298 * Creates a new SSLUtil instance that will not have a custom key manager or 299 * trust manager. It will not be able to provide a certificate to the server 300 * if one is requested, and it will only trust certificates signed by a 301 * predefined set of authorities. 302 */ 303 public SSLUtil() 304 { 305 keyManagers = null; 306 trustManagers = null; 307 usingPKCS11KeyManager = false; 308 } 309 310 311 312 /** 313 * Creates a new SSLUtil instance that will use the provided trust manager to 314 * determine whether to trust server certificates presented to the client. 315 * It will not be able to provide a certificate to the server if one is 316 * requested. 317 * 318 * @param trustManager The trust manager to use to determine whether to 319 * trust server certificates presented to the client. 320 * It may be {@code null} if the default set of trust 321 * managers should be used. 322 */ 323 public SSLUtil(@Nullable final TrustManager trustManager) 324 { 325 keyManagers = null; 326 usingPKCS11KeyManager = false; 327 328 if (trustManager == null) 329 { 330 trustManagers = null; 331 } 332 else 333 { 334 trustManagers = new TrustManager[] { trustManager }; 335 } 336 } 337 338 339 340 /** 341 * Creates a new SSLUtil instance that will use the provided trust managers 342 * to determine whether to trust server certificates presented to the client. 343 * It will not be able to provide a certificate to the server if one is 344 * requested. 345 * 346 * @param trustManagers The set of trust managers to use to determine 347 * whether to trust server certificates presented to 348 * the client. It may be {@code null} or empty if the 349 * default set of trust managers should be used. 350 */ 351 public SSLUtil(@Nullable final TrustManager[] trustManagers) 352 { 353 keyManagers = null; 354 usingPKCS11KeyManager = false; 355 356 if ((trustManagers == null) || (trustManagers.length == 0)) 357 { 358 this.trustManagers = null; 359 } 360 else 361 { 362 this.trustManagers = trustManagers; 363 } 364 } 365 366 367 368 /** 369 * Creates a new SSLUtil instance that will use the provided key manager to 370 * obtain certificates to present to the server, and the provided trust 371 * manager to determine whether to trust server certificates presented to the 372 * client. 373 * 374 * @param keyManager The key manager to use to obtain certificates to 375 * present to the server if requested. It may be 376 * {@code null} if no client certificates will be 377 * required or should be provided. 378 * @param trustManager The trust manager to use to determine whether to 379 * trust server certificates presented to the client. 380 * It may be {@code null} if the default set of trust 381 * managers should be used. 382 */ 383 public SSLUtil(@Nullable final KeyManager keyManager, 384 @Nullable final TrustManager trustManager) 385 { 386 if (keyManager == null) 387 { 388 keyManagers = null; 389 usingPKCS11KeyManager = false; 390 } 391 else 392 { 393 keyManagers = new KeyManager[] { keyManager }; 394 usingPKCS11KeyManager = (keyManager instanceof PKCS11KeyManager); 395 } 396 397 if (trustManager == null) 398 { 399 trustManagers = null; 400 } 401 else 402 { 403 trustManagers = new TrustManager[] { trustManager }; 404 } 405 } 406 407 408 409 /** 410 * Creates a new SSLUtil instance that will use the provided key managers to 411 * obtain certificates to present to the server, and the provided trust 412 * managers to determine whether to trust server certificates presented to the 413 * client. 414 * 415 * @param keyManagers The set of key managers to use to obtain 416 * certificates to present to the server if requested. 417 * It may be {@code null} or empty if no client 418 * certificates will be required or should be provided. 419 * @param trustManagers The set of trust managers to use to determine 420 * whether to trust server certificates presented to 421 * the client. It may be {@code null} or empty if the 422 * default set of trust managers should be used. 423 */ 424 public SSLUtil(@Nullable final KeyManager[] keyManagers, 425 @Nullable final TrustManager[] trustManagers) 426 { 427 if ((keyManagers == null) || (keyManagers.length == 0)) 428 { 429 this.keyManagers = null; 430 usingPKCS11KeyManager = false; 431 } 432 else 433 { 434 this.keyManagers = keyManagers; 435 436 boolean usingPKCS11 = false; 437 for (final KeyManager km : keyManagers) 438 { 439 if (km instanceof PKCS11KeyManager) 440 { 441 usingPKCS11 = true; 442 break; 443 } 444 } 445 446 usingPKCS11KeyManager = usingPKCS11; 447 } 448 449 if ((trustManagers == null) || (trustManagers.length == 0)) 450 { 451 this.trustManagers = null; 452 } 453 else 454 { 455 this.trustManagers = trustManagers; 456 } 457 } 458 459 460 461 /** 462 * Retrieves the set of key managers configured for use by this class, if any. 463 * 464 * @return The set of key managers configured for use by this class, or 465 * {@code null} if none were provided. 466 */ 467 @Nullable() 468 public KeyManager[] getKeyManagers() 469 { 470 return keyManagers; 471 } 472 473 474 475 /** 476 * Retrieves the set of trust managers configured for use by this class, if 477 * any. 478 * 479 * @return The set of trust managers configured for use by this class, or 480 * {@code null} if none were provided. 481 */ 482 @Nullable() 483 public TrustManager[] getTrustManagers() 484 { 485 return trustManagers; 486 } 487 488 489 490 /** 491 * Creates an initialized SSL context created with the configured key and 492 * trust managers. It will use the protocol returned by the 493 * {@link #getDefaultSSLProtocol} method and the JVM-default provider. 494 * 495 * @return The created SSL context. 496 * 497 * @throws GeneralSecurityException If a problem occurs while creating or 498 * initializing the SSL context. 499 */ 500 @NotNull() 501 public SSLContext createSSLContext() 502 throws GeneralSecurityException 503 { 504 return createSSLContext(DEFAULT_SSL_PROTOCOL.get()); 505 } 506 507 508 509 /** 510 * Creates an initialized SSL context created with the configured key and 511 * trust managers. It will use a default provider. 512 * 513 * @param protocol The SSL protocol to use. The Java Secure Socket 514 * Extension (JSSE) Reference Guide provides a list of the 515 * supported protocols, but commonly used values are 516 * "TLSv1.3", "TLSv1.2", "TLSv1.1", and "TLSv1". This must 517 * not be {@code null}. 518 * 519 * 520 * @return The created SSL context. 521 * 522 * @throws GeneralSecurityException If a problem occurs while creating or 523 * initializing the SSL context. 524 */ 525 @NotNull() 526 public SSLContext createSSLContext(@NotNull final String protocol) 527 throws GeneralSecurityException 528 { 529 Validator.ensureNotNull(protocol); 530 531 SSLContext sslContext = null; 532 if (usingPKCS11KeyManager) 533 { 534 final Provider pkcs11JSSEProvider = 535 PKCS11KeyManager.getPKCS11JSSESProvider(); 536 if ((pkcs11JSSEProvider != null) && (pkcs11JSSEProvider.getService( 537 PROVIDER_SERVICE_TYPE_SSL_CONTEXT, protocol) != null)) 538 { 539 if (JVM_SSL_DEBUGGING_ENABLED) 540 { 541 System.err.println("SSLUtil.createSSLContext creating a PKCS #11 " + 542 "SSLContext for protocol " + protocol); 543 } 544 545 sslContext = CryptoHelper.getSSLContext(protocol, pkcs11JSSEProvider); 546 } 547 } 548 549 if (sslContext == null) 550 { 551 if (JVM_SSL_DEBUGGING_ENABLED) 552 { 553 System.err.println("SSLUtil.createSSLContext creating an SSLContext " + 554 "for protocol " + protocol); 555 } 556 557 sslContext = CryptoHelper.getSSLContext(protocol); 558 } 559 560 sslContext.init(keyManagers, trustManagers, ThreadLocalSecureRandom.get()); 561 return sslContext; 562 } 563 564 565 566 /** 567 * Creates an initialized SSL context created with the configured key and 568 * trust managers. 569 * 570 * @param protocol The SSL protocol to use. The Java Secure Socket 571 * Extension (JSSE) Reference Guide provides a list of the 572 * supported protocols, but commonly used values are 573 * "TLSv1.3", "TLSv1.2", "TLSv1.1", and "TLSv1". This must 574 * not be {@code null}. 575 * @param provider The name of the provider to use for cryptographic 576 * operations. It must not be {@code null}. 577 * 578 * @return The created SSL context. 579 * 580 * @throws GeneralSecurityException If a problem occurs while creating or 581 * initializing the SSL context. 582 */ 583 @NotNull() 584 public SSLContext createSSLContext(@NotNull final String protocol, 585 @NotNull final String provider) 586 throws GeneralSecurityException 587 { 588 Validator.ensureNotNull(protocol, provider); 589 590 if (JVM_SSL_DEBUGGING_ENABLED) 591 { 592 System.err.println("SSLUtil.createSSLContext creating an SSLContext " + 593 "for protocol " + protocol + " and provider " + provider); 594 } 595 596 final SSLContext sslContext = 597 CryptoHelper.getSSLContext(protocol, provider); 598 sslContext.init(keyManagers, trustManagers, null); 599 return sslContext; 600 } 601 602 603 604 /** 605 * Creates an SSL socket factory using the configured key and trust manager 606 * providers. It will use the protocol returned by the 607 * {@link #getDefaultSSLProtocol} method and the JVM-default provider. 608 * 609 * @return The created SSL socket factory. 610 * 611 * @throws GeneralSecurityException If a problem occurs while creating or 612 * initializing the SSL socket factory. 613 */ 614 @NotNull() 615 public SSLSocketFactory createSSLSocketFactory() 616 throws GeneralSecurityException 617 { 618 if (JVM_SSL_DEBUGGING_ENABLED) 619 { 620 System.err.println("SSLUtil.createSSLSocketFactory creating a " + 621 "SetEnabledProtocolsAndCipherSuitesSSLSocketFactory with enabled " + 622 "protocols " + ENABLED_SSL_PROTOCOLS.get() + 623 " and enabled cipher suites " + ENABLED_SSL_CIPHER_SUITES.get()); 624 } 625 626 return new SetEnabledProtocolsAndCipherSuitesSSLSocketFactory( 627 createSSLContext().getSocketFactory(), 628 ENABLED_SSL_PROTOCOLS.get(), ENABLED_SSL_CIPHER_SUITES.get()); 629 } 630 631 632 633 /** 634 * Creates an SSL socket factory with the configured key and trust managers. 635 * It will use the default provider. 636 * 637 * @param protocol The SSL protocol to use. The Java Secure Socket 638 * Extension (JSSE) Reference Guide provides a list of the 639 * supported protocols, but commonly used values are 640 * "TLSv1.3", "TLSv1.2", "TLSv1.1", and "TLSv1". This must 641 * not be {@code null}. 642 * 643 * @return The created SSL socket factory. 644 * 645 * @throws GeneralSecurityException If a problem occurs while creating or 646 * initializing the SSL socket factory. 647 */ 648 @NotNull() 649 public SSLSocketFactory createSSLSocketFactory( 650 @NotNull final String protocol) 651 throws GeneralSecurityException 652 { 653 if (JVM_SSL_DEBUGGING_ENABLED) 654 { 655 System.err.println("SSLUtil.createSSLSocketFactory creating a " + 656 "SetEnabledProtocolsAndCipherSuitesSSLSocketFactory with protocol " + 657 protocol + " and enabled cipher suites " + 658 ENABLED_SSL_CIPHER_SUITES.get()); 659 } 660 661 return new SetEnabledProtocolsAndCipherSuitesSSLSocketFactory( 662 createSSLContext(protocol).getSocketFactory(), protocol, 663 ENABLED_SSL_CIPHER_SUITES.get()); 664 } 665 666 667 668 /** 669 * Creates an SSL socket factory with the configured key and trust managers. 670 * 671 * @param protocol The SSL protocol to use. The Java Secure Socket 672 * Extension (JSSE) Reference Guide provides a list of the 673 * supported protocols, but commonly used values are 674 * "TLSv1.3", "TLSv1.2", "TLSv1.1", and "TLSv1". This must 675 * not be {@code null}. 676 * @param provider The name of the provider to use for cryptographic 677 * operations. It must not be {@code null}. 678 * 679 * @return The created SSL socket factory. 680 * 681 * @throws GeneralSecurityException If a problem occurs while creating or 682 * initializing the SSL socket factory. 683 */ 684 @NotNull() 685 public SSLSocketFactory createSSLSocketFactory(@NotNull final String protocol, 686 @NotNull final String provider) 687 throws GeneralSecurityException 688 { 689 if (JVM_SSL_DEBUGGING_ENABLED) 690 { 691 System.err.println("SSLUtil.createSSLSocketFactory creating an " + 692 693 "SetEnabledProtocolsAndCipherSuitesSSLSocketFactory with protocol " + 694 protocol + ", provider " + provider + 695 ", and enabled cipher suites " + ENABLED_SSL_CIPHER_SUITES.get()); 696 } 697 698 return new SetEnabledProtocolsAndCipherSuitesSSLSocketFactory( 699 createSSLContext(protocol, provider).getSocketFactory(), protocol, 700 ENABLED_SSL_CIPHER_SUITES.get()); 701 } 702 703 704 705 /** 706 * Creates an SSL server socket factory using the configured key and trust 707 * manager providers. It will use the protocol returned by the 708 * {@link #getDefaultSSLProtocol} method and the JVM-default provider. 709 * 710 * @return The created SSL server socket factory. 711 * 712 * @throws GeneralSecurityException If a problem occurs while creating or 713 * initializing the SSL server socket 714 * factory. 715 */ 716 @NotNull() 717 public SSLServerSocketFactory createSSLServerSocketFactory() 718 throws GeneralSecurityException 719 { 720 if (JVM_SSL_DEBUGGING_ENABLED) 721 { 722 System.err.println("SSLUtil.createSSLServerSocketFactory creating a " + 723 "SetEnabledProtocolsAndCipherSuitesSSLServerSocketFactory with " + 724 "enabled protocols " + ENABLED_SSL_PROTOCOLS.get() + 725 " and enabled cipher suites " + ENABLED_SSL_CIPHER_SUITES.get()); 726 } 727 728 return new SetEnabledProtocolsAndCipherSuitesSSLServerSocketFactory( 729 createSSLContext().getServerSocketFactory(), 730 ENABLED_SSL_PROTOCOLS.get(), ENABLED_SSL_CIPHER_SUITES.get()); 731 } 732 733 734 735 /** 736 * Creates an SSL server socket factory using the configured key and trust 737 * manager providers. It will use the JVM-default provider. 738 * 739 * @param protocol The SSL protocol to use. The Java Secure Socket 740 * Extension (JSSE) Reference Guide provides a list of the 741 * supported protocols, but commonly used values are 742 * "TLSv1.3", "TLSv1.2", "TLSv1.1", and "TLSv1". This must 743 * not be {@code null}. 744 * 745 * @return The created SSL server socket factory. 746 * 747 * @throws GeneralSecurityException If a problem occurs while creating or 748 * initializing the SSL server socket 749 * factory. 750 */ 751 @NotNull() 752 public SSLServerSocketFactory createSSLServerSocketFactory( 753 @NotNull final String protocol) 754 throws GeneralSecurityException 755 { 756 if (JVM_SSL_DEBUGGING_ENABLED) 757 { 758 System.err.println("SSLUtil.createSSLServerSocketFactory creating a " + 759 "SetEnabledProtocolsAndCipherSuitesSSLServerSocketFactory with " + 760 "protocol " + protocol + " and enabled cipher suites " + 761 ENABLED_SSL_CIPHER_SUITES.get()); 762 } 763 764 return new SetEnabledProtocolsAndCipherSuitesSSLServerSocketFactory( 765 createSSLContext(protocol).getServerSocketFactory(), protocol, 766 ENABLED_SSL_CIPHER_SUITES.get()); 767 } 768 769 770 771 /** 772 * Creates an SSL server socket factory using the configured key and trust 773 * manager providers. 774 * 775 * @param protocol The SSL protocol to use. The Java Secure Socket 776 * Extension (JSSE) Reference Guide provides a list of the 777 * supported protocols, but commonly used values are 778 * "TLSv1.3", "TLSv1.2", "TLSv1.1", and "TLSv1". This must 779 * not be {@code null}. 780 * @param provider The name of the provider to use for cryptographic 781 * operations. It must not be {@code null}. 782 * 783 * @return The created SSL server socket factory. 784 * 785 * @throws GeneralSecurityException If a problem occurs while creating or 786 * initializing the SSL server socket 787 * factory. 788 */ 789 @NotNull() 790 public SSLServerSocketFactory createSSLServerSocketFactory( 791 @NotNull final String protocol, 792 @NotNull final String provider) 793 throws GeneralSecurityException 794 { 795 if (JVM_SSL_DEBUGGING_ENABLED) 796 { 797 System.err.println("SSLUtil.createSSLServerSocketFactory creating a " + 798 "SetEnabledProtocolsAndCipherSuitesSSLServerSocketFactory with " + 799 "protocol " + protocol + ", provider " + provider + 800 ", and enabled cipher suites " + ENABLED_SSL_CIPHER_SUITES.get()); 801 } 802 803 return new SetEnabledProtocolsAndCipherSuitesSSLServerSocketFactory( 804 createSSLContext(protocol, provider).getServerSocketFactory(), 805 protocol, ENABLED_SSL_CIPHER_SUITES.get()); 806 } 807 808 809 810 /** 811 * Retrieves the SSL protocol string that will be used by calls to 812 * {@link #createSSLContext()} that do not explicitly specify which protocol 813 * to use. 814 * 815 * @return The SSL protocol string that will be used by calls to create an 816 * SSL context that do not explicitly specify which protocol to use. 817 */ 818 @NotNull() 819 public static String getDefaultSSLProtocol() 820 { 821 return DEFAULT_SSL_PROTOCOL.get(); 822 } 823 824 825 826 /** 827 * Specifies the SSL protocol string that will be used by calls to 828 * {@link #createSSLContext()} that do not explicitly specify which protocol 829 * to use. 830 * 831 * @param defaultSSLProtocol The SSL protocol string that will be used by 832 * calls to create an SSL context that do not 833 * explicitly specify which protocol to use. It 834 * must not be {@code null}. 835 */ 836 public static void setDefaultSSLProtocol( 837 @NotNull final String defaultSSLProtocol) 838 { 839 Validator.ensureNotNull(defaultSSLProtocol); 840 841 if (JVM_SSL_DEBUGGING_ENABLED) 842 { 843 System.err.println("SSLUtil.setDefaultSSLProtocol setting the " + 844 "default SSL protocol to " + defaultSSLProtocol); 845 } 846 847 DEFAULT_SSL_PROTOCOL.set(defaultSSLProtocol); 848 } 849 850 851 852 /** 853 * Retrieves the set of SSL protocols that will be enabled for use, if 854 * available, for SSL sockets created within the LDAP SDK. 855 * 856 * @return The set of SSL protocols that will be enabled for use, if 857 * available, for SSL sockets created within the LDAP SDK. 858 */ 859 @NotNull() 860 public static Set<String> getEnabledSSLProtocols() 861 { 862 return ENABLED_SSL_PROTOCOLS.get(); 863 } 864 865 866 867 /** 868 * Specifies the set of SSL protocols that will be enabled for use for SSL 869 * sockets created within the LDAP SDK. When creating an SSL socket, the 870 * {@code SSLSocket.getSupportedProtocols} method will be used to determine 871 * which protocols are supported for that socket, and then the 872 * {@code SSLSocket.setEnabledProtocols} method will be used to enable those 873 * protocols which are listed as both supported by the socket and included in 874 * this set. If the provided set is {@code null} or empty, then the default 875 * set of enabled protocols will be used. 876 * 877 * @param enabledSSLProtocols The set of SSL protocols that will be enabled 878 * for use for SSL sockets created within the 879 * LDAP SDK. It may be {@code null} or empty to 880 * indicate that the JDK-default set of enabled 881 * protocols should be used for the socket. 882 */ 883 public static void setEnabledSSLProtocols( 884 @Nullable final Collection<String> enabledSSLProtocols) 885 { 886 if (enabledSSLProtocols == null) 887 { 888 if (JVM_SSL_DEBUGGING_ENABLED) 889 { 890 System.err.println("SSLUtil.setEnabledSSLProtocols setting the " + 891 "enabled SSL protocols to an empty set"); 892 } 893 894 ENABLED_SSL_PROTOCOLS.set(Collections.<String>emptySet()); 895 } 896 else 897 { 898 if (JVM_SSL_DEBUGGING_ENABLED) 899 { 900 System.err.println("SSLUtil.setEnabledSSLProtocols setting the " + 901 "enabled SSL protocols to " + enabledSSLProtocols); 902 } 903 904 ENABLED_SSL_PROTOCOLS.set(Collections.unmodifiableSet( 905 new LinkedHashSet<>(enabledSSLProtocols))); 906 } 907 } 908 909 910 911 /** 912 * Updates the provided socket to apply the appropriate set of enabled SSL 913 * protocols. This will only have any effect for sockets that are instances 914 * of {@code javax.net.ssl.SSLSocket}, but it is safe to call for any kind of 915 * {@code java.net.Socket}. This should be called before attempting any 916 * communication over the socket. 917 * 918 * @param socket The socket on which to apply the configured set of enabled 919 * SSL protocols. 920 * 921 * @throws LDAPException If {@link #getEnabledSSLProtocols} returns a 922 * non-empty set but none of the values in that set 923 * are supported by the socket. 924 */ 925 public static void applyEnabledSSLProtocols(@NotNull final Socket socket) 926 throws LDAPException 927 { 928 try 929 { 930 applyEnabledSSLProtocols(socket, ENABLED_SSL_PROTOCOLS.get()); 931 } 932 catch (final IOException ioe) 933 { 934 Debug.debugException(ioe); 935 throw new LDAPException(ResultCode.CONNECT_ERROR, ioe.getMessage(), ioe); 936 } 937 } 938 939 940 941 /** 942 * Updates the provided socket to apply the appropriate set of enabled SSL 943 * protocols. This will only have any effect for sockets that are instances 944 * of {@code javax.net.ssl.SSLSocket}, but it is safe to call for any kind of 945 * {@code java.net.Socket}. This should be called before attempting any 946 * communication over the socket. 947 * 948 * @param socket The socket on which to apply the configured set of 949 * enabled SSL protocols. 950 * @param protocols The set of protocols that should be enabled for the 951 * socket, if available. 952 * 953 * @throws IOException If a problem is encountered while applying the 954 * desired set of enabled protocols to the given socket. 955 */ 956 static void applyEnabledSSLProtocols(@Nullable final Socket socket, 957 @NotNull final Set<String> protocols) 958 throws IOException 959 { 960 if ((socket == null) || (!(socket instanceof SSLSocket)) || 961 protocols.isEmpty()) 962 { 963 return; 964 } 965 966 final SSLSocket sslSocket = (SSLSocket) socket; 967 final String[] protocolsToEnable = 968 getSSLProtocolsToEnable(protocols, sslSocket.getSupportedProtocols()); 969 970 try 971 { 972 if (JVM_SSL_DEBUGGING_ENABLED) 973 { 974 System.err.println("SSLUtil.applyEnabledSSLProtocols applying " + 975 "protocolsToEnable " + Arrays.toString(protocolsToEnable) + 976 " to SSLSocket " + sslSocket); 977 } 978 979 sslSocket.setEnabledProtocols(protocolsToEnable); 980 } 981 catch (final Exception e) 982 { 983 Debug.debugException(e); 984 } 985 } 986 987 988 989 /** 990 * Updates the provided server socket to apply the appropriate set of enabled 991 * SSL protocols. This will only have any effect for server sockets that are 992 * instances of {@code javax.net.ssl.SSLServerSocket}, but it is safe to call 993 * for any kind of {@code java.net.ServerSocket}. This should be called 994 * before attempting any communication over the socket. 995 * 996 * @param serverSocket The server socket on which to apply the configured 997 * set of enabled SSL protocols. 998 * @param protocols The set of protocols that should be enabled for the 999 * server socket, if available. 1000 * 1001 * @throws IOException If a problem is encountered while applying the 1002 * desired set of enabled protocols to the given server 1003 * socket. 1004 */ 1005 static void applyEnabledSSLProtocols( 1006 @Nullable final ServerSocket serverSocket, 1007 @NotNull final Set<String> protocols) 1008 throws IOException 1009 { 1010 if ((serverSocket == null) || 1011 (!(serverSocket instanceof SSLServerSocket)) || 1012 protocols.isEmpty()) 1013 { 1014 return; 1015 } 1016 1017 final SSLServerSocket sslServerSocket = (SSLServerSocket) serverSocket; 1018 final String[] protocolsToEnable = getSSLProtocolsToEnable(protocols, 1019 sslServerSocket.getSupportedProtocols()); 1020 1021 try 1022 { 1023 if (JVM_SSL_DEBUGGING_ENABLED) 1024 { 1025 System.err.println("SSLUtil.applyEnabledSSLProtocols applying " + 1026 "protocolsToEnable " + Arrays.toString(protocolsToEnable) + 1027 " to SSLServerSocket " + sslServerSocket); 1028 } 1029 1030 sslServerSocket.setEnabledProtocols(protocolsToEnable); 1031 } 1032 catch (final Exception e) 1033 { 1034 Debug.debugException(e); 1035 } 1036 } 1037 1038 1039 1040 /** 1041 * Retrieves the names of the SSL protocols that should be enabled given the 1042 * provided information. 1043 * 1044 * @param desiredProtocols The set of protocols that are desired to be 1045 * enabled. 1046 * @param supportedProtocols The set of all protocols that are supported. 1047 * 1048 * @return The names of the SSL protocols that should be enabled. 1049 * 1050 * @throws IOException If none of the desired values are included in the 1051 * supported set. 1052 */ 1053 @NotNull() 1054 private static String[] getSSLProtocolsToEnable( 1055 @NotNull final Set<String> desiredProtocols, 1056 @NotNull final String[] supportedProtocols) 1057 throws IOException 1058 { 1059 final Set<String> lowerProtocols = new LinkedHashSet<>( 1060 StaticUtils.computeMapCapacity(desiredProtocols.size())); 1061 for (final String s : desiredProtocols) 1062 { 1063 lowerProtocols.add(StaticUtils.toLowerCase(s)); 1064 } 1065 1066 final ArrayList<String> enabledList = 1067 new ArrayList<>(supportedProtocols.length); 1068 for (final String supportedProtocol : supportedProtocols) 1069 { 1070 if (lowerProtocols.contains(StaticUtils.toLowerCase(supportedProtocol))) 1071 { 1072 enabledList.add(supportedProtocol); 1073 } 1074 } 1075 1076 if (enabledList.isEmpty()) 1077 { 1078 final StringBuilder enabledBuffer = new StringBuilder(); 1079 final Iterator<String> enabledIterator = desiredProtocols.iterator(); 1080 while (enabledIterator.hasNext()) 1081 { 1082 enabledBuffer.append('\''); 1083 enabledBuffer.append(enabledIterator.next()); 1084 enabledBuffer.append('\''); 1085 1086 if (enabledIterator.hasNext()) 1087 { 1088 enabledBuffer.append(", "); 1089 } 1090 } 1091 1092 final StringBuilder supportedBuffer = new StringBuilder(); 1093 for (int i=0; i < supportedProtocols.length; i++) 1094 { 1095 if (i > 0) 1096 { 1097 supportedBuffer.append(", "); 1098 } 1099 1100 supportedBuffer.append('\''); 1101 supportedBuffer.append(supportedProtocols[i]); 1102 supportedBuffer.append('\''); 1103 } 1104 1105 throw new IOException( 1106 ERR_NO_ENABLED_SSL_PROTOCOLS_AVAILABLE_FOR_SOCKET.get( 1107 enabledBuffer.toString(), supportedBuffer.toString(), 1108 PROPERTY_ENABLED_SSL_PROTOCOLS, 1109 SSLUtil.class.getName() + ".setEnabledSSLProtocols")); 1110 } 1111 else 1112 { 1113 return enabledList.toArray(StaticUtils.NO_STRINGS); 1114 } 1115 } 1116 1117 1118 1119 /** 1120 * Retrieves the set of SSL cipher suites that will be enabled for use, if 1121 * available, for SSL sockets created within the LDAP SDK. 1122 * 1123 * @return The set of SSL cipher suites that will be enabled for use, if 1124 * available, for SSL sockets created within the LDAP SDK. 1125 */ 1126 @NotNull() 1127 public static Set<String> getEnabledSSLCipherSuites() 1128 { 1129 return ENABLED_SSL_CIPHER_SUITES.get(); 1130 } 1131 1132 1133 1134 /** 1135 * Specifies the set of SSL cipher suites that will be enabled for SSL sockets 1136 * created within the LDAP SDK. When creating an SSL socket, the 1137 * {@code SSLSocket.getSupportedCipherSuites} method will be used to determine 1138 * which cipher suites are supported for that socket, and then the 1139 * {@code SSLSocket.setEnabledCipherSuites} method will be used to enable 1140 * those suites which are listed as both supported by the socket and included 1141 * in this set. If the provided set is {@code null} or empty, then the 1142 * default set of enabled cipher suites will be used. 1143 * 1144 * @param enabledSSLCipherSuites The set of SSL cipher suites that will be 1145 * enabled for use for SSL sockets created 1146 * within the LDAP SDK. It may be 1147 * {@code null} or empty to indicate that the 1148 * JDK-default set of enabled cipher suites 1149 * should be used for the socket. 1150 */ 1151 public static void setEnabledSSLCipherSuites( 1152 @Nullable final Collection<String> enabledSSLCipherSuites) 1153 { 1154 if (enabledSSLCipherSuites == null) 1155 { 1156 if (JVM_SSL_DEBUGGING_ENABLED) 1157 { 1158 System.err.println("SSLUtil.setEnabledSSLCipherSuites setting the " + 1159 "enabled SSL cipher suites to an empty set"); 1160 } 1161 1162 ENABLED_SSL_CIPHER_SUITES.set(Collections.<String>emptySet()); 1163 } 1164 else 1165 { 1166 if (JVM_SSL_DEBUGGING_ENABLED) 1167 { 1168 System.err.println("SSLUtil.setEnabledSSLCipherSuites setting the " + 1169 "enabled SSL cipher suites to " + enabledSSLCipherSuites); 1170 } 1171 1172 ENABLED_SSL_CIPHER_SUITES.set(Collections.unmodifiableSet( 1173 new LinkedHashSet<>(enabledSSLCipherSuites))); 1174 } 1175 } 1176 1177 1178 1179 /** 1180 * Updates the provided socket to apply the appropriate set of enabled SSL 1181 * cipher suites. This will only have any effect for sockets that are 1182 * instances of {@code javax.net.ssl.SSLSocket}, but it is safe to call for 1183 * any kind of {@code java.net.Socket}. This should be called before 1184 * attempting any communication over the socket. 1185 * 1186 * @param socket The socket on which to apply the configured set of enabled 1187 * SSL cipher suites. 1188 * 1189 * @throws LDAPException If {@link #getEnabledSSLCipherSuites} returns a 1190 * non-empty set but none of the values in that set 1191 * are supported by the socket. 1192 */ 1193 public static void applyEnabledSSLCipherSuites(@NotNull final Socket socket) 1194 throws LDAPException 1195 { 1196 try 1197 { 1198 applyEnabledSSLCipherSuites(socket, ENABLED_SSL_CIPHER_SUITES.get()); 1199 } 1200 catch (final IOException ioe) 1201 { 1202 Debug.debugException(ioe); 1203 throw new LDAPException(ResultCode.CONNECT_ERROR, ioe.getMessage(), ioe); 1204 } 1205 } 1206 1207 1208 1209 /** 1210 * Updates the provided socket to apply the appropriate set of enabled SSL 1211 * cipher suites. This will only have any effect for sockets that are 1212 * instances of {@code javax.net.ssl.SSLSocket}, but it is safe to call for 1213 * any kind of {@code java.net.Socket}. This should be called before 1214 * attempting any communication over the socket. 1215 * 1216 * @param socket The socket on which to apply the configured set of 1217 * enabled SSL cipher suites. 1218 * @param cipherSuites The set of cipher suites that should be enabled for 1219 * the socket, if available. 1220 * 1221 * @throws IOException If a problem is encountered while applying the 1222 * desired set of enabled cipher suites to the given 1223 * socket. 1224 */ 1225 static void applyEnabledSSLCipherSuites(@Nullable final Socket socket, 1226 @NotNull final Set<String> cipherSuites) 1227 throws IOException 1228 { 1229 if ((socket == null) || (!(socket instanceof SSLSocket)) || 1230 cipherSuites.isEmpty()) 1231 { 1232 return; 1233 } 1234 1235 final SSLSocket sslSocket = (SSLSocket) socket; 1236 final String[] cipherSuitesToEnable = 1237 getSSLCipherSuitesToEnable(cipherSuites, 1238 sslSocket.getSupportedCipherSuites()); 1239 try 1240 { 1241 if (JVM_SSL_DEBUGGING_ENABLED) 1242 { 1243 System.err.println("SSLUtil.applyEnabledSSLCipherSuites applying " + 1244 "cinpherSuitesToEnable " + Arrays.toString(cipherSuitesToEnable) + 1245 " to SSLSocket " + sslSocket); 1246 } 1247 1248 sslSocket.setEnabledCipherSuites(cipherSuitesToEnable); 1249 } 1250 catch (final Exception e) 1251 { 1252 Debug.debugException(e); 1253 } 1254 } 1255 1256 1257 1258 /** 1259 * Updates the provided server socket to apply the appropriate set of enabled 1260 * SSL cipher suites. This will only have any effect for server sockets that 1261 * are instances of {@code javax.net.ssl.SSLServerSocket}, but it is safe to 1262 * call for any kind of {@code java.net.ServerSocket}. This should be called 1263 * before attempting any communication over the socket. 1264 * 1265 * @param serverSocket The server socket on which to apply the configured 1266 * set of enabled SSL cipher suites. 1267 * @param cipherSuites The set of cipher suites that should be enabled 1268 * for the server socket, if available. 1269 * 1270 * @throws IOException If a problem is encountered while applying the 1271 * desired set of enabled cipher suites to the given 1272 * server socket. 1273 */ 1274 static void applyEnabledSSLCipherSuites( 1275 @Nullable final ServerSocket serverSocket, 1276 @NotNull final Set<String> cipherSuites) 1277 throws IOException 1278 { 1279 if ((serverSocket == null) || 1280 (! (serverSocket instanceof SSLServerSocket)) || 1281 cipherSuites.isEmpty()) 1282 { 1283 return; 1284 } 1285 1286 final SSLServerSocket sslServerSocket = (SSLServerSocket) serverSocket; 1287 final String[] cipherSuitesToEnable = 1288 getSSLCipherSuitesToEnable(cipherSuites, 1289 sslServerSocket.getSupportedCipherSuites()); 1290 1291 try 1292 { 1293 if (JVM_SSL_DEBUGGING_ENABLED) 1294 { 1295 System.err.println("SSLUtil.applyEnabledSSLCipherSuites applying " + 1296 "cinpherSuitesToEnable " + Arrays.toString(cipherSuitesToEnable) + 1297 " to SSLServerSocket " + sslServerSocket); 1298 } 1299 1300 sslServerSocket.setEnabledCipherSuites(cipherSuitesToEnable); 1301 } 1302 catch (final Exception e) 1303 { 1304 Debug.debugException(e); 1305 } 1306 } 1307 1308 1309 1310 /** 1311 * Retrieves the names of the SSL cipher suites that should be enabled given 1312 * the provided information. 1313 * 1314 * @param desiredCipherSuites The set of cipher suites that are desired to 1315 * be enabled. 1316 * @param supportedCipherSuites The set of all cipher suites that are 1317 * supported. 1318 * 1319 * @return The names of the SSL cipher suites that should be enabled. 1320 * 1321 * @throws IOException If none of the desired values are included in the 1322 * supported set. 1323 */ 1324 @NotNull() 1325 private static String[] getSSLCipherSuitesToEnable( 1326 @NotNull final Set<String> desiredCipherSuites, 1327 @NotNull final String[] supportedCipherSuites) 1328 throws IOException 1329 { 1330 final Set<String> upperCipherSuites = new LinkedHashSet<>( 1331 StaticUtils.computeMapCapacity(desiredCipherSuites.size())); 1332 for (final String s : desiredCipherSuites) 1333 { 1334 upperCipherSuites.add(StaticUtils.toUpperCase(s)); 1335 } 1336 1337 final ArrayList<String> enabledList = 1338 new ArrayList<>(supportedCipherSuites.length); 1339 for (final String supportedCipherSuite : supportedCipherSuites) 1340 { 1341 if (upperCipherSuites.contains(StaticUtils.toUpperCase( 1342 supportedCipherSuite))) 1343 { 1344 enabledList.add(supportedCipherSuite); 1345 } 1346 } 1347 1348 if (enabledList.isEmpty()) 1349 { 1350 final StringBuilder enabledBuffer = new StringBuilder(); 1351 final Iterator<String> enabledIterator = desiredCipherSuites.iterator(); 1352 while (enabledIterator.hasNext()) 1353 { 1354 enabledBuffer.append('\''); 1355 enabledBuffer.append(enabledIterator.next()); 1356 enabledBuffer.append('\''); 1357 1358 if (enabledIterator.hasNext()) 1359 { 1360 enabledBuffer.append(", "); 1361 } 1362 } 1363 1364 final StringBuilder supportedBuffer = new StringBuilder(); 1365 for (int i=0; i < supportedCipherSuites.length; i++) 1366 { 1367 if (i > 0) 1368 { 1369 supportedBuffer.append(", "); 1370 } 1371 1372 supportedBuffer.append('\''); 1373 supportedBuffer.append(supportedCipherSuites[i]); 1374 supportedBuffer.append('\''); 1375 } 1376 1377 throw new IOException( 1378 ERR_NO_ENABLED_SSL_CIPHER_SUITES_AVAILABLE_FOR_SOCKET.get( 1379 enabledBuffer.toString(), supportedBuffer.toString(), 1380 PROPERTY_ENABLED_SSL_CIPHER_SUITES, 1381 SSLUtil.class.getName() + ".setEnabledSSLCipherSuites")); 1382 } 1383 else 1384 { 1385 return enabledList.toArray(StaticUtils.NO_STRINGS); 1386 } 1387 } 1388 1389 1390 1391 /** 1392 * Configures SSL default settings for the LDAP SDK. This method is 1393 * non-private for purposes of easier test coverage. 1394 */ 1395 static void configureSSLDefaults() 1396 { 1397 // Determine the set of TLS protocols that the JVM supports. 1398 String tls13Protocol = null; 1399 String tls12Protocol = null; 1400 String tls11Protocol = null; 1401 String tls1Protocol = null; 1402 try 1403 { 1404 final SSLContext defaultContext = CryptoHelper.getDefaultSSLContext(); 1405 for (final String supportedProtocol : 1406 defaultContext.getSupportedSSLParameters().getProtocols()) 1407 { 1408 if (supportedProtocol.equalsIgnoreCase(SSL_PROTOCOL_TLS_1_3)) 1409 { 1410 tls13Protocol = supportedProtocol; 1411 } 1412 else if (supportedProtocol.equalsIgnoreCase(SSL_PROTOCOL_TLS_1_2)) 1413 { 1414 tls12Protocol = supportedProtocol; 1415 } 1416 else if (supportedProtocol.equalsIgnoreCase(SSL_PROTOCOL_TLS_1_1)) 1417 { 1418 tls11Protocol = supportedProtocol; 1419 } 1420 else if (supportedProtocol.equalsIgnoreCase(SSL_PROTOCOL_TLS_1)) 1421 { 1422 tls1Protocol = supportedProtocol; 1423 } 1424 } 1425 } 1426 catch (final Exception e) 1427 { 1428 Debug.debugException(e); 1429 } 1430 1431 1432 // Determine the set of TLS protocols that should be enabled. 1433 final String enabledProtocolsPropertyValue = 1434 StaticUtils.getSystemProperty(PROPERTY_ENABLED_SSL_PROTOCOLS); 1435 final Set<String> enabledProtocols = new LinkedHashSet<>(); 1436 if (enabledProtocolsPropertyValue != null) 1437 { 1438 final StringTokenizer tokenizer = 1439 new StringTokenizer(enabledProtocolsPropertyValue, ", ", false); 1440 while (tokenizer.hasMoreTokens()) 1441 { 1442 final String enabledProtocol = tokenizer.nextToken().trim(); 1443 if (! enabledProtocol.isEmpty()) 1444 { 1445 enabledProtocols.add(enabledProtocol); 1446 } 1447 } 1448 } 1449 else 1450 { 1451 if (tls13Protocol != null) 1452 { 1453 enabledProtocols.add(tls13Protocol); 1454 if (tls12Protocol != null) 1455 { 1456 enabledProtocols.add(tls12Protocol); 1457 } 1458 } 1459 else if (tls12Protocol != null) 1460 { 1461 enabledProtocols.add(tls12Protocol); 1462 } 1463 else if (tls11Protocol != null) 1464 { 1465 enabledProtocols.add(tls11Protocol); 1466 } 1467 else if (tls1Protocol != null) 1468 { 1469 enabledProtocols.add(tls1Protocol); 1470 } 1471 } 1472 1473 ENABLED_SSL_PROTOCOLS.set(Collections.unmodifiableSet(enabledProtocols)); 1474 1475 1476 // Determine the default TLS protocol. 1477 final String defaultProtocol; 1478 final String defaultProtocolPropertyValue = 1479 StaticUtils.getSystemProperty(PROPERTY_DEFAULT_SSL_PROTOCOL); 1480 if (defaultProtocolPropertyValue != null) 1481 { 1482 defaultProtocol = defaultProtocolPropertyValue; 1483 } 1484 else 1485 { 1486 defaultProtocol = enabledProtocols.iterator().next(); 1487 } 1488 1489 DEFAULT_SSL_PROTOCOL.set(defaultProtocol); 1490 1491 1492 // Determine the set of TLS cipher suites to enable by default. 1493 TLSCipherSuiteSelector.recompute(); 1494 final String enabledSuitesPropertyValue = 1495 StaticUtils.getSystemProperty(PROPERTY_ENABLED_SSL_CIPHER_SUITES); 1496 final LinkedHashSet<String> enabledCipherSuites = new LinkedHashSet<>(); 1497 if ((enabledSuitesPropertyValue != null) && 1498 (! enabledSuitesPropertyValue.isEmpty())) 1499 { 1500 final StringTokenizer tokenizer = 1501 new StringTokenizer(enabledSuitesPropertyValue, ", ", false); 1502 while (tokenizer.hasMoreTokens()) 1503 { 1504 final String token = tokenizer.nextToken().trim(); 1505 if (! token.isEmpty()) 1506 { 1507 enabledCipherSuites.add(token); 1508 } 1509 } 1510 } 1511 else 1512 { 1513 enabledCipherSuites.addAll( 1514 TLSCipherSuiteSelector.getRecommendedCipherSuites()); 1515 } 1516 1517 ENABLED_SSL_CIPHER_SUITES.set(enabledCipherSuites); 1518 } 1519 1520 1521 1522 /** 1523 * Creates a string representation of the provided certificate. 1524 * 1525 * @param certificate The certificate for which to generate the string 1526 * representation. It must not be {@code null}. 1527 * 1528 * @return A string representation of the provided certificate. 1529 */ 1530 @NotNull() 1531 public static String certificateToString( 1532 @NotNull final X509Certificate certificate) 1533 { 1534 final StringBuilder buffer = new StringBuilder(); 1535 certificateToString(certificate, buffer); 1536 return buffer.toString(); 1537 } 1538 1539 1540 1541 /** 1542 * Appends a string representation of the provided certificate to the given 1543 * buffer. 1544 * 1545 * @param certificate The certificate for which to generate the string 1546 * representation. It must not be {@code null}. 1547 * @param buffer The buffer to which to append the string 1548 * representation. 1549 */ 1550 public static void certificateToString( 1551 @NotNull final X509Certificate certificate, 1552 @NotNull final StringBuilder buffer) 1553 { 1554 buffer.append("Certificate(subject='"); 1555 buffer.append( 1556 certificate.getSubjectX500Principal().getName(X500Principal.RFC2253)); 1557 buffer.append("', serialNumber="); 1558 buffer.append(certificate.getSerialNumber()); 1559 buffer.append(", notBefore="); 1560 StaticUtils.encodeGeneralizedTime(certificate.getNotBefore()); 1561 buffer.append(", notAfter="); 1562 StaticUtils.encodeGeneralizedTime(certificate.getNotAfter()); 1563 buffer.append(", signatureAlgorithm='"); 1564 buffer.append(certificate.getSigAlgName()); 1565 buffer.append("', signatureBytes='"); 1566 StaticUtils.toHex(certificate.getSignature(), buffer); 1567 buffer.append("', issuerSubject='"); 1568 buffer.append( 1569 certificate.getIssuerX500Principal().getName(X500Principal.RFC2253)); 1570 buffer.append("')"); 1571 } 1572}