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