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