< prev index next >

src/share/classes/sun/security/ssl/SSLContextImpl.java

Print this page
rev 11548 : 8133070: Hot lock on BulkCipher.isAvailable
Reviewed-by: mullan
Contributed-by: xuelei.fan@oracle.com, kungu.mjh@alibaba-inc.com
   1 /*
   2  * Copyright (c) 1999, 2013, 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


  35 
  36 import javax.net.ssl.*;
  37 
  38 import sun.security.provider.certpath.AlgorithmChecker;
  39 import sun.security.action.GetPropertyAction;
  40 
  41 public abstract class SSLContextImpl extends SSLContextSpi {
  42 
  43     private static final Debug debug = Debug.getInstance("ssl");
  44 
  45     private final EphemeralKeyManager ephemeralKeyManager;
  46     private final SSLSessionContextImpl clientCache;
  47     private final SSLSessionContextImpl serverCache;
  48 
  49     private boolean isInitialized;
  50 
  51     private X509ExtendedKeyManager keyManager;
  52     private X509TrustManager trustManager;
  53     private SecureRandom secureRandom;
  54 
  55     // supported and default protocols
  56     private ProtocolList defaultServerProtocolList;
  57     private ProtocolList defaultClientProtocolList;
  58     private ProtocolList supportedProtocolList;
  59 
  60     // supported and default cipher suites
  61     private CipherSuiteList defaultServerCipherSuiteList;
  62     private CipherSuiteList defaultClientCipherSuiteList;
  63     private CipherSuiteList supportedCipherSuiteList;
  64 
  65     SSLContextImpl() {
  66         ephemeralKeyManager = new EphemeralKeyManager();
  67         clientCache = new SSLSessionContextImpl();
  68         serverCache = new SSLSessionContextImpl();
  69     }
  70 
  71     @Override
  72     protected void engineInit(KeyManager[] km, TrustManager[] tm,
  73                                 SecureRandom sr) throws KeyManagementException {
  74         isInitialized = false;
  75         keyManager = chooseKeyManager(km);
  76 
  77         if (tm == null) {
  78             try {
  79                 TrustManagerFactory tmf = TrustManagerFactory.getInstance(
  80                         TrustManagerFactory.getDefaultAlgorithm());
  81                 tmf.init((KeyStore)null);
  82                 tm = tmf.getTrustManagers();
  83             } catch (Exception e) {
  84                 // eat


 174         // nothing found, return a dummy X509ExtendedKeyManager
 175         return DummyX509KeyManager.INSTANCE;
 176     }
 177 
 178     @Override
 179     protected SSLSocketFactory engineGetSocketFactory() {
 180         if (!isInitialized) {
 181             throw new IllegalStateException(
 182                 "SSLContextImpl is not initialized");
 183         }
 184        return new SSLSocketFactoryImpl(this);
 185     }
 186 
 187     @Override
 188     protected SSLServerSocketFactory engineGetServerSocketFactory() {
 189         if (!isInitialized) {
 190             throw new IllegalStateException("SSLContext is not initialized");
 191         }
 192         return new SSLServerSocketFactoryImpl(this);
 193     }


 194 
 195     @Override
 196     protected SSLEngine engineCreateSSLEngine() {
 197         if (!isInitialized) {
 198             throw new IllegalStateException(
 199                 "SSLContextImpl is not initialized");
 200         }
 201         return new SSLEngineImpl(this);
 202     }
 203 
 204     @Override
 205     protected SSLEngine engineCreateSSLEngine(String host, int port) {
 206         if (!isInitialized) {
 207             throw new IllegalStateException(
 208                 "SSLContextImpl is not initialized");
 209         }
 210         return new SSLEngineImpl(this, host, port);
 211     }
 212 
 213     @Override
 214     protected SSLSessionContext engineGetClientSessionContext() {
 215         return clientCache;
 216     }
 217 
 218     @Override
 219     protected SSLSessionContext engineGetServerSessionContext() {
 220         return serverCache;
 221     }
 222 
 223     SecureRandom getSecureRandom() {
 224         return secureRandom;
 225     }
 226 
 227     X509ExtendedKeyManager getX509KeyManager() {
 228         return keyManager;
 229     }
 230 
 231     X509TrustManager getX509TrustManager() {
 232         return trustManager;
 233     }
 234 
 235     EphemeralKeyManager getEphemeralKeyManager() {
 236         return ephemeralKeyManager;
 237     }
 238 
 239     abstract SSLParameters getDefaultServerSSLParams();
 240     abstract SSLParameters getDefaultClientSSLParams();
 241     abstract SSLParameters getSupportedSSLParams();
 242 
 243     // Get supported ProtocolList.
 244     ProtocolList getSuportedProtocolList() {
 245         if (supportedProtocolList == null) {
 246             supportedProtocolList =
 247                 new ProtocolList(getSupportedSSLParams().getProtocols());
 248         }
 249 
 250         return supportedProtocolList;
 251     }
 252 
 253     // Get default ProtocolList.
 254     ProtocolList getDefaultProtocolList(boolean roleIsServer) {
 255         if (roleIsServer) {
 256             if (defaultServerProtocolList == null) {
 257                 defaultServerProtocolList = new ProtocolList(
 258                         getDefaultServerSSLParams().getProtocols());
 259             }
 260 
 261             return defaultServerProtocolList;
 262         } else {
 263             if (defaultClientProtocolList == null) {
 264                 defaultClientProtocolList = new ProtocolList(
 265                         getDefaultClientSSLParams().getProtocols());
 266             }
 267 
 268             return defaultClientProtocolList;
 269         }
 270     }
 271 
 272     // Get supported CipherSuiteList.
 273     CipherSuiteList getSupportedCipherSuiteList() {
 274         // The maintenance of cipher suites needs to be synchronized.
 275         synchronized (this) {
 276             // Clear cache of available ciphersuites.
 277             clearAvailableCache();
 278 
 279             if (supportedCipherSuiteList == null) {
 280                 supportedCipherSuiteList = getApplicableCipherSuiteList(
 281                         getSuportedProtocolList(), false);
 282             }
 283 
 284             return supportedCipherSuiteList;
 285         }





 286     }
 287 
 288     // Get default CipherSuiteList.
 289     CipherSuiteList getDefaultCipherSuiteList(boolean roleIsServer) {
 290         // The maintenance of cipher suites needs to be synchronized.
 291         synchronized (this) {
 292             // Clear cache of available ciphersuites.
 293             clearAvailableCache();
 294 
 295             if (roleIsServer) {
 296                 if (defaultServerCipherSuiteList == null) {
 297                     defaultServerCipherSuiteList = getApplicableCipherSuiteList(
 298                         getDefaultProtocolList(true), true);
 299                 }
 300 
 301                 return defaultServerCipherSuiteList;
 302             } else {
 303                 if (defaultClientCipherSuiteList == null) {
 304                     defaultClientCipherSuiteList = getApplicableCipherSuiteList(
 305                         getDefaultProtocolList(false), true);
 306                 }
 307 
 308                 return defaultClientCipherSuiteList;
 309             }
 310         }
 311     }
 312 
 313     /**
 314      * Return whether a protocol list is the original default enabled
 315      * protocols.  See: SSLSocket/SSLEngine.setEnabledProtocols()
 316      */
 317     boolean isDefaultProtocolList(ProtocolList protocols) {
 318         return (protocols == defaultServerProtocolList) ||
 319                (protocols == defaultClientProtocolList);
 320     }
 321 








 322 
 323     /*
 324      * Return the list of all available CipherSuites with a priority of
 325      * minPriority or above.
 326      */
 327     private CipherSuiteList getApplicableCipherSuiteList(
 328             ProtocolList protocols, boolean onlyEnabled) {
 329 
 330         int minPriority = CipherSuite.SUPPORTED_SUITES_PRIORITY;
 331         if (onlyEnabled) {
 332             minPriority = CipherSuite.DEFAULT_SUITES_PRIORITY;
 333         }
 334 
 335         Collection<CipherSuite> allowedCipherSuites =
 336                                     CipherSuite.allowedCipherSuites();
 337 
 338         TreeSet<CipherSuite> suites = new TreeSet<>();
 339         if (!(protocols.collection().isEmpty()) &&
 340                 protocols.min.v != ProtocolVersion.NONE.v) {
 341             for (CipherSuite suite : allowedCipherSuites) {
 342                 if (!suite.allowed || suite.priority < minPriority) {
 343                     continue;
 344                 }
 345 
 346                 if (suite.isAvailable() &&
 347                         suite.obsoleted > protocols.min.v &&


 353                     }
 354                 } else if (debug != null &&
 355                         Debug.isOn("sslctx") && Debug.isOn("verbose")) {
 356                     if (suite.obsoleted <= protocols.min.v) {
 357                         System.out.println(
 358                             "Ignoring obsoleted cipher suite: " + suite);
 359                     } else if (suite.supported > protocols.max.v) {
 360                         System.out.println(
 361                             "Ignoring unsupported cipher suite: " + suite);
 362                     } else {
 363                         System.out.println(
 364                             "Ignoring unavailable cipher suite: " + suite);
 365                     }
 366                 }
 367             }
 368         }
 369 
 370         return new CipherSuiteList(suites);
 371     }
 372 
 373     /**
 374      * Clear cache of available ciphersuites. If we support all ciphers
 375      * internally, there is no need to clear the cache and calling this
 376      * method has no effect.
 377      *
 378      * Note that every call to clearAvailableCache() and the maintenance of
 379      * cipher suites need to be synchronized with this instance.
 380      */
 381     private void clearAvailableCache() {
 382         if (CipherSuite.DYNAMIC_AVAILABILITY) {
 383             supportedCipherSuiteList = null;
 384             defaultServerCipherSuiteList = null;
 385             defaultClientCipherSuiteList = null;
 386             CipherSuite.BulkCipher.clearAvailableCache();
 387             JsseJce.clearEcAvailable();
 388         }
 389     }
 390 



 391     /*
 392      * The SSLContext implementation for TLS/SSL algorithm
 393      *
 394      * SSL/TLS protocols specify the forward compatibility and version
 395      * roll-back attack protections, however, a number of SSL/TLS server
 396      * vendors did not implement these aspects properly, and some current
 397      * SSL/TLS servers may refuse to talk to a TLS 1.1 or later client.
 398      *
 399      * Considering above interoperability issues, SunJSSE will not set
 400      * TLS 1.1 and TLS 1.2 as the enabled protocols for client by default.
 401      *
 402      * For SSL/TLS servers, there is no such interoperability issues as
 403      * SSL/TLS clients. In SunJSSE, TLS 1.1 or later version will be the
 404      * enabled protocols for server by default.
 405      *
 406      * We may change the behavior when popular TLS/SSL vendors support TLS
 407      * forward compatibility properly.
 408      *
 409      * SSLv2Hello is no longer necessary.  This interoperability option was
 410      * put in place in the late 90's when SSLv3/TLS1.0 were relatively new
 411      * and there were a fair number of SSLv2-only servers deployed.  Because
 412      * of the security issues in SSLv2, it is rarely (if ever) used, as
 413      * deployments should now be using SSLv3 and TLSv1.
 414      *
 415      * Considering the issues of SSLv2Hello, we should not enable SSLv2Hello
 416      * by default. Applications still can use it by enabling SSLv2Hello with
 417      * the series of setEnabledProtocols APIs.
 418      */
 419 
 420     /*
 421      * The base abstract SSLContext implementation.

 422      *
 423      * This abstract class encapsulates supported and the default server
 424      * SSL parameters.
 425      *
 426      * @see SSLContext
 427      */
 428     private abstract static class AbstractSSLContext extends SSLContextImpl {
 429         // parameters
 430         private static final SSLParameters defaultServerSSLParams;
 431         private static final SSLParameters supportedSSLParams;
 432 
 433         static {
 434             // supported SSL parameters
 435             supportedSSLParams = new SSLParameters();
 436 
 437             // candidates for available protocols
 438             ProtocolVersion[] candidates;
 439 

 440             if (SunJSSE.isFIPS()) {
 441                 supportedSSLParams.setProtocols(new String[] {
 442                     ProtocolVersion.TLS10.name,
 443                     ProtocolVersion.TLS11.name,
 444                     ProtocolVersion.TLS12.name
 445                 });
 446 
 447                 candidates = new ProtocolVersion[] {

 448                     ProtocolVersion.TLS10,
 449                     ProtocolVersion.TLS11,
 450                     ProtocolVersion.TLS12
 451                 };
 452             } else {
 453                 supportedSSLParams.setProtocols(new String[] {
 454                     ProtocolVersion.SSL20Hello.name,
 455                     ProtocolVersion.SSL30.name,
 456                     ProtocolVersion.TLS10.name,
 457                     ProtocolVersion.TLS11.name,
 458                     ProtocolVersion.TLS12.name
 459                 });
 460 
 461                 candidates = new ProtocolVersion[] {

 462                     ProtocolVersion.SSL20Hello,
 463                     ProtocolVersion.SSL30,
 464                     ProtocolVersion.TLS10,
 465                     ProtocolVersion.TLS11,
 466                     ProtocolVersion.TLS12
 467                 };
 468             }
 469 
 470             defaultServerSSLParams = new SSLParameters();
 471             defaultServerSSLParams.setProtocols(
 472                 getAvailableProtocols(candidates).toArray(new String[0]));

 473         }
 474 
 475         @Override
 476         SSLParameters getDefaultServerSSLParams() {
 477             return defaultServerSSLParams;
 478         }
 479 
 480         @Override
 481         SSLParameters getSupportedSSLParams() {
 482             return supportedSSLParams;
 483         }
 484 
 485         static List<String> getAvailableProtocols(
 486                 ProtocolVersion[] protocolCandidates) {
 487 
 488             List<String> availableProtocols = Collections.<String>emptyList();
 489             if (protocolCandidates !=  null && protocolCandidates.length != 0) {
 490                 availableProtocols = new ArrayList<>(protocolCandidates.length);
 491                 for (ProtocolVersion p : protocolCandidates) {
 492                     if (ProtocolVersion.availableProtocols.contains(p)) {
 493                         availableProtocols.add(p.name);
 494                     }




 495                 }




 496             }
 497 
 498             return availableProtocols;


 499         }
 500     }
 501 
 502     /*
 503      * The SSLContext implementation for SSLv3 and TLS10 algorithm
 504      *
 505      * @see SSLContext
 506      */
 507     public static final class TLS10Context extends AbstractSSLContext {
 508         private static final SSLParameters defaultClientSSLParams;

 509 
 510         static {
 511             // candidates for available protocols
 512             ProtocolVersion[] candidates;
 513             if (SunJSSE.isFIPS()) {
 514                 candidates = new ProtocolVersion[] {

 515                     ProtocolVersion.TLS10
 516                 };
 517             } else {
 518                 candidates = new ProtocolVersion[] {

 519                     ProtocolVersion.SSL30,
 520                     ProtocolVersion.TLS10
 521                 };




 522             }
 523 
 524             defaultClientSSLParams = new SSLParameters();
 525             defaultClientSSLParams.setProtocols(
 526                 getAvailableProtocols(candidates).toArray(new String[0]));
 527         }
 528 
 529         @Override
 530         SSLParameters getDefaultClientSSLParams() {
 531             return defaultClientSSLParams;
 532         }
 533     }
 534 
 535     /*
 536      * The SSLContext implementation for TLS11 algorithm
 537      *
 538      * @see SSLContext
 539      */
 540     public static final class TLS11Context extends AbstractSSLContext {
 541         private static final SSLParameters defaultClientSSLParams;

 542 
 543         static {
 544             // candidates for available protocols
 545             ProtocolVersion[] candidates;
 546             if (SunJSSE.isFIPS()) {
 547                 candidates = new ProtocolVersion[] {

 548                     ProtocolVersion.TLS10,
 549                     ProtocolVersion.TLS11
 550                 };
 551             } else {
 552                 candidates = new ProtocolVersion[] {

 553                     ProtocolVersion.SSL30,
 554                     ProtocolVersion.TLS10,
 555                     ProtocolVersion.TLS11
 556                 };
 557             }
 558 
 559             defaultClientSSLParams = new SSLParameters();
 560             defaultClientSSLParams.setProtocols(
 561                 getAvailableProtocols(candidates).toArray(new String[0]));
 562         }
 563 
 564         @Override
 565         SSLParameters getDefaultClientSSLParams() {
 566             return defaultClientSSLParams;





 567         }
 568     }
 569 
 570     /*
 571      * The SSLContext implementation for TLS12 algorithm
 572      *
 573      * @see SSLContext
 574      */
 575     public static final class TLS12Context extends AbstractSSLContext {
 576         private static final SSLParameters defaultClientSSLParams;

 577 
 578         static {
 579             // candidates for available protocols
 580             ProtocolVersion[] candidates;
 581             if (SunJSSE.isFIPS()) {
 582                 candidates = new ProtocolVersion[] {

 583                     ProtocolVersion.TLS10,
 584                     ProtocolVersion.TLS11,
 585                     ProtocolVersion.TLS12
 586                 };
 587             } else {
 588                 candidates = new ProtocolVersion[] {

 589                     ProtocolVersion.SSL30,
 590                     ProtocolVersion.TLS10,
 591                     ProtocolVersion.TLS11,
 592                     ProtocolVersion.TLS12
 593                 };




 594             }
 595 
 596             defaultClientSSLParams = new SSLParameters();
 597             defaultClientSSLParams.setProtocols(
 598                 getAvailableProtocols(candidates).toArray(new String[0]));
 599         }
 600 
 601         @Override
 602         SSLParameters getDefaultClientSSLParams() {
 603             return defaultClientSSLParams;
 604         }
 605     }
 606 
 607     /*
 608      * The SSLContext implementation for customized TLS protocols
 609      *
 610      * @see SSLContext
 611      */
 612     private static class CustomizedSSLContext extends AbstractSSLContext {
 613         private static final String PROPERTY_NAME = "jdk.tls.client.protocols";
 614         private static final SSLParameters defaultClientSSLParams;
 615         private static IllegalArgumentException reservedException = null;

 616 
 617         // Don't want a java.lang.LinkageError for illegal system property.
 618         //
 619         // Please don't throw exception in this static block.  Otherwise,
 620         // java.lang.LinkageError may be thrown during the instantiation of
 621         // the provider service. Instead, let's handle the initialization
 622         // exception in constructor.
 623         static {
 624             // candidates for available protocols
 625             ProtocolVersion[] candidates;
 626 
 627             String property = AccessController.doPrivileged(
 628                     new GetPropertyAction(PROPERTY_NAME));
 629             if (property == null || property.length() == 0) {
 630                 // the default enabled client TLS protocols
 631                 if (SunJSSE.isFIPS()) {
 632                     candidates = new ProtocolVersion[] {
 633                         ProtocolVersion.TLS10,
 634                         ProtocolVersion.TLS11,
 635                         ProtocolVersion.TLS12
 636                     };
 637                 } else {
 638                     candidates = new ProtocolVersion[] {
 639                         ProtocolVersion.SSL30,
 640                         ProtocolVersion.TLS10,
 641                         ProtocolVersion.TLS11,
 642                         ProtocolVersion.TLS12
 643                     };
 644                 }
 645             } else {
 646                 // remove double quote marks from beginning/end of the property
 647                 if (property.length() > 1 && property.charAt(0) == '"' &&
 648                         property.charAt(property.length() - 1) == '"') {
 649                     property = property.substring(1, property.length() - 1);
 650                 }
 651 
 652                 String[] protocols = null;
 653                 if (property != null && property.length() != 0) {
 654                     protocols = property.split(",");
 655                 } else {
 656                     reservedException = new IllegalArgumentException(
 657                         "No protocol specified in " +
 658                         PROPERTY_NAME + " system property");
 659                     protocols = new String[0];
 660                 }
 661 
 662                 candidates = new ProtocolVersion[protocols.length];

 663                 for (int i = 0; i < protocols.length; i++) {
 664                     protocols[i] = protocols[i].trim();
 665                     // Is it a supported protocol name?
 666                     try {
 667                         candidates[i] = ProtocolVersion.valueOf(protocols[i]);
 668                     } catch (IllegalArgumentException iae) {




 669                         reservedException = new IllegalArgumentException(
 670                             PROPERTY_NAME + ": " + protocols[i] +
 671                             " is not a standard SSL/TLS protocol name", iae);

 672                         break;
 673                     }
 674                 }
 675 
 676                 if ((reservedException == null) && SunJSSE.isFIPS()) {
 677                     for (ProtocolVersion protocolVersion : candidates) {
 678                         if (ProtocolVersion.SSL20Hello.v == protocolVersion.v ||
 679                                 ProtocolVersion.SSL30.v == protocolVersion.v) {

 680                             reservedException = new IllegalArgumentException(
 681                                     PROPERTY_NAME + ": " + protocolVersion +
 682                                     " is not FIPS compliant");

 683                         }
 684                     }
 685                 }
 686             }
 687 
 688             defaultClientSSLParams = new SSLParameters();



















 689             if (reservedException == null) {
 690                 defaultClientSSLParams.setProtocols(
 691                     getAvailableProtocols(candidates).toArray(new String[0]));






































 692             }
 693         }
 694 
 695         protected CustomizedSSLContext() {
 696             if (reservedException != null) {
 697                 throw reservedException;
 698             }
 699         }
 700 
 701         @Override
 702         SSLParameters getDefaultClientSSLParams() {
 703             return defaultClientSSLParams;





 704         }
 705     }
 706 
 707     /*
 708      * The SSLContext implementation for default "TLS" algorithm
 709      *
 710      * @see SSLContext
 711      */
 712     public static final class TLSContext extends CustomizedSSLContext {
 713         // use the default constructor and methods
 714     }
 715 
 716     /*
 717      * The SSLContext implementation for default "Default" algorithm
 718      *
 719      * @see SSLContext
 720      */
 721     public static final class DefaultSSLContext extends CustomizedSSLContext {
 722         private static final String NONE = "NONE";
 723         private static final String P11KEYSTORE = "PKCS11";
 724 
 725         private static volatile SSLContextImpl defaultImpl;

 726 
 727         private static TrustManager[] defaultTrustManagers;
 728         private static KeyManager[] defaultKeyManagers;
 729 
 730         public DefaultSSLContext() throws Exception {

 731             try {
 732                 super.engineInit(getDefaultKeyManager(),
 733                         getDefaultTrustManager(), null);
 734             } catch (Exception e) {
 735                 if (debug != null && Debug.isOn("defaultctx")) {
 736                     System.out.println("default context init failed: " + e);
 737                 }
 738                 throw e;
 739             }
 740 
 741             if (defaultImpl == null) {
 742                 defaultImpl = this;
 743             }
 744         }
 745 
 746         @Override
 747         protected void engineInit(KeyManager[] km, TrustManager[] tm,
 748             SecureRandom sr) throws KeyManagementException {
 749             throw new KeyManagementException
 750                 ("Default SSLContext is initialized automatically");
 751         }

 752 
 753         static synchronized SSLContextImpl getDefaultImpl() throws Exception {
 754             if (defaultImpl == null) {
 755                 new DefaultSSLContext();




 756             }
 757             return defaultImpl;


 758         }
 759 
 760         private static synchronized TrustManager[] getDefaultTrustManager()
 761                 throws Exception {
 762             if (defaultTrustManagers != null) {
 763                 return defaultTrustManagers;
 764             }
 765 

 766             KeyStore ks =
 767                 TrustManagerFactoryImpl.getCacertsKeyStore("defaultctx");
 768 
 769             TrustManagerFactory tmf = TrustManagerFactory.getInstance(
 770                 TrustManagerFactory.getDefaultAlgorithm());
 771             tmf.init(ks);
 772             defaultTrustManagers = tmf.getTrustManagers();
 773             return defaultTrustManagers;
 774         }
 775 
 776         private static synchronized KeyManager[] getDefaultKeyManager()
 777                 throws Exception {
 778             if (defaultKeyManagers != null) {
 779                 return defaultKeyManagers;
 780             }
 781 
 782             final Map<String,String> props = new HashMap<>();
 783             AccessController.doPrivileged(
 784                         new PrivilegedExceptionAction<Object>() {
 785                 @Override
 786                 public Object run() throws Exception {
 787                     props.put("keyStore",  System.getProperty(
 788                                 "javax.net.ssl.keyStore", ""));
 789                     props.put("keyStoreType", System.getProperty(
 790                                 "javax.net.ssl.keyStoreType",
 791                                 KeyStore.getDefaultType()));
 792                     props.put("keyStoreProvider", System.getProperty(
 793                                 "javax.net.ssl.keyStoreProvider", ""));
 794                     props.put("keyStorePasswd", System.getProperty(
 795                                 "javax.net.ssl.keyStorePassword", ""));
 796                     return null;
 797                 }
 798             });
 799 
 800             final String defaultKeyStore = props.get("keyStore");


 857                     fs = null;
 858                 }
 859             }
 860 
 861             /*
 862              * Try to initialize key manager.
 863              */
 864             if (debug != null && Debug.isOn("defaultctx")) {
 865                 System.out.println("init keymanager of type " +
 866                     KeyManagerFactory.getDefaultAlgorithm());
 867             }
 868             KeyManagerFactory kmf = KeyManagerFactory.getInstance(
 869                 KeyManagerFactory.getDefaultAlgorithm());
 870 
 871             if (P11KEYSTORE.equals(defaultKeyStoreType)) {
 872                 kmf.init(ks, null); // do not pass key passwd if using token
 873             } else {
 874                 kmf.init(ks, passwd);
 875             }
 876 
 877             defaultKeyManagers = kmf.getKeyManagers();
 878             return defaultKeyManagers;































































 879         }
 880     }

 881 
 882 }
 883 
 884 
 885 final class AbstractTrustManagerWrapper extends X509ExtendedTrustManager
 886             implements X509TrustManager {
 887 
 888     // the delegated trust manager
 889     private final X509TrustManager tm;
 890 
 891     AbstractTrustManagerWrapper(X509TrustManager tm) {
 892         this.tm = tm;
 893     }
 894 
 895     @Override
 896     public void checkClientTrusted(X509Certificate[] chain, String authType)
 897         throws CertificateException {
 898         tm.checkClientTrusted(chain, authType);
 899     }
 900 


   1 /*
   2  * Copyright (c) 1999, 2015, 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


  35 
  36 import javax.net.ssl.*;
  37 
  38 import sun.security.provider.certpath.AlgorithmChecker;
  39 import sun.security.action.GetPropertyAction;
  40 
  41 public abstract class SSLContextImpl extends SSLContextSpi {
  42 
  43     private static final Debug debug = Debug.getInstance("ssl");
  44 
  45     private final EphemeralKeyManager ephemeralKeyManager;
  46     private final SSLSessionContextImpl clientCache;
  47     private final SSLSessionContextImpl serverCache;
  48 
  49     private boolean isInitialized;
  50 
  51     private X509ExtendedKeyManager keyManager;
  52     private X509TrustManager trustManager;
  53     private SecureRandom secureRandom;
  54 










  55     SSLContextImpl() {
  56         ephemeralKeyManager = new EphemeralKeyManager();
  57         clientCache = new SSLSessionContextImpl();
  58         serverCache = new SSLSessionContextImpl();
  59     }
  60 
  61     @Override
  62     protected void engineInit(KeyManager[] km, TrustManager[] tm,
  63                                 SecureRandom sr) throws KeyManagementException {
  64         isInitialized = false;
  65         keyManager = chooseKeyManager(km);
  66 
  67         if (tm == null) {
  68             try {
  69                 TrustManagerFactory tmf = TrustManagerFactory.getInstance(
  70                         TrustManagerFactory.getDefaultAlgorithm());
  71                 tmf.init((KeyStore)null);
  72                 tm = tmf.getTrustManagers();
  73             } catch (Exception e) {
  74                 // eat


 164         // nothing found, return a dummy X509ExtendedKeyManager
 165         return DummyX509KeyManager.INSTANCE;
 166     }
 167 
 168     @Override
 169     protected SSLSocketFactory engineGetSocketFactory() {
 170         if (!isInitialized) {
 171             throw new IllegalStateException(
 172                 "SSLContextImpl is not initialized");
 173         }
 174        return new SSLSocketFactoryImpl(this);
 175     }
 176 
 177     @Override
 178     protected SSLServerSocketFactory engineGetServerSocketFactory() {
 179         if (!isInitialized) {
 180             throw new IllegalStateException("SSLContext is not initialized");
 181         }
 182         return new SSLServerSocketFactoryImpl(this);
 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(
 191                 "SSLContextImpl is not initialized");
 192         }
 193         return createSSLEngineImpl();
 194     }
 195 
 196     @Override
 197     protected SSLEngine engineCreateSSLEngine(String host, int port) {
 198         if (!isInitialized) {
 199             throw new IllegalStateException(
 200                 "SSLContextImpl is not initialized");
 201         }
 202         return createSSLEngineImpl(host, port);
 203     }
 204 
 205     @Override
 206     protected SSLSessionContext engineGetClientSessionContext() {
 207         return clientCache;
 208     }
 209 
 210     @Override
 211     protected SSLSessionContext engineGetServerSessionContext() {
 212         return serverCache;
 213     }
 214 
 215     SecureRandom getSecureRandom() {
 216         return secureRandom;
 217     }
 218 
 219     X509ExtendedKeyManager getX509KeyManager() {
 220         return keyManager;
 221     }
 222 
 223     X509TrustManager getX509TrustManager() {
 224         return trustManager;
 225     }
 226 
 227     EphemeralKeyManager getEphemeralKeyManager() {
 228         return ephemeralKeyManager;
 229     }
 230 



 231 
 232     // Get supported ProtocolList.
 233     abstract ProtocolList getSuportedProtocolList();




 234 
 235     // Get default ProtocolList for server mode.
 236     abstract ProtocolList getServerDefaultProtocolList();
 237 
 238     // Get default ProtocolList for client mode.
 239     abstract ProtocolList getClientDefaultProtocolList();
















 240 
 241     // Get supported CipherSuiteList.
 242     abstract CipherSuiteList getSupportedCipherSuiteList();




 243 
 244     // Get default CipherSuiteList for server mode.
 245     abstract CipherSuiteList getServerDefaultCipherSuiteList();


 246 
 247     // Get default CipherSuiteList for client mode.
 248     abstract CipherSuiteList getClientDefaultCipherSuiteList();
 249 
 250     // Get default ProtocolList.
 251     ProtocolList getDefaultProtocolList(boolean roleIsServer) {
 252         return roleIsServer ? getServerDefaultProtocolList()
 253                 : getClientDefaultProtocolList();
 254     }
 255 
 256     // Get default CipherSuiteList.
 257     CipherSuiteList getDefaultCipherSuiteList(boolean roleIsServer) {
 258         return roleIsServer ? getServerDefaultCipherSuiteList()
 259                 : getClientDefaultCipherSuiteList();



















 260     }
 261 
 262     /**
 263      * Return whether a protocol list is the original default enabled
 264      * protocols.  See: SSLSocket/SSLEngine.setEnabledProtocols()
 265      */
 266     boolean isDefaultProtocolList(ProtocolList protocols) {
 267         return (protocols == getServerDefaultProtocolList()) ||
 268                 (protocols == getClientDefaultProtocolList());
 269     }
 270 
 271     /**
 272      * Return whether a protocol list is the original default enabled
 273      * protocols.  See: SSLSocket/SSLEngine.setEnabledProtocols()
 274      */
 275     boolean isDefaultCipherSuiteList(CipherSuiteList cipherSuites) {
 276         return (cipherSuites == getServerDefaultCipherSuiteList()) ||
 277                 (cipherSuites == getClientDefaultCipherSuiteList());
 278     }
 279 
 280     /*
 281      * Return the list of all available CipherSuites with a priority of
 282      * minPriority or above.
 283      */
 284     private static CipherSuiteList getApplicableCipherSuiteList(
 285             ProtocolList protocols, boolean onlyEnabled) {
 286 
 287         int minPriority = CipherSuite.SUPPORTED_SUITES_PRIORITY;
 288         if (onlyEnabled) {
 289             minPriority = CipherSuite.DEFAULT_SUITES_PRIORITY;
 290         }
 291 
 292         Collection<CipherSuite> allowedCipherSuites =
 293                                     CipherSuite.allowedCipherSuites();
 294 
 295         TreeSet<CipherSuite> suites = new TreeSet<>();
 296         if (!(protocols.collection().isEmpty()) &&
 297                 protocols.min.v != ProtocolVersion.NONE.v) {
 298             for (CipherSuite suite : allowedCipherSuites) {
 299                 if (!suite.allowed || suite.priority < minPriority) {
 300                     continue;
 301                 }
 302 
 303                 if (suite.isAvailable() &&
 304                         suite.obsoleted > protocols.min.v &&


 310                     }
 311                 } else if (debug != null &&
 312                         Debug.isOn("sslctx") && Debug.isOn("verbose")) {
 313                     if (suite.obsoleted <= protocols.min.v) {
 314                         System.out.println(
 315                             "Ignoring obsoleted cipher suite: " + suite);
 316                     } else if (suite.supported > protocols.max.v) {
 317                         System.out.println(
 318                             "Ignoring unsupported cipher suite: " + suite);
 319                     } else {
 320                         System.out.println(
 321                             "Ignoring unavailable cipher suite: " + suite);
 322                     }
 323                 }
 324             }
 325         }
 326 
 327         return new CipherSuiteList(suites);
 328     }
 329 
 330     private static String[] getAvailableProtocols(
 331             ProtocolVersion[] protocolCandidates) {
 332 
 333         List<String> availableProtocols = Collections.<String>emptyList();
 334         if (protocolCandidates !=  null && protocolCandidates.length != 0) {
 335             availableProtocols = new ArrayList<>(protocolCandidates.length);
 336             for (ProtocolVersion p : protocolCandidates) {
 337                 if (ProtocolVersion.availableProtocols.contains(p)) {
 338                     availableProtocols.add(p.name);
 339                 }





 340             }
 341         }
 342 
 343         return availableProtocols.toArray(new String[0]);
 344     }
 345 
 346     /*
 347      * The SSLContext implementation for TLS/SSL algorithm
 348      *
 349      * SSL/TLS protocols specify the forward compatibility and version
 350      * roll-back attack protections, however, a number of SSL/TLS server
 351      * vendors did not implement these aspects properly, and some current
 352      * SSL/TLS servers may refuse to talk to a TLS 1.1 or later client.
 353      *
 354      * Considering above interoperability issues, SunJSSE will not set
 355      * TLS 1.1 and TLS 1.2 as the enabled protocols for client by default.
 356      *
 357      * For SSL/TLS servers, there is no such interoperability issues as
 358      * SSL/TLS clients. In SunJSSE, TLS 1.1 or later version will be the
 359      * enabled protocols for server by default.
 360      *
 361      * We may change the behavior when popular TLS/SSL vendors support TLS
 362      * forward compatibility properly.
 363      *
 364      * SSLv2Hello is no longer necessary.  This interoperability option was
 365      * put in place in the late 90's when SSLv3/TLS1.0 were relatively new
 366      * and there were a fair number of SSLv2-only servers deployed.  Because
 367      * of the security issues in SSLv2, it is rarely (if ever) used, as
 368      * deployments should now be using SSLv3 and TLSv1.
 369      *
 370      * Considering the issues of SSLv2Hello, we should not enable SSLv2Hello
 371      * by default. Applications still can use it by enabling SSLv2Hello with
 372      * the series of setEnabledProtocols APIs.
 373      */
 374 
 375     /*
 376      * The base abstract SSLContext implementation for the Transport Layer
 377      * Security (TLS) protocols.
 378      *
 379      * This abstract class encapsulates supported and the default server
 380      * SSL/TLS parameters.
 381      *
 382      * @see SSLContext
 383      */
 384     private abstract static class AbstractTLSContext extends SSLContextImpl {
 385         private static final ProtocolList supportedProtocolList;
 386         private static final ProtocolList serverDefaultProtocolList;

 387 
 388         private static final CipherSuiteList supportedCipherSuiteList;
 389         private static final CipherSuiteList serverDefaultCipherSuiteList;




 390 
 391         static {
 392             if (SunJSSE.isFIPS()) {
 393                 supportedProtocolList = new ProtocolList(new String[] {
 394                     ProtocolVersion.TLS10.name,
 395                     ProtocolVersion.TLS11.name,
 396                     ProtocolVersion.TLS12.name
 397                 });
 398 
 399                 serverDefaultProtocolList = new ProtocolList(
 400                         getAvailableProtocols(new ProtocolVersion[] {
 401                     ProtocolVersion.TLS10,
 402                     ProtocolVersion.TLS11,
 403                     ProtocolVersion.TLS12
 404                 }));
 405             } else {
 406                 supportedProtocolList = new ProtocolList(new String[] {
 407                     ProtocolVersion.SSL20Hello.name,
 408                     ProtocolVersion.SSL30.name,
 409                     ProtocolVersion.TLS10.name,
 410                     ProtocolVersion.TLS11.name,
 411                     ProtocolVersion.TLS12.name
 412                 });
 413 
 414                 serverDefaultProtocolList = new ProtocolList(
 415                         getAvailableProtocols(new ProtocolVersion[] {
 416                     ProtocolVersion.SSL20Hello,
 417                     ProtocolVersion.SSL30,
 418                     ProtocolVersion.TLS10,
 419                     ProtocolVersion.TLS11,
 420                     ProtocolVersion.TLS12
 421                 }));
 422             }
 423 
 424             supportedCipherSuiteList = getApplicableCipherSuiteList(
 425                     supportedProtocolList, false);          // all supported
 426             serverDefaultCipherSuiteList = getApplicableCipherSuiteList(
 427                     serverDefaultProtocolList, true);       // enabled only
 428         }
 429 
 430         @Override
 431         ProtocolList getSuportedProtocolList() {
 432             return supportedProtocolList;
 433         }
 434 
 435         @Override
 436         CipherSuiteList getSupportedCipherSuiteList() {
 437             return supportedCipherSuiteList;
 438         }
 439 
 440         @Override
 441         ProtocolList getServerDefaultProtocolList() {
 442             return serverDefaultProtocolList;






 443         }
 444 
 445         @Override
 446         CipherSuiteList getServerDefaultCipherSuiteList() {
 447             return serverDefaultCipherSuiteList;
 448         }
 449 
 450         @Override
 451         SSLEngine createSSLEngineImpl() {
 452             return new SSLEngineImpl(this);
 453         }
 454 
 455         @Override
 456         SSLEngine createSSLEngineImpl(String host, int port) {
 457             return new SSLEngineImpl(this, host, port);
 458         }
 459     }
 460 
 461     /*
 462      * The SSLContext implementation for SSLv3 and TLS10 algorithm
 463      *
 464      * @see SSLContext
 465      */
 466     public static final class TLS10Context extends AbstractTLSContext {
 467         private static final ProtocolList clientDefaultProtocolList;
 468         private static final CipherSuiteList clientDefaultCipherSuiteList;
 469 
 470         static {


 471             if (SunJSSE.isFIPS()) {
 472                 clientDefaultProtocolList = new ProtocolList(
 473                         getAvailableProtocols(new ProtocolVersion[] {
 474                     ProtocolVersion.TLS10
 475                 }));
 476             } else {
 477                 clientDefaultProtocolList = new ProtocolList(
 478                         getAvailableProtocols(new ProtocolVersion[] {
 479                     ProtocolVersion.SSL30,
 480                     ProtocolVersion.TLS10
 481                 }));
 482             }
 483 
 484             clientDefaultCipherSuiteList = getApplicableCipherSuiteList(
 485                     clientDefaultProtocolList, true);       // enabled only
 486         }
 487 
 488         @Override
 489         ProtocolList getClientDefaultProtocolList() {
 490             return clientDefaultProtocolList;
 491         }
 492 
 493         @Override
 494         CipherSuiteList getClientDefaultCipherSuiteList() {
 495             return clientDefaultCipherSuiteList;
 496         }
 497     }
 498 
 499     /*
 500      * The SSLContext implementation for TLS11 algorithm
 501      *
 502      * @see SSLContext
 503      */
 504     public static final class TLS11Context extends AbstractTLSContext {
 505         private static final ProtocolList clientDefaultProtocolList;
 506         private static final CipherSuiteList clientDefaultCipherSuiteList;
 507 
 508         static {


 509             if (SunJSSE.isFIPS()) {
 510                 clientDefaultProtocolList = new ProtocolList(
 511                         getAvailableProtocols(new ProtocolVersion[] {
 512                     ProtocolVersion.TLS10,
 513                     ProtocolVersion.TLS11
 514                 }));
 515             } else {
 516                 clientDefaultProtocolList = new ProtocolList(
 517                         getAvailableProtocols(new ProtocolVersion[] {
 518                     ProtocolVersion.SSL30,
 519                     ProtocolVersion.TLS10,
 520                     ProtocolVersion.TLS11
 521                 }));
 522             }
 523 
 524             clientDefaultCipherSuiteList = getApplicableCipherSuiteList(
 525                     clientDefaultProtocolList, true);       // enabled only

 526         }
 527 
 528         @Override
 529         ProtocolList getClientDefaultProtocolList() {
 530             return clientDefaultProtocolList;
 531         }
 532 
 533         @Override
 534         CipherSuiteList getClientDefaultCipherSuiteList() {
 535             return clientDefaultCipherSuiteList;
 536         }
 537     }
 538 
 539     /*
 540      * The SSLContext implementation for TLS12 algorithm
 541      *
 542      * @see SSLContext
 543      */
 544     public static final class TLS12Context extends AbstractTLSContext {
 545         private static final ProtocolList clientDefaultProtocolList;
 546         private static final CipherSuiteList clientDefaultCipherSuiteList;
 547 
 548         static {


 549             if (SunJSSE.isFIPS()) {
 550                 clientDefaultProtocolList = new ProtocolList(
 551                         getAvailableProtocols(new ProtocolVersion[] {
 552                     ProtocolVersion.TLS10,
 553                     ProtocolVersion.TLS11,
 554                     ProtocolVersion.TLS12
 555                 }));
 556             } else {
 557                 clientDefaultProtocolList = new ProtocolList(
 558                         getAvailableProtocols(new ProtocolVersion[] {
 559                     ProtocolVersion.SSL30,
 560                     ProtocolVersion.TLS10,
 561                     ProtocolVersion.TLS11,
 562                     ProtocolVersion.TLS12
 563                 }));
 564             }
 565 
 566             clientDefaultCipherSuiteList = getApplicableCipherSuiteList(
 567                     clientDefaultProtocolList, true);       // enabled only
 568         }
 569 
 570         @Override
 571         ProtocolList getClientDefaultProtocolList() {
 572             return clientDefaultProtocolList;
 573         }
 574 
 575         @Override
 576         CipherSuiteList getClientDefaultCipherSuiteList() {
 577             return clientDefaultCipherSuiteList;
 578         }
 579     }
 580 
 581     /*
 582      * The interface for the customized SSL/(D)TLS SSLContext.
 583      *
 584      * @see SSLContext
 585      */
 586     private static class CustomizedSSLProtocols {
 587         private static final String PROPERTY_NAME = "jdk.tls.client.protocols";
 588         static IllegalArgumentException reservedException = null;
 589         static ArrayList<ProtocolVersion>
 590                 customizedProtocols = new ArrayList<>();
 591 
 592         // Don't want a java.lang.LinkageError for illegal system property.
 593         //
 594         // Please don't throw exception in this static block.  Otherwise,
 595         // java.lang.LinkageError may be thrown during the instantiation of
 596         // the provider service. Instead, please handle the initialization
 597         // exception in the caller's constructor.
 598         static {



 599             String property = AccessController.doPrivileged(
 600                     new GetPropertyAction(PROPERTY_NAME));
 601             if (property != null && property.length() != 0) {
















 602                 // remove double quote marks from beginning/end of the property
 603                 if (property.length() > 1 && property.charAt(0) == '"' &&
 604                         property.charAt(property.length() - 1) == '"') {
 605                     property = property.substring(1, property.length() - 1);
 606                 }









 607             }
 608 
 609             if (property != null && property.length() != 0) {
 610                 String[] protocols = property.split(",");
 611                 for (int i = 0; i < protocols.length; i++) {
 612                     protocols[i] = protocols[i].trim();
 613                     // Is it a supported protocol name?
 614                     try {
 615                         ProtocolVersion pro =
 616                                 ProtocolVersion.valueOf(protocols[i]);
 617 
 618                         if (SunJSSE.isFIPS() &&
 619                                 ((pro.v == ProtocolVersion.SSL30.v) ||
 620                                         (pro.v == ProtocolVersion.SSL20Hello.v))) {
 621                             reservedException = new IllegalArgumentException(
 622                                     PROPERTY_NAME + ": " + pro +
 623                                             " is not FIPS compliant");
 624 
 625                             break;
 626                         }

 627 
 628                         // ignore duplicated protocols
 629                         if (!customizedProtocols.contains(pro)) {
 630                             customizedProtocols.add(pro);
 631                         }
 632                     } catch (IllegalArgumentException iae) {
 633                         reservedException = new IllegalArgumentException(
 634                                 PROPERTY_NAME + ": " + protocols[i] +
 635                                         " is not a standard SSL protocol name", iae);
 636                     }
 637                 }
 638             }
 639         }
 640     }
 641 
 642     /*
 643      * The SSLContext implementation for customized TLS protocols
 644      *
 645      * @see SSLContext
 646      */
 647     private static class CustomizedTLSContext extends AbstractTLSContext {
 648 
 649         private static final ProtocolList clientDefaultProtocolList;
 650         private static final CipherSuiteList clientDefaultCipherSuiteList;
 651 
 652         private static IllegalArgumentException reservedException = null;
 653 
 654         // Don't want a java.lang.LinkageError for illegal system property.
 655         //
 656         // Please don't throw exception in this static block.  Otherwise,
 657         // java.lang.LinkageError may be thrown during the instantiation of
 658         // the provider service. Instead, let's handle the initialization
 659         // exception in constructor.
 660         static {
 661             reservedException = CustomizedSSLProtocols.reservedException;
 662             if (reservedException == null) {
 663                 ArrayList<ProtocolVersion>
 664                         customizedTLSProtocols = new ArrayList<>();
 665                 for (ProtocolVersion protocol :
 666                         CustomizedSSLProtocols.customizedProtocols) {
 667                         customizedTLSProtocols.add(protocol);
 668                 }
 669 
 670                 // candidates for available protocols
 671                 ProtocolVersion[] candidates;
 672                 if (customizedTLSProtocols.isEmpty()) {
 673                     // Use the default enabled client protocols if no
 674                     // customized TLS protocols.
 675                     if (SunJSSE.isFIPS()) {
 676                         candidates = new ProtocolVersion[] {
 677                                 ProtocolVersion.TLS10,
 678                                 ProtocolVersion.TLS11,
 679                                 ProtocolVersion.TLS12
 680                         };
 681                     } else {
 682                         candidates = new ProtocolVersion[] {
 683                                 ProtocolVersion.SSL30,
 684                                 ProtocolVersion.TLS10,
 685                                 ProtocolVersion.TLS11,
 686                                 ProtocolVersion.TLS12
 687                         };
 688                     }
 689                 } else {
 690                     // Use the customized TLS protocols.
 691                     candidates =
 692                             new ProtocolVersion[customizedTLSProtocols.size()];
 693                     candidates = customizedTLSProtocols.toArray(candidates);
 694                 }
 695 
 696                 clientDefaultProtocolList = new ProtocolList(
 697                         getAvailableProtocols(candidates));
 698                 clientDefaultCipherSuiteList = getApplicableCipherSuiteList(
 699                         clientDefaultProtocolList, true);   // enabled only
 700             } else {
 701                 clientDefaultProtocolList = null;       // unlikely to be used
 702                 clientDefaultCipherSuiteList = null;    // unlikely to be used
 703             }
 704         }
 705 
 706         protected CustomizedTLSContext() {
 707             if (reservedException != null) {
 708                 throw reservedException;
 709             }
 710         }
 711 
 712         @Override
 713         ProtocolList getClientDefaultProtocolList() {
 714             return clientDefaultProtocolList;
 715         }
 716 
 717         @Override
 718         CipherSuiteList getClientDefaultCipherSuiteList() {
 719             return clientDefaultCipherSuiteList;
 720         }
 721     }
 722 
 723     /*
 724      * The SSLContext implementation for default "TLS" algorithm
 725      *
 726      * @see SSLContext
 727      */
 728     public static final class TLSContext extends CustomizedTLSContext {
 729         // use the default constructor and methods
 730     }
 731 
 732     // lazy initialization holder class idiom for static default parameters
 733     //
 734     // See Effective Java Second Edition: Item 71.
 735     private static final class DefaultManagersHolder {


 736         private static final String NONE = "NONE";
 737         private static final String P11KEYSTORE = "PKCS11";
 738 
 739         private static final TrustManager[] trustManagers;
 740         private static final KeyManager[] keyManagers;
 741 
 742         static Exception reservedException = null;

 743 
 744         static {
 745             TrustManager[] tmMediator;
 746             try {
 747                 tmMediator = getTrustManagers();

 748             } catch (Exception e) {
 749                 reservedException = e;
 750                 tmMediator = new TrustManager[0];














 751             }
 752             trustManagers = tmMediator;
 753 
 754             if (reservedException == null) {
 755                 KeyManager[] kmMediator;
 756                 try {
 757                     kmMediator = getKeyManagers();
 758                 } catch (Exception e) {
 759                     reservedException = e;
 760                     kmMediator = new KeyManager[0];
 761                 }
 762                 keyManagers = kmMediator;
 763             } else {
 764                 keyManagers = new KeyManager[0];
 765             }





 766         }
 767 
 768         private static TrustManager[] getTrustManagers() throws Exception {
 769             KeyStore ks =
 770                 TrustManagerFactoryImpl.getCacertsKeyStore("defaultctx");
 771 
 772             TrustManagerFactory tmf = TrustManagerFactory.getInstance(
 773                 TrustManagerFactory.getDefaultAlgorithm());
 774             tmf.init(ks);
 775             return tmf.getTrustManagers();

 776         }
 777 
 778         private static KeyManager[] getKeyManagers() throws Exception {




 779 
 780             final Map<String,String> props = new HashMap<>();
 781             AccessController.doPrivileged(
 782                         new PrivilegedExceptionAction<Object>() {
 783                 @Override
 784                 public Object run() throws Exception {
 785                     props.put("keyStore",  System.getProperty(
 786                                 "javax.net.ssl.keyStore", ""));
 787                     props.put("keyStoreType", System.getProperty(
 788                                 "javax.net.ssl.keyStoreType",
 789                                 KeyStore.getDefaultType()));
 790                     props.put("keyStoreProvider", System.getProperty(
 791                                 "javax.net.ssl.keyStoreProvider", ""));
 792                     props.put("keyStorePasswd", System.getProperty(
 793                                 "javax.net.ssl.keyStorePassword", ""));
 794                     return null;
 795                 }
 796             });
 797 
 798             final String defaultKeyStore = props.get("keyStore");


 855                     fs = null;
 856                 }
 857             }
 858 
 859             /*
 860              * Try to initialize key manager.
 861              */
 862             if (debug != null && Debug.isOn("defaultctx")) {
 863                 System.out.println("init keymanager of type " +
 864                     KeyManagerFactory.getDefaultAlgorithm());
 865             }
 866             KeyManagerFactory kmf = KeyManagerFactory.getInstance(
 867                 KeyManagerFactory.getDefaultAlgorithm());
 868 
 869             if (P11KEYSTORE.equals(defaultKeyStoreType)) {
 870                 kmf.init(ks, null); // do not pass key passwd if using token
 871             } else {
 872                 kmf.init(ks, passwd);
 873             }
 874 
 875             return kmf.getKeyManagers();
 876         }
 877     }
 878 
 879     // lazy initialization holder class idiom for static default parameters
 880     //
 881     // See Effective Java Second Edition: Item 71.
 882     private static final class DefaultSSLContextHolder {
 883 
 884         private static final SSLContextImpl sslContext;
 885         static Exception reservedException = null;
 886 
 887         static {
 888             SSLContextImpl mediator = null;
 889             if (DefaultManagersHolder.reservedException != null) {
 890                 reservedException = DefaultManagersHolder.reservedException;
 891             } else {
 892                 try {
 893                     mediator = new DefaultSSLContext();
 894                 } catch (Exception e) {
 895                     reservedException = e;
 896                 }
 897             }
 898 
 899             sslContext = mediator;
 900         }
 901     }
 902 
 903     /*
 904      * The SSLContext implementation for default "Default" algorithm
 905      *
 906      * @see SSLContext
 907      */
 908     public static final class DefaultSSLContext extends CustomizedTLSContext {
 909 
 910         // public constructor for SSLContext.getInstance("Default")
 911         public DefaultSSLContext() throws Exception {
 912             if (DefaultManagersHolder.reservedException != null) {
 913                 throw DefaultManagersHolder.reservedException;
 914             }
 915 
 916             try {
 917                 super.engineInit(DefaultManagersHolder.keyManagers,
 918                         DefaultManagersHolder.trustManagers, null);
 919             } catch (Exception e) {
 920                 if (debug != null && Debug.isOn("defaultctx")) {
 921                     System.out.println("default context init failed: " + e);
 922                 }
 923                 throw e;
 924             }
 925         }
 926 
 927         @Override
 928         protected void engineInit(KeyManager[] km, TrustManager[] tm,
 929                                   SecureRandom sr) throws KeyManagementException {
 930             throw new KeyManagementException
 931                     ("Default SSLContext is initialized automatically");
 932         }
 933 
 934         static SSLContextImpl getDefaultImpl() throws Exception {
 935             if (DefaultSSLContextHolder.reservedException != null) {
 936                 throw DefaultSSLContextHolder.reservedException;
 937             }
 938 
 939             return DefaultSSLContextHolder.sslContext;
 940         }
 941     }
 942 
 943 
 944 }
 945 
 946 
 947 final class AbstractTrustManagerWrapper extends X509ExtendedTrustManager
 948             implements X509TrustManager {
 949 
 950     // the delegated trust manager
 951     private final X509TrustManager tm;
 952 
 953     AbstractTrustManagerWrapper(X509TrustManager tm) {
 954         this.tm = tm;
 955     }
 956 
 957     @Override
 958     public void checkClientTrusted(X509Certificate[] chain, String authType)
 959         throws CertificateException {
 960         tm.checkClientTrusted(chain, authType);
 961     }
 962 


< prev index next >