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