1 /*
   2  * Copyright (c) 1996, 2017, 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 
  27 package sun.security.ssl;
  28 
  29 import java.io.*;
  30 import java.util.*;
  31 import java.security.*;
  32 import java.nio.ByteBuffer;
  33 import java.security.NoSuchAlgorithmException;
  34 import java.security.AccessController;
  35 import java.security.AlgorithmConstraints;
  36 import java.security.AccessControlContext;
  37 import java.security.PrivilegedExceptionAction;
  38 import java.security.PrivilegedActionException;
  39 import java.util.function.BiFunction;
  40 
  41 import javax.crypto.*;
  42 import javax.crypto.spec.*;
  43 
  44 import javax.net.ssl.*;
  45 import sun.security.util.HexDumpEncoder;
  46 
  47 import sun.security.internal.spec.*;
  48 import sun.security.internal.interfaces.TlsMasterSecret;
  49 
  50 import sun.security.ssl.HandshakeMessage.*;
  51 import sun.security.ssl.CipherSuite.*;
  52 
  53 import static sun.security.ssl.CipherSuite.PRF.*;
  54 import static sun.security.ssl.CipherSuite.CipherType.*;
  55 import static sun.security.ssl.NamedGroupType.*;
  56 
  57 /**
  58  * Handshaker ... processes handshake records from an SSL V3.0
  59  * data stream, handling all the details of the handshake protocol.
  60  *
  61  * Note that the real protocol work is done in two subclasses, the  base
  62  * class just provides the control flow and key generation framework.
  63  *
  64  * @author David Brownell
  65  */
  66 abstract class Handshaker {
  67 
  68     // protocol version being established using this Handshaker
  69     ProtocolVersion protocolVersion;
  70 
  71     // the currently active protocol version during a renegotiation
  72     ProtocolVersion     activeProtocolVersion;
  73 
  74     // security parameters for secure renegotiation.
  75     boolean             secureRenegotiation;
  76     byte[]              clientVerifyData;
  77     byte[]              serverVerifyData;
  78 
  79     // Is it an initial negotiation  or a renegotiation?
  80     boolean                     isInitialHandshake;
  81 
  82     // List of enabled protocols
  83     private ProtocolList        enabledProtocols;
  84 
  85     // List of enabled CipherSuites
  86     private CipherSuiteList     enabledCipherSuites;
  87 
  88     // The endpoint identification protocol
  89     String                      identificationProtocol;
  90 
  91     // The cryptographic algorithm constraints
  92     AlgorithmConstraints        algorithmConstraints = null;
  93 
  94     // Local supported signature and algorithms
  95     private Collection<SignatureAndHashAlgorithm> localSupportedSignAlgs;
  96 
  97     // Peer supported signature and algorithms
  98     Collection<SignatureAndHashAlgorithm> peerSupportedSignAlgs;
  99 
 100     /*
 101      * List of active protocols
 102      *
 103      * Active protocols is a subset of enabled protocols, and will
 104      * contain only those protocols that have vaild cipher suites
 105      * enabled.
 106      */
 107     private ProtocolList       activeProtocols;
 108 
 109     /*
 110      * List of active cipher suites
 111      *
 112      * Active cipher suites is a subset of enabled cipher suites, and will
 113      * contain only those cipher suites available for the active protocols.
 114      */
 115     private CipherSuiteList     activeCipherSuites;
 116 
 117     // The server name indication and matchers
 118     List<SNIServerName> serverNames = Collections.<SNIServerName>emptyList();
 119     Collection<SNIMatcher> sniMatchers = Collections.<SNIMatcher>emptyList();
 120 
 121     // List of local ApplicationProtocols
 122     String[] localApl = null;
 123 
 124     // Negotiated ALPN value
 125     String applicationProtocol = null;
 126 
 127     // Application protocol callback function (for SSLEngine)
 128     BiFunction<SSLEngine,List<String>,String>
 129         appProtocolSelectorSSLEngine = null;
 130 
 131     // Application protocol callback function (for SSLSocket)
 132     BiFunction<SSLSocket,List<String>,String>
 133         appProtocolSelectorSSLSocket = null;
 134 
 135     // The maximum expected network packet size for SSL/TLS/DTLS records.
 136     int                         maximumPacketSize = 0;
 137 
 138     private boolean             isClient;
 139     private boolean             needCertVerify;
 140 
 141     SSLSocketImpl               conn = null;
 142     SSLEngineImpl               engine = null;
 143 
 144     HandshakeHash               handshakeHash;
 145     HandshakeInStream           input;
 146     HandshakeOutStream          output;
 147     SSLContextImpl              sslContext;
 148     RandomCookie                clnt_random, svr_random;
 149     SSLSessionImpl              session;
 150 
 151     HandshakeStateManager       handshakeState;
 152     boolean                     clientHelloDelivered;
 153     boolean                     serverHelloRequested;
 154     boolean                     handshakeActivated;
 155     boolean                     handshakeFinished;
 156 
 157     // current CipherSuite. Never null, initially SSL_NULL_WITH_NULL_NULL
 158     CipherSuite         cipherSuite;
 159 
 160     // current key exchange. Never null, initially K_NULL
 161     KeyExchange         keyExchange;
 162 
 163     // True if this session is being resumed (fast handshake)
 164     boolean             resumingSession;
 165 
 166     // True if it's OK to start a new SSL session
 167     boolean             enableNewSession;
 168 
 169     // Whether local cipher suites preference should be honored during
 170     // handshaking?
 171     //
 172     // Note that in this provider, this option only applies to server side.
 173     // Local cipher suites preference is always honored in client side in
 174     // this provider.
 175     boolean preferLocalCipherSuites = false;
 176 
 177     // Temporary storage for the individual keys. Set by
 178     // calculateConnectionKeys() and cleared once the ciphers are
 179     // activated.
 180     private SecretKey clntWriteKey, svrWriteKey;
 181     private IvParameterSpec clntWriteIV, svrWriteIV;
 182     private SecretKey clntMacSecret, svrMacSecret;
 183 
 184     /*
 185      * Delegated task subsystem data structures.
 186      *
 187      * If thrown is set, we need to propagate this back immediately
 188      * on entry into processMessage().
 189      *
 190      * Data is protected by the SSLEngine.this lock.
 191      */
 192     private volatile boolean taskDelegated = false;
 193     private volatile DelegatedTask<?> delegatedTask = null;
 194     private volatile Exception thrown = null;
 195 
 196     // Could probably use a java.util.concurrent.atomic.AtomicReference
 197     // here instead of using this lock.  Consider changing.
 198     private Object thrownLock = new Object();
 199 
 200     /* Class and subclass dynamic debugging support */
 201     static final Debug debug = Debug.getInstance("ssl");
 202 
 203     // By default, disable the unsafe legacy session renegotiation
 204     static final boolean allowUnsafeRenegotiation = Debug.getBooleanProperty(
 205                     "sun.security.ssl.allowUnsafeRenegotiation", false);
 206 
 207     // For maximum interoperability and backward compatibility, RFC 5746
 208     // allows server (or client) to accept ClientHello (or ServerHello)
 209     // message without the secure renegotiation_info extension or SCSV.
 210     //
 211     // For maximum security, RFC 5746 also allows server (or client) to
 212     // reject such message with a fatal "handshake_failure" alert.
 213     //
 214     // By default, allow such legacy hello messages.
 215     static final boolean allowLegacyHelloMessages = Debug.getBooleanProperty(
 216                     "sun.security.ssl.allowLegacyHelloMessages", true);
 217 
 218     // To prevent the TLS renegotiation issues, by setting system property
 219     // "jdk.tls.rejectClientInitiatedRenegotiation" to true, applications in
 220     // server side can disable all client initiated SSL renegotiations
 221     // regardless of the support of TLS protocols.
 222     //
 223     // By default, allow client initiated renegotiations.
 224     static final boolean rejectClientInitiatedRenego =
 225             Debug.getBooleanProperty(
 226                 "jdk.tls.rejectClientInitiatedRenegotiation", false);
 227 
 228     // To switch off the extended_master_secret extension.
 229     static final boolean useExtendedMasterSecretExtension =
 230             Debug.getBooleanProperty("jsse.useExtendedMasterSecret", true);
 231 
 232     // need to dispose the object when it is invalidated
 233     boolean invalidated;
 234 
 235     /*
 236      * Is this an instance for Datagram Transport Layer Security (DTLS)?
 237      */
 238     final boolean isDTLS;
 239 
 240     Handshaker(SSLSocketImpl c, SSLContextImpl context,
 241             ProtocolList enabledProtocols, boolean needCertVerify,
 242             boolean isClient, ProtocolVersion activeProtocolVersion,
 243             boolean isInitialHandshake, boolean secureRenegotiation,
 244             byte[] clientVerifyData, byte[] serverVerifyData) {
 245         this.conn = c;
 246         this.isDTLS = false;
 247         init(context, enabledProtocols, needCertVerify, isClient,
 248             activeProtocolVersion, isInitialHandshake, secureRenegotiation,
 249             clientVerifyData, serverVerifyData);
 250     }
 251 
 252     Handshaker(SSLEngineImpl engine, SSLContextImpl context,
 253             ProtocolList enabledProtocols, boolean needCertVerify,
 254             boolean isClient, ProtocolVersion activeProtocolVersion,
 255             boolean isInitialHandshake, boolean secureRenegotiation,
 256             byte[] clientVerifyData, byte[] serverVerifyData,
 257             boolean isDTLS) {
 258         this.engine = engine;
 259         this.isDTLS = isDTLS;
 260         init(context, enabledProtocols, needCertVerify, isClient,
 261             activeProtocolVersion, isInitialHandshake, secureRenegotiation,
 262             clientVerifyData, serverVerifyData);
 263     }
 264 
 265     private void init(SSLContextImpl context, ProtocolList enabledProtocols,
 266             boolean needCertVerify, boolean isClient,
 267             ProtocolVersion activeProtocolVersion,
 268             boolean isInitialHandshake, boolean secureRenegotiation,
 269             byte[] clientVerifyData, byte[] serverVerifyData) {
 270 
 271         if (debug != null && Debug.isOn("handshake")) {
 272             System.out.println(
 273                 "Allow unsafe renegotiation: " + allowUnsafeRenegotiation +
 274                 "\nAllow legacy hello messages: " + allowLegacyHelloMessages +
 275                 "\nIs initial handshake: " + isInitialHandshake +
 276                 "\nIs secure renegotiation: " + secureRenegotiation);
 277         }
 278 
 279         this.sslContext = context;
 280         this.isClient = isClient;
 281         this.needCertVerify = needCertVerify;
 282         this.activeProtocolVersion = activeProtocolVersion;
 283         this.isInitialHandshake = isInitialHandshake;
 284         this.secureRenegotiation = secureRenegotiation;
 285         this.clientVerifyData = clientVerifyData;
 286         this.serverVerifyData = serverVerifyData;
 287         this.enableNewSession = true;
 288         this.invalidated = false;
 289         this.handshakeState = new HandshakeStateManager(isDTLS);
 290         this.clientHelloDelivered = false;
 291         this.serverHelloRequested = false;
 292         this.handshakeActivated = false;
 293         this.handshakeFinished = false;
 294 
 295         setCipherSuite(CipherSuite.C_NULL);
 296         setEnabledProtocols(enabledProtocols);
 297 
 298         if (conn != null) {
 299             algorithmConstraints = new SSLAlgorithmConstraints(conn, true);
 300         } else {        // engine != null
 301             algorithmConstraints = new SSLAlgorithmConstraints(engine, true);
 302         }
 303     }
 304 
 305     /*
 306      * Reroutes calls to the SSLSocket or SSLEngine (*SE).
 307      *
 308      * We could have also done it by extra classes
 309      * and letting them override, but this seemed much
 310      * less involved.
 311      */
 312     void fatalSE(byte b, String diagnostic) throws IOException {
 313         fatalSE(b, diagnostic, null);
 314     }
 315 
 316     void fatalSE(byte b, Throwable cause) throws IOException {
 317         fatalSE(b, null, cause);
 318     }
 319 
 320     void fatalSE(byte b, String diagnostic, Throwable cause)
 321             throws IOException {
 322         if (conn != null) {
 323             conn.fatal(b, diagnostic, cause);
 324         } else {
 325             engine.fatal(b, diagnostic, cause);
 326         }
 327     }
 328 
 329     void warningSE(byte b) {
 330         if (conn != null) {
 331             conn.warning(b);
 332         } else {
 333             engine.warning(b);
 334         }
 335     }
 336 
 337     // ONLY used by ClientHandshaker to setup the peer host in SSLSession.
 338     String getHostSE() {
 339         if (conn != null) {
 340             return conn.getHost();
 341         } else {
 342             return engine.getPeerHost();
 343         }
 344     }
 345 
 346     // ONLY used by ServerHandshaker to setup the peer host in SSLSession.
 347     String getHostAddressSE() {
 348         if (conn != null) {
 349             return conn.getInetAddress().getHostAddress();
 350         } else {
 351             /*
 352              * This is for caching only, doesn't matter that's is really
 353              * a hostname.  The main thing is that it doesn't do
 354              * a reverse DNS lookup, potentially slowing things down.
 355              */
 356             return engine.getPeerHost();
 357         }
 358     }
 359 
 360     int getPortSE() {
 361         if (conn != null) {
 362             return conn.getPort();
 363         } else {
 364             return engine.getPeerPort();
 365         }
 366     }
 367 
 368     int getLocalPortSE() {
 369         if (conn != null) {
 370             return conn.getLocalPort();
 371         } else {
 372             return -1;
 373         }
 374     }
 375 
 376     AccessControlContext getAccSE() {
 377         if (conn != null) {
 378             return conn.getAcc();
 379         } else {
 380             return engine.getAcc();
 381         }
 382     }
 383 
 384     String getEndpointIdentificationAlgorithmSE() {
 385         SSLParameters paras;
 386         if (conn != null) {
 387             paras = conn.getSSLParameters();
 388         } else {
 389             paras = engine.getSSLParameters();
 390         }
 391 
 392         return paras.getEndpointIdentificationAlgorithm();
 393     }
 394 
 395     private void setVersionSE(ProtocolVersion protocolVersion) {
 396         if (conn != null) {
 397             conn.setVersion(protocolVersion);
 398         } else {
 399             engine.setVersion(protocolVersion);
 400         }
 401     }
 402 
 403     /**
 404      * Set the active protocol version and propagate it to the SSLSocket
 405      * and our handshake streams. Called from ClientHandshaker
 406      * and ServerHandshaker with the negotiated protocol version.
 407      */
 408     void setVersion(ProtocolVersion protocolVersion) {
 409         this.protocolVersion = protocolVersion;
 410         setVersionSE(protocolVersion);
 411     }
 412 
 413     /**
 414      * Set the enabled protocols. Called from the constructor or
 415      * SSLSocketImpl/SSLEngineImpl.setEnabledProtocols() (if the
 416      * handshake is not yet in progress).
 417      */
 418     void setEnabledProtocols(ProtocolList enabledProtocols) {
 419         activeCipherSuites = null;
 420         activeProtocols = null;
 421 
 422         this.enabledProtocols = enabledProtocols;
 423     }
 424 
 425     /**
 426      * Set the enabled cipher suites. Called from
 427      * SSLSocketImpl/SSLEngineImpl.setEnabledCipherSuites() (if the
 428      * handshake is not yet in progress).
 429      */
 430     void setEnabledCipherSuites(CipherSuiteList enabledCipherSuites) {
 431         activeCipherSuites = null;
 432         activeProtocols = null;
 433         this.enabledCipherSuites = enabledCipherSuites;
 434     }
 435 
 436     /**
 437      * Set the algorithm constraints. Called from the constructor or
 438      * SSLSocketImpl/SSLEngineImpl.setAlgorithmConstraints() (if the
 439      * handshake is not yet in progress).
 440      */
 441     void setAlgorithmConstraints(AlgorithmConstraints algorithmConstraints) {
 442         activeCipherSuites = null;
 443         activeProtocols = null;
 444 
 445         this.algorithmConstraints =
 446             new SSLAlgorithmConstraints(algorithmConstraints);
 447         this.localSupportedSignAlgs = null;
 448     }
 449 
 450     Collection<SignatureAndHashAlgorithm> getLocalSupportedSignAlgs() {
 451         if (localSupportedSignAlgs == null) {
 452             localSupportedSignAlgs =
 453                 SignatureAndHashAlgorithm.getSupportedAlgorithms(
 454                                                     algorithmConstraints);
 455         }
 456 
 457         return localSupportedSignAlgs;
 458     }
 459 
 460     void setPeerSupportedSignAlgs(
 461             Collection<SignatureAndHashAlgorithm> algorithms) {
 462         peerSupportedSignAlgs =
 463             new ArrayList<SignatureAndHashAlgorithm>(algorithms);
 464     }
 465 
 466     Collection<SignatureAndHashAlgorithm> getPeerSupportedSignAlgs() {
 467         return peerSupportedSignAlgs;
 468     }
 469 
 470 
 471     /**
 472      * Set the identification protocol. Called from the constructor or
 473      * SSLSocketImpl/SSLEngineImpl.setIdentificationProtocol() (if the
 474      * handshake is not yet in progress).
 475      */
 476     void setIdentificationProtocol(String protocol) {
 477         this.identificationProtocol = protocol;
 478     }
 479 
 480     /**
 481      * Sets the server name indication of the handshake.
 482      */
 483     void setSNIServerNames(List<SNIServerName> serverNames) {
 484         // The serverNames parameter is unmodifiable.
 485         this.serverNames = serverNames;
 486     }
 487 
 488     /**
 489      * Sets the server name matchers of the handshaking.
 490      */
 491     void setSNIMatchers(Collection<SNIMatcher> sniMatchers) {
 492         // The sniMatchers parameter is unmodifiable.
 493         this.sniMatchers = sniMatchers;
 494     }
 495 
 496     /**
 497      * Sets the maximum packet size of the handshaking.
 498      */
 499     void setMaximumPacketSize(int maximumPacketSize) {
 500         this.maximumPacketSize = maximumPacketSize;
 501     }
 502 
 503     /**
 504      * Sets the Application Protocol list.
 505      */
 506     void setApplicationProtocols(String[] apl) {
 507         this.localApl = apl;
 508     }
 509 
 510     /**
 511      * Gets the "negotiated" ALPN value.
 512      */
 513     String getHandshakeApplicationProtocol() {
 514         return applicationProtocol;
 515     }
 516 
 517     /**
 518      * Sets the Application Protocol selector function for SSLEngine.
 519      */
 520     void setApplicationProtocolSelectorSSLEngine(
 521         BiFunction<SSLEngine,List<String>,String> selector) {
 522         this.appProtocolSelectorSSLEngine = selector;
 523     }
 524 
 525     /**
 526      * Sets the Application Protocol selector function for SSLSocket.
 527      */
 528     void setApplicationProtocolSelectorSSLSocket(
 529         BiFunction<SSLSocket,List<String>,String> selector) {
 530         this.appProtocolSelectorSSLSocket = selector;
 531     }
 532 
 533     /**
 534      * Sets the cipher suites preference.
 535      */
 536     void setUseCipherSuitesOrder(boolean on) {
 537         this.preferLocalCipherSuites = on;
 538     }
 539 
 540     /**
 541      * Prior to handshaking, activate the handshake and initialize the version,
 542      * input stream and output stream.
 543      */
 544     void activate(ProtocolVersion helloVersion) throws IOException {
 545         if (activeProtocols == null) {
 546             activeProtocols = getActiveProtocols();
 547         }
 548 
 549         if (activeProtocols.collection().isEmpty() ||
 550                 activeProtocols.max.v == ProtocolVersion.NONE.v) {
 551             throw new SSLHandshakeException(
 552                     "No appropriate protocol (protocol is disabled or " +
 553                     "cipher suites are inappropriate)");
 554         }
 555 
 556         if (activeCipherSuites == null) {
 557             activeCipherSuites = getActiveCipherSuites();
 558         }
 559 
 560         if (activeCipherSuites.collection().isEmpty()) {
 561             throw new SSLHandshakeException("No appropriate cipher suite");
 562         }
 563 
 564         // temporary protocol version until the actual protocol version
 565         // is negotiated in the Hello exchange. This affects the record
 566         // version we sent with the ClientHello.
 567         if (!isInitialHandshake) {
 568             protocolVersion = activeProtocolVersion;
 569         } else {
 570             protocolVersion = activeProtocols.max;
 571         }
 572 
 573         if (helloVersion == null || helloVersion.v == ProtocolVersion.NONE.v) {
 574             helloVersion = activeProtocols.helloVersion;
 575         }
 576 
 577         // We accumulate digests of the handshake messages so that
 578         // we can read/write CertificateVerify and Finished messages,
 579         // getting assurance against some particular active attacks.
 580         handshakeHash = new HandshakeHash(needCertVerify);
 581 
 582         // Generate handshake input/output stream.
 583         if (conn != null) {
 584             input = new HandshakeInStream();
 585             output = new HandshakeOutStream(conn.outputRecord);
 586 
 587             conn.inputRecord.setHandshakeHash(handshakeHash);
 588             conn.inputRecord.setHelloVersion(helloVersion);
 589 
 590             conn.outputRecord.setHandshakeHash(handshakeHash);
 591             conn.outputRecord.setHelloVersion(helloVersion);
 592             conn.outputRecord.setVersion(protocolVersion);
 593         } else if (engine != null) {
 594             input = new HandshakeInStream();
 595             output = new HandshakeOutStream(engine.outputRecord);
 596 
 597             engine.inputRecord.setHandshakeHash(handshakeHash);
 598             engine.inputRecord.setHelloVersion(helloVersion);
 599 
 600             engine.outputRecord.setHandshakeHash(handshakeHash);
 601             engine.outputRecord.setHelloVersion(helloVersion);
 602             engine.outputRecord.setVersion(protocolVersion);
 603         }
 604 
 605         handshakeActivated = true;
 606     }
 607 
 608     /**
 609      * Set cipherSuite and keyExchange to the given CipherSuite.
 610      * Does not perform any verification that this is a valid selection,
 611      * this must be done before calling this method.
 612      */
 613     void setCipherSuite(CipherSuite s) {
 614         this.cipherSuite = s;
 615         this.keyExchange = s.keyExchange;
 616     }
 617 
 618     /**
 619      * Check if the given ciphersuite is enabled and available within the
 620      * current active cipher suites.
 621      *
 622      * Does not check if the required server certificates are available.
 623      */
 624     boolean isNegotiable(CipherSuite s) {
 625         if (activeCipherSuites == null) {
 626             activeCipherSuites = getActiveCipherSuites();
 627         }
 628 
 629         return isNegotiable(activeCipherSuites, s);
 630     }
 631 
 632     /**
 633      * Check if the given ciphersuite is enabled and available within the
 634      * proposed cipher suite list.
 635      *
 636      * Does not check if the required server certificates are available.
 637      */
 638     static final boolean isNegotiable(CipherSuiteList proposed, CipherSuite s) {
 639         return proposed.contains(s) && s.isNegotiable();
 640     }
 641 
 642     /**
 643      * Check if the given protocol version is enabled and available.
 644      */
 645     boolean isNegotiable(ProtocolVersion protocolVersion) {
 646         if (activeProtocols == null) {
 647             activeProtocols = getActiveProtocols();
 648         }
 649 
 650         return activeProtocols.contains(protocolVersion);
 651     }
 652 
 653     /**
 654      * Select a protocol version from the list. Called from
 655      * ServerHandshaker to negotiate protocol version.
 656      *
 657      * Return the lower of the protocol version suggested in the
 658      * clien hello and the highest supported by the server.
 659      */
 660     ProtocolVersion selectProtocolVersion(ProtocolVersion protocolVersion) {
 661         if (activeProtocols == null) {
 662             activeProtocols = getActiveProtocols();
 663         }
 664 
 665         return activeProtocols.selectProtocolVersion(protocolVersion);
 666     }
 667 
 668     /**
 669      * Get the active cipher suites.
 670      *
 671      * In TLS 1.1, many weak or vulnerable cipher suites were obsoleted,
 672      * such as TLS_RSA_EXPORT_WITH_RC4_40_MD5. The implementation MUST NOT
 673      * negotiate these cipher suites in TLS 1.1 or later mode.
 674      *
 675      * Therefore, when the active protocols only include TLS 1.1 or later,
 676      * the client cannot request to negotiate those obsoleted cipher
 677      * suites.  That is, the obsoleted suites should not be included in the
 678      * client hello. So we need to create a subset of the enabled cipher
 679      * suites, the active cipher suites, which does not contain obsoleted
 680      * cipher suites of the minimum active protocol.
 681      *
 682      * Return empty list instead of null if no active cipher suites.
 683      */
 684     CipherSuiteList getActiveCipherSuites() {
 685         if (activeCipherSuites == null) {
 686             if (activeProtocols == null) {
 687                 activeProtocols = getActiveProtocols();
 688             }
 689 
 690             ArrayList<CipherSuite> suites = new ArrayList<>();
 691             if (!(activeProtocols.collection().isEmpty()) &&
 692                     activeProtocols.min.v != ProtocolVersion.NONE.v) {
 693                 Map<NamedGroupType, Boolean> cachedStatus =
 694                         new EnumMap<>(NamedGroupType.class);
 695                 for (CipherSuite suite : enabledCipherSuites.collection()) {
 696                     if (suite.isAvailable() &&
 697                             (!activeProtocols.min.obsoletes(suite)) &&
 698                             activeProtocols.max.supports(suite)) {
 699                         if (isActivatable(suite, cachedStatus)) {
 700                             suites.add(suite);
 701                         }
 702                     } else if (debug != null && Debug.isOn("verbose")) {
 703                         if (activeProtocols.min.obsoletes(suite)) {
 704                             System.out.println(
 705                                 "Ignoring obsoleted cipher suite: " + suite);
 706                         } else {
 707                             System.out.println(
 708                                 "Ignoring unsupported cipher suite: " + suite);
 709                         }
 710                     }
 711                 }
 712             }
 713             activeCipherSuites = new CipherSuiteList(suites);
 714         }
 715 
 716         return activeCipherSuites;
 717     }
 718 
 719     /*
 720      * Get the active protocol versions.
 721      *
 722      * In TLS 1.1, many weak or vulnerable cipher suites were obsoleted,
 723      * such as TLS_RSA_EXPORT_WITH_RC4_40_MD5. The implementation MUST NOT
 724      * negotiate these cipher suites in TLS 1.1 or later mode.
 725      *
 726      * For example, if "TLS_RSA_EXPORT_WITH_RC4_40_MD5" is the
 727      * only enabled cipher suite, the client cannot request TLS 1.1 or
 728      * later, even though TLS 1.1 or later is enabled.  We need to create a
 729      * subset of the enabled protocols, called the active protocols, which
 730      * contains protocols appropriate to the list of enabled Ciphersuites.
 731      *
 732      * Return empty list instead of null if no active protocol versions.
 733      */
 734     ProtocolList getActiveProtocols() {
 735         if (activeProtocols == null) {
 736             boolean enabledSSL20Hello = false;
 737             boolean checkedCurves = false;
 738             boolean hasCurves = false;
 739             ArrayList<ProtocolVersion> protocols = new ArrayList<>(4);
 740             for (ProtocolVersion protocol : enabledProtocols.collection()) {
 741                 // Need not to check the SSL20Hello protocol.
 742                 if (protocol.v == ProtocolVersion.SSL20Hello.v) {
 743                     enabledSSL20Hello = true;
 744                     continue;
 745                 }
 746 
 747                 if (!algorithmConstraints.permits(
 748                         EnumSet.of(CryptoPrimitive.KEY_AGREEMENT),
 749                         protocol.name, null)) {
 750                     if (debug != null && Debug.isOn("verbose")) {
 751                         System.out.println(
 752                             "Ignoring disabled protocol: " + protocol);
 753                     }
 754 
 755                     continue;
 756                 }
 757 
 758                 boolean found = false;
 759                 Map<NamedGroupType, Boolean> cachedStatus =
 760                         new EnumMap<>(NamedGroupType.class);
 761                 for (CipherSuite suite : enabledCipherSuites.collection()) {
 762                     if (suite.isAvailable() && (!protocol.obsoletes(suite)) &&
 763                                                protocol.supports(suite)) {
 764                         if (isActivatable(suite, cachedStatus)) {
 765                             protocols.add(protocol);
 766                             found = true;
 767                             break;
 768                         }
 769                     } else if (debug != null && Debug.isOn("verbose")) {
 770                         System.out.println(
 771                             "Ignoring unsupported cipher suite: " + suite +
 772                                  " for " + protocol);
 773                     }
 774                 }
 775 
 776                 if (!found && (debug != null) && Debug.isOn("handshake")) {
 777                     System.out.println(
 778                         "No available cipher suite for " + protocol);
 779                 }
 780             }
 781 
 782             if (!protocols.isEmpty() && enabledSSL20Hello) {
 783                 protocols.add(ProtocolVersion.SSL20Hello);
 784             }
 785 
 786             activeProtocols = new ProtocolList(protocols);
 787         }
 788 
 789         return activeProtocols;
 790     }
 791 
 792     private boolean isActivatable(CipherSuite suite,
 793             Map<NamedGroupType, Boolean> cachedStatus) {
 794 
 795         if (algorithmConstraints.permits(
 796                 EnumSet.of(CryptoPrimitive.KEY_AGREEMENT), suite.name, null)) {
 797             boolean available = true;
 798             NamedGroupType groupType = suite.keyExchange.groupType;
 799             if (groupType != NAMED_GROUP_NONE) {
 800                 Boolean checkedStatus = cachedStatus.get(groupType);
 801                 if (checkedStatus == null) {
 802                     available = SupportedGroupsExtension.isActivatable(
 803                             algorithmConstraints, groupType);
 804                     cachedStatus.put(groupType, available);
 805 
 806                     if (!available && debug != null && Debug.isOn("verbose")) {
 807                         System.out.println("No activated named group");
 808                     }
 809                 } else {
 810                     available = checkedStatus.booleanValue();
 811                 }
 812 
 813                 if (!available && debug != null && Debug.isOn("verbose")) {
 814                     System.out.println(
 815                         "No active named group, ignore " + suite);
 816                 }
 817 
 818                 return available;
 819             } else {
 820                 return true;
 821             }
 822         } else if (debug != null && Debug.isOn("verbose")) {
 823             System.out.println("Ignoring disabled cipher suite: " + suite);
 824         }
 825 
 826         return false;
 827     }
 828 
 829     /**
 830      * As long as handshaking has not activated, we can
 831      * change whether session creations are allowed.
 832      *
 833      * Callers should do their own checking if handshaking
 834      * has activated.
 835      */
 836     void setEnableSessionCreation(boolean newSessions) {
 837         enableNewSession = newSessions;
 838     }
 839 
 840     /**
 841      * Create a new read cipher and return it to caller.
 842      */
 843     CipherBox newReadCipher() throws NoSuchAlgorithmException {
 844         BulkCipher cipher = cipherSuite.cipher;
 845         CipherBox box;
 846         if (isClient) {
 847             box = cipher.newCipher(protocolVersion, svrWriteKey, svrWriteIV,
 848                                    sslContext.getSecureRandom(), false);
 849             svrWriteKey = null;
 850             svrWriteIV = null;
 851         } else {
 852             box = cipher.newCipher(protocolVersion, clntWriteKey, clntWriteIV,
 853                                    sslContext.getSecureRandom(), false);
 854             clntWriteKey = null;
 855             clntWriteIV = null;
 856         }
 857         return box;
 858     }
 859 
 860     /**
 861      * Create a new write cipher and return it to caller.
 862      */
 863     CipherBox newWriteCipher() throws NoSuchAlgorithmException {
 864         BulkCipher cipher = cipherSuite.cipher;
 865         CipherBox box;
 866         if (isClient) {
 867             box = cipher.newCipher(protocolVersion, clntWriteKey, clntWriteIV,
 868                                    sslContext.getSecureRandom(), true);
 869             clntWriteKey = null;
 870             clntWriteIV = null;
 871         } else {
 872             box = cipher.newCipher(protocolVersion, svrWriteKey, svrWriteIV,
 873                                    sslContext.getSecureRandom(), true);
 874             svrWriteKey = null;
 875             svrWriteIV = null;
 876         }
 877         return box;
 878     }
 879 
 880     /**
 881      * Create a new read MAC and return it to caller.
 882      */
 883     Authenticator newReadAuthenticator()
 884             throws NoSuchAlgorithmException, InvalidKeyException {
 885 
 886         Authenticator authenticator = null;
 887         if (cipherSuite.cipher.cipherType == AEAD_CIPHER) {
 888             authenticator = new Authenticator(protocolVersion);
 889         } else {
 890             MacAlg macAlg = cipherSuite.macAlg;
 891             if (isClient) {
 892                 authenticator = macAlg.newMac(protocolVersion, svrMacSecret);
 893                 svrMacSecret = null;
 894             } else {
 895                 authenticator = macAlg.newMac(protocolVersion, clntMacSecret);
 896                 clntMacSecret = null;
 897             }
 898         }
 899 
 900         return authenticator;
 901     }
 902 
 903     /**
 904      * Create a new write MAC and return it to caller.
 905      */
 906     Authenticator newWriteAuthenticator()
 907             throws NoSuchAlgorithmException, InvalidKeyException {
 908 
 909         Authenticator authenticator = null;
 910         if (cipherSuite.cipher.cipherType == AEAD_CIPHER) {
 911             authenticator = new Authenticator(protocolVersion);
 912         } else {
 913             MacAlg macAlg = cipherSuite.macAlg;
 914             if (isClient) {
 915                 authenticator = macAlg.newMac(protocolVersion, clntMacSecret);
 916                 clntMacSecret = null;
 917             } else {
 918                 authenticator = macAlg.newMac(protocolVersion, svrMacSecret);
 919                 svrMacSecret = null;
 920             }
 921         }
 922 
 923         return authenticator;
 924     }
 925 
 926     /*
 927      * Returns true iff the handshake sequence is done, so that
 928      * this freshly created session can become the current one.
 929      */
 930     boolean isDone() {
 931         return started() && handshakeState.isEmpty() && handshakeFinished;
 932     }
 933 
 934 
 935     /*
 936      * Returns the session which was created through this
 937      * handshake sequence ... should be called after isDone()
 938      * returns true.
 939      */
 940     SSLSessionImpl getSession() {
 941         return session;
 942     }
 943 
 944     /*
 945      * Set the handshake session
 946      */
 947     void setHandshakeSessionSE(SSLSessionImpl handshakeSession) {
 948         if (conn != null) {
 949             conn.setHandshakeSession(handshakeSession);
 950         } else {
 951             engine.setHandshakeSession(handshakeSession);
 952         }
 953     }
 954 
 955     void expectingFinishFlightSE() {
 956         if (conn != null) {
 957             conn.expectingFinishFlight();
 958         } else {
 959             engine.expectingFinishFlight();
 960         }
 961     }
 962 
 963     /*
 964      * Returns true if renegotiation is in use for this connection.
 965      */
 966     boolean isSecureRenegotiation() {
 967         return secureRenegotiation;
 968     }
 969 
 970     /*
 971      * Returns the verify_data from the Finished message sent by the client.
 972      */
 973     byte[] getClientVerifyData() {
 974         return clientVerifyData;
 975     }
 976 
 977     /*
 978      * Returns the verify_data from the Finished message sent by the server.
 979      */
 980     byte[] getServerVerifyData() {
 981         return serverVerifyData;
 982     }
 983 
 984     /*
 985      * This routine is fed SSL handshake records when they become available,
 986      * and processes messages found therein.
 987      */
 988     void processRecord(ByteBuffer record,
 989             boolean expectingFinished) throws IOException {
 990 
 991         checkThrown();
 992 
 993         /*
 994          * Store the incoming handshake data, then see if we can
 995          * now process any completed handshake messages
 996          */
 997         input.incomingRecord(record);
 998 
 999         /*
1000          * We don't need to create a separate delegatable task
1001          * for finished messages.
1002          */
1003         if ((conn != null) || expectingFinished) {
1004             processLoop();
1005         } else {
1006             delegateTask(new PrivilegedExceptionAction<Void>() {
1007                 @Override
1008                 public Void run() throws Exception {
1009                     processLoop();
1010                     return null;
1011                 }
1012             });
1013         }
1014     }
1015 
1016     /*
1017      * On input, we hash messages one at a time since servers may need
1018      * to access an intermediate hash to validate a CertificateVerify
1019      * message.
1020      *
1021      * Note that many handshake messages can come in one record (and often
1022      * do, to reduce network resource utilization), and one message can also
1023      * require multiple records (e.g. very large Certificate messages).
1024      */
1025     void processLoop() throws IOException {
1026 
1027         // need to read off 4 bytes at least to get the handshake
1028         // message type and length.
1029         while (input.available() >= 4) {
1030             byte messageType;
1031             int messageLen;
1032 
1033             /*
1034              * See if we can read the handshake message header, and
1035              * then the entire handshake message.  If not, wait till
1036              * we can read and process an entire message.
1037              */
1038             input.mark(4);
1039 
1040             messageType = (byte)input.getInt8();
1041             if (HandshakeMessage.isUnsupported(messageType)) {
1042                 throw new SSLProtocolException(
1043                     "Received unsupported or unknown handshake message: " +
1044                     messageType);
1045             }
1046 
1047             messageLen = input.getInt24();
1048 
1049             if (input.available() < messageLen) {
1050                 input.reset();
1051                 return;
1052             }
1053 
1054             // Set the flags in the message receiving side.
1055             if (messageType == HandshakeMessage.ht_client_hello) {
1056                 clientHelloDelivered = true;
1057             } else if (messageType == HandshakeMessage.ht_hello_request) {
1058                 serverHelloRequested = true;
1059             }
1060 
1061             /*
1062              * Process the message.  We require
1063              * that processMessage() consumes the entire message.  In
1064              * lieu of explicit error checks (how?!) we assume that the
1065              * data will look like garbage on encoding/processing errors,
1066              * and that other protocol code will detect such errors.
1067              *
1068              * Note that digesting is normally deferred till after the
1069              * message has been processed, though to process at least the
1070              * client's Finished message (i.e. send the server's) we need
1071              * to acccelerate that digesting.
1072              *
1073              * Also, note that hello request messages are never hashed;
1074              * that includes the hello request header, too.
1075              */
1076             processMessage(messageType, messageLen);
1077 
1078             // Reload if this message has been reserved.
1079             //
1080             // Note: in the implementation, only certificate_verify and
1081             // finished messages are reserved.
1082             if ((messageType == HandshakeMessage.ht_finished) ||
1083                 (messageType == HandshakeMessage.ht_certificate_verify)) {
1084 
1085                 handshakeHash.reload();
1086             }
1087         }
1088     }
1089 
1090 
1091     /**
1092      * Returns true iff the handshaker has been activated.
1093      *
1094      * In activated state, the handshaker may not send any messages out.
1095      */
1096     boolean activated() {
1097         return handshakeActivated;
1098     }
1099 
1100     /**
1101      * Returns true iff the handshaker has sent any messages.
1102      */
1103     boolean started() {
1104         return (serverHelloRequested || clientHelloDelivered);
1105     }
1106 
1107     /*
1108      * Used to kickstart the negotiation ... either writing a
1109      * ClientHello or a HelloRequest as appropriate, whichever
1110      * the subclass returns.  NOP if handshaking's already started.
1111      */
1112     void kickstart() throws IOException {
1113         if ((isClient && clientHelloDelivered) ||
1114                 (!isClient && serverHelloRequested)) {
1115             return;
1116         }
1117 
1118         HandshakeMessage m = getKickstartMessage();
1119         handshakeState.update(m, resumingSession);
1120 
1121         if (debug != null && Debug.isOn("handshake")) {
1122             m.print(System.out);
1123         }
1124         m.write(output);
1125         output.flush();
1126 
1127         // Set the flags in the message delivering side.
1128         int handshakeType = m.messageType();
1129         if (handshakeType == HandshakeMessage.ht_hello_request) {
1130             serverHelloRequested = true;
1131         } else {        // HandshakeMessage.ht_client_hello
1132             clientHelloDelivered = true;
1133         }
1134     }
1135 
1136     /**
1137      * Both client and server modes can start handshaking; but the
1138      * message they send to do so is different.
1139      */
1140     abstract HandshakeMessage getKickstartMessage() throws SSLException;
1141 
1142     /*
1143      * Client and Server side protocols are each driven though this
1144      * call, which processes a single message and drives the appropriate
1145      * side of the protocol state machine (depending on the subclass).
1146      */
1147     abstract void processMessage(byte messageType, int messageLen)
1148         throws IOException;
1149 
1150     /*
1151      * Most alerts in the protocol relate to handshaking problems.
1152      * Alerts are detected as the connection reads data.
1153      */
1154     abstract void handshakeAlert(byte description) throws SSLProtocolException;
1155 
1156     /*
1157      * Sends a change cipher spec message and updates the write side
1158      * cipher state so that future messages use the just-negotiated spec.
1159      */
1160     void sendChangeCipherSpec(Finished mesg, boolean lastMessage)
1161             throws IOException {
1162 
1163         output.flush(); // i.e. handshake data
1164 
1165         /*
1166          * The write cipher state is protected by the connection write lock
1167          * so we must grab it while making the change. We also
1168          * make sure no writes occur between sending the ChangeCipherSpec
1169          * message, installing the new cipher state, and sending the
1170          * Finished message.
1171          *
1172          * We already hold SSLEngine/SSLSocket "this" by virtue
1173          * of this being called from the readRecord code.
1174          */
1175         if (conn != null) {
1176             conn.writeLock.lock();
1177             try {
1178                 handshakeState.changeCipherSpec(false, isClient);
1179                 conn.changeWriteCiphers();
1180                 if (debug != null && Debug.isOn("handshake")) {
1181                     mesg.print(System.out);
1182                 }
1183 
1184                 handshakeState.update(mesg, resumingSession);
1185                 mesg.write(output);
1186                 output.flush();
1187             } finally {
1188                 conn.writeLock.unlock();
1189             }
1190         } else {
1191             synchronized (engine.writeLock) {
1192                 handshakeState.changeCipherSpec(false, isClient);
1193                 engine.changeWriteCiphers();
1194                 if (debug != null && Debug.isOn("handshake")) {
1195                     mesg.print(System.out);
1196                 }
1197 
1198                 handshakeState.update(mesg, resumingSession);
1199                 mesg.write(output);
1200                 output.flush();
1201             }
1202         }
1203 
1204         if (lastMessage) {
1205             handshakeFinished = true;
1206         }
1207     }
1208 
1209     void receiveChangeCipherSpec() throws IOException {
1210         handshakeState.changeCipherSpec(true, isClient);
1211     }
1212 
1213     /*
1214      * Single access point to key calculation logic.  Given the
1215      * pre-master secret and the nonces from client and server,
1216      * produce all the keying material to be used.
1217      */
1218     void calculateKeys(SecretKey preMasterSecret, ProtocolVersion version) {
1219         SecretKey master = calculateMasterSecret(preMasterSecret, version);
1220         session.setMasterSecret(master);
1221         calculateConnectionKeys(master);
1222     }
1223 
1224     /*
1225      * Calculate the master secret from its various components.  This is
1226      * used for key exchange by all cipher suites.
1227      *
1228      * The master secret is the catenation of three MD5 hashes, each
1229      * consisting of the pre-master secret and a SHA1 hash.  Those three
1230      * SHA1 hashes are of (different) constant strings, the pre-master
1231      * secret, and the nonces provided by the client and the server.
1232      */
1233     private SecretKey calculateMasterSecret(SecretKey preMasterSecret,
1234             ProtocolVersion requestedVersion) {
1235 
1236         if (debug != null && Debug.isOn("keygen")) {
1237             HexDumpEncoder      dump = new HexDumpEncoder();
1238 
1239             System.out.println("SESSION KEYGEN:");
1240 
1241             System.out.println("PreMaster Secret:");
1242             printHex(dump, preMasterSecret.getEncoded());
1243 
1244             // Nonces are dumped with connection keygen, no
1245             // benefit to doing it twice
1246         }
1247 
1248         // What algs/params do we need to use?
1249         String masterAlg;
1250         PRF prf;
1251 
1252         byte majorVersion = protocolVersion.major;
1253         byte minorVersion = protocolVersion.minor;
1254         if (protocolVersion.isDTLSProtocol()) {
1255             // Use TLS version number for DTLS key calculation
1256             if (protocolVersion.v == ProtocolVersion.DTLS10.v) {
1257                 majorVersion = ProtocolVersion.TLS11.major;
1258                 minorVersion = ProtocolVersion.TLS11.minor;
1259 
1260                 masterAlg = "SunTlsMasterSecret";
1261                 prf = P_NONE;
1262             } else {    // DTLS 1.2
1263                 majorVersion = ProtocolVersion.TLS12.major;
1264                 minorVersion = ProtocolVersion.TLS12.minor;
1265 
1266                 masterAlg = "SunTls12MasterSecret";
1267                 prf = cipherSuite.prfAlg;
1268             }
1269         } else {
1270             if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
1271                 masterAlg = "SunTls12MasterSecret";
1272                 prf = cipherSuite.prfAlg;
1273             } else {
1274                 masterAlg = "SunTlsMasterSecret";
1275                 prf = P_NONE;
1276             }
1277         }
1278 
1279         String prfHashAlg = prf.getPRFHashAlg();
1280         int prfHashLength = prf.getPRFHashLength();
1281         int prfBlockSize = prf.getPRFBlockSize();
1282 
1283         byte[] sessionHash = null;
1284         if (session.getUseExtendedMasterSecret()){
1285             sessionHash = handshakeHash.getFinishedHash();
1286         }
1287 
1288         @SuppressWarnings("deprecation")
1289         TlsMasterSecretParameterSpec spec = new TlsMasterSecretParameterSpec(
1290                 preMasterSecret, (majorVersion & 0xFF), (minorVersion & 0xFF),
1291                 clnt_random.random_bytes, svr_random.random_bytes, sessionHash,
1292                 prfHashAlg, prfHashLength, prfBlockSize);
1293 
1294         try {
1295             KeyGenerator kg = JsseJce.getKeyGenerator(masterAlg);
1296             kg.init(spec);
1297             return kg.generateKey();
1298         } catch (InvalidAlgorithmParameterException |
1299                 NoSuchAlgorithmException iae) {
1300             // unlikely to happen, otherwise, must be a provider exception
1301             //
1302             // For RSA premaster secrets, do not signal a protocol error
1303             // due to the Bleichenbacher attack. See comments further down.
1304             if (debug != null && Debug.isOn("handshake")) {
1305                 System.out.println("RSA master secret generation error:");
1306                 iae.printStackTrace(System.out);
1307             }
1308             throw new ProviderException(iae);
1309 
1310         }
1311     }
1312 
1313     /*
1314      * Calculate the keys needed for this connection, once the session's
1315      * master secret has been calculated.  Uses the master key and nonces;
1316      * the amount of keying material generated is a function of the cipher
1317      * suite that's been negotiated.
1318      *
1319      * This gets called both on the "full handshake" (where we exchanged
1320      * a premaster secret and started a new session) as well as on the
1321      * "fast handshake" (where we just resumed a pre-existing session).
1322      */
1323     @SuppressWarnings("deprecation")
1324     void calculateConnectionKeys(SecretKey masterKey) {
1325         /*
1326          * For both the read and write sides of the protocol, we use the
1327          * master to generate MAC secrets and cipher keying material.  Block
1328          * ciphers need initialization vectors, which we also generate.
1329          *
1330          * First we figure out how much keying material is needed.
1331          */
1332         int hashSize = cipherSuite.macAlg.size;
1333         boolean is_exportable = cipherSuite.exportable;
1334         BulkCipher cipher = cipherSuite.cipher;
1335         int expandedKeySize = is_exportable ? cipher.expandedKeySize : 0;
1336 
1337         // Which algs/params do we need to use?
1338         String keyMaterialAlg;
1339         PRF prf;
1340 
1341         byte majorVersion = protocolVersion.major;
1342         byte minorVersion = protocolVersion.minor;
1343         if (protocolVersion.isDTLSProtocol()) {
1344             // Use TLS version number for DTLS key calculation
1345             if (protocolVersion.v == ProtocolVersion.DTLS10.v) {
1346                 majorVersion = ProtocolVersion.TLS11.major;
1347                 minorVersion = ProtocolVersion.TLS11.minor;
1348 
1349                 keyMaterialAlg = "SunTlsKeyMaterial";
1350                 prf = P_NONE;
1351             } else {    // DTLS 1.2+
1352                 majorVersion = ProtocolVersion.TLS12.major;
1353                 minorVersion = ProtocolVersion.TLS12.minor;
1354 
1355                 keyMaterialAlg = "SunTls12KeyMaterial";
1356                 prf = cipherSuite.prfAlg;
1357             }
1358         } else {
1359             if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
1360                 keyMaterialAlg = "SunTls12KeyMaterial";
1361                 prf = cipherSuite.prfAlg;
1362             } else {
1363                 keyMaterialAlg = "SunTlsKeyMaterial";
1364                 prf = P_NONE;
1365             }
1366         }
1367 
1368         String prfHashAlg = prf.getPRFHashAlg();
1369         int prfHashLength = prf.getPRFHashLength();
1370         int prfBlockSize = prf.getPRFBlockSize();
1371 
1372         // TLS v1.1+ and DTLS use an explicit IV in CBC cipher suites to
1373         // protect against the CBC attacks.  AEAD/GCM cipher suites in TLS
1374         // v1.2 or later use a fixed IV as the implicit part of the partially
1375         // implicit nonce technique described in RFC 5116.
1376         int ivSize = cipher.ivSize;
1377         if (cipher.cipherType == AEAD_CIPHER) {
1378             ivSize = cipher.fixedIvSize;
1379         } else if ((cipher.cipherType == BLOCK_CIPHER) &&
1380                 protocolVersion.useTLS11PlusSpec()) {
1381             ivSize = 0;
1382         }
1383 
1384         TlsKeyMaterialParameterSpec spec = new TlsKeyMaterialParameterSpec(
1385                 masterKey, (majorVersion & 0xFF), (minorVersion & 0xFF),
1386                 clnt_random.random_bytes, svr_random.random_bytes,
1387                 cipher.algorithm, cipher.keySize, expandedKeySize,
1388                 ivSize, hashSize,
1389                 prfHashAlg, prfHashLength, prfBlockSize);
1390 
1391         try {
1392             KeyGenerator kg = JsseJce.getKeyGenerator(keyMaterialAlg);
1393             kg.init(spec);
1394             TlsKeyMaterialSpec keySpec = (TlsKeyMaterialSpec)kg.generateKey();
1395 
1396             // Return null if cipher keys are not supposed to be generated.
1397             clntWriteKey = keySpec.getClientCipherKey();
1398             svrWriteKey = keySpec.getServerCipherKey();
1399 
1400             // Return null if IVs are not supposed to be generated.
1401             clntWriteIV = keySpec.getClientIv();
1402             svrWriteIV = keySpec.getServerIv();
1403 
1404             // Return null if MAC keys are not supposed to be generated.
1405             clntMacSecret = keySpec.getClientMacKey();
1406             svrMacSecret = keySpec.getServerMacKey();
1407         } catch (GeneralSecurityException e) {
1408             throw new ProviderException(e);
1409         }
1410 
1411         //
1412         // Dump the connection keys as they're generated.
1413         //
1414         if (debug != null && Debug.isOn("keygen")) {
1415             synchronized (System.out) {
1416                 HexDumpEncoder  dump = new HexDumpEncoder();
1417 
1418                 System.out.println("CONNECTION KEYGEN:");
1419 
1420                 // Inputs:
1421                 System.out.println("Client Nonce:");
1422                 printHex(dump, clnt_random.random_bytes);
1423                 System.out.println("Server Nonce:");
1424                 printHex(dump, svr_random.random_bytes);
1425                 System.out.println("Master Secret:");
1426                 printHex(dump, masterKey.getEncoded());
1427 
1428                 // Outputs:
1429                 if (clntMacSecret != null) {
1430                     System.out.println("Client MAC write Secret:");
1431                     printHex(dump, clntMacSecret.getEncoded());
1432                     System.out.println("Server MAC write Secret:");
1433                     printHex(dump, svrMacSecret.getEncoded());
1434                 } else {
1435                     System.out.println("... no MAC keys used for this cipher");
1436                 }
1437 
1438                 if (clntWriteKey != null) {
1439                     System.out.println("Client write key:");
1440                     printHex(dump, clntWriteKey.getEncoded());
1441                     System.out.println("Server write key:");
1442                     printHex(dump, svrWriteKey.getEncoded());
1443                 } else {
1444                     System.out.println("... no encryption keys used");
1445                 }
1446 
1447                 if (clntWriteIV != null) {
1448                     System.out.println("Client write IV:");
1449                     printHex(dump, clntWriteIV.getIV());
1450                     System.out.println("Server write IV:");
1451                     printHex(dump, svrWriteIV.getIV());
1452                 } else {
1453                     if (protocolVersion.useTLS11PlusSpec()) {
1454                         System.out.println(
1455                                 "... no IV derived for this protocol");
1456                     } else {
1457                         System.out.println("... no IV used for this cipher");
1458                     }
1459                 }
1460                 System.out.flush();
1461             }
1462         }
1463     }
1464 
1465     private static void printHex(HexDumpEncoder dump, byte[] bytes) {
1466         if (bytes == null) {
1467             System.out.println("(key bytes not available)");
1468         } else {
1469             try {
1470                 dump.encodeBuffer(bytes, System.out);
1471             } catch (IOException e) {
1472                 // just for debugging, ignore this
1473             }
1474         }
1475     }
1476 
1477     /*
1478      * Implement a simple task delegator.
1479      *
1480      * We are currently implementing this as a single delegator, may
1481      * try for parallel tasks later.  Client Authentication could
1482      * benefit from this, where ClientKeyExchange/CertificateVerify
1483      * could be carried out in parallel.
1484      */
1485     class DelegatedTask<E> implements Runnable {
1486 
1487         private PrivilegedExceptionAction<E> pea;
1488 
1489         DelegatedTask(PrivilegedExceptionAction<E> pea) {
1490             this.pea = pea;
1491         }
1492 
1493         public void run() {
1494             synchronized (engine) {
1495                 try {
1496                     AccessController.doPrivileged(pea, engine.getAcc());
1497                 } catch (PrivilegedActionException pae) {
1498                     thrown = pae.getException();
1499                 } catch (RuntimeException rte) {
1500                     thrown = rte;
1501                 }
1502                 delegatedTask = null;
1503                 taskDelegated = false;
1504             }
1505         }
1506     }
1507 
1508     private <T> void delegateTask(PrivilegedExceptionAction<T> pea) {
1509         delegatedTask = new DelegatedTask<T>(pea);
1510         taskDelegated = false;
1511         thrown = null;
1512     }
1513 
1514     DelegatedTask<?> getTask() {
1515         if (!taskDelegated) {
1516             taskDelegated = true;
1517             return delegatedTask;
1518         } else {
1519             return null;
1520         }
1521     }
1522 
1523     /*
1524      * See if there are any tasks which need to be delegated
1525      *
1526      * Locked by SSLEngine.this.
1527      */
1528     boolean taskOutstanding() {
1529         return (delegatedTask != null);
1530     }
1531 
1532     /*
1533      * The previous caller failed for some reason, report back the
1534      * Exception.  We won't worry about Error's.
1535      *
1536      * Locked by SSLEngine.this.
1537      */
1538     void checkThrown() throws SSLException {
1539         synchronized (thrownLock) {
1540             if (thrown != null) {
1541 
1542                 String msg = thrown.getMessage();
1543 
1544                 if (msg == null) {
1545                     msg = "Delegated task threw Exception/Error";
1546                 }
1547 
1548                 /*
1549                  * See what the underlying type of exception is.  We should
1550                  * throw the same thing.  Chain thrown to the new exception.
1551                  */
1552                 Exception e = thrown;
1553                 thrown = null;
1554 
1555                 if (e instanceof RuntimeException) {
1556                     throw new RuntimeException(msg, e);
1557                 } else if (e instanceof SSLHandshakeException) {
1558                     throw (SSLHandshakeException)
1559                         new SSLHandshakeException(msg).initCause(e);
1560                 } else if (e instanceof SSLKeyException) {
1561                     throw (SSLKeyException)
1562                         new SSLKeyException(msg).initCause(e);
1563                 } else if (e instanceof SSLPeerUnverifiedException) {
1564                     throw (SSLPeerUnverifiedException)
1565                         new SSLPeerUnverifiedException(msg).initCause(e);
1566                 } else if (e instanceof SSLProtocolException) {
1567                     throw (SSLProtocolException)
1568                         new SSLProtocolException(msg).initCause(e);
1569                 } else {
1570                     /*
1571                      * If it's SSLException or any other Exception,
1572                      * we'll wrap it in an SSLException.
1573                      */
1574                     throw new SSLException(msg, e);
1575                 }
1576             }
1577         }
1578     }
1579 }