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