1 /* 2 * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package sun.security.ssl; 27 28 import java.io.*; 29 import java.net.Socket; 30 import java.security.*; 31 import java.security.cert.*; 32 import java.util.*; 33 import java.util.concurrent.locks.ReentrantLock; 34 import javax.net.ssl.*; 35 import sun.security.action.GetPropertyAction; 36 import sun.security.provider.certpath.AlgorithmChecker; 37 import sun.security.validator.Validator; 38 39 /** 40 * Implementation of an SSLContext. 41 * 42 * Implementation note: Instances of this class and the child classes are 43 * immutable, except that the context initialization (SSLContext.init()) may 44 * reset the key, trust managers and source of secure random. 45 */ 46 47 public abstract class SSLContextImpl extends SSLContextSpi { 48 49 private final EphemeralKeyManager ephemeralKeyManager; 50 private final SSLSessionContextImpl clientCache; 51 private final SSLSessionContextImpl serverCache; 52 53 private boolean isInitialized; 54 55 private X509ExtendedKeyManager keyManager; 56 private X509TrustManager trustManager; 57 private SecureRandom secureRandom; 58 59 // DTLS cookie exchange manager 60 private volatile HelloCookieManager.Builder helloCookieManagerBuilder; 61 62 private final boolean clientEnableStapling = Utilities.getBooleanProperty( 63 "jdk.tls.client.enableStatusRequestExtension", true); 64 private final boolean serverEnableStapling = Utilities.getBooleanProperty( 65 "jdk.tls.server.enableStatusRequestExtension", false); 66 private static final Collection<CipherSuite> clientCustomizedCipherSuites = 67 getCustomizedCipherSuites("jdk.tls.client.cipherSuites"); 68 private static final Collection<CipherSuite> serverCustomizedCipherSuites = 69 getCustomizedCipherSuites("jdk.tls.server.cipherSuites"); 70 71 private volatile StatusResponseManager statusResponseManager; 72 73 private final ReentrantLock contextLock = new ReentrantLock(); 74 final HashMap<Integer, SessionTicketExtension.StatelessKey> keyHashMap = new HashMap<>(); 75 76 77 SSLContextImpl() { 78 ephemeralKeyManager = new EphemeralKeyManager(); 79 clientCache = new SSLSessionContextImpl(false); 80 serverCache = new SSLSessionContextImpl(true); 81 } 82 83 @Override 84 protected void engineInit(KeyManager[] km, TrustManager[] tm, 85 SecureRandom sr) throws KeyManagementException { 86 isInitialized = false; 87 keyManager = chooseKeyManager(km); 88 89 if (tm == null) { 90 try { 91 TrustManagerFactory tmf = TrustManagerFactory.getInstance( 92 TrustManagerFactory.getDefaultAlgorithm()); 93 tmf.init((KeyStore)null); 94 tm = tmf.getTrustManagers(); 95 } catch (Exception e) { 96 // eat 97 } 98 } 99 trustManager = chooseTrustManager(tm); 100 101 if (sr == null) { 102 secureRandom = new SecureRandom(); 103 } else { 104 secureRandom = sr; 105 } 106 107 /* 108 * The initial delay of seeding the random number generator 109 * could be long enough to cause the initial handshake on our 110 * first connection to timeout and fail. Make sure it is 111 * primed and ready by getting some initial output from it. 112 */ 113 if (SSLLogger.isOn && SSLLogger.isOn("ssl,sslctx")) { 114 SSLLogger.finest("trigger seeding of SecureRandom"); 115 } 116 secureRandom.nextInt(); 117 if (SSLLogger.isOn && SSLLogger.isOn("ssl,sslctx")) { 118 SSLLogger.finest("done seeding of SecureRandom"); 119 } 120 121 isInitialized = true; 122 } 123 124 private X509TrustManager chooseTrustManager(TrustManager[] tm) 125 throws KeyManagementException { 126 // We only use the first instance of X509TrustManager passed to us. 127 for (int i = 0; tm != null && i < tm.length; i++) { 128 if (tm[i] instanceof X509TrustManager) { 129 if (tm[i] instanceof X509ExtendedTrustManager) { 130 return (X509TrustManager)tm[i]; 131 } else { 132 return new AbstractTrustManagerWrapper( 133 (X509TrustManager)tm[i]); 134 } 135 } 136 } 137 138 // nothing found, return a dummy X509TrustManager. 139 return DummyX509TrustManager.INSTANCE; 140 } 141 142 private X509ExtendedKeyManager chooseKeyManager(KeyManager[] kms) 143 throws KeyManagementException { 144 for (int i = 0; kms != null && i < kms.length; i++) { 145 KeyManager km = kms[i]; 146 if (!(km instanceof X509KeyManager)) { 147 continue; 148 } 149 150 if (km instanceof X509ExtendedKeyManager) { 151 return (X509ExtendedKeyManager)km; 152 } 153 154 if (SSLLogger.isOn && SSLLogger.isOn("ssl,sslctx")) { 155 SSLLogger.warning( 156 "X509KeyManager passed to SSLContext.init(): need an " + 157 "X509ExtendedKeyManager for SSLEngine use"); 158 } 159 return new AbstractKeyManagerWrapper((X509KeyManager)km); 160 } 161 162 // nothing found, return a dummy X509ExtendedKeyManager 163 return DummyX509KeyManager.INSTANCE; 164 } 165 166 abstract SSLEngine createSSLEngineImpl(); 167 abstract SSLEngine createSSLEngineImpl(String host, int port); 168 169 @Override 170 protected SSLEngine engineCreateSSLEngine() { 171 if (!isInitialized) { 172 throw new IllegalStateException("SSLContext is not initialized"); 173 } 174 return createSSLEngineImpl(); 175 } 176 177 @Override 178 protected SSLEngine engineCreateSSLEngine(String host, int port) { 179 if (!isInitialized) { 180 throw new IllegalStateException("SSLContext is not initialized"); 181 } 182 return createSSLEngineImpl(host, port); 183 } 184 185 @Override 186 protected SSLSocketFactory engineGetSocketFactory() { 187 if (!isInitialized) { 188 throw new IllegalStateException("SSLContext is not initialized"); 189 } 190 if (isDTLS()) { 191 throw new UnsupportedOperationException( 192 "DTLS not supported with SSLSocket"); 193 } 194 return new SSLSocketFactoryImpl(this); 195 } 196 197 @Override 198 protected SSLServerSocketFactory engineGetServerSocketFactory() { 199 if (!isInitialized) { 200 throw new IllegalStateException("SSLContext is not initialized"); 201 } 202 if (isDTLS()) { 203 throw new UnsupportedOperationException( 204 "DTLS not supported with SSLServerSocket"); 205 } 206 return new SSLServerSocketFactoryImpl(this); 207 } 208 209 @Override 210 protected SSLSessionContext engineGetClientSessionContext() { 211 return clientCache; 212 } 213 214 @Override 215 protected SSLSessionContext engineGetServerSessionContext() { 216 return serverCache; 217 } 218 219 SecureRandom getSecureRandom() { 220 return secureRandom; 221 } 222 223 X509ExtendedKeyManager getX509KeyManager() { 224 return keyManager; 225 } 226 227 X509TrustManager getX509TrustManager() { 228 return trustManager; 229 } 230 231 EphemeralKeyManager getEphemeralKeyManager() { 232 return ephemeralKeyManager; 233 } 234 235 // Used for DTLS in server mode only. 236 HelloCookieManager getHelloCookieManager(ProtocolVersion protocolVersion) { 237 if (helloCookieManagerBuilder == null) { 238 contextLock.lock(); 239 try { 240 if (helloCookieManagerBuilder == null) { 241 helloCookieManagerBuilder = 242 new HelloCookieManager.Builder(secureRandom); 243 } 244 } finally { 245 contextLock.unlock(); 246 } 247 } 248 249 return helloCookieManagerBuilder.valueOf(protocolVersion); 250 } 251 252 StatusResponseManager getStatusResponseManager() { 253 if (serverEnableStapling && statusResponseManager == null) { 254 contextLock.lock(); 255 try { 256 if (statusResponseManager == null) { 257 if (SSLLogger.isOn && SSLLogger.isOn("ssl,sslctx")) { 258 SSLLogger.finest( 259 "Initializing StatusResponseManager"); 260 } 261 statusResponseManager = new StatusResponseManager(); 262 } 263 } finally { 264 contextLock.unlock(); 265 } 266 } 267 268 return statusResponseManager; 269 } 270 271 // Get supported protocols. 272 abstract List<ProtocolVersion> getSupportedProtocolVersions(); 273 274 // Get default protocols for server mode. 275 abstract List<ProtocolVersion> getServerDefaultProtocolVersions(); 276 277 // Get default protocols for client mode. 278 abstract List<ProtocolVersion> getClientDefaultProtocolVersions(); 279 280 // Get supported CipherSuite list. 281 abstract List<CipherSuite> getSupportedCipherSuites(); 282 283 // Get default CipherSuite list for server mode. 284 abstract List<CipherSuite> getServerDefaultCipherSuites(); 285 286 // Get default CipherSuite list for client mode. 287 abstract List<CipherSuite> getClientDefaultCipherSuites(); 288 289 // Is the context for DTLS protocols? 290 abstract boolean isDTLS(); 291 292 // Get default protocols. 293 List<ProtocolVersion> getDefaultProtocolVersions(boolean roleIsServer) { 294 return roleIsServer ? getServerDefaultProtocolVersions() 295 : getClientDefaultProtocolVersions(); 296 } 297 298 // Get default CipherSuite list. 299 List<CipherSuite> getDefaultCipherSuites(boolean roleIsServer) { 300 return roleIsServer ? getServerDefaultCipherSuites() 301 : getClientDefaultCipherSuites(); 302 } 303 304 /** 305 * Return whether a protocol list is the original default enabled 306 * protocols. See: SSLSocket/SSLEngine.setEnabledProtocols() 307 */ 308 boolean isDefaultProtocolVesions(List<ProtocolVersion> protocols) { 309 return (protocols == getServerDefaultProtocolVersions()) || 310 (protocols == getClientDefaultProtocolVersions()); 311 } 312 313 /** 314 * Return whether a protocol list is the original default enabled 315 * protocols. See: SSLSocket/SSLEngine.setEnabledProtocols() 316 */ 317 boolean isDefaultCipherSuiteList(List<CipherSuite> cipherSuites) { 318 return (cipherSuites == getServerDefaultCipherSuites()) || 319 (cipherSuites == getClientDefaultCipherSuites()); 320 } 321 322 /** 323 * Return whether client or server side stapling has been enabled 324 * for this SSLContextImpl 325 * @param isClient true if the caller is operating in a client side role, 326 * false if acting as a server. 327 * @return true if stapling has been enabled for the specified role, false 328 * otherwise. 329 */ 330 boolean isStaplingEnabled(boolean isClient) { 331 return isClient ? clientEnableStapling : serverEnableStapling; 332 } 333 334 /* 335 * Return the list of all available CipherSuites that are supported 336 * using currently installed providers. 337 */ 338 private static List<CipherSuite> getApplicableSupportedCipherSuites( 339 List<ProtocolVersion> protocols) { 340 341 return getApplicableCipherSuites( 342 CipherSuite.allowedCipherSuites(), protocols); 343 } 344 345 /* 346 * Return the list of all available CipherSuites that are default enabled 347 * in client or server side. 348 */ 349 private static List<CipherSuite> getApplicableEnabledCipherSuites( 350 List<ProtocolVersion> protocols, boolean isClient) { 351 352 if (isClient) { 353 if (!clientCustomizedCipherSuites.isEmpty()) { 354 return getApplicableCipherSuites( 355 clientCustomizedCipherSuites, protocols); 356 } 357 } else { 358 if (!serverCustomizedCipherSuites.isEmpty()) { 359 return getApplicableCipherSuites( 360 serverCustomizedCipherSuites, protocols); 361 } 362 } 363 364 return getApplicableCipherSuites( 365 CipherSuite.defaultCipherSuites(), protocols); 366 } 367 368 /* 369 * Return the list of available CipherSuites which are applicable to 370 * the specified protocols. 371 */ 372 private static List<CipherSuite> getApplicableCipherSuites( 373 Collection<CipherSuite> allowedCipherSuites, 374 List<ProtocolVersion> protocols) { 375 TreeSet<CipherSuite> suites = new TreeSet<>(); 376 if (protocols != null && (!protocols.isEmpty())) { 377 for (CipherSuite suite : allowedCipherSuites) { 378 if (!suite.isAvailable()) { 379 continue; 380 } 381 382 boolean isSupported = false; 383 for (ProtocolVersion protocol : protocols) { 384 if (!suite.supports(protocol) || 385 !suite.bulkCipher.isAvailable()) { 386 continue; 387 } 388 389 if (SSLAlgorithmConstraints.DEFAULT.permits( 390 EnumSet.of(CryptoPrimitive.KEY_AGREEMENT), 391 suite.name, null)) { 392 suites.add(suite); 393 isSupported = true; 394 } else if (SSLLogger.isOn && 395 SSLLogger.isOn("ssl,sslctx,verbose")) { 396 SSLLogger.fine( 397 "Ignore disabled cipher suite: " + suite.name); 398 } 399 400 break; 401 } 402 403 if (!isSupported && SSLLogger.isOn && 404 SSLLogger.isOn("ssl,sslctx,verbose")) { 405 SSLLogger.finest( 406 "Ignore unsupported cipher suite: " + suite); 407 } 408 } 409 } 410 411 return new ArrayList<>(suites); 412 } 413 414 /* 415 * Get the customized cipher suites specified by the given system property. 416 */ 417 private static Collection<CipherSuite> getCustomizedCipherSuites( 418 String propertyName) { 419 420 String property = GetPropertyAction.privilegedGetProperty(propertyName); 421 if (SSLLogger.isOn && SSLLogger.isOn("ssl,sslctx")) { 422 SSLLogger.fine( 423 "System property " + propertyName + " is set to '" + 424 property + "'"); 425 } 426 if (property != null && !property.isEmpty()) { 427 // remove double quote marks from beginning/end of the property 428 if (property.length() > 1 && property.charAt(0) == '"' && 429 property.charAt(property.length() - 1) == '"') { 430 property = property.substring(1, property.length() - 1); 431 } 432 } 433 434 if (property != null && !property.isEmpty()) { 435 String[] cipherSuiteNames = property.split(","); 436 Collection<CipherSuite> cipherSuites = 437 new ArrayList<>(cipherSuiteNames.length); 438 for (int i = 0; i < cipherSuiteNames.length; i++) { 439 cipherSuiteNames[i] = cipherSuiteNames[i].trim(); 440 if (cipherSuiteNames[i].isEmpty()) { 441 continue; 442 } 443 444 CipherSuite suite; 445 try { 446 suite = CipherSuite.nameOf(cipherSuiteNames[i]); 447 } catch (IllegalArgumentException iae) { 448 if (SSLLogger.isOn && SSLLogger.isOn("ssl,sslctx")) { 449 SSLLogger.fine( 450 "Unknown or unsupported cipher suite name: " + 451 cipherSuiteNames[i]); 452 } 453 454 continue; 455 } 456 457 if (suite != null && suite.isAvailable()) { 458 cipherSuites.add(suite); 459 } else { 460 if (SSLLogger.isOn && SSLLogger.isOn("ssl,sslctx")) { 461 SSLLogger.fine( 462 "The current installed providers do not " + 463 "support cipher suite: " + cipherSuiteNames[i]); 464 } 465 } 466 } 467 468 return cipherSuites; 469 } 470 471 return Collections.emptyList(); 472 } 473 474 475 private static List<ProtocolVersion> getAvailableProtocols( 476 ProtocolVersion[] protocolCandidates) { 477 478 List<ProtocolVersion> availableProtocols = 479 Collections.<ProtocolVersion>emptyList(); 480 if (protocolCandidates != null && protocolCandidates.length != 0) { 481 availableProtocols = new ArrayList<>(protocolCandidates.length); 482 for (ProtocolVersion p : protocolCandidates) { 483 if (p.isAvailable) { 484 availableProtocols.add(p); 485 } 486 } 487 } 488 489 return availableProtocols; 490 } 491 492 /* 493 * The SSLContext implementation for SSL/(D)TLS algorithm 494 * 495 * SSL/TLS protocols specify the forward compatibility and version 496 * roll-back attack protections, however, a number of SSL/TLS server 497 * vendors did not implement these aspects properly, and some current 498 * SSL/TLS servers may refuse to talk to a TLS 1.1 or later client. 499 * 500 * Considering above interoperability issues, SunJSSE will not set 501 * TLS 1.1 and TLS 1.2 as the enabled protocols for client by default. 502 * 503 * For SSL/TLS servers, there is no such interoperability issues as 504 * SSL/TLS clients. In SunJSSE, TLS 1.1 or later version will be the 505 * enabled protocols for server by default. 506 * 507 * We may change the behavior when popular TLS/SSL vendors support TLS 508 * forward compatibility properly. 509 * 510 * SSLv2Hello is no longer necessary. This interoperability option was 511 * put in place in the late 90's when SSLv3/TLS1.0 were relatively new 512 * and there were a fair number of SSLv2-only servers deployed. Because 513 * of the security issues in SSLv2, it is rarely (if ever) used, as 514 * deployments should now be using SSLv3 and TLSv1. 515 * 516 * Considering the issues of SSLv2Hello, we should not enable SSLv2Hello 517 * by default. Applications still can use it by enabling SSLv2Hello with 518 * the series of setEnabledProtocols APIs. 519 */ 520 521 /* 522 * The base abstract SSLContext implementation for the Transport Layer 523 * Security (TLS) protocols. 524 * 525 * This abstract class encapsulates supported and the default server 526 * SSL/TLS parameters. 527 * 528 * @see SSLContext 529 */ 530 private abstract static class AbstractTLSContext extends SSLContextImpl { 531 private static final List<ProtocolVersion> supportedProtocols; 532 private static final List<ProtocolVersion> serverDefaultProtocols; 533 534 private static final List<CipherSuite> supportedCipherSuites; 535 private static final List<CipherSuite> serverDefaultCipherSuites; 536 537 static { 538 supportedProtocols = Arrays.asList( 539 ProtocolVersion.TLS13, 540 ProtocolVersion.TLS12, 541 ProtocolVersion.TLS11, 542 ProtocolVersion.TLS10, 543 ProtocolVersion.SSL30, 544 ProtocolVersion.SSL20Hello 545 ); 546 547 serverDefaultProtocols = getAvailableProtocols( 548 new ProtocolVersion[] { 549 ProtocolVersion.TLS13, 550 ProtocolVersion.TLS12, 551 ProtocolVersion.TLS11, 552 ProtocolVersion.TLS10, 553 ProtocolVersion.SSL30, 554 ProtocolVersion.SSL20Hello 555 }); 556 557 supportedCipherSuites = getApplicableSupportedCipherSuites( 558 supportedProtocols); 559 serverDefaultCipherSuites = getApplicableEnabledCipherSuites( 560 serverDefaultProtocols, false); 561 } 562 563 @Override 564 List<ProtocolVersion> getSupportedProtocolVersions() { 565 return supportedProtocols; 566 } 567 568 @Override 569 List<CipherSuite> getSupportedCipherSuites() { 570 return supportedCipherSuites; 571 } 572 573 @Override 574 List<ProtocolVersion> getServerDefaultProtocolVersions() { 575 return serverDefaultProtocols; 576 } 577 578 @Override 579 List<CipherSuite> getServerDefaultCipherSuites() { 580 return serverDefaultCipherSuites; 581 } 582 583 @Override 584 SSLEngine createSSLEngineImpl() { 585 return new SSLEngineImpl(this); 586 } 587 588 @Override 589 SSLEngine createSSLEngineImpl(String host, int port) { 590 return new SSLEngineImpl(this, host, port); 591 } 592 593 @Override 594 boolean isDTLS() { 595 return false; 596 } 597 598 static ProtocolVersion[] getSupportedProtocols() { 599 return new ProtocolVersion[]{ 600 ProtocolVersion.TLS13, 601 ProtocolVersion.TLS12, 602 ProtocolVersion.TLS11, 603 ProtocolVersion.TLS10, 604 ProtocolVersion.SSL30, 605 ProtocolVersion.SSL20Hello 606 }; 607 } 608 } 609 610 /* 611 * The SSLContext implementation for SSLv3 and TLS10 algorithm 612 * 613 * @see SSLContext 614 */ 615 public static final class TLS10Context extends AbstractTLSContext { 616 private static final List<ProtocolVersion> clientDefaultProtocols; 617 private static final List<CipherSuite> clientDefaultCipherSuites; 618 619 static { 620 clientDefaultProtocols = getAvailableProtocols( 621 new ProtocolVersion[] { 622 ProtocolVersion.TLS10, 623 ProtocolVersion.SSL30 624 }); 625 626 clientDefaultCipherSuites = getApplicableEnabledCipherSuites( 627 clientDefaultProtocols, true); 628 } 629 630 @Override 631 List<ProtocolVersion> getClientDefaultProtocolVersions() { 632 return clientDefaultProtocols; 633 } 634 635 @Override 636 List<CipherSuite> getClientDefaultCipherSuites() { 637 return clientDefaultCipherSuites; 638 } 639 } 640 641 /* 642 * The SSLContext implementation for TLS11 algorithm 643 * 644 * @see SSLContext 645 */ 646 public static final class TLS11Context extends AbstractTLSContext { 647 private static final List<ProtocolVersion> clientDefaultProtocols; 648 private static final List<CipherSuite> clientDefaultCipherSuites; 649 650 static { 651 clientDefaultProtocols = getAvailableProtocols( 652 new ProtocolVersion[] { 653 ProtocolVersion.TLS11, 654 ProtocolVersion.TLS10, 655 ProtocolVersion.SSL30 656 }); 657 658 clientDefaultCipherSuites = getApplicableEnabledCipherSuites( 659 clientDefaultProtocols, true); 660 661 } 662 663 @Override 664 List<ProtocolVersion> getClientDefaultProtocolVersions() { 665 return clientDefaultProtocols; 666 } 667 668 @Override 669 List<CipherSuite> getClientDefaultCipherSuites() { 670 return clientDefaultCipherSuites; 671 } 672 } 673 674 /* 675 * The SSLContext implementation for TLS12 algorithm 676 * 677 * @see SSLContext 678 */ 679 public static final class TLS12Context extends AbstractTLSContext { 680 private static final List<ProtocolVersion> clientDefaultProtocols; 681 private static final List<CipherSuite> clientDefaultCipherSuites; 682 683 static { 684 clientDefaultProtocols = getAvailableProtocols( 685 new ProtocolVersion[] { 686 ProtocolVersion.TLS12, 687 ProtocolVersion.TLS11, 688 ProtocolVersion.TLS10, 689 ProtocolVersion.SSL30 690 }); 691 692 clientDefaultCipherSuites = getApplicableEnabledCipherSuites( 693 clientDefaultProtocols, true); 694 } 695 696 @Override 697 List<ProtocolVersion> getClientDefaultProtocolVersions() { 698 return clientDefaultProtocols; 699 } 700 701 @Override 702 List<CipherSuite> getClientDefaultCipherSuites() { 703 return clientDefaultCipherSuites; 704 } 705 } 706 707 /* 708 * The SSLContext implementation for TLS1.3 algorithm 709 * 710 * @see SSLContext 711 */ 712 public static final class TLS13Context extends AbstractTLSContext { 713 private static final List<ProtocolVersion> clientDefaultProtocols; 714 private static final List<CipherSuite> clientDefaultCipherSuites; 715 716 static { 717 clientDefaultProtocols = getAvailableProtocols( 718 new ProtocolVersion[] { 719 ProtocolVersion.TLS13, 720 ProtocolVersion.TLS12, 721 ProtocolVersion.TLS11, 722 ProtocolVersion.TLS10, 723 ProtocolVersion.SSL30 724 }); 725 726 clientDefaultCipherSuites = getApplicableEnabledCipherSuites( 727 clientDefaultProtocols, true); 728 } 729 730 @Override 731 List<ProtocolVersion> getClientDefaultProtocolVersions() { 732 return clientDefaultProtocols; 733 } 734 735 @Override 736 List<CipherSuite> getClientDefaultCipherSuites() { 737 return clientDefaultCipherSuites; 738 } 739 } 740 741 /* 742 * The interface for the customized SSL/(D)TLS SSLContext. 743 * 744 * @see SSLContext 745 */ 746 private static class CustomizedSSLProtocols { 747 private static final String JDK_TLS_CLIENT_PROTOCOLS = 748 "jdk.tls.client.protocols"; 749 private static final String JDK_TLS_SERVER_PROTOCOLS = 750 "jdk.tls.server.protocols"; 751 static IllegalArgumentException reservedException = null; 752 static final ArrayList<ProtocolVersion> customizedClientProtocols = 753 new ArrayList<>(); 754 static final ArrayList<ProtocolVersion> customizedServerProtocols = 755 new ArrayList<>(); 756 757 // Don't want a java.lang.LinkageError for illegal system property. 758 // 759 // Please don't throw exception in this static block. Otherwise, 760 // java.lang.LinkageError may be thrown during the instantiation of 761 // the provider service. Instead, please handle the initialization 762 // exception in the caller's constructor. 763 static { 764 populate(JDK_TLS_CLIENT_PROTOCOLS, customizedClientProtocols); 765 populate(JDK_TLS_SERVER_PROTOCOLS, customizedServerProtocols); 766 } 767 768 private static void populate(String propname, 769 ArrayList<ProtocolVersion> arrayList) { 770 String property = GetPropertyAction.privilegedGetProperty(propname); 771 if (property == null) { 772 return; 773 } 774 775 if (!property.isEmpty()) { 776 // remove double quote marks from beginning/end of the property 777 if (property.length() > 1 && property.charAt(0) == '"' && 778 property.charAt(property.length() - 1) == '"') { 779 property = property.substring(1, property.length() - 1); 780 } 781 } 782 783 if (!property.isEmpty()) { 784 String[] protocols = property.split(","); 785 for (int i = 0; i < protocols.length; i++) { 786 protocols[i] = protocols[i].trim(); 787 // Is it a supported protocol name? 788 ProtocolVersion pv = 789 ProtocolVersion.nameOf(protocols[i]); 790 if (pv == null) { 791 reservedException = new IllegalArgumentException( 792 propname + ": " + protocols[i] + 793 " is not a supported SSL protocol name"); 794 } 795 796 // ignore duplicated protocols 797 if (!arrayList.contains(pv)) { 798 arrayList.add(pv); 799 } 800 } 801 } 802 } 803 } 804 805 /* 806 * The SSLContext implementation for customized TLS protocols 807 * 808 * @see SSLContext 809 */ 810 private static class CustomizedTLSContext extends AbstractTLSContext { 811 812 private static final List<ProtocolVersion> clientDefaultProtocols; 813 private static final List<ProtocolVersion> serverDefaultProtocols; 814 private static final List<CipherSuite> clientDefaultCipherSuites; 815 private static final List<CipherSuite> serverDefaultCipherSuites; 816 private static final IllegalArgumentException reservedException; 817 818 // Don't want a java.lang.LinkageError for illegal system property. 819 // 820 // Please don't throw exception in this static block. Otherwise, 821 // java.lang.LinkageError may be thrown during the instantiation of 822 // the provider service. Instead, let's handle the initialization 823 // exception in constructor. 824 static { 825 reservedException = CustomizedSSLProtocols.reservedException; 826 if (reservedException == null) { 827 clientDefaultProtocols = customizedProtocols(true, 828 CustomizedSSLProtocols.customizedClientProtocols); 829 serverDefaultProtocols = customizedProtocols(false, 830 CustomizedSSLProtocols.customizedServerProtocols); 831 832 clientDefaultCipherSuites = 833 getApplicableEnabledCipherSuites( 834 clientDefaultProtocols, true); 835 serverDefaultCipherSuites = 836 getApplicableEnabledCipherSuites( 837 serverDefaultProtocols, false); 838 839 } else { 840 // unlikely to be used 841 clientDefaultProtocols = null; 842 serverDefaultProtocols = null; 843 clientDefaultCipherSuites = null; 844 serverDefaultCipherSuites = null; 845 } 846 } 847 848 private static List<ProtocolVersion> customizedProtocols( 849 boolean client, List<ProtocolVersion> customized) { 850 List<ProtocolVersion> refactored = new ArrayList<>(); 851 for (ProtocolVersion pv : customized) { 852 if (!pv.isDTLS) { 853 refactored.add(pv); 854 } 855 } 856 857 // Use the default enabled protocols if no customization 858 ProtocolVersion[] candidates; 859 if (refactored.isEmpty()) { 860 if (client) { 861 candidates = getProtocols(); 862 } else { 863 candidates = getSupportedProtocols(); 864 } 865 } else { 866 // Use the customized TLS protocols. 867 candidates = 868 refactored.toArray(new ProtocolVersion[refactored.size()]); 869 } 870 871 return getAvailableProtocols(candidates); 872 } 873 874 static ProtocolVersion[] getProtocols() { 875 return new ProtocolVersion[]{ 876 ProtocolVersion.TLS13, 877 ProtocolVersion.TLS12, 878 ProtocolVersion.TLS11, 879 ProtocolVersion.TLS10, 880 ProtocolVersion.SSL30 881 }; 882 } 883 884 protected CustomizedTLSContext() { 885 if (reservedException != null) { 886 throw reservedException; 887 } 888 } 889 890 @Override 891 List<ProtocolVersion> getClientDefaultProtocolVersions() { 892 return clientDefaultProtocols; 893 } 894 895 @Override 896 List<ProtocolVersion> getServerDefaultProtocolVersions() { 897 return serverDefaultProtocols; 898 } 899 900 @Override 901 List<CipherSuite> getClientDefaultCipherSuites() { 902 return clientDefaultCipherSuites; 903 } 904 905 @Override 906 List<CipherSuite> getServerDefaultCipherSuites() { 907 return serverDefaultCipherSuites; 908 } 909 910 911 } 912 913 /* 914 * The SSLContext implementation for default "TLS" algorithm 915 * 916 * @see SSLContext 917 */ 918 public static final class TLSContext extends CustomizedTLSContext { 919 // use the default constructor and methods 920 } 921 922 // lazy initialization holder class idiom for static default parameters 923 // 924 // See Effective Java Second Edition: Item 71. 925 private static final class DefaultManagersHolder { 926 private static final String NONE = "NONE"; 927 private static final String P11KEYSTORE = "PKCS11"; 928 929 private static final TrustManager[] trustManagers; 930 private static final KeyManager[] keyManagers; 931 932 private static final Exception reservedException; 933 934 static { 935 Exception reserved = null; 936 TrustManager[] tmMediator = null; 937 try { 938 tmMediator = getTrustManagers(); 939 } catch (Exception e) { 940 reserved = e; 941 if (SSLLogger.isOn && SSLLogger.isOn("ssl,defaultctx")) { 942 SSLLogger.warning( 943 "Failed to load default trust managers", e); 944 } 945 } 946 947 KeyManager[] kmMediator = null; 948 if (reserved == null) { 949 try { 950 kmMediator = getKeyManagers(); 951 } catch (Exception e) { 952 reserved = e; 953 if (SSLLogger.isOn && SSLLogger.isOn("ssl,defaultctx")) { 954 SSLLogger.warning( 955 "Failed to load default key managers", e); 956 } 957 } 958 } 959 960 if (reserved != null) { 961 trustManagers = new TrustManager[0]; 962 keyManagers = new KeyManager[0]; 963 964 // Important note: please don't reserve the original exception 965 // object, which may be not garbage collection friendly as 966 // 'reservedException' is a static filed. 967 reservedException = 968 new KeyManagementException(reserved.getMessage()); 969 } else { 970 trustManagers = tmMediator; 971 keyManagers = kmMediator; 972 973 reservedException = null; 974 } 975 } 976 977 private static TrustManager[] getTrustManagers() throws Exception { 978 TrustManagerFactory tmf = TrustManagerFactory.getInstance( 979 TrustManagerFactory.getDefaultAlgorithm()); 980 if ("SunJSSE".equals(tmf.getProvider().getName())) { 981 // The implementation will load the default KeyStore 982 // automatically. Cached trust materials may be used 983 // for performance improvement. 984 tmf.init((KeyStore)null); 985 } else { 986 // Use the explicitly specified KeyStore for third party's 987 // TrustManagerFactory implementation. 988 KeyStore ks = TrustStoreManager.getTrustedKeyStore(); 989 tmf.init(ks); 990 } 991 992 return tmf.getTrustManagers(); 993 } 994 995 private static KeyManager[] getKeyManagers() throws Exception { 996 997 final Map<String,String> props = new HashMap<>(); 998 AccessController.doPrivileged( 999 new PrivilegedExceptionAction<Object>() { 1000 @Override 1001 public Object run() throws Exception { 1002 props.put("keyStore", System.getProperty( 1003 "javax.net.ssl.keyStore", "")); 1004 props.put("keyStoreType", System.getProperty( 1005 "javax.net.ssl.keyStoreType", 1006 KeyStore.getDefaultType())); 1007 props.put("keyStoreProvider", System.getProperty( 1008 "javax.net.ssl.keyStoreProvider", "")); 1009 props.put("keyStorePasswd", System.getProperty( 1010 "javax.net.ssl.keyStorePassword", "")); 1011 return null; 1012 } 1013 }); 1014 1015 final String defaultKeyStore = props.get("keyStore"); 1016 String defaultKeyStoreType = props.get("keyStoreType"); 1017 String defaultKeyStoreProvider = props.get("keyStoreProvider"); 1018 if (SSLLogger.isOn && SSLLogger.isOn("ssl,defaultctx")) { 1019 SSLLogger.fine("keyStore is : " + defaultKeyStore); 1020 SSLLogger.fine("keyStore type is : " + 1021 defaultKeyStoreType); 1022 SSLLogger.fine("keyStore provider is : " + 1023 defaultKeyStoreProvider); 1024 } 1025 1026 if (P11KEYSTORE.equals(defaultKeyStoreType) && 1027 !NONE.equals(defaultKeyStore)) { 1028 throw new IllegalArgumentException("if keyStoreType is " 1029 + P11KEYSTORE + ", then keyStore must be " + NONE); 1030 } 1031 1032 FileInputStream fs = null; 1033 KeyStore ks = null; 1034 char[] passwd = null; 1035 try { 1036 if (!defaultKeyStore.isEmpty() && 1037 !NONE.equals(defaultKeyStore)) { 1038 fs = AccessController.doPrivileged( 1039 new PrivilegedExceptionAction<FileInputStream>() { 1040 @Override 1041 public FileInputStream run() throws Exception { 1042 return new FileInputStream(defaultKeyStore); 1043 } 1044 }); 1045 } 1046 1047 String defaultKeyStorePassword = props.get("keyStorePasswd"); 1048 if (!defaultKeyStorePassword.isEmpty()) { 1049 passwd = defaultKeyStorePassword.toCharArray(); 1050 } 1051 1052 /** 1053 * Try to initialize key store. 1054 */ 1055 if ((defaultKeyStoreType.length()) != 0) { 1056 if (SSLLogger.isOn && SSLLogger.isOn("ssl,defaultctx")) { 1057 SSLLogger.finest("init keystore"); 1058 } 1059 if (defaultKeyStoreProvider.isEmpty()) { 1060 ks = KeyStore.getInstance(defaultKeyStoreType); 1061 } else { 1062 ks = KeyStore.getInstance(defaultKeyStoreType, 1063 defaultKeyStoreProvider); 1064 } 1065 1066 // if defaultKeyStore is NONE, fs will be null 1067 ks.load(fs, passwd); 1068 } 1069 } finally { 1070 if (fs != null) { 1071 fs.close(); 1072 fs = null; 1073 } 1074 } 1075 1076 /* 1077 * Try to initialize key manager. 1078 */ 1079 if (SSLLogger.isOn && SSLLogger.isOn("ssl,defaultctx")) { 1080 SSLLogger.fine("init keymanager of type " + 1081 KeyManagerFactory.getDefaultAlgorithm()); 1082 } 1083 KeyManagerFactory kmf = KeyManagerFactory.getInstance( 1084 KeyManagerFactory.getDefaultAlgorithm()); 1085 1086 if (P11KEYSTORE.equals(defaultKeyStoreType)) { 1087 kmf.init(ks, null); // do not pass key passwd if using token 1088 } else { 1089 kmf.init(ks, passwd); 1090 } 1091 1092 return kmf.getKeyManagers(); 1093 } 1094 } 1095 1096 // lazy initialization holder class idiom for static default parameters 1097 // 1098 // See Effective Java Second Edition: Item 71. 1099 private static final class DefaultSSLContextHolder { 1100 1101 private static final SSLContextImpl sslContext; 1102 private static final Exception reservedException; 1103 1104 static { 1105 Exception reserved = null; 1106 SSLContextImpl mediator = null; 1107 if (DefaultManagersHolder.reservedException != null) { 1108 reserved = DefaultManagersHolder.reservedException; 1109 } else { 1110 try { 1111 mediator = new DefaultSSLContext(); 1112 } catch (Exception e) { 1113 // Important note: please don't reserve the original 1114 // exception object, which may be not garbage collection 1115 // friendly as 'reservedException' is a static filed. 1116 reserved = new KeyManagementException(e.getMessage()); 1117 if (SSLLogger.isOn && SSLLogger.isOn("ssl,defaultctx")) { 1118 SSLLogger.warning( 1119 "Failed to load default SSLContext", e); 1120 } 1121 } 1122 } 1123 1124 sslContext = mediator; 1125 reservedException = reserved; 1126 } 1127 } 1128 1129 /* 1130 * The SSLContext implementation for default "Default" algorithm 1131 * 1132 * @see SSLContext 1133 */ 1134 public static final class DefaultSSLContext extends CustomizedTLSContext { 1135 1136 // public constructor for SSLContext.getInstance("Default") 1137 public DefaultSSLContext() throws Exception { 1138 if (DefaultManagersHolder.reservedException != null) { 1139 throw DefaultManagersHolder.reservedException; 1140 } 1141 1142 try { 1143 super.engineInit(DefaultManagersHolder.keyManagers, 1144 DefaultManagersHolder.trustManagers, null); 1145 } catch (Exception e) { 1146 if (SSLLogger.isOn && SSLLogger.isOn("ssl,defaultctx")) { 1147 SSLLogger.fine("default context init failed: ", e); 1148 } 1149 throw e; 1150 } 1151 } 1152 1153 @Override 1154 protected void engineInit(KeyManager[] km, TrustManager[] tm, 1155 SecureRandom sr) throws KeyManagementException { 1156 throw new KeyManagementException 1157 ("Default SSLContext is initialized automatically"); 1158 } 1159 1160 static SSLContextImpl getDefaultImpl() throws Exception { 1161 if (DefaultSSLContextHolder.reservedException != null) { 1162 throw DefaultSSLContextHolder.reservedException; 1163 } 1164 1165 return DefaultSSLContextHolder.sslContext; 1166 } 1167 } 1168 1169 /* 1170 * The base abstract SSLContext implementation for the Datagram Transport 1171 * Layer Security (DTLS) protocols. 1172 * 1173 * This abstract class encapsulates supported and the default server DTLS 1174 * parameters. 1175 * 1176 * @see SSLContext 1177 */ 1178 private abstract static class AbstractDTLSContext extends SSLContextImpl { 1179 private static final List<ProtocolVersion> supportedProtocols; 1180 private static final List<ProtocolVersion> serverDefaultProtocols; 1181 1182 private static final List<CipherSuite> supportedCipherSuites; 1183 private static final List<CipherSuite> serverDefaultCipherSuites; 1184 1185 static { 1186 // Both DTLSv1.0 and DTLSv1.2 can be used in FIPS mode. 1187 supportedProtocols = Arrays.asList( 1188 ProtocolVersion.DTLS12, 1189 ProtocolVersion.DTLS10 1190 ); 1191 1192 // available protocols for server mode 1193 serverDefaultProtocols = getAvailableProtocols( 1194 new ProtocolVersion[] { 1195 ProtocolVersion.DTLS12, 1196 ProtocolVersion.DTLS10 1197 }); 1198 1199 supportedCipherSuites = getApplicableSupportedCipherSuites( 1200 supportedProtocols); 1201 serverDefaultCipherSuites = getApplicableEnabledCipherSuites( 1202 serverDefaultProtocols, false); 1203 } 1204 1205 @Override 1206 protected SSLParameters engineGetDefaultSSLParameters() { 1207 SSLEngine engine = createSSLEngineImpl(); 1208 return engine.getSSLParameters(); 1209 } 1210 1211 @Override 1212 protected SSLParameters engineGetSupportedSSLParameters() { 1213 SSLEngine engine = createSSLEngineImpl(); 1214 SSLParameters params = new SSLParameters(); 1215 params.setCipherSuites(engine.getSupportedCipherSuites()); 1216 params.setProtocols(engine.getSupportedProtocols()); 1217 return params; 1218 } 1219 1220 @Override 1221 List<ProtocolVersion> getSupportedProtocolVersions() { 1222 return supportedProtocols; 1223 } 1224 1225 @Override 1226 List<CipherSuite> getSupportedCipherSuites() { 1227 return supportedCipherSuites; 1228 } 1229 1230 @Override 1231 List<ProtocolVersion> getServerDefaultProtocolVersions() { 1232 return serverDefaultProtocols; 1233 } 1234 1235 @Override 1236 List<CipherSuite> getServerDefaultCipherSuites() { 1237 return serverDefaultCipherSuites; 1238 } 1239 1240 @Override 1241 SSLEngine createSSLEngineImpl() { 1242 return new SSLEngineImpl(this); 1243 } 1244 1245 @Override 1246 SSLEngine createSSLEngineImpl(String host, int port) { 1247 return new SSLEngineImpl(this, host, port); 1248 } 1249 1250 @Override 1251 boolean isDTLS() { 1252 return true; 1253 } 1254 } 1255 1256 /* 1257 * The SSLContext implementation for DTLSv1.0 algorithm. 1258 * 1259 * @see SSLContext 1260 */ 1261 public static final class DTLS10Context extends AbstractDTLSContext { 1262 private static final List<ProtocolVersion> clientDefaultProtocols; 1263 private static final List<CipherSuite> clientDefaultCipherSuites; 1264 1265 static { 1266 // available protocols for client mode 1267 clientDefaultProtocols = getAvailableProtocols( 1268 new ProtocolVersion[] { 1269 ProtocolVersion.DTLS10 1270 }); 1271 1272 clientDefaultCipherSuites = getApplicableEnabledCipherSuites( 1273 clientDefaultProtocols, true); 1274 } 1275 1276 @Override 1277 List<ProtocolVersion> getClientDefaultProtocolVersions() { 1278 return clientDefaultProtocols; 1279 } 1280 1281 @Override 1282 List<CipherSuite> getClientDefaultCipherSuites() { 1283 return clientDefaultCipherSuites; 1284 } 1285 } 1286 1287 /* 1288 * The SSLContext implementation for DTLSv1.2 algorithm. 1289 * 1290 * @see SSLContext 1291 */ 1292 public static final class DTLS12Context extends AbstractDTLSContext { 1293 private static final List<ProtocolVersion> clientDefaultProtocols; 1294 private static final List<CipherSuite> clientDefaultCipherSuites; 1295 1296 static { 1297 // available protocols for client mode 1298 clientDefaultProtocols = getAvailableProtocols( 1299 new ProtocolVersion[] { 1300 ProtocolVersion.DTLS12, 1301 ProtocolVersion.DTLS10 1302 }); 1303 1304 clientDefaultCipherSuites = getApplicableEnabledCipherSuites( 1305 clientDefaultProtocols, true); 1306 } 1307 1308 @Override 1309 List<ProtocolVersion> getClientDefaultProtocolVersions() { 1310 return clientDefaultProtocols; 1311 } 1312 1313 @Override 1314 List<CipherSuite> getClientDefaultCipherSuites() { 1315 return clientDefaultCipherSuites; 1316 } 1317 } 1318 1319 /* 1320 * The SSLContext implementation for customized TLS protocols 1321 * 1322 * @see SSLContext 1323 */ 1324 private static class CustomizedDTLSContext extends AbstractDTLSContext { 1325 private static final List<ProtocolVersion> clientDefaultProtocols; 1326 private static final List<ProtocolVersion> serverDefaultProtocols; 1327 private static final List<CipherSuite> clientDefaultCipherSuites; 1328 private static final List<CipherSuite> serverDefaultCipherSuites; 1329 1330 private static IllegalArgumentException reservedException = null; 1331 1332 // Don't want a java.lang.LinkageError for illegal system property. 1333 // 1334 // Please don't throw exception in this static block. Otherwise, 1335 // java.lang.LinkageError may be thrown during the instantiation of 1336 // the provider service. Instead, let's handle the initialization 1337 // exception in constructor. 1338 static { 1339 reservedException = CustomizedSSLProtocols.reservedException; 1340 if (reservedException == null) { 1341 clientDefaultProtocols = customizedProtocols(true, 1342 CustomizedSSLProtocols.customizedClientProtocols); 1343 serverDefaultProtocols = customizedProtocols(false, 1344 CustomizedSSLProtocols.customizedServerProtocols); 1345 1346 clientDefaultCipherSuites = 1347 getApplicableEnabledCipherSuites( 1348 clientDefaultProtocols, true); 1349 serverDefaultCipherSuites = 1350 getApplicableEnabledCipherSuites( 1351 serverDefaultProtocols, false); 1352 1353 } else { 1354 // unlikely to be used 1355 clientDefaultProtocols = null; 1356 serverDefaultProtocols = null; 1357 clientDefaultCipherSuites = null; 1358 serverDefaultCipherSuites = null; 1359 } 1360 } 1361 1362 private static List<ProtocolVersion> customizedProtocols(boolean client, 1363 List<ProtocolVersion> customized) { 1364 List<ProtocolVersion> refactored = new ArrayList<>(); 1365 for (ProtocolVersion pv : customized) { 1366 if (pv.isDTLS) { 1367 refactored.add(pv); 1368 } 1369 } 1370 1371 ProtocolVersion[] candidates; 1372 // Use the default enabled protocols if no customization 1373 if (refactored.isEmpty()) { 1374 candidates = new ProtocolVersion[]{ 1375 ProtocolVersion.DTLS12, 1376 ProtocolVersion.DTLS10 1377 }; 1378 if (!client) 1379 return Arrays.asList(candidates); 1380 } else { 1381 // Use the customized TLS protocols. 1382 candidates = 1383 new ProtocolVersion[customized.size()]; 1384 candidates = customized.toArray(candidates); 1385 } 1386 1387 return getAvailableProtocols(candidates); 1388 } 1389 1390 protected CustomizedDTLSContext() { 1391 if (reservedException != null) { 1392 throw reservedException; 1393 } 1394 } 1395 1396 @Override 1397 List<ProtocolVersion> getClientDefaultProtocolVersions() { 1398 return clientDefaultProtocols; 1399 } 1400 1401 @Override 1402 List<ProtocolVersion> getServerDefaultProtocolVersions() { 1403 return serverDefaultProtocols; 1404 } 1405 1406 @Override 1407 List<CipherSuite> getClientDefaultCipherSuites() { 1408 return clientDefaultCipherSuites; 1409 } 1410 1411 @Override 1412 List<CipherSuite> getServerDefaultCipherSuites() { 1413 return serverDefaultCipherSuites; 1414 } 1415 } 1416 1417 /* 1418 * The SSLContext implementation for default "DTLS" algorithm 1419 * 1420 * @see SSLContext 1421 */ 1422 public static final class DTLSContext extends CustomizedDTLSContext { 1423 // use the default constructor and methods 1424 } 1425 1426 } 1427 1428 final class AbstractTrustManagerWrapper extends X509ExtendedTrustManager 1429 implements X509TrustManager { 1430 1431 // the delegated trust manager 1432 private final X509TrustManager tm; 1433 1434 AbstractTrustManagerWrapper(X509TrustManager tm) { 1435 this.tm = tm; 1436 } 1437 1438 @Override 1439 public void checkClientTrusted(X509Certificate[] chain, String authType) 1440 throws CertificateException { 1441 tm.checkClientTrusted(chain, authType); 1442 } 1443 1444 @Override 1445 public void checkServerTrusted(X509Certificate[] chain, String authType) 1446 throws CertificateException { 1447 tm.checkServerTrusted(chain, authType); 1448 } 1449 1450 @Override 1451 public X509Certificate[] getAcceptedIssuers() { 1452 return tm.getAcceptedIssuers(); 1453 } 1454 1455 @Override 1456 public void checkClientTrusted(X509Certificate[] chain, String authType, 1457 Socket socket) throws CertificateException { 1458 tm.checkClientTrusted(chain, authType); 1459 checkAdditionalTrust(chain, authType, socket, true); 1460 } 1461 1462 @Override 1463 public void checkServerTrusted(X509Certificate[] chain, String authType, 1464 Socket socket) throws CertificateException { 1465 tm.checkServerTrusted(chain, authType); 1466 checkAdditionalTrust(chain, authType, socket, false); 1467 } 1468 1469 @Override 1470 public void checkClientTrusted(X509Certificate[] chain, String authType, 1471 SSLEngine engine) throws CertificateException { 1472 tm.checkClientTrusted(chain, authType); 1473 checkAdditionalTrust(chain, authType, engine, true); 1474 } 1475 1476 @Override 1477 public void checkServerTrusted(X509Certificate[] chain, String authType, 1478 SSLEngine engine) throws CertificateException { 1479 tm.checkServerTrusted(chain, authType); 1480 checkAdditionalTrust(chain, authType, engine, false); 1481 } 1482 1483 private void checkAdditionalTrust(X509Certificate[] chain, 1484 String authType, Socket socket, 1485 boolean checkClientTrusted) throws CertificateException { 1486 if (socket != null && socket.isConnected() && 1487 socket instanceof SSLSocket) { 1488 1489 SSLSocket sslSocket = (SSLSocket)socket; 1490 SSLSession session = sslSocket.getHandshakeSession(); 1491 if (session == null) { 1492 throw new CertificateException("No handshake session"); 1493 } 1494 1495 // check endpoint identity 1496 String identityAlg = sslSocket.getSSLParameters(). 1497 getEndpointIdentificationAlgorithm(); 1498 if (identityAlg != null && !identityAlg.isEmpty()) { 1499 X509TrustManagerImpl.checkIdentity(session, chain, 1500 identityAlg, checkClientTrusted); 1501 } 1502 1503 // try the best to check the algorithm constraints 1504 AlgorithmConstraints constraints; 1505 if (ProtocolVersion.useTLS12PlusSpec(session.getProtocol())) { 1506 if (session instanceof ExtendedSSLSession) { 1507 ExtendedSSLSession extSession = 1508 (ExtendedSSLSession)session; 1509 String[] peerSupportedSignAlgs = 1510 extSession.getLocalSupportedSignatureAlgorithms(); 1511 1512 constraints = new SSLAlgorithmConstraints( 1513 sslSocket, peerSupportedSignAlgs, true); 1514 } else { 1515 constraints = 1516 new SSLAlgorithmConstraints(sslSocket, true); 1517 } 1518 } else { 1519 constraints = new SSLAlgorithmConstraints(sslSocket, true); 1520 } 1521 1522 checkAlgorithmConstraints(chain, constraints, checkClientTrusted); 1523 } 1524 } 1525 1526 private void checkAdditionalTrust(X509Certificate[] chain, 1527 String authType, SSLEngine engine, 1528 boolean checkClientTrusted) throws CertificateException { 1529 if (engine != null) { 1530 SSLSession session = engine.getHandshakeSession(); 1531 if (session == null) { 1532 throw new CertificateException("No handshake session"); 1533 } 1534 1535 // check endpoint identity 1536 String identityAlg = engine.getSSLParameters(). 1537 getEndpointIdentificationAlgorithm(); 1538 if (identityAlg != null && !identityAlg.isEmpty()) { 1539 X509TrustManagerImpl.checkIdentity(session, chain, 1540 identityAlg, checkClientTrusted); 1541 } 1542 1543 // try the best to check the algorithm constraints 1544 AlgorithmConstraints constraints; 1545 if (ProtocolVersion.useTLS12PlusSpec(session.getProtocol())) { 1546 if (session instanceof ExtendedSSLSession) { 1547 ExtendedSSLSession extSession = 1548 (ExtendedSSLSession)session; 1549 String[] peerSupportedSignAlgs = 1550 extSession.getLocalSupportedSignatureAlgorithms(); 1551 1552 constraints = new SSLAlgorithmConstraints( 1553 engine, peerSupportedSignAlgs, true); 1554 } else { 1555 constraints = 1556 new SSLAlgorithmConstraints(engine, true); 1557 } 1558 } else { 1559 constraints = new SSLAlgorithmConstraints(engine, true); 1560 } 1561 1562 checkAlgorithmConstraints(chain, constraints, checkClientTrusted); 1563 } 1564 } 1565 1566 private void checkAlgorithmConstraints(X509Certificate[] chain, 1567 AlgorithmConstraints constraints, 1568 boolean checkClientTrusted) throws CertificateException { 1569 try { 1570 // Does the certificate chain end with a trusted certificate? 1571 int checkedLength = chain.length - 1; 1572 1573 Collection<X509Certificate> trustedCerts = new HashSet<>(); 1574 X509Certificate[] certs = tm.getAcceptedIssuers(); 1575 if ((certs != null) && (certs.length > 0)){ 1576 Collections.addAll(trustedCerts, certs); 1577 } 1578 1579 if (trustedCerts.contains(chain[checkedLength])) { 1580 checkedLength--; 1581 } 1582 1583 // A forward checker, need to check from trust to target 1584 if (checkedLength >= 0) { 1585 AlgorithmChecker checker = 1586 new AlgorithmChecker(constraints, null, 1587 (checkClientTrusted ? Validator.VAR_TLS_CLIENT : 1588 Validator.VAR_TLS_SERVER)); 1589 checker.init(false); 1590 for (int i = checkedLength; i >= 0; i--) { 1591 X509Certificate cert = chain[i]; 1592 // We don't care about the unresolved critical extensions. 1593 checker.check(cert, Collections.<String>emptySet()); 1594 } 1595 } 1596 } catch (CertPathValidatorException cpve) { 1597 throw new CertificateException( 1598 "Certificates do not conform to algorithm constraints", cpve); 1599 } 1600 } 1601 } 1602 1603 // Dummy X509TrustManager implementation, rejects all peer certificates. 1604 // Used if the application did not specify a proper X509TrustManager. 1605 final class DummyX509TrustManager extends X509ExtendedTrustManager 1606 implements X509TrustManager { 1607 1608 static final X509TrustManager INSTANCE = new DummyX509TrustManager(); 1609 1610 private DummyX509TrustManager() { 1611 // empty 1612 } 1613 1614 /* 1615 * Given the partial or complete certificate chain 1616 * provided by the peer, build a certificate path 1617 * to a trusted root and return if it can be 1618 * validated and is trusted for client SSL authentication. 1619 * If not, it throws an exception. 1620 */ 1621 @Override 1622 public void checkClientTrusted(X509Certificate[] chain, String authType) 1623 throws CertificateException { 1624 throw new CertificateException( 1625 "No X509TrustManager implementation avaiable"); 1626 } 1627 1628 /* 1629 * Given the partial or complete certificate chain 1630 * provided by the peer, build a certificate path 1631 * to a trusted root and return if it can be 1632 * validated and is trusted for server SSL authentication. 1633 * If not, it throws an exception. 1634 */ 1635 @Override 1636 public void checkServerTrusted(X509Certificate[] chain, String authType) 1637 throws CertificateException { 1638 throw new CertificateException( 1639 "No X509TrustManager implementation available"); 1640 } 1641 1642 /* 1643 * Return an array of issuer certificates which are trusted 1644 * for authenticating peers. 1645 */ 1646 @Override 1647 public X509Certificate[] getAcceptedIssuers() { 1648 return new X509Certificate[0]; 1649 } 1650 1651 @Override 1652 public void checkClientTrusted(X509Certificate[] chain, String authType, 1653 Socket socket) throws CertificateException { 1654 throw new CertificateException( 1655 "No X509TrustManager implementation available"); 1656 } 1657 1658 @Override 1659 public void checkServerTrusted(X509Certificate[] chain, String authType, 1660 Socket socket) throws CertificateException { 1661 throw new CertificateException( 1662 "No X509TrustManager implementation available"); 1663 } 1664 1665 @Override 1666 public void checkClientTrusted(X509Certificate[] chain, String authType, 1667 SSLEngine engine) throws CertificateException { 1668 throw new CertificateException( 1669 "No X509TrustManager implementation available"); 1670 } 1671 1672 @Override 1673 public void checkServerTrusted(X509Certificate[] chain, String authType, 1674 SSLEngine engine) throws CertificateException { 1675 throw new CertificateException( 1676 "No X509TrustManager implementation available"); 1677 } 1678 } 1679 1680 /* 1681 * A wrapper class to turn a X509KeyManager into an X509ExtendedKeyManager 1682 */ 1683 final class AbstractKeyManagerWrapper extends X509ExtendedKeyManager { 1684 1685 private final X509KeyManager km; 1686 1687 AbstractKeyManagerWrapper(X509KeyManager km) { 1688 this.km = km; 1689 } 1690 1691 @Override 1692 public String[] getClientAliases(String keyType, Principal[] issuers) { 1693 return km.getClientAliases(keyType, issuers); 1694 } 1695 1696 @Override 1697 public String chooseClientAlias(String[] keyType, Principal[] issuers, 1698 Socket socket) { 1699 return km.chooseClientAlias(keyType, issuers, socket); 1700 } 1701 1702 @Override 1703 public String[] getServerAliases(String keyType, Principal[] issuers) { 1704 return km.getServerAliases(keyType, issuers); 1705 } 1706 1707 @Override 1708 public String chooseServerAlias(String keyType, Principal[] issuers, 1709 Socket socket) { 1710 return km.chooseServerAlias(keyType, issuers, socket); 1711 } 1712 1713 @Override 1714 public X509Certificate[] getCertificateChain(String alias) { 1715 return km.getCertificateChain(alias); 1716 } 1717 1718 @Override 1719 public PrivateKey getPrivateKey(String alias) { 1720 return km.getPrivateKey(alias); 1721 } 1722 1723 // Inherit chooseEngineClientAlias() and chooseEngineServerAlias() from 1724 // X509ExtendedKeymanager. It defines them to return null; 1725 } 1726 1727 1728 // Dummy X509KeyManager implementation, never returns any certificates/keys. 1729 // Used if the application did not specify a proper X509TrustManager. 1730 final class DummyX509KeyManager extends X509ExtendedKeyManager { 1731 1732 static final X509ExtendedKeyManager INSTANCE = new DummyX509KeyManager(); 1733 1734 private DummyX509KeyManager() { 1735 // empty 1736 } 1737 1738 /* 1739 * Get the matching aliases for authenticating the client side of a secure 1740 * socket given the public key type and the list of 1741 * certificate issuer authorities recognized by the peer (if any). 1742 */ 1743 @Override 1744 public String[] getClientAliases(String keyType, Principal[] issuers) { 1745 return null; 1746 } 1747 1748 /* 1749 * Choose an alias to authenticate the client side of a secure 1750 * socket given the public key type and the list of 1751 * certificate issuer authorities recognized by the peer (if any). 1752 */ 1753 @Override 1754 public String chooseClientAlias(String[] keyTypes, Principal[] issuers, 1755 Socket socket) { 1756 return null; 1757 } 1758 1759 /* 1760 * Choose an alias to authenticate the client side of an 1761 * engine given the public key type and the list of 1762 * certificate issuer authorities recognized by the peer (if any). 1763 */ 1764 @Override 1765 public String chooseEngineClientAlias( 1766 String[] keyTypes, Principal[] issuers, SSLEngine engine) { 1767 return null; 1768 } 1769 1770 /* 1771 * Get the matching aliases for authenticating the server side of a secure 1772 * socket given the public key type and the list of 1773 * certificate issuer authorities recognized by the peer (if any). 1774 */ 1775 @Override 1776 public String[] getServerAliases(String keyType, Principal[] issuers) { 1777 return null; 1778 } 1779 1780 /* 1781 * Choose an alias to authenticate the server side of a secure 1782 * socket given the public key type and the list of 1783 * certificate issuer authorities recognized by the peer (if any). 1784 */ 1785 @Override 1786 public String chooseServerAlias(String keyType, Principal[] issuers, 1787 Socket socket) { 1788 return null; 1789 } 1790 1791 /* 1792 * Choose an alias to authenticate the server side of an engine 1793 * given the public key type and the list of 1794 * certificate issuer authorities recognized by the peer (if any). 1795 */ 1796 @Override 1797 public String chooseEngineServerAlias( 1798 String keyType, Principal[] issuers, SSLEngine engine) { 1799 return null; 1800 } 1801 1802 /** 1803 * Returns the certificate chain associated with the given alias. 1804 * 1805 * @param alias the alias name 1806 * 1807 * @return the certificate chain (ordered with the user's certificate first 1808 * and the root certificate authority last) 1809 */ 1810 @Override 1811 public X509Certificate[] getCertificateChain(String alias) { 1812 return null; 1813 } 1814 1815 /* 1816 * Returns the key associated with the given alias, using the given 1817 * password to recover it. 1818 * 1819 * @param alias the alias name 1820 * 1821 * @return the requested key 1822 */ 1823 @Override 1824 public PrivateKey getPrivateKey(String alias) { 1825 return null; 1826 } 1827 }