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