src/java.base/share/classes/sun/security/ssl/Handshaker.java

Print this page




  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.security.NoSuchAlgorithmException;
  33 import java.security.AccessController;
  34 import java.security.AlgorithmConstraints;
  35 import java.security.AccessControlContext;
  36 import java.security.PrivilegedExceptionAction;
  37 import java.security.PrivilegedActionException;
  38 
  39 import javax.crypto.*;
  40 import javax.crypto.spec.*;
  41 
  42 import javax.net.ssl.*;
  43 import sun.misc.HexDumpEncoder;
  44 
  45 import sun.security.internal.spec.*;
  46 import sun.security.internal.interfaces.TlsMasterSecret;
  47 
  48 import sun.security.ssl.HandshakeMessage.*;
  49 import sun.security.ssl.CipherSuite.*;
  50 
  51 import static sun.security.ssl.CipherSuite.PRF.*;


  98      * List of active protocols
  99      *
 100      * Active protocols is a subset of enabled protocols, and will
 101      * contain only those protocols that have vaild cipher suites
 102      * enabled.
 103      */
 104     private ProtocolList       activeProtocols;
 105 
 106     /*
 107      * List of active cipher suites
 108      *
 109      * Active cipher suites is a subset of enabled cipher suites, and will
 110      * contain only those cipher suites available for the active protocols.
 111      */
 112     private CipherSuiteList    activeCipherSuites;
 113 
 114     // The server name indication and matchers
 115     List<SNIServerName> serverNames = Collections.<SNIServerName>emptyList();
 116     Collection<SNIMatcher> sniMatchers = Collections.<SNIMatcher>emptyList();
 117 



 118     private boolean             isClient;
 119     private boolean             needCertVerify;
 120 
 121     SSLSocketImpl               conn = null;
 122     SSLEngineImpl               engine = null;
 123 
 124     HandshakeHash               handshakeHash;
 125     HandshakeInStream           input;
 126     HandshakeOutStream          output;
 127     int                         state;
 128     SSLContextImpl              sslContext;
 129     RandomCookie                clnt_random, svr_random;
 130     SSLSessionImpl              session;
 131 






 132     // current CipherSuite. Never null, initially SSL_NULL_WITH_NULL_NULL
 133     CipherSuite         cipherSuite;
 134 
 135     // current key exchange. Never null, initially K_NULL
 136     KeyExchange         keyExchange;
 137 
 138     // True if this session is being resumed (fast handshake)
 139     boolean             resumingSession;
 140 
 141     // True if it's OK to start a new SSL session
 142     boolean             enableNewSession;
 143 
 144     // True if session keys have been calculated and the caller may receive
 145     // and process a ChangeCipherSpec message
 146     private boolean sessKeysCalculated;
 147 
 148     // Whether local cipher suites preference should be honored during
 149     // handshaking?
 150     //
 151     // Note that in this provider, this option only applies to server side.
 152     // Local cipher suites preference is always honored in client side in
 153     // this provider.
 154     boolean preferLocalCipherSuites = false;
 155 
 156     // Temporary storage for the individual keys. Set by
 157     // calculateConnectionKeys() and cleared once the ciphers are
 158     // activated.
 159     private SecretKey clntWriteKey, svrWriteKey;
 160     private IvParameterSpec clntWriteIV, svrWriteIV;
 161     private SecretKey clntMacSecret, svrMacSecret;
 162 
 163     /*
 164      * Delegated task subsystem data structures.
 165      *
 166      * If thrown is set, we need to propagate this back immediately
 167      * on entry into processMessage().


 190     // For maximum security, RFC 5746 also allows server (or client) to
 191     // reject such message with a fatal "handshake_failure" alert.
 192     //
 193     // By default, allow such legacy hello messages.
 194     static final boolean allowLegacyHelloMessages = Debug.getBooleanProperty(
 195                     "sun.security.ssl.allowLegacyHelloMessages", true);
 196 
 197     // To prevent the TLS renegotiation issues, by setting system property
 198     // "jdk.tls.rejectClientInitiatedRenegotiation" to true, applications in
 199     // server side can disable all client initiated SSL renegotiations
 200     // regardless of the support of TLS protocols.
 201     //
 202     // By default, allow client initiated renegotiations.
 203     static final boolean rejectClientInitiatedRenego =
 204             Debug.getBooleanProperty(
 205                 "jdk.tls.rejectClientInitiatedRenegotiation", false);
 206 
 207     // need to dispose the object when it is invalidated
 208     boolean invalidated;
 209 





 210     Handshaker(SSLSocketImpl c, SSLContextImpl context,
 211             ProtocolList enabledProtocols, boolean needCertVerify,
 212             boolean isClient, ProtocolVersion activeProtocolVersion,
 213             boolean isInitialHandshake, boolean secureRenegotiation,
 214             byte[] clientVerifyData, byte[] serverVerifyData) {
 215         this.conn = c;

 216         init(context, enabledProtocols, needCertVerify, isClient,
 217             activeProtocolVersion, isInitialHandshake, secureRenegotiation,
 218             clientVerifyData, serverVerifyData);
 219     }
 220 
 221     Handshaker(SSLEngineImpl engine, SSLContextImpl context,
 222             ProtocolList enabledProtocols, boolean needCertVerify,
 223             boolean isClient, ProtocolVersion activeProtocolVersion,
 224             boolean isInitialHandshake, boolean secureRenegotiation,
 225             byte[] clientVerifyData, byte[] serverVerifyData) {

 226         this.engine = engine;

 227         init(context, enabledProtocols, needCertVerify, isClient,
 228             activeProtocolVersion, isInitialHandshake, secureRenegotiation,
 229             clientVerifyData, serverVerifyData);
 230     }
 231 
 232     private void init(SSLContextImpl context, ProtocolList enabledProtocols,
 233             boolean needCertVerify, boolean isClient,
 234             ProtocolVersion activeProtocolVersion,
 235             boolean isInitialHandshake, boolean secureRenegotiation,
 236             byte[] clientVerifyData, byte[] serverVerifyData) {
 237 
 238         if (debug != null && Debug.isOn("handshake")) {
 239             System.out.println(
 240                 "Allow unsafe renegotiation: " + allowUnsafeRenegotiation +
 241                 "\nAllow legacy hello messages: " + allowLegacyHelloMessages +
 242                 "\nIs initial handshake: " + isInitialHandshake +
 243                 "\nIs secure renegotiation: " + secureRenegotiation);
 244         }
 245 
 246         this.sslContext = context;
 247         this.isClient = isClient;
 248         this.needCertVerify = needCertVerify;
 249         this.activeProtocolVersion = activeProtocolVersion;
 250         this.isInitialHandshake = isInitialHandshake;
 251         this.secureRenegotiation = secureRenegotiation;
 252         this.clientVerifyData = clientVerifyData;
 253         this.serverVerifyData = serverVerifyData;
 254         enableNewSession = true;
 255         invalidated = false;
 256         sessKeysCalculated = false;




 257 
 258         setCipherSuite(CipherSuite.C_NULL);
 259         setEnabledProtocols(enabledProtocols);
 260 
 261         if (conn != null) {
 262             algorithmConstraints = new SSLAlgorithmConstraints(conn, true);
 263         } else {        // engine != null
 264             algorithmConstraints = new SSLAlgorithmConstraints(engine, true);
 265         }
 266 
 267 
 268         //
 269         // In addition to the connection state machine, controlling
 270         // how the connection deals with the different sorts of records
 271         // that get sent (notably handshake transitions!), there's
 272         // also a handshaking state machine that controls message
 273         // sequencing.
 274         //
 275         // It's a convenient artifact of the protocol that this can,
 276         // with only a couple of minor exceptions, be driven by the
 277         // type constant for the last message seen:  except for the
 278         // client's cert verify, those constants are in a convenient
 279         // order to drastically simplify state machine checking.
 280         //
 281         state = -2;  // initialized but not activated
 282     }
 283 
 284     /*
 285      * Reroutes calls to the SSLSocket or SSLEngine (*SE).
 286      *
 287      * We could have also done it by extra classes
 288      * and letting them override, but this seemed much
 289      * less involved.
 290      */
 291     void fatalSE(byte b, String diagnostic) throws IOException {
 292         fatalSE(b, diagnostic, null);
 293     }
 294 
 295     void fatalSE(byte b, Throwable cause) throws IOException {
 296         fatalSE(b, null, cause);
 297     }
 298 
 299     void fatalSE(byte b, String diagnostic, Throwable cause)
 300             throws IOException {
 301         if (conn != null) {


 343             return engine.getPeerPort();
 344         }
 345     }
 346 
 347     int getLocalPortSE() {
 348         if (conn != null) {
 349             return conn.getLocalPort();
 350         } else {
 351             return -1;
 352         }
 353     }
 354 
 355     AccessControlContext getAccSE() {
 356         if (conn != null) {
 357             return conn.getAcc();
 358         } else {
 359             return engine.getAcc();
 360         }
 361     }
 362 
 363     final boolean receivedChangeCipherSpec() {
 364         if (conn != null) {
 365             return conn.receivedChangeCipherSpec();
 366         } else {
 367             return engine.receivedChangeCipherSpec();
 368         }
 369     }
 370 
 371     String getEndpointIdentificationAlgorithmSE() {
 372         SSLParameters paras;
 373         if (conn != null) {
 374             paras = conn.getSSLParameters();
 375         } else {
 376             paras = engine.getSSLParameters();
 377         }
 378 
 379         return paras.getEndpointIdentificationAlgorithm();
 380     }
 381 
 382     private void setVersionSE(ProtocolVersion protocolVersion) {
 383         if (conn != null) {
 384             conn.setVersion(protocolVersion);
 385         } else {
 386             engine.setVersion(protocolVersion);
 387         }
 388     }
 389 
 390     /**
 391      * Set the active protocol version and propagate it to the SSLSocket
 392      * and our handshake streams. Called from ClientHandshaker
 393      * and ServerHandshaker with the negotiated protocol version.
 394      */
 395     void setVersion(ProtocolVersion protocolVersion) {
 396         this.protocolVersion = protocolVersion;
 397         setVersionSE(protocolVersion);
 398 
 399         output.r.setVersion(protocolVersion);
 400     }
 401 
 402     /**
 403      * Set the enabled protocols. Called from the constructor or
 404      * SSLSocketImpl/SSLEngineImpl.setEnabledProtocols() (if the
 405      * handshake is not yet in progress).
 406      */
 407     void setEnabledProtocols(ProtocolList enabledProtocols) {
 408         activeCipherSuites = null;
 409         activeProtocols = null;
 410 
 411         this.enabledProtocols = enabledProtocols;
 412     }
 413 
 414     /**
 415      * Set the enabled cipher suites. Called from
 416      * SSLSocketImpl/SSLEngineImpl.setEnabledCipherSuites() (if the
 417      * handshake is not yet in progress).
 418      */
 419     void setEnabledCipherSuites(CipherSuiteList enabledCipherSuites) {


 466         this.identificationProtocol = protocol;
 467     }
 468 
 469     /**
 470      * Sets the server name indication of the handshake.
 471      */
 472     void setSNIServerNames(List<SNIServerName> serverNames) {
 473         // The serverNames parameter is unmodifiable.
 474         this.serverNames = serverNames;
 475     }
 476 
 477     /**
 478      * Sets the server name matchers of the handshaking.
 479      */
 480     void setSNIMatchers(Collection<SNIMatcher> sniMatchers) {
 481         // The sniMatchers parameter is unmodifiable.
 482         this.sniMatchers = sniMatchers;
 483     }
 484 
 485     /**







 486      * Sets the cipher suites preference.
 487      */
 488     void setUseCipherSuitesOrder(boolean on) {
 489         this.preferLocalCipherSuites = on;
 490     }
 491 
 492     /**
 493      * Prior to handshaking, activate the handshake and initialize the version,
 494      * input stream and output stream.
 495      */
 496     void activate(ProtocolVersion helloVersion) throws IOException {
 497         if (activeProtocols == null) {
 498             activeProtocols = getActiveProtocols();
 499         }
 500 
 501         if (activeProtocols.collection().isEmpty() ||
 502                 activeProtocols.max.v == ProtocolVersion.NONE.v) {
 503             throw new SSLHandshakeException(
 504                     "No appropriate protocol (protocol is disabled or " +
 505                     "cipher suites are inappropriate)");


 515 
 516         // temporary protocol version until the actual protocol version
 517         // is negotiated in the Hello exchange. This affects the record
 518         // version we sent with the ClientHello.
 519         if (!isInitialHandshake) {
 520             protocolVersion = activeProtocolVersion;
 521         } else {
 522             protocolVersion = activeProtocols.max;
 523         }
 524 
 525         if (helloVersion == null || helloVersion.v == ProtocolVersion.NONE.v) {
 526             helloVersion = activeProtocols.helloVersion;
 527         }
 528 
 529         // We accumulate digests of the handshake messages so that
 530         // we can read/write CertificateVerify and Finished messages,
 531         // getting assurance against some particular active attacks.
 532         handshakeHash = new HandshakeHash(needCertVerify);
 533 
 534         // Generate handshake input/output stream.
 535         input = new HandshakeInStream(handshakeHash);
 536         if (conn != null) {
 537             output = new HandshakeOutStream(protocolVersion, helloVersion,
 538                                         handshakeHash, conn);
 539             conn.getAppInputStream().r.setHandshakeHash(handshakeHash);
 540             conn.getAppInputStream().r.setHelloVersion(helloVersion);
 541             conn.getAppOutputStream().r.setHelloVersion(helloVersion);
 542         } else {
 543             output = new HandshakeOutStream(protocolVersion, helloVersion,
 544                                         handshakeHash, engine);





 545             engine.inputRecord.setHandshakeHash(handshakeHash);
 546             engine.inputRecord.setHelloVersion(helloVersion);


 547             engine.outputRecord.setHelloVersion(helloVersion);

 548         }
 549 
 550         // move state to activated
 551         state = -1;
 552     }
 553 
 554     /**
 555      * Set cipherSuite and keyExchange to the given CipherSuite.
 556      * Does not perform any verification that this is a valid selection,
 557      * this must be done before calling this method.
 558      */
 559     void setCipherSuite(CipherSuite s) {
 560         this.cipherSuite = s;
 561         this.keyExchange = s.keyExchange;
 562     }
 563 
 564     /**
 565      * Check if the given ciphersuite is enabled and available within the
 566      * current active cipher suites.
 567      *
 568      * Does not check if the required server certificates are available.
 569      */
 570     boolean isNegotiable(CipherSuite s) {
 571         if (activeCipherSuites == null) {


 620      *
 621      * Therefore, when the active protocols only include TLS 1.1 or later,
 622      * the client cannot request to negotiate those obsoleted cipher
 623      * suites.  That is, the obsoleted suites should not be included in the
 624      * client hello. So we need to create a subset of the enabled cipher
 625      * suites, the active cipher suites, which does not contain obsoleted
 626      * cipher suites of the minimum active protocol.
 627      *
 628      * Return empty list instead of null if no active cipher suites.
 629      */
 630     CipherSuiteList getActiveCipherSuites() {
 631         if (activeCipherSuites == null) {
 632             if (activeProtocols == null) {
 633                 activeProtocols = getActiveProtocols();
 634             }
 635 
 636             ArrayList<CipherSuite> suites = new ArrayList<>();
 637             if (!(activeProtocols.collection().isEmpty()) &&
 638                     activeProtocols.min.v != ProtocolVersion.NONE.v) {
 639                 for (CipherSuite suite : enabledCipherSuites.collection()) {
 640                     if (suite.obsoleted > activeProtocols.min.v &&
 641                             suite.supported <= activeProtocols.max.v) {
 642                         if (algorithmConstraints.permits(
 643                                 EnumSet.of(CryptoPrimitive.KEY_AGREEMENT),
 644                                 suite.name, null)) {
 645                             suites.add(suite);
 646                         }
 647                     } else if (debug != null && Debug.isOn("verbose")) {
 648                         if (suite.obsoleted <= activeProtocols.min.v) {
 649                             System.out.println(
 650                                 "Ignoring obsoleted cipher suite: " + suite);
 651                         } else {
 652                             System.out.println(
 653                                 "Ignoring unsupported cipher suite: " + suite);
 654                         }
 655                     }
 656                 }
 657             }
 658             activeCipherSuites = new CipherSuiteList(suites);
 659         }
 660 
 661         return activeCipherSuites;
 662     }
 663 
 664     /*
 665      * Get the active protocol versions.
 666      *
 667      * In TLS 1.1, many weak or vulnerable cipher suites were obsoleted,
 668      * such as TLS_RSA_EXPORT_WITH_RC4_40_MD5. The implementation MUST NOT


 683             for (ProtocolVersion protocol : enabledProtocols.collection()) {
 684                 // Need not to check the SSL20Hello protocol.
 685                 if (protocol.v == ProtocolVersion.SSL20Hello.v) {
 686                     enabledSSL20Hello = true;
 687                     continue;
 688                 }
 689 
 690                 if (!algorithmConstraints.permits(
 691                         EnumSet.of(CryptoPrimitive.KEY_AGREEMENT),
 692                         protocol.name, null)) {
 693                     if (debug != null && Debug.isOn("verbose")) {
 694                         System.out.println(
 695                             "Ignoring disabled protocol: " + protocol);
 696                     }
 697 
 698                     continue;
 699                 }
 700 
 701                 boolean found = false;
 702                 for (CipherSuite suite : enabledCipherSuites.collection()) {
 703                     if (suite.isAvailable() && suite.obsoleted > protocol.v &&
 704                                                suite.supported <= protocol.v) {
 705                         if (algorithmConstraints.permits(
 706                                 EnumSet.of(CryptoPrimitive.KEY_AGREEMENT),
 707                                 suite.name, null)) {
 708                             protocols.add(protocol);
 709                             found = true;
 710                             break;
 711                         } else if (debug != null && Debug.isOn("verbose")) {
 712                             System.out.println(
 713                                 "Ignoring disabled cipher suite: " + suite +
 714                                  " for " + protocol);
 715                         }
 716                     } else if (debug != null && Debug.isOn("verbose")) {
 717                         System.out.println(
 718                             "Ignoring unsupported cipher suite: " + suite +
 719                                  " for " + protocol);
 720                     }
 721                 }
 722                 if (!found && (debug != null) && Debug.isOn("handshake")) {
 723                     System.out.println(
 724                         "No available cipher suite for " + protocol);


 820             authenticator = new Authenticator(protocolVersion);
 821         } else {
 822             MacAlg macAlg = cipherSuite.macAlg;
 823             if (isClient) {
 824                 authenticator = macAlg.newMac(protocolVersion, clntMacSecret);
 825                 clntMacSecret = null;
 826             } else {
 827                 authenticator = macAlg.newMac(protocolVersion, svrMacSecret);
 828                 svrMacSecret = null;
 829             }
 830         }
 831 
 832         return authenticator;
 833     }
 834 
 835     /*
 836      * Returns true iff the handshake sequence is done, so that
 837      * this freshly created session can become the current one.
 838      */
 839     boolean isDone() {
 840         return state == HandshakeMessage.ht_finished;
 841     }
 842 
 843 
 844     /*
 845      * Returns the session which was created through this
 846      * handshake sequence ... should be called after isDone()
 847      * returns true.
 848      */
 849     SSLSessionImpl getSession() {
 850         return session;
 851     }
 852 
 853     /*
 854      * Set the handshake session
 855      */
 856     void setHandshakeSessionSE(SSLSessionImpl handshakeSession) {
 857         if (conn != null) {
 858             conn.setHandshakeSession(handshakeSession);
 859         } else {
 860             engine.setHandshakeSession(handshakeSession);
 861         }
 862     }
 863 








 864     /*
 865      * Returns true if renegotiation is in use for this connection.
 866      */
 867     boolean isSecureRenegotiation() {
 868         return secureRenegotiation;
 869     }
 870 
 871     /*
 872      * Returns the verify_data from the Finished message sent by the client.
 873      */
 874     byte[] getClientVerifyData() {
 875         return clientVerifyData;
 876     }
 877 
 878     /*
 879      * Returns the verify_data from the Finished message sent by the server.
 880      */
 881     byte[] getServerVerifyData() {
 882         return serverVerifyData;
 883     }
 884 
 885     /*
 886      * This routine is fed SSL handshake records when they become available,
 887      * and processes messages found therein.
 888      */
 889     void process_record(InputRecord r, boolean expectingFinished)
 890             throws IOException {
 891 
 892         checkThrown();
 893 
 894         /*
 895          * Store the incoming handshake data, then see if we can
 896          * now process any completed handshake messages
 897          */
 898         input.incomingRecord(r);
 899 
 900         /*
 901          * We don't need to create a separate delegatable task
 902          * for finished messages.
 903          */
 904         if ((conn != null) || expectingFinished) {
 905             processLoop();
 906         } else {
 907             delegateTask(new PrivilegedExceptionAction<Void>() {
 908                 @Override
 909                 public Void run() throws Exception {
 910                     processLoop();
 911                     return null;
 912                 }
 913             });
 914         }
 915     }
 916 
 917     /*
 918      * On input, we hash messages one at a time since servers may need


 929         // message type and length.
 930         while (input.available() >= 4) {
 931             byte messageType;
 932             int messageLen;
 933 
 934             /*
 935              * See if we can read the handshake message header, and
 936              * then the entire handshake message.  If not, wait till
 937              * we can read and process an entire message.
 938              */
 939             input.mark(4);
 940 
 941             messageType = (byte)input.getInt8();
 942             messageLen = input.getInt24();
 943 
 944             if (input.available() < messageLen) {
 945                 input.reset();
 946                 return;
 947             }
 948 







 949             /*
 950              * Process the message.  We require
 951              * that processMessage() consumes the entire message.  In
 952              * lieu of explicit error checks (how?!) we assume that the
 953              * data will look like garbage on encoding/processing errors,
 954              * and that other protocol code will detect such errors.
 955              *
 956              * Note that digesting is normally deferred till after the
 957              * message has been processed, though to process at least the
 958              * client's Finished message (i.e. send the server's) we need
 959              * to acccelerate that digesting.
 960              *
 961              * Also, note that hello request messages are never hashed;
 962              * that includes the hello request header, too.
 963              */
 964             if (messageType == HandshakeMessage.ht_hello_request) {
 965                 input.reset();
 966                 processMessage(messageType, messageLen);
 967                 input.ignore(4 + messageLen);
 968             } else {
 969                 input.mark(messageLen);
 970                 processMessage(messageType, messageLen);
 971                 input.digestNow();




 972             }
 973         }
 974     }
 975 
 976 
 977     /**
 978      * Returns true iff the handshaker has been activated.
 979      *
 980      * In activated state, the handshaker may not send any messages out.
 981      */
 982     boolean activated() {
 983         return state >= -1;
 984     }
 985 
 986     /**
 987      * Returns true iff the handshaker has sent any messages.
 988      */
 989     boolean started() {
 990         return state >= 0;  // 0: HandshakeMessage.ht_hello_request
 991                             // 1: HandshakeMessage.ht_client_hello
 992     }
 993 
 994 
 995     /*
 996      * Used to kickstart the negotiation ... either writing a
 997      * ClientHello or a HelloRequest as appropriate, whichever
 998      * the subclass returns.  NOP if handshaking's already started.
 999      */
1000     void kickstart() throws IOException {
1001         if (state >= 0) {

1002             return;
1003         }
1004 
1005         HandshakeMessage m = getKickstartMessage();

1006 
1007         if (debug != null && Debug.isOn("handshake")) {
1008             m.print(System.out);
1009         }
1010         m.write(output);
1011         output.flush();
1012 
1013         state = m.messageType();





1014     }

1015 
1016     /**
1017      * Both client and server modes can start handshaking; but the
1018      * message they send to do so is different.
1019      */
1020     abstract HandshakeMessage getKickstartMessage() throws SSLException;
1021 
1022     /*
1023      * Client and Server side protocols are each driven though this
1024      * call, which processes a single message and drives the appropriate
1025      * side of the protocol state machine (depending on the subclass).
1026      */
1027     abstract void processMessage(byte messageType, int messageLen)
1028         throws IOException;
1029 
1030     /*
1031      * Most alerts in the protocol relate to handshaking problems.
1032      * Alerts are detected as the connection reads data.
1033      */
1034     abstract void handshakeAlert(byte description) throws SSLProtocolException;
1035 
1036     /*
1037      * Sends a change cipher spec message and updates the write side
1038      * cipher state so that future messages use the just-negotiated spec.
1039      */
1040     void sendChangeCipherSpec(Finished mesg, boolean lastMessage)
1041             throws IOException {
1042 
1043         output.flush(); // i.e. handshake data
1044 
1045         /*
1046          * The write cipher state is protected by the connection write lock
1047          * so we must grab it while making the change. We also
1048          * make sure no writes occur between sending the ChangeCipherSpec
1049          * message, installing the new cipher state, and sending the
1050          * Finished message.
1051          *
1052          * We already hold SSLEngine/SSLSocket "this" by virtue
1053          * of this being called from the readRecord code.
1054          */
1055         OutputRecord r;
1056         if (conn != null) {
1057             r = new OutputRecord(Record.ct_change_cipher_spec);
1058         } else {
1059             r = new EngineOutputRecord(Record.ct_change_cipher_spec, engine);
1060         }
1061 
1062         r.setVersion(protocolVersion);
1063         r.write(1);     // single byte of data
1064 
1065         if (conn != null) {
1066             conn.writeLock.lock();
1067             try {
1068                 conn.writeRecord(r);
1069                 conn.changeWriteCiphers();
1070                 if (debug != null && Debug.isOn("handshake")) {
1071                     mesg.print(System.out);
1072                 }


1073                 mesg.write(output);
1074                 output.flush();
1075             } finally {
1076                 conn.writeLock.unlock();
1077             }
1078         } else {
1079             synchronized (engine.writeLock) {
1080                 engine.writeRecord((EngineOutputRecord)r);
1081                 engine.changeWriteCiphers();
1082                 if (debug != null && Debug.isOn("handshake")) {
1083                     mesg.print(System.out);
1084                 }


1085                 mesg.write(output);



1086 
1087                 if (lastMessage) {
1088                     output.setFinishedMsg();
1089                 }
1090                 output.flush();
1091             }



1092         }
1093     }
1094 
1095     /*
1096      * Single access point to key calculation logic.  Given the
1097      * pre-master secret and the nonces from client and server,
1098      * produce all the keying material to be used.
1099      */
1100     void calculateKeys(SecretKey preMasterSecret, ProtocolVersion version) {
1101         SecretKey master = calculateMasterSecret(preMasterSecret, version);
1102         session.setMasterSecret(master);
1103         calculateConnectionKeys(master);
1104     }
1105 
1106     /*
1107      * Calculate the master secret from its various components.  This is
1108      * used for key exchange by all cipher suites.
1109      *
1110      * The master secret is the catenation of three MD5 hashes, each
1111      * consisting of the pre-master secret and a SHA1 hash.  Those three
1112      * SHA1 hashes are of (different) constant strings, the pre-master
1113      * secret, and the nonces provided by the client and the server.
1114      */
1115     private SecretKey calculateMasterSecret(SecretKey preMasterSecret,
1116             ProtocolVersion requestedVersion) {
1117 
1118         if (debug != null && Debug.isOn("keygen")) {
1119             HexDumpEncoder      dump = new HexDumpEncoder();
1120 
1121             System.out.println("SESSION KEYGEN:");
1122 
1123             System.out.println("PreMaster Secret:");
1124             printHex(dump, preMasterSecret.getEncoded());
1125 
1126             // Nonces are dumped with connection keygen, no
1127             // benefit to doing it twice
1128         }
1129 
1130         // What algs/params do we need to use?
1131         String masterAlg;
1132         PRF prf;
1133 


















1134         if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
1135             masterAlg = "SunTls12MasterSecret";
1136             prf = cipherSuite.prfAlg;
1137         } else {
1138             masterAlg = "SunTlsMasterSecret";
1139             prf = P_NONE;
1140         }

1141 
1142         String prfHashAlg = prf.getPRFHashAlg();
1143         int prfHashLength = prf.getPRFHashLength();
1144         int prfBlockSize = prf.getPRFBlockSize();
1145 
1146         @SuppressWarnings("deprecation")
1147         TlsMasterSecretParameterSpec spec = new TlsMasterSecretParameterSpec(
1148                 preMasterSecret, protocolVersion.major, protocolVersion.minor,
1149                 clnt_random.random_bytes, svr_random.random_bytes,
1150                 prfHashAlg, prfHashLength, prfBlockSize);
1151 
1152         try {
1153             KeyGenerator kg = JsseJce.getKeyGenerator(masterAlg);
1154             kg.init(spec);
1155             return kg.generateKey();
1156         } catch (InvalidAlgorithmParameterException |
1157                 NoSuchAlgorithmException iae) {
1158             // unlikely to happen, otherwise, must be a provider exception
1159             //
1160             // For RSA premaster secrets, do not signal a protocol error
1161             // due to the Bleichenbacher attack. See comments further down.
1162             if (debug != null && Debug.isOn("handshake")) {
1163                 System.out.println("RSA master secret generation error:");
1164                 iae.printStackTrace(System.out);
1165             }
1166             throw new ProviderException(iae);
1167 
1168         }


1179      * "fast handshake" (where we just resumed a pre-existing session).
1180      */
1181     @SuppressWarnings("deprecation")
1182     void calculateConnectionKeys(SecretKey masterKey) {
1183         /*
1184          * For both the read and write sides of the protocol, we use the
1185          * master to generate MAC secrets and cipher keying material.  Block
1186          * ciphers need initialization vectors, which we also generate.
1187          *
1188          * First we figure out how much keying material is needed.
1189          */
1190         int hashSize = cipherSuite.macAlg.size;
1191         boolean is_exportable = cipherSuite.exportable;
1192         BulkCipher cipher = cipherSuite.cipher;
1193         int expandedKeySize = is_exportable ? cipher.expandedKeySize : 0;
1194 
1195         // Which algs/params do we need to use?
1196         String keyMaterialAlg;
1197         PRF prf;
1198 


















1199         if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
1200             keyMaterialAlg = "SunTls12KeyMaterial";
1201             prf = cipherSuite.prfAlg;
1202         } else {
1203             keyMaterialAlg = "SunTlsKeyMaterial";
1204             prf = P_NONE;
1205         }

1206 
1207         String prfHashAlg = prf.getPRFHashAlg();
1208         int prfHashLength = prf.getPRFHashLength();
1209         int prfBlockSize = prf.getPRFBlockSize();
1210 
1211         // TLS v1.1 or later uses an explicit IV in CBC cipher suites to
1212         // protect against the CBC attacks.  AEAD/GCM cipher suites in TLS
1213         // v1.2 or later use a fixed IV as the implicit part of the partially
1214         // implicit nonce technique described in RFC 5116.
1215         int ivSize = cipher.ivSize;
1216         if (cipher.cipherType == AEAD_CIPHER) {
1217             ivSize = cipher.fixedIvSize;
1218         } else if (protocolVersion.v >= ProtocolVersion.TLS11.v &&
1219                 cipher.cipherType == BLOCK_CIPHER) {
1220             ivSize = 0;
1221         }
1222 
1223         TlsKeyMaterialParameterSpec spec = new TlsKeyMaterialParameterSpec(
1224             masterKey, protocolVersion.major, protocolVersion.minor,
1225             clnt_random.random_bytes, svr_random.random_bytes,
1226             cipher.algorithm, cipher.keySize, expandedKeySize,
1227             ivSize, hashSize,
1228             prfHashAlg, prfHashLength, prfBlockSize);
1229 
1230         try {
1231             KeyGenerator kg = JsseJce.getKeyGenerator(keyMaterialAlg);
1232             kg.init(spec);
1233             TlsKeyMaterialSpec keySpec = (TlsKeyMaterialSpec)kg.generateKey();
1234 
1235             // Return null if cipher keys are not supposed to be generated.
1236             clntWriteKey = keySpec.getClientCipherKey();
1237             svrWriteKey = keySpec.getServerCipherKey();
1238 
1239             // Return null if IVs are not supposed to be generated.
1240             clntWriteIV = keySpec.getClientIv();
1241             svrWriteIV = keySpec.getServerIv();
1242 
1243             // Return null if MAC keys are not supposed to be generated.
1244             clntMacSecret = keySpec.getClientMacKey();
1245             svrMacSecret = keySpec.getServerMacKey();
1246         } catch (GeneralSecurityException e) {
1247             throw new ProviderException(e);
1248         }
1249 
1250         // Mark a flag that allows outside entities (like SSLSocket/SSLEngine)
1251         // determine if a ChangeCipherSpec message could be processed.
1252         sessKeysCalculated = true;
1253 
1254         //
1255         // Dump the connection keys as they're generated.
1256         //
1257         if (debug != null && Debug.isOn("keygen")) {
1258             synchronized (System.out) {
1259                 HexDumpEncoder  dump = new HexDumpEncoder();
1260 
1261                 System.out.println("CONNECTION KEYGEN:");
1262 
1263                 // Inputs:
1264                 System.out.println("Client Nonce:");
1265                 printHex(dump, clnt_random.random_bytes);
1266                 System.out.println("Server Nonce:");
1267                 printHex(dump, svr_random.random_bytes);
1268                 System.out.println("Master Secret:");
1269                 printHex(dump, masterKey.getEncoded());
1270 
1271                 // Outputs:
1272                 if (clntMacSecret != null) {
1273                     System.out.println("Client MAC write Secret:");


1276                     printHex(dump, svrMacSecret.getEncoded());
1277                 } else {
1278                     System.out.println("... no MAC keys used for this cipher");
1279                 }
1280 
1281                 if (clntWriteKey != null) {
1282                     System.out.println("Client write key:");
1283                     printHex(dump, clntWriteKey.getEncoded());
1284                     System.out.println("Server write key:");
1285                     printHex(dump, svrWriteKey.getEncoded());
1286                 } else {
1287                     System.out.println("... no encryption keys used");
1288                 }
1289 
1290                 if (clntWriteIV != null) {
1291                     System.out.println("Client write IV:");
1292                     printHex(dump, clntWriteIV.getIV());
1293                     System.out.println("Server write IV:");
1294                     printHex(dump, svrWriteIV.getIV());
1295                 } else {
1296                     if (protocolVersion.v >= ProtocolVersion.TLS11.v) {
1297                         System.out.println(
1298                                 "... no IV derived for this protocol");
1299                     } else {
1300                         System.out.println("... no IV used for this cipher");
1301                     }
1302                 }
1303                 System.out.flush();
1304             }
1305         }
1306     }
1307 
1308     /**
1309      * Return whether or not the Handshaker has derived session keys for
1310      * this handshake.  This is used for determining readiness to process
1311      * an incoming ChangeCipherSpec message.
1312      */
1313     boolean sessionKeysCalculated() {
1314         return sessKeysCalculated;
1315     }
1316 
1317     private static void printHex(HexDumpEncoder dump, byte[] bytes) {
1318         if (bytes == null) {
1319             System.out.println("(key bytes not available)");
1320         } else {
1321             try {
1322                 dump.encodeBuffer(bytes, System.out);
1323             } catch (IOException e) {
1324                 // just for debugging, ignore this
1325             }
1326         }
1327     }
1328 
1329     /**
1330      * Throw an SSLException with the specified message and cause.
1331      * Shorthand until a new SSLException constructor is added.
1332      * This method never returns.
1333      */
1334     static void throwSSLException(String msg, Throwable cause)
1335             throws SSLException {
1336         SSLException e = new SSLException(msg);
1337         e.initCause(cause);
1338         throw e;
1339     }
1340 
1341 
1342     /*
1343      * Implement a simple task delegator.
1344      *
1345      * We are currently implementing this as a single delegator, may
1346      * try for parallel tasks later.  Client Authentication could
1347      * benefit from this, where ClientKeyExchange/CertificateVerify
1348      * could be carried out in parallel.
1349      */
1350     class DelegatedTask<E> implements Runnable {
1351 
1352         private PrivilegedExceptionAction<E> pea;
1353 
1354         DelegatedTask(PrivilegedExceptionAction<E> pea) {
1355             this.pea = pea;
1356         }
1357 
1358         public void run() {
1359             synchronized (engine) {
1360                 try {
1361                     AccessController.doPrivileged(pea, engine.getAcc());




  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 
  40 import javax.crypto.*;
  41 import javax.crypto.spec.*;
  42 
  43 import javax.net.ssl.*;
  44 import sun.misc.HexDumpEncoder;
  45 
  46 import sun.security.internal.spec.*;
  47 import sun.security.internal.interfaces.TlsMasterSecret;
  48 
  49 import sun.security.ssl.HandshakeMessage.*;
  50 import sun.security.ssl.CipherSuite.*;
  51 
  52 import static sun.security.ssl.CipherSuite.PRF.*;


  99      * List of active protocols
 100      *
 101      * Active protocols is a subset of enabled protocols, and will
 102      * contain only those protocols that have vaild cipher suites
 103      * enabled.
 104      */
 105     private ProtocolList       activeProtocols;
 106 
 107     /*
 108      * List of active cipher suites
 109      *
 110      * Active cipher suites is a subset of enabled cipher suites, and will
 111      * contain only those cipher suites available for the active protocols.
 112      */
 113     private CipherSuiteList     activeCipherSuites;
 114 
 115     // The server name indication and matchers
 116     List<SNIServerName> serverNames = Collections.<SNIServerName>emptyList();
 117     Collection<SNIMatcher> sniMatchers = Collections.<SNIMatcher>emptyList();
 118 
 119     // The maximum expected network packet size for SSL/TLS/DTLS records.
 120     int                         maximumPacketSize = 0;
 121 
 122     private boolean             isClient;
 123     private boolean             needCertVerify;
 124 
 125     SSLSocketImpl               conn = null;
 126     SSLEngineImpl               engine = null;
 127 
 128     HandshakeHash               handshakeHash;
 129     HandshakeInStream           input;
 130     HandshakeOutStream          output;

 131     SSLContextImpl              sslContext;
 132     RandomCookie                clnt_random, svr_random;
 133     SSLSessionImpl              session;
 134 
 135     HandshakeStateManager       handshakeState;
 136     boolean                     clientHelloDelivered;
 137     boolean                     serverHelloRequested;
 138     boolean                     handshakeActivated;
 139     boolean                     handshakeFinished;
 140 
 141     // current CipherSuite. Never null, initially SSL_NULL_WITH_NULL_NULL
 142     CipherSuite         cipherSuite;
 143 
 144     // current key exchange. Never null, initially K_NULL
 145     KeyExchange         keyExchange;
 146 
 147     // True if this session is being resumed (fast handshake)
 148     boolean             resumingSession;
 149 
 150     // True if it's OK to start a new SSL session
 151     boolean             enableNewSession;
 152 




 153     // Whether local cipher suites preference should be honored during
 154     // handshaking?
 155     //
 156     // Note that in this provider, this option only applies to server side.
 157     // Local cipher suites preference is always honored in client side in
 158     // this provider.
 159     boolean preferLocalCipherSuites = false;
 160 
 161     // Temporary storage for the individual keys. Set by
 162     // calculateConnectionKeys() and cleared once the ciphers are
 163     // activated.
 164     private SecretKey clntWriteKey, svrWriteKey;
 165     private IvParameterSpec clntWriteIV, svrWriteIV;
 166     private SecretKey clntMacSecret, svrMacSecret;
 167 
 168     /*
 169      * Delegated task subsystem data structures.
 170      *
 171      * If thrown is set, we need to propagate this back immediately
 172      * on entry into processMessage().


 195     // For maximum security, RFC 5746 also allows server (or client) to
 196     // reject such message with a fatal "handshake_failure" alert.
 197     //
 198     // By default, allow such legacy hello messages.
 199     static final boolean allowLegacyHelloMessages = Debug.getBooleanProperty(
 200                     "sun.security.ssl.allowLegacyHelloMessages", true);
 201 
 202     // To prevent the TLS renegotiation issues, by setting system property
 203     // "jdk.tls.rejectClientInitiatedRenegotiation" to true, applications in
 204     // server side can disable all client initiated SSL renegotiations
 205     // regardless of the support of TLS protocols.
 206     //
 207     // By default, allow client initiated renegotiations.
 208     static final boolean rejectClientInitiatedRenego =
 209             Debug.getBooleanProperty(
 210                 "jdk.tls.rejectClientInitiatedRenegotiation", false);
 211 
 212     // need to dispose the object when it is invalidated
 213     boolean invalidated;
 214 
 215     /*
 216      * Is this an instance for Datagram Transport Layer Security (DTLS)?
 217      */
 218     final boolean isDTLS;
 219 
 220     Handshaker(SSLSocketImpl c, SSLContextImpl context,
 221             ProtocolList enabledProtocols, boolean needCertVerify,
 222             boolean isClient, ProtocolVersion activeProtocolVersion,
 223             boolean isInitialHandshake, boolean secureRenegotiation,
 224             byte[] clientVerifyData, byte[] serverVerifyData) {
 225         this.conn = c;
 226         this.isDTLS = false;
 227         init(context, enabledProtocols, needCertVerify, isClient,
 228             activeProtocolVersion, isInitialHandshake, secureRenegotiation,
 229             clientVerifyData, serverVerifyData);
 230     }
 231 
 232     Handshaker(SSLEngineImpl engine, SSLContextImpl context,
 233             ProtocolList enabledProtocols, boolean needCertVerify,
 234             boolean isClient, ProtocolVersion activeProtocolVersion,
 235             boolean isInitialHandshake, boolean secureRenegotiation,
 236             byte[] clientVerifyData, byte[] serverVerifyData,
 237             boolean isDTLS) {
 238         this.engine = engine;
 239         this.isDTLS = isDTLS;
 240         init(context, enabledProtocols, needCertVerify, isClient,
 241             activeProtocolVersion, isInitialHandshake, secureRenegotiation,
 242             clientVerifyData, serverVerifyData);
 243     }
 244 
 245     private void init(SSLContextImpl context, ProtocolList enabledProtocols,
 246             boolean needCertVerify, boolean isClient,
 247             ProtocolVersion activeProtocolVersion,
 248             boolean isInitialHandshake, boolean secureRenegotiation,
 249             byte[] clientVerifyData, byte[] serverVerifyData) {
 250 
 251         if (debug != null && Debug.isOn("handshake")) {
 252             System.out.println(
 253                 "Allow unsafe renegotiation: " + allowUnsafeRenegotiation +
 254                 "\nAllow legacy hello messages: " + allowLegacyHelloMessages +
 255                 "\nIs initial handshake: " + isInitialHandshake +
 256                 "\nIs secure renegotiation: " + secureRenegotiation);
 257         }
 258 
 259         this.sslContext = context;
 260         this.isClient = isClient;
 261         this.needCertVerify = needCertVerify;
 262         this.activeProtocolVersion = activeProtocolVersion;
 263         this.isInitialHandshake = isInitialHandshake;
 264         this.secureRenegotiation = secureRenegotiation;
 265         this.clientVerifyData = clientVerifyData;
 266         this.serverVerifyData = serverVerifyData;
 267         this.enableNewSession = true;
 268         this.invalidated = false;
 269         this.handshakeState = new HandshakeStateManager(isDTLS);
 270         this.clientHelloDelivered = false;
 271         this.serverHelloRequested = false;
 272         this.handshakeActivated = false;
 273         this.handshakeFinished = false;
 274 
 275         setCipherSuite(CipherSuite.C_NULL);
 276         setEnabledProtocols(enabledProtocols);
 277 
 278         if (conn != null) {
 279             algorithmConstraints = new SSLAlgorithmConstraints(conn, true);
 280         } else {        // engine != null
 281             algorithmConstraints = new SSLAlgorithmConstraints(engine, true);
 282         }
















 283     }
 284 
 285     /*
 286      * Reroutes calls to the SSLSocket or SSLEngine (*SE).
 287      *
 288      * We could have also done it by extra classes
 289      * and letting them override, but this seemed much
 290      * less involved.
 291      */
 292     void fatalSE(byte b, String diagnostic) throws IOException {
 293         fatalSE(b, diagnostic, null);
 294     }
 295 
 296     void fatalSE(byte b, Throwable cause) throws IOException {
 297         fatalSE(b, null, cause);
 298     }
 299 
 300     void fatalSE(byte b, String diagnostic, Throwable cause)
 301             throws IOException {
 302         if (conn != null) {


 344             return engine.getPeerPort();
 345         }
 346     }
 347 
 348     int getLocalPortSE() {
 349         if (conn != null) {
 350             return conn.getLocalPort();
 351         } else {
 352             return -1;
 353         }
 354     }
 355 
 356     AccessControlContext getAccSE() {
 357         if (conn != null) {
 358             return conn.getAcc();
 359         } else {
 360             return engine.getAcc();
 361         }
 362     }
 363 








 364     String getEndpointIdentificationAlgorithmSE() {
 365         SSLParameters paras;
 366         if (conn != null) {
 367             paras = conn.getSSLParameters();
 368         } else {
 369             paras = engine.getSSLParameters();
 370         }
 371 
 372         return paras.getEndpointIdentificationAlgorithm();
 373     }
 374 
 375     private void setVersionSE(ProtocolVersion protocolVersion) {
 376         if (conn != null) {
 377             conn.setVersion(protocolVersion);
 378         } else {
 379             engine.setVersion(protocolVersion);
 380         }
 381     }
 382 
 383     /**
 384      * Set the active protocol version and propagate it to the SSLSocket
 385      * and our handshake streams. Called from ClientHandshaker
 386      * and ServerHandshaker with the negotiated protocol version.
 387      */
 388     void setVersion(ProtocolVersion protocolVersion) {
 389         this.protocolVersion = protocolVersion;
 390         setVersionSE(protocolVersion);


 391     }
 392 
 393     /**
 394      * Set the enabled protocols. Called from the constructor or
 395      * SSLSocketImpl/SSLEngineImpl.setEnabledProtocols() (if the
 396      * handshake is not yet in progress).
 397      */
 398     void setEnabledProtocols(ProtocolList enabledProtocols) {
 399         activeCipherSuites = null;
 400         activeProtocols = null;
 401 
 402         this.enabledProtocols = enabledProtocols;
 403     }
 404 
 405     /**
 406      * Set the enabled cipher suites. Called from
 407      * SSLSocketImpl/SSLEngineImpl.setEnabledCipherSuites() (if the
 408      * handshake is not yet in progress).
 409      */
 410     void setEnabledCipherSuites(CipherSuiteList enabledCipherSuites) {


 457         this.identificationProtocol = protocol;
 458     }
 459 
 460     /**
 461      * Sets the server name indication of the handshake.
 462      */
 463     void setSNIServerNames(List<SNIServerName> serverNames) {
 464         // The serverNames parameter is unmodifiable.
 465         this.serverNames = serverNames;
 466     }
 467 
 468     /**
 469      * Sets the server name matchers of the handshaking.
 470      */
 471     void setSNIMatchers(Collection<SNIMatcher> sniMatchers) {
 472         // The sniMatchers parameter is unmodifiable.
 473         this.sniMatchers = sniMatchers;
 474     }
 475 
 476     /**
 477      * Sets the maximum packet size of the handshaking.
 478      */
 479     void setMaximumPacketSize(int maximumPacketSize) {
 480         this.maximumPacketSize = maximumPacketSize;
 481     }
 482 
 483     /**
 484      * Sets the cipher suites preference.
 485      */
 486     void setUseCipherSuitesOrder(boolean on) {
 487         this.preferLocalCipherSuites = on;
 488     }
 489 
 490     /**
 491      * Prior to handshaking, activate the handshake and initialize the version,
 492      * input stream and output stream.
 493      */
 494     void activate(ProtocolVersion helloVersion) throws IOException {
 495         if (activeProtocols == null) {
 496             activeProtocols = getActiveProtocols();
 497         }
 498 
 499         if (activeProtocols.collection().isEmpty() ||
 500                 activeProtocols.max.v == ProtocolVersion.NONE.v) {
 501             throw new SSLHandshakeException(
 502                     "No appropriate protocol (protocol is disabled or " +
 503                     "cipher suites are inappropriate)");


 513 
 514         // temporary protocol version until the actual protocol version
 515         // is negotiated in the Hello exchange. This affects the record
 516         // version we sent with the ClientHello.
 517         if (!isInitialHandshake) {
 518             protocolVersion = activeProtocolVersion;
 519         } else {
 520             protocolVersion = activeProtocols.max;
 521         }
 522 
 523         if (helloVersion == null || helloVersion.v == ProtocolVersion.NONE.v) {
 524             helloVersion = activeProtocols.helloVersion;
 525         }
 526 
 527         // We accumulate digests of the handshake messages so that
 528         // we can read/write CertificateVerify and Finished messages,
 529         // getting assurance against some particular active attacks.
 530         handshakeHash = new HandshakeHash(needCertVerify);
 531 
 532         // Generate handshake input/output stream.

 533         if (conn != null) {
 534             input = new HandshakeInStream();
 535             output = new HandshakeOutStream(conn.outputRecord);
 536 
 537             conn.inputRecord.setHandshakeHash(handshakeHash);
 538             conn.inputRecord.setHelloVersion(helloVersion);
 539 
 540             conn.outputRecord.setHandshakeHash(handshakeHash);
 541             conn.outputRecord.setHelloVersion(helloVersion);
 542             conn.outputRecord.setVersion(protocolVersion);
 543         } else if (engine != null) {
 544             input = new HandshakeInStream();
 545             output = new HandshakeOutStream(engine.outputRecord);
 546 
 547             engine.inputRecord.setHandshakeHash(handshakeHash);
 548             engine.inputRecord.setHelloVersion(helloVersion);
 549 
 550             engine.outputRecord.setHandshakeHash(handshakeHash);
 551             engine.outputRecord.setHelloVersion(helloVersion);
 552             engine.outputRecord.setVersion(protocolVersion);
 553         }
 554 
 555         handshakeActivated = true;

 556     }
 557 
 558     /**
 559      * Set cipherSuite and keyExchange to the given CipherSuite.
 560      * Does not perform any verification that this is a valid selection,
 561      * this must be done before calling this method.
 562      */
 563     void setCipherSuite(CipherSuite s) {
 564         this.cipherSuite = s;
 565         this.keyExchange = s.keyExchange;
 566     }
 567 
 568     /**
 569      * Check if the given ciphersuite is enabled and available within the
 570      * current active cipher suites.
 571      *
 572      * Does not check if the required server certificates are available.
 573      */
 574     boolean isNegotiable(CipherSuite s) {
 575         if (activeCipherSuites == null) {


 624      *
 625      * Therefore, when the active protocols only include TLS 1.1 or later,
 626      * the client cannot request to negotiate those obsoleted cipher
 627      * suites.  That is, the obsoleted suites should not be included in the
 628      * client hello. So we need to create a subset of the enabled cipher
 629      * suites, the active cipher suites, which does not contain obsoleted
 630      * cipher suites of the minimum active protocol.
 631      *
 632      * Return empty list instead of null if no active cipher suites.
 633      */
 634     CipherSuiteList getActiveCipherSuites() {
 635         if (activeCipherSuites == null) {
 636             if (activeProtocols == null) {
 637                 activeProtocols = getActiveProtocols();
 638             }
 639 
 640             ArrayList<CipherSuite> suites = new ArrayList<>();
 641             if (!(activeProtocols.collection().isEmpty()) &&
 642                     activeProtocols.min.v != ProtocolVersion.NONE.v) {
 643                 for (CipherSuite suite : enabledCipherSuites.collection()) {
 644                     if (!activeProtocols.min.obsoletes(suite) &&
 645                             activeProtocols.max.supports(suite)) {
 646                         if (algorithmConstraints.permits(
 647                                 EnumSet.of(CryptoPrimitive.KEY_AGREEMENT),
 648                                 suite.name, null)) {
 649                             suites.add(suite);
 650                         }
 651                     } else if (debug != null && Debug.isOn("verbose")) {
 652                         if (activeProtocols.min.obsoletes(suite)) {
 653                             System.out.println(
 654                                 "Ignoring obsoleted cipher suite: " + suite);
 655                         } else {
 656                             System.out.println(
 657                                 "Ignoring unsupported cipher suite: " + suite);
 658                         }
 659                     }
 660                 }
 661             }
 662             activeCipherSuites = new CipherSuiteList(suites);
 663         }
 664 
 665         return activeCipherSuites;
 666     }
 667 
 668     /*
 669      * Get the active protocol versions.
 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


 687             for (ProtocolVersion protocol : enabledProtocols.collection()) {
 688                 // Need not to check the SSL20Hello protocol.
 689                 if (protocol.v == ProtocolVersion.SSL20Hello.v) {
 690                     enabledSSL20Hello = true;
 691                     continue;
 692                 }
 693 
 694                 if (!algorithmConstraints.permits(
 695                         EnumSet.of(CryptoPrimitive.KEY_AGREEMENT),
 696                         protocol.name, null)) {
 697                     if (debug != null && Debug.isOn("verbose")) {
 698                         System.out.println(
 699                             "Ignoring disabled protocol: " + protocol);
 700                     }
 701 
 702                     continue;
 703                 }
 704 
 705                 boolean found = false;
 706                 for (CipherSuite suite : enabledCipherSuites.collection()) {
 707                     if (suite.isAvailable() && (!protocol.obsoletes(suite)) &&
 708                                                protocol.supports(suite)) {
 709                         if (algorithmConstraints.permits(
 710                                 EnumSet.of(CryptoPrimitive.KEY_AGREEMENT),
 711                                 suite.name, null)) {
 712                             protocols.add(protocol);
 713                             found = true;
 714                             break;
 715                         } else if (debug != null && Debug.isOn("verbose")) {
 716                             System.out.println(
 717                                 "Ignoring disabled cipher suite: " + suite +
 718                                  " for " + protocol);
 719                         }
 720                     } else if (debug != null && Debug.isOn("verbose")) {
 721                         System.out.println(
 722                             "Ignoring unsupported cipher suite: " + suite +
 723                                  " for " + protocol);
 724                     }
 725                 }
 726                 if (!found && (debug != null) && Debug.isOn("handshake")) {
 727                     System.out.println(
 728                         "No available cipher suite for " + protocol);


 824             authenticator = new Authenticator(protocolVersion);
 825         } else {
 826             MacAlg macAlg = cipherSuite.macAlg;
 827             if (isClient) {
 828                 authenticator = macAlg.newMac(protocolVersion, clntMacSecret);
 829                 clntMacSecret = null;
 830             } else {
 831                 authenticator = macAlg.newMac(protocolVersion, svrMacSecret);
 832                 svrMacSecret = null;
 833             }
 834         }
 835 
 836         return authenticator;
 837     }
 838 
 839     /*
 840      * Returns true iff the handshake sequence is done, so that
 841      * this freshly created session can become the current one.
 842      */
 843     boolean isDone() {
 844         return started() && handshakeState.isEmpty() && handshakeFinished;
 845     }
 846 
 847 
 848     /*
 849      * Returns the session which was created through this
 850      * handshake sequence ... should be called after isDone()
 851      * returns true.
 852      */
 853     SSLSessionImpl getSession() {
 854         return session;
 855     }
 856 
 857     /*
 858      * Set the handshake session
 859      */
 860     void setHandshakeSessionSE(SSLSessionImpl handshakeSession) {
 861         if (conn != null) {
 862             conn.setHandshakeSession(handshakeSession);
 863         } else {
 864             engine.setHandshakeSession(handshakeSession);
 865         }
 866     }
 867 
 868     void expectingFinishFlightSE() {
 869         if (conn != null) {
 870             conn.expectingFinishFlight();
 871         } else {
 872             engine.expectingFinishFlight();
 873         }
 874     }
 875 
 876     /*
 877      * Returns true if renegotiation is in use for this connection.
 878      */
 879     boolean isSecureRenegotiation() {
 880         return secureRenegotiation;
 881     }
 882 
 883     /*
 884      * Returns the verify_data from the Finished message sent by the client.
 885      */
 886     byte[] getClientVerifyData() {
 887         return clientVerifyData;
 888     }
 889 
 890     /*
 891      * Returns the verify_data from the Finished message sent by the server.
 892      */
 893     byte[] getServerVerifyData() {
 894         return serverVerifyData;
 895     }
 896 
 897     /*
 898      * This routine is fed SSL handshake records when they become available,
 899      * and processes messages found therein.
 900      */
 901     void processRecord(ByteBuffer record,
 902             boolean expectingFinished) throws IOException {
 903 
 904         checkThrown();
 905 
 906         /*
 907          * Store the incoming handshake data, then see if we can
 908          * now process any completed handshake messages
 909          */
 910         input.incomingRecord(record);
 911 
 912         /*
 913          * We don't need to create a separate delegatable task
 914          * for finished messages.
 915          */
 916         if ((conn != null) || expectingFinished) {
 917             processLoop();
 918         } else {
 919             delegateTask(new PrivilegedExceptionAction<Void>() {
 920                 @Override
 921                 public Void run() throws Exception {
 922                     processLoop();
 923                     return null;
 924                 }
 925             });
 926         }
 927     }
 928 
 929     /*
 930      * On input, we hash messages one at a time since servers may need


 941         // message type and length.
 942         while (input.available() >= 4) {
 943             byte messageType;
 944             int messageLen;
 945 
 946             /*
 947              * See if we can read the handshake message header, and
 948              * then the entire handshake message.  If not, wait till
 949              * we can read and process an entire message.
 950              */
 951             input.mark(4);
 952 
 953             messageType = (byte)input.getInt8();
 954             messageLen = input.getInt24();
 955 
 956             if (input.available() < messageLen) {
 957                 input.reset();
 958                 return;
 959             }
 960 
 961             // Set the flags in the message receiving side.
 962             if (messageType == HandshakeMessage.ht_client_hello) {
 963                 clientHelloDelivered = true;
 964             } else if (messageType == HandshakeMessage.ht_hello_request) {
 965                 serverHelloRequested = true;
 966             }
 967 
 968             /*
 969              * Process the message.  We require
 970              * that processMessage() consumes the entire message.  In
 971              * lieu of explicit error checks (how?!) we assume that the
 972              * data will look like garbage on encoding/processing errors,
 973              * and that other protocol code will detect such errors.
 974              *
 975              * Note that digesting is normally deferred till after the
 976              * message has been processed, though to process at least the
 977              * client's Finished message (i.e. send the server's) we need
 978              * to acccelerate that digesting.
 979              *
 980              * Also, note that hello request messages are never hashed;
 981              * that includes the hello request header, too.
 982              */


 983             processMessage(messageType, messageLen);
 984 
 985             // Reload if this message has been reserved.
 986             //
 987             // Note: in the implementation, only certificate_verify and
 988             // finished messages are reserved.
 989             if ((messageType == HandshakeMessage.ht_finished) ||
 990                 (messageType == HandshakeMessage.ht_certificate_verify)) {
 991 
 992                 handshakeHash.reload();
 993             }
 994         }
 995     }
 996 
 997 
 998     /**
 999      * Returns true iff the handshaker has been activated.
1000      *
1001      * In activated state, the handshaker may not send any messages out.
1002      */
1003     boolean activated() {
1004         return handshakeActivated;
1005     }
1006 
1007     /**
1008      * Returns true iff the handshaker has sent any messages.
1009      */
1010     boolean started() {
1011         return (serverHelloRequested || clientHelloDelivered);

1012     }
1013 

1014     /*
1015      * Used to kickstart the negotiation ... either writing a
1016      * ClientHello or a HelloRequest as appropriate, whichever
1017      * the subclass returns.  NOP if handshaking's already started.
1018      */
1019     void kickstart() throws IOException {
1020         if ((isClient && clientHelloDelivered) ||
1021                 (!isClient && serverHelloRequested)) {
1022             return;
1023         }
1024 
1025         HandshakeMessage m = getKickstartMessage();
1026         handshakeState.update(m, resumingSession);
1027 
1028         if (debug != null && Debug.isOn("handshake")) {
1029             m.print(System.out);
1030         }
1031         m.write(output);
1032         output.flush();
1033 
1034         // Set the flags in the message delivering side.
1035         int handshakeType = m.messageType();
1036         if (handshakeType == HandshakeMessage.ht_hello_request) {
1037             serverHelloRequested = true;
1038         } else {        // HandshakeMessage.ht_client_hello
1039             clientHelloDelivered = true;
1040         }
1041     }
1042 
1043     /**
1044      * Both client and server modes can start handshaking; but the
1045      * message they send to do so is different.
1046      */
1047     abstract HandshakeMessage getKickstartMessage() throws SSLException;
1048 
1049     /*
1050      * Client and Server side protocols are each driven though this
1051      * call, which processes a single message and drives the appropriate
1052      * side of the protocol state machine (depending on the subclass).
1053      */
1054     abstract void processMessage(byte messageType, int messageLen)
1055         throws IOException;
1056 
1057     /*
1058      * Most alerts in the protocol relate to handshaking problems.
1059      * Alerts are detected as the connection reads data.
1060      */
1061     abstract void handshakeAlert(byte description) throws SSLProtocolException;
1062 
1063     /*
1064      * Sends a change cipher spec message and updates the write side
1065      * cipher state so that future messages use the just-negotiated spec.
1066      */
1067     void sendChangeCipherSpec(Finished mesg, boolean lastMessage)
1068             throws IOException {
1069 
1070         output.flush(); // i.e. handshake data
1071 
1072         /*
1073          * The write cipher state is protected by the connection write lock
1074          * so we must grab it while making the change. We also
1075          * make sure no writes occur between sending the ChangeCipherSpec
1076          * message, installing the new cipher state, and sending the
1077          * Finished message.
1078          *
1079          * We already hold SSLEngine/SSLSocket "this" by virtue
1080          * of this being called from the readRecord code.
1081          */

1082         if (conn != null) {









1083             conn.writeLock.lock();
1084             try {
1085                 handshakeState.changeCipherSpec(false, isClient);
1086                 conn.changeWriteCiphers();
1087                 if (debug != null && Debug.isOn("handshake")) {
1088                     mesg.print(System.out);
1089                 }
1090 
1091                 handshakeState.update(mesg, resumingSession);
1092                 mesg.write(output);
1093                 output.flush();
1094             } finally {
1095                 conn.writeLock.unlock();
1096             }
1097         } else {
1098             synchronized (engine.writeLock) {
1099                 handshakeState.changeCipherSpec(false, isClient);
1100                 engine.changeWriteCiphers();
1101                 if (debug != null && Debug.isOn("handshake")) {
1102                     mesg.print(System.out);
1103                 }
1104 
1105                 handshakeState.update(mesg, resumingSession);
1106                 mesg.write(output);
1107                 output.flush();
1108             }
1109         }
1110 
1111         if (lastMessage) {
1112             handshakeFinished = true;
1113         }

1114     }
1115 
1116     void receiveChangeCipherSpec() throws IOException {
1117         handshakeState.changeCipherSpec(true, isClient);
1118     }

1119 
1120     /*
1121      * Single access point to key calculation logic.  Given the
1122      * pre-master secret and the nonces from client and server,
1123      * produce all the keying material to be used.
1124      */
1125     void calculateKeys(SecretKey preMasterSecret, ProtocolVersion version) {
1126         SecretKey master = calculateMasterSecret(preMasterSecret, version);
1127         session.setMasterSecret(master);
1128         calculateConnectionKeys(master);
1129     }
1130 
1131     /*
1132      * Calculate the master secret from its various components.  This is
1133      * used for key exchange by all cipher suites.
1134      *
1135      * The master secret is the catenation of three MD5 hashes, each
1136      * consisting of the pre-master secret and a SHA1 hash.  Those three
1137      * SHA1 hashes are of (different) constant strings, the pre-master
1138      * secret, and the nonces provided by the client and the server.
1139      */
1140     private SecretKey calculateMasterSecret(SecretKey preMasterSecret,
1141             ProtocolVersion requestedVersion) {
1142 
1143         if (debug != null && Debug.isOn("keygen")) {
1144             HexDumpEncoder      dump = new HexDumpEncoder();
1145 
1146             System.out.println("SESSION KEYGEN:");
1147 
1148             System.out.println("PreMaster Secret:");
1149             printHex(dump, preMasterSecret.getEncoded());
1150 
1151             // Nonces are dumped with connection keygen, no
1152             // benefit to doing it twice
1153         }
1154 
1155         // What algs/params do we need to use?
1156         String masterAlg;
1157         PRF prf;
1158 
1159         byte majorVersion = protocolVersion.major;
1160         byte minorVersion = protocolVersion.minor;
1161         if (protocolVersion.isDTLSProtocol()) {
1162             // Use TLS version number for DTLS key calculation
1163             if (protocolVersion.v == ProtocolVersion.DTLS10.v) {
1164                 majorVersion = ProtocolVersion.TLS11.major;
1165                 minorVersion = ProtocolVersion.TLS11.minor;
1166 
1167                 masterAlg = "SunTlsMasterSecret";
1168                 prf = P_NONE;
1169             } else {    // DTLS 1.2
1170                 majorVersion = ProtocolVersion.TLS12.major;
1171                 minorVersion = ProtocolVersion.TLS12.minor;
1172 
1173                 masterAlg = "SunTls12MasterSecret";
1174                 prf = cipherSuite.prfAlg;
1175             }
1176         } else {
1177             if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
1178                 masterAlg = "SunTls12MasterSecret";
1179                 prf = cipherSuite.prfAlg;
1180             } else {
1181                 masterAlg = "SunTlsMasterSecret";
1182                 prf = P_NONE;
1183             }
1184         }
1185 
1186         String prfHashAlg = prf.getPRFHashAlg();
1187         int prfHashLength = prf.getPRFHashLength();
1188         int prfBlockSize = prf.getPRFBlockSize();
1189 
1190         @SuppressWarnings("deprecation")
1191         TlsMasterSecretParameterSpec spec = new TlsMasterSecretParameterSpec(
1192                 preMasterSecret, (majorVersion & 0xFF), (minorVersion & 0xFF),
1193                 clnt_random.random_bytes, svr_random.random_bytes,
1194                 prfHashAlg, prfHashLength, prfBlockSize);
1195 
1196         try {
1197             KeyGenerator kg = JsseJce.getKeyGenerator(masterAlg);
1198             kg.init(spec);
1199             return kg.generateKey();
1200         } catch (InvalidAlgorithmParameterException |
1201                 NoSuchAlgorithmException iae) {
1202             // unlikely to happen, otherwise, must be a provider exception
1203             //
1204             // For RSA premaster secrets, do not signal a protocol error
1205             // due to the Bleichenbacher attack. See comments further down.
1206             if (debug != null && Debug.isOn("handshake")) {
1207                 System.out.println("RSA master secret generation error:");
1208                 iae.printStackTrace(System.out);
1209             }
1210             throw new ProviderException(iae);
1211 
1212         }


1223      * "fast handshake" (where we just resumed a pre-existing session).
1224      */
1225     @SuppressWarnings("deprecation")
1226     void calculateConnectionKeys(SecretKey masterKey) {
1227         /*
1228          * For both the read and write sides of the protocol, we use the
1229          * master to generate MAC secrets and cipher keying material.  Block
1230          * ciphers need initialization vectors, which we also generate.
1231          *
1232          * First we figure out how much keying material is needed.
1233          */
1234         int hashSize = cipherSuite.macAlg.size;
1235         boolean is_exportable = cipherSuite.exportable;
1236         BulkCipher cipher = cipherSuite.cipher;
1237         int expandedKeySize = is_exportable ? cipher.expandedKeySize : 0;
1238 
1239         // Which algs/params do we need to use?
1240         String keyMaterialAlg;
1241         PRF prf;
1242 
1243         byte majorVersion = protocolVersion.major;
1244         byte minorVersion = protocolVersion.minor;
1245         if (protocolVersion.isDTLSProtocol()) {
1246             // Use TLS version number for DTLS key calculation
1247             if (protocolVersion.v == ProtocolVersion.DTLS10.v) {
1248                 majorVersion = ProtocolVersion.TLS11.major;
1249                 minorVersion = ProtocolVersion.TLS11.minor;
1250 
1251                 keyMaterialAlg = "SunTlsKeyMaterial";
1252                 prf = P_NONE;
1253             } else {    // DTLS 1.2+
1254                 majorVersion = ProtocolVersion.TLS12.major;
1255                 minorVersion = ProtocolVersion.TLS12.minor;
1256 
1257                 keyMaterialAlg = "SunTls12KeyMaterial";
1258                 prf = cipherSuite.prfAlg;
1259             }
1260         } else {
1261             if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
1262                 keyMaterialAlg = "SunTls12KeyMaterial";
1263                 prf = cipherSuite.prfAlg;
1264             } else {
1265                 keyMaterialAlg = "SunTlsKeyMaterial";
1266                 prf = P_NONE;
1267             }
1268         }
1269 
1270         String prfHashAlg = prf.getPRFHashAlg();
1271         int prfHashLength = prf.getPRFHashLength();
1272         int prfBlockSize = prf.getPRFBlockSize();
1273 
1274         // TLS v1.1+ and DTLS use an explicit IV in CBC cipher suites to
1275         // protect against the CBC attacks.  AEAD/GCM cipher suites in TLS
1276         // v1.2 or later use a fixed IV as the implicit part of the partially
1277         // implicit nonce technique described in RFC 5116.
1278         int ivSize = cipher.ivSize;
1279         if (cipher.cipherType == AEAD_CIPHER) {
1280             ivSize = cipher.fixedIvSize;
1281         } else if ((cipher.cipherType == BLOCK_CIPHER) &&
1282                 protocolVersion.useTLS11PlusSpec()) {
1283             ivSize = 0;
1284         }
1285 
1286         TlsKeyMaterialParameterSpec spec = new TlsKeyMaterialParameterSpec(
1287                 masterKey, (majorVersion & 0xFF), (minorVersion & 0xFF),
1288                 clnt_random.random_bytes, svr_random.random_bytes,
1289                 cipher.algorithm, cipher.keySize, expandedKeySize,
1290                 ivSize, hashSize,
1291                 prfHashAlg, prfHashLength, prfBlockSize);
1292 
1293         try {
1294             KeyGenerator kg = JsseJce.getKeyGenerator(keyMaterialAlg);
1295             kg.init(spec);
1296             TlsKeyMaterialSpec keySpec = (TlsKeyMaterialSpec)kg.generateKey();
1297 
1298             // Return null if cipher keys are not supposed to be generated.
1299             clntWriteKey = keySpec.getClientCipherKey();
1300             svrWriteKey = keySpec.getServerCipherKey();
1301 
1302             // Return null if IVs are not supposed to be generated.
1303             clntWriteIV = keySpec.getClientIv();
1304             svrWriteIV = keySpec.getServerIv();
1305 
1306             // Return null if MAC keys are not supposed to be generated.
1307             clntMacSecret = keySpec.getClientMacKey();
1308             svrMacSecret = keySpec.getServerMacKey();
1309         } catch (GeneralSecurityException e) {
1310             throw new ProviderException(e);
1311         }
1312 




1313         //
1314         // Dump the connection keys as they're generated.
1315         //
1316         if (debug != null && Debug.isOn("keygen")) {
1317             synchronized (System.out) {
1318                 HexDumpEncoder  dump = new HexDumpEncoder();
1319 
1320                 System.out.println("CONNECTION KEYGEN:");
1321 
1322                 // Inputs:
1323                 System.out.println("Client Nonce:");
1324                 printHex(dump, clnt_random.random_bytes);
1325                 System.out.println("Server Nonce:");
1326                 printHex(dump, svr_random.random_bytes);
1327                 System.out.println("Master Secret:");
1328                 printHex(dump, masterKey.getEncoded());
1329 
1330                 // Outputs:
1331                 if (clntMacSecret != null) {
1332                     System.out.println("Client MAC write Secret:");


1335                     printHex(dump, svrMacSecret.getEncoded());
1336                 } else {
1337                     System.out.println("... no MAC keys used for this cipher");
1338                 }
1339 
1340                 if (clntWriteKey != null) {
1341                     System.out.println("Client write key:");
1342                     printHex(dump, clntWriteKey.getEncoded());
1343                     System.out.println("Server write key:");
1344                     printHex(dump, svrWriteKey.getEncoded());
1345                 } else {
1346                     System.out.println("... no encryption keys used");
1347                 }
1348 
1349                 if (clntWriteIV != null) {
1350                     System.out.println("Client write IV:");
1351                     printHex(dump, clntWriteIV.getIV());
1352                     System.out.println("Server write IV:");
1353                     printHex(dump, svrWriteIV.getIV());
1354                 } else {
1355                     if (protocolVersion.useTLS11PlusSpec()) {
1356                         System.out.println(
1357                                 "... no IV derived for this protocol");
1358                     } else {
1359                         System.out.println("... no IV used for this cipher");
1360                     }
1361                 }
1362                 System.out.flush();
1363             }
1364         }
1365     }
1366 









1367     private static void printHex(HexDumpEncoder dump, byte[] bytes) {
1368         if (bytes == null) {
1369             System.out.println("(key bytes not available)");
1370         } else {
1371             try {
1372                 dump.encodeBuffer(bytes, System.out);
1373             } catch (IOException e) {
1374                 // just for debugging, ignore this
1375             }
1376         }
1377     }
1378 













1379     /*
1380      * Implement a simple task delegator.
1381      *
1382      * We are currently implementing this as a single delegator, may
1383      * try for parallel tasks later.  Client Authentication could
1384      * benefit from this, where ClientKeyExchange/CertificateVerify
1385      * could be carried out in parallel.
1386      */
1387     class DelegatedTask<E> implements Runnable {
1388 
1389         private PrivilegedExceptionAction<E> pea;
1390 
1391         DelegatedTask(PrivilegedExceptionAction<E> pea) {
1392             this.pea = pea;
1393         }
1394 
1395         public void run() {
1396             synchronized (engine) {
1397                 try {
1398                     AccessController.doPrivileged(pea, engine.getAcc());