1 /*
   2  * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package sun.security.ssl;
  27 
  28 import java.io.*;
  29 import java.math.BigInteger;
  30 import java.security.*;
  31 import java.util.*;
  32 
  33 import java.security.interfaces.ECPublicKey;
  34 import java.security.interfaces.RSAPublicKey;
  35 import java.security.spec.ECParameterSpec;
  36 
  37 import java.security.cert.X509Certificate;
  38 import java.security.cert.CertificateException;
  39 import java.security.cert.CertificateParsingException;
  40 import javax.security.auth.x500.X500Principal;
  41 
  42 import javax.crypto.SecretKey;
  43 import javax.crypto.spec.SecretKeySpec;
  44 
  45 import javax.net.ssl.*;
  46 
  47 import javax.security.auth.Subject;
  48 
  49 import sun.security.ssl.HandshakeMessage.*;
  50 import static sun.security.ssl.CipherSuite.KeyExchange.*;
  51 
  52 /**
  53  * ClientHandshaker does the protocol handshaking from the point
  54  * of view of a client.  It is driven asychronously by handshake messages
  55  * as delivered by the parent Handshaker class, and also uses
  56  * common functionality (e.g. key generation) that is provided there.
  57  *
  58  * @author David Brownell
  59  */
  60 final class ClientHandshaker extends Handshaker {
  61 
  62     // constants for subject alt names of type DNS and IP
  63     private final static int ALTNAME_DNS = 2;
  64     private final static int ALTNAME_IP  = 7;
  65 
  66     // the server's public key from its certificate.
  67     private PublicKey serverKey;
  68 
  69     // the server's ephemeral public key from the server key exchange message
  70     // for ECDHE/ECDH_anon and RSA_EXPORT.
  71     private PublicKey ephemeralServerKey;
  72 
  73     // server's ephemeral public value for DHE/DH_anon key exchanges
  74     private BigInteger          serverDH;
  75 
  76     private DHCrypt             dh;
  77 
  78     private ECDHCrypt ecdh;
  79 
  80     private CertificateRequest  certRequest;
  81 
  82     private boolean serverKeyExchangeReceived;
  83 
  84     /*
  85      * The RSA PreMasterSecret needs to know the version of
  86      * ClientHello that was used on this handshake.  This represents
  87      * the "max version" this client is supporting.  In the
  88      * case of an initial handshake, it's the max version enabled,
  89      * but in the case of a resumption attempt, it's the version
  90      * of the session we're trying to resume.
  91      */
  92     private ProtocolVersion maxProtocolVersion;
  93 
  94     // To switch off the SNI extension.
  95     private final static boolean enableSNIExtension =
  96             Debug.getBooleanProperty("jsse.enableSNIExtension", true);
  97 
  98     /*
  99      * Allow unsafe server certificate change?
 100      *
 101      * Server certificate change during SSL/TLS renegotiation may be considered
 102      * unsafe, as described in the Triple Handshake attacks:
 103      *
 104      *     https://secure-resumption.com/tlsauth.pdf
 105      *
 106      * Endpoint identification (See
 107      * SSLParameters.getEndpointIdentificationAlgorithm()) is a pretty nice
 108      * guarantee that the server certificate change in renegotiation is legal.
 109      * However, endpoing identification is only enabled for HTTPS and LDAP
 110      * over SSL/TLS by default.  It is not enough to protect SSL/TLS
 111      * connections other than HTTPS and LDAP.
 112      *
 113      * The renegotiation indication extension (See RFC 5764) is a pretty
 114      * strong guarantee that the endpoints on both client and server sides
 115      * are identical on the same connection.  However, the Triple Handshake
 116      * attacks can bypass this guarantee if there is a session-resumption
 117      * handshake between the initial full handshake and the renegotiation
 118      * full handshake.
 119      *
 120      * Server certificate change may be unsafe and should be restricted if
 121      * endpoint identification is not enabled and the previous handshake is
 122      * a session-resumption abbreviated initial handshake, unless the
 123      * identities represented by both certificates can be regraded as the
 124      * same (See isIdentityEquivalent()).
 125      *
 126      * Considering the compatibility impact and the actual requirements to
 127      * support server certificate change in practice, the system property,
 128      * jdk.tls.allowUnsafeServerCertChange, is used to define whether unsafe
 129      * server certificate change in renegotiation is allowed or not.  The
 130      * default value of the system property is "false".  To mitigate the
 131      * compactibility impact, applications may want to set the system
 132      * property to "true" at their own risk.
 133      *
 134      * If the value of the system property is "false", server certificate
 135      * change in renegotiation after a session-resumption abbreviated initial
 136      * handshake is restricted (See isIdentityEquivalent()).
 137      *
 138      * If the system property is set to "true" explicitly, the restriction on
 139      * server certificate change in renegotiation is disabled.
 140      */
 141     private final static boolean allowUnsafeServerCertChange =
 142         Debug.getBooleanProperty("jdk.tls.allowUnsafeServerCertChange", false);
 143 
 144     private List<SNIServerName> requestedServerNames =
 145             Collections.<SNIServerName>emptyList();
 146 
 147     private boolean serverNamesAccepted = false;
 148 
 149     /*
 150      * the reserved server certificate chain in previous handshaking
 151      *
 152      * The server certificate chain is only reserved if the previous
 153      * handshake is a session-resumption abbreviated initial handshake.
 154      */
 155     private X509Certificate[] reservedServerCerts = null;
 156 
 157     /*
 158      * Constructors
 159      */
 160     ClientHandshaker(SSLSocketImpl socket, SSLContextImpl context,
 161             ProtocolList enabledProtocols,
 162             ProtocolVersion activeProtocolVersion,
 163             boolean isInitialHandshake, boolean secureRenegotiation,
 164             byte[] clientVerifyData, byte[] serverVerifyData) {
 165 
 166         super(socket, context, enabledProtocols, true, true,
 167             activeProtocolVersion, isInitialHandshake, secureRenegotiation,
 168             clientVerifyData, serverVerifyData);
 169     }
 170 
 171     ClientHandshaker(SSLEngineImpl engine, SSLContextImpl context,
 172             ProtocolList enabledProtocols,
 173             ProtocolVersion activeProtocolVersion,
 174             boolean isInitialHandshake, boolean secureRenegotiation,
 175             byte[] clientVerifyData, byte[] serverVerifyData) {
 176 
 177         super(engine, context, enabledProtocols, true, true,
 178             activeProtocolVersion, isInitialHandshake, secureRenegotiation,
 179             clientVerifyData, serverVerifyData);
 180     }
 181 
 182     /*
 183      * This routine handles all the client side handshake messages, one at
 184      * a time.  Given the message type (and in some cases the pending cipher
 185      * spec) it parses the type-specific message.  Then it calls a function
 186      * that handles that specific message.
 187      *
 188      * It updates the state machine (need to verify it) as each message
 189      * is processed, and writes responses as needed using the connection
 190      * in the constructor.
 191      */
 192     @Override
 193     void processMessage(byte type, int messageLen) throws IOException {
 194         if (state >= type
 195                 && (type != HandshakeMessage.ht_hello_request)) {
 196             throw new SSLProtocolException(
 197                     "Handshake message sequence violation, " + type);
 198         }
 199 
 200         switch (type) {
 201         case HandshakeMessage.ht_hello_request:
 202             this.serverHelloRequest(new HelloRequest(input));
 203             break;
 204 
 205         case HandshakeMessage.ht_server_hello:
 206             this.serverHello(new ServerHello(input, messageLen));
 207             break;
 208 
 209         case HandshakeMessage.ht_certificate:
 210             if (keyExchange == K_DH_ANON || keyExchange == K_ECDH_ANON
 211                     || keyExchange == K_KRB5 || keyExchange == K_KRB5_EXPORT) {
 212                 fatalSE(Alerts.alert_unexpected_message,
 213                     "unexpected server cert chain");
 214                 // NOTREACHED
 215             }
 216             this.serverCertificate(new CertificateMsg(input));
 217             serverKey =
 218                 session.getPeerCertificates()[0].getPublicKey();
 219             break;
 220 
 221         case HandshakeMessage.ht_server_key_exchange:
 222             serverKeyExchangeReceived = true;
 223             switch (keyExchange) {
 224             case K_RSA_EXPORT:
 225                 /**
 226                  * The server key exchange message is sent by the server only
 227                  * when the server certificate message does not contain the
 228                  * proper amount of data to allow the client to exchange a
 229                  * premaster secret, such as when RSA_EXPORT is used and the
 230                  * public key in the server certificate is longer than 512 bits.
 231                  */
 232                 if (serverKey == null) {
 233                     throw new SSLProtocolException
 234                         ("Server did not send certificate message");
 235                 }
 236 
 237                 if (!(serverKey instanceof RSAPublicKey)) {
 238                     throw new SSLProtocolException("Protocol violation:" +
 239                         " the certificate type must be appropriate for the" +
 240                         " selected cipher suite's key exchange algorithm");
 241                 }
 242 
 243                 if (JsseJce.getRSAKeyLength(serverKey) <= 512) {
 244                     throw new SSLProtocolException("Protocol violation:" +
 245                         " server sent a server key exchange message for" +
 246                         " key exchange " + keyExchange +
 247                         " when the public key in the server certificate" +
 248                         " is less than or equal to 512 bits in length");
 249                 }
 250 
 251                 try {
 252                     this.serverKeyExchange(new RSA_ServerKeyExchange(input));
 253                 } catch (GeneralSecurityException e) {
 254                     throwSSLException("Server key", e);
 255                 }
 256                 break;
 257             case K_DH_ANON:
 258                 try {
 259                     this.serverKeyExchange(new DH_ServerKeyExchange(
 260                                                 input, protocolVersion));
 261                 } catch (GeneralSecurityException e) {
 262                     throwSSLException("Server key", e);
 263                 }
 264                 break;
 265             case K_DHE_DSS:
 266             case K_DHE_RSA:
 267                 try {
 268                     this.serverKeyExchange(new DH_ServerKeyExchange(
 269                         input, serverKey,
 270                         clnt_random.random_bytes, svr_random.random_bytes,
 271                         messageLen,
 272                         localSupportedSignAlgs, protocolVersion));
 273                 } catch (GeneralSecurityException e) {
 274                     throwSSLException("Server key", e);
 275                 }
 276                 break;
 277             case K_ECDHE_ECDSA:
 278             case K_ECDHE_RSA:
 279             case K_ECDH_ANON:
 280                 try {
 281                     this.serverKeyExchange(new ECDH_ServerKeyExchange
 282                         (input, serverKey, clnt_random.random_bytes,
 283                         svr_random.random_bytes,
 284                         localSupportedSignAlgs, protocolVersion));
 285                 } catch (GeneralSecurityException e) {
 286                     throwSSLException("Server key", e);
 287                 }
 288                 break;
 289             case K_RSA:
 290             case K_DH_RSA:
 291             case K_DH_DSS:
 292             case K_ECDH_ECDSA:
 293             case K_ECDH_RSA:
 294                 throw new SSLProtocolException(
 295                     "Protocol violation: server sent a server key exchange"
 296                     + "message for key exchange " + keyExchange);
 297             case K_KRB5:
 298             case K_KRB5_EXPORT:
 299                 throw new SSLProtocolException(
 300                     "unexpected receipt of server key exchange algorithm");
 301             default:
 302                 throw new SSLProtocolException(
 303                     "unsupported key exchange algorithm = "
 304                     + keyExchange);
 305             }
 306             break;
 307 
 308         case HandshakeMessage.ht_certificate_request:
 309             // save for later, it's handled by serverHelloDone
 310             if ((keyExchange == K_DH_ANON) || (keyExchange == K_ECDH_ANON)) {
 311                 throw new SSLHandshakeException(
 312                     "Client authentication requested for "+
 313                     "anonymous cipher suite.");
 314             } else if (keyExchange == K_KRB5 || keyExchange == K_KRB5_EXPORT) {
 315                 throw new SSLHandshakeException(
 316                     "Client certificate requested for "+
 317                     "kerberos cipher suite.");
 318             }
 319             certRequest = new CertificateRequest(input, protocolVersion);
 320             if (debug != null && Debug.isOn("handshake")) {
 321                 certRequest.print(System.out);
 322             }
 323 
 324             if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
 325                 Collection<SignatureAndHashAlgorithm> peerSignAlgs =
 326                                         certRequest.getSignAlgorithms();
 327                 if (peerSignAlgs == null || peerSignAlgs.isEmpty()) {
 328                     throw new SSLHandshakeException(
 329                         "No peer supported signature algorithms");
 330                 }
 331 
 332                 Collection<SignatureAndHashAlgorithm> supportedPeerSignAlgs =
 333                     SignatureAndHashAlgorithm.getSupportedAlgorithms(
 334                                                             peerSignAlgs);
 335                 if (supportedPeerSignAlgs.isEmpty()) {
 336                     throw new SSLHandshakeException(
 337                         "No supported signature and hash algorithm in common");
 338                 }
 339 
 340                 setPeerSupportedSignAlgs(supportedPeerSignAlgs);
 341                 session.setPeerSupportedSignatureAlgorithms(
 342                                                 supportedPeerSignAlgs);
 343             }
 344 
 345             break;
 346 
 347         case HandshakeMessage.ht_server_hello_done:
 348             this.serverHelloDone(new ServerHelloDone(input));
 349             break;
 350 
 351         case HandshakeMessage.ht_finished:
 352             // A ChangeCipherSpec record must have been received prior to
 353             // reception of the Finished message (RFC 5246, 7.4.9).
 354             if (!receivedChangeCipherSpec()) {
 355                 fatalSE(Alerts.alert_handshake_failure,
 356                         "Received Finished message before ChangeCipherSpec");
 357             }
 358 
 359             this.serverFinished(
 360                 new Finished(protocolVersion, input, cipherSuite));
 361             break;
 362 
 363         default:
 364             throw new SSLProtocolException(
 365                 "Illegal client handshake msg, " + type);
 366         }
 367 
 368         //
 369         // Move state machine forward if the message handling
 370         // code didn't already do so
 371         //
 372         if (state < type) {
 373             state = type;
 374         }
 375     }
 376 
 377     /*
 378      * Used by the server to kickstart negotiations -- this requests a
 379      * "client hello" to renegotiate current cipher specs (e.g. maybe lots
 380      * of data has been encrypted with the same keys, or the server needs
 381      * the client to present a certificate).
 382      */
 383     private void serverHelloRequest(HelloRequest mesg) throws IOException {
 384         if (debug != null && Debug.isOn("handshake")) {
 385             mesg.print(System.out);
 386         }
 387 
 388         //
 389         // Could be (e.g. at connection setup) that we already
 390         // sent the "client hello" but the server's not seen it.
 391         //
 392         if (state < HandshakeMessage.ht_client_hello) {
 393             if (!secureRenegotiation && !allowUnsafeRenegotiation) {
 394                 // renegotiation is not allowed.
 395                 if (activeProtocolVersion.v >= ProtocolVersion.TLS10.v) {
 396                     // response with a no_renegotiation warning,
 397                     warningSE(Alerts.alert_no_renegotiation);
 398 
 399                     // invalidate the handshake so that the caller can
 400                     // dispose this object.
 401                     invalidated = true;
 402 
 403                     // If there is still unread block in the handshake
 404                     // input stream, it would be truncated with the disposal
 405                     // and the next handshake message will become incomplete.
 406                     //
 407                     // However, according to SSL/TLS specifications, no more
 408                     // handshake message should immediately follow ClientHello
 409                     // or HelloRequest. So just let it be.
 410                 } else {
 411                     // For SSLv3, send the handshake_failure fatal error.
 412                     // Note that SSLv3 does not define a no_renegotiation
 413                     // alert like TLSv1. However we cannot ignore the message
 414                     // simply, otherwise the other side was waiting for a
 415                     // response that would never come.
 416                     fatalSE(Alerts.alert_handshake_failure,
 417                         "Renegotiation is not allowed");
 418                 }
 419             } else {
 420                 if (!secureRenegotiation) {
 421                     if (debug != null && Debug.isOn("handshake")) {
 422                         System.out.println(
 423                             "Warning: continue with insecure renegotiation");
 424                     }
 425                 }
 426                 kickstart();
 427             }
 428         }
 429     }
 430 
 431 
 432     /*
 433      * Server chooses session parameters given options created by the
 434      * client -- basically, cipher options, session id, and someday a
 435      * set of compression options.
 436      *
 437      * There are two branches of the state machine, decided by the
 438      * details of this message.  One is the "fast" handshake, where we
 439      * can resume the pre-existing session we asked resume.  The other
 440      * is a more expensive "full" handshake, with key exchange and
 441      * probably authentication getting done.
 442      */
 443     private void serverHello(ServerHello mesg) throws IOException {
 444         serverKeyExchangeReceived = false;
 445         if (debug != null && Debug.isOn("handshake")) {
 446             mesg.print(System.out);
 447         }
 448 
 449         // check if the server selected protocol version is OK for us
 450         ProtocolVersion mesgVersion = mesg.protocolVersion;
 451         if (!isNegotiable(mesgVersion)) {
 452             throw new SSLHandshakeException(
 453                 "Server chose " + mesgVersion +
 454                 ", but that protocol version is not enabled or not supported " +
 455                 "by the client.");
 456         }
 457 
 458         handshakeHash.protocolDetermined(mesgVersion);
 459 
 460         // Set protocolVersion and propagate to SSLSocket and the
 461         // Handshake streams
 462         setVersion(mesgVersion);
 463 
 464         // check the "renegotiation_info" extension
 465         RenegotiationInfoExtension serverHelloRI = (RenegotiationInfoExtension)
 466                     mesg.extensions.get(ExtensionType.EXT_RENEGOTIATION_INFO);
 467         if (serverHelloRI != null) {
 468             if (isInitialHandshake) {
 469                 // verify the length of the "renegotiated_connection" field
 470                 if (!serverHelloRI.isEmpty()) {
 471                     // abort the handshake with a fatal handshake_failure alert
 472                     fatalSE(Alerts.alert_handshake_failure,
 473                         "The renegotiation_info field is not empty");
 474                 }
 475 
 476                 secureRenegotiation = true;
 477             } else {
 478                 // For a legacy renegotiation, the client MUST verify that
 479                 // it does not contain the "renegotiation_info" extension.
 480                 if (!secureRenegotiation) {
 481                     fatalSE(Alerts.alert_handshake_failure,
 482                         "Unexpected renegotiation indication extension");
 483                 }
 484 
 485                 // verify the client_verify_data and server_verify_data values
 486                 byte[] verifyData =
 487                     new byte[clientVerifyData.length + serverVerifyData.length];
 488                 System.arraycopy(clientVerifyData, 0, verifyData,
 489                         0, clientVerifyData.length);
 490                 System.arraycopy(serverVerifyData, 0, verifyData,
 491                         clientVerifyData.length, serverVerifyData.length);
 492                 if (!Arrays.equals(verifyData,
 493                                 serverHelloRI.getRenegotiatedConnection())) {
 494                     fatalSE(Alerts.alert_handshake_failure,
 495                         "Incorrect verify data in ServerHello " +
 496                         "renegotiation_info message");
 497                 }
 498             }
 499         } else {
 500             // no renegotiation indication extension
 501             if (isInitialHandshake) {
 502                 if (!allowLegacyHelloMessages) {
 503                     // abort the handshake with a fatal handshake_failure alert
 504                     fatalSE(Alerts.alert_handshake_failure,
 505                         "Failed to negotiate the use of secure renegotiation");
 506                 }
 507 
 508                 secureRenegotiation = false;
 509                 if (debug != null && Debug.isOn("handshake")) {
 510                     System.out.println("Warning: No renegotiation " +
 511                                     "indication extension in ServerHello");
 512                 }
 513             } else {
 514                 // For a secure renegotiation, the client must abort the
 515                 // handshake if no "renegotiation_info" extension is present.
 516                 if (secureRenegotiation) {
 517                     fatalSE(Alerts.alert_handshake_failure,
 518                         "No renegotiation indication extension");
 519                 }
 520 
 521                 // we have already allowed unsafe renegotation before request
 522                 // the renegotiation.
 523             }
 524         }
 525 
 526         //
 527         // Save server nonce, we always use it to compute connection
 528         // keys and it's also used to create the master secret if we're
 529         // creating a new session (i.e. in the full handshake).
 530         //
 531         svr_random = mesg.svr_random;
 532 
 533         if (isNegotiable(mesg.cipherSuite) == false) {
 534             fatalSE(Alerts.alert_illegal_parameter,
 535                 "Server selected improper ciphersuite " + mesg.cipherSuite);
 536         }
 537 
 538         setCipherSuite(mesg.cipherSuite);
 539         if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
 540             handshakeHash.setFinishedAlg(cipherSuite.prfAlg.getPRFHashAlg());
 541         }
 542 
 543         if (mesg.compression_method != 0) {
 544             fatalSE(Alerts.alert_illegal_parameter,
 545                 "compression type not supported, "
 546                 + mesg.compression_method);
 547             // NOTREACHED
 548         }
 549 
 550         // so far so good, let's look at the session
 551         if (session != null) {
 552             // we tried to resume, let's see what the server decided
 553             if (session.getSessionId().equals(mesg.sessionId)) {
 554                 // server resumed the session, let's make sure everything
 555                 // checks out
 556 
 557                 // Verify that the session ciphers are unchanged.
 558                 CipherSuite sessionSuite = session.getSuite();
 559                 if (cipherSuite != sessionSuite) {
 560                     throw new SSLProtocolException
 561                         ("Server returned wrong cipher suite for session");
 562                 }
 563 
 564                 // verify protocol version match
 565                 ProtocolVersion sessionVersion = session.getProtocolVersion();
 566                 if (protocolVersion != sessionVersion) {
 567                     throw new SSLProtocolException
 568                         ("Server resumed session with wrong protocol version");
 569                 }
 570 
 571                 // validate subject identity
 572                 if (sessionSuite.keyExchange == K_KRB5 ||
 573                     sessionSuite.keyExchange == K_KRB5_EXPORT) {
 574                     Principal localPrincipal = session.getLocalPrincipal();
 575 
 576                     Subject subject = null;
 577                     try {
 578                         subject = AccessController.doPrivileged(
 579                             new PrivilegedExceptionAction<Subject>() {
 580                             @Override
 581                             public Subject run() throws Exception {
 582                                 return Krb5Helper.getClientSubject(getAccSE());
 583                             }});
 584                     } catch (PrivilegedActionException e) {
 585                         subject = null;
 586                         if (debug != null && Debug.isOn("session")) {
 587                             System.out.println("Attempt to obtain" +
 588                                         " subject failed!");
 589                         }
 590                     }
 591 
 592                     if (subject != null) {
 593                         // Eliminate dependency on KerberosPrincipal
 594                         Set<Principal> principals =
 595                             subject.getPrincipals(Principal.class);
 596                         if (!principals.contains(localPrincipal)) {
 597                             throw new SSLProtocolException("Server resumed" +
 598                                 " session with wrong subject identity");
 599                         } else {
 600                             if (debug != null && Debug.isOn("session"))
 601                                 System.out.println("Subject identity is same");
 602                         }
 603                     } else {
 604                         if (debug != null && Debug.isOn("session"))
 605                             System.out.println("Kerberos credentials are not" +
 606                                 " present in the current Subject; check if " +
 607                                 " javax.security.auth.useSubjectAsCreds" +
 608                                 " system property has been set to false");
 609                         throw new SSLProtocolException
 610                             ("Server resumed session with no subject");
 611                     }
 612                 }
 613 
 614                 // looks fine; resume it, and update the state machine.
 615                 resumingSession = true;
 616                 state = HandshakeMessage.ht_finished - 1;
 617                 calculateConnectionKeys(session.getMasterSecret());
 618                 if (debug != null && Debug.isOn("session")) {
 619                     System.out.println("%% Server resumed " + session);
 620                 }
 621             } else {
 622                 // we wanted to resume, but the server refused
 623                 session = null;
 624                 if (!enableNewSession) {
 625                     throw new SSLException("New session creation is disabled");
 626                 }
 627             }
 628         }
 629 
 630         if (resumingSession && session != null) {
 631             setHandshakeSessionSE(session);
 632             // Reserve the handshake state if this is a session-resumption
 633             // abbreviated initial handshake.
 634             if (isInitialHandshake) {
 635                 session.setAsSessionResumption(true);
 636             }
 637 
 638             return;
 639         }
 640 
 641         // check extensions
 642         for (HelloExtension ext : mesg.extensions.list()) {
 643             ExtensionType type = ext.type;
 644             if (type == ExtensionType.EXT_SERVER_NAME) {
 645                 serverNamesAccepted = true;
 646             } else if ((type != ExtensionType.EXT_ELLIPTIC_CURVES)
 647                     && (type != ExtensionType.EXT_EC_POINT_FORMATS)
 648                     && (type != ExtensionType.EXT_SERVER_NAME)
 649                     && (type != ExtensionType.EXT_RENEGOTIATION_INFO)) {
 650                 fatalSE(Alerts.alert_unsupported_extension,
 651                     "Server sent an unsupported extension: " + type);
 652             }
 653         }
 654 
 655         // Create a new session, we need to do the full handshake
 656         session = new SSLSessionImpl(protocolVersion, cipherSuite,
 657                             getLocalSupportedSignAlgs(),
 658                             mesg.sessionId, getHostSE(), getPortSE());
 659         session.setRequestedServerNames(requestedServerNames);
 660         setHandshakeSessionSE(session);
 661         if (debug != null && Debug.isOn("handshake")) {
 662             System.out.println("** " + cipherSuite);
 663         }
 664     }
 665 
 666     /*
 667      * Server's own key was either a signing-only key, or was too
 668      * large for export rules ... this message holds an ephemeral
 669      * RSA key to use for key exchange.
 670      */
 671     private void serverKeyExchange(RSA_ServerKeyExchange mesg)
 672             throws IOException, GeneralSecurityException {
 673         if (debug != null && Debug.isOn("handshake")) {
 674             mesg.print(System.out);
 675         }
 676         if (!mesg.verify(serverKey, clnt_random, svr_random)) {
 677             fatalSE(Alerts.alert_handshake_failure,
 678                 "server key exchange invalid");
 679             // NOTREACHED
 680         }
 681         ephemeralServerKey = mesg.getPublicKey();
 682     }
 683 
 684 
 685     /*
 686      * Diffie-Hellman key exchange.  We save the server public key and
 687      * our own D-H algorithm object so we can defer key calculations
 688      * until after we've sent the client key exchange message (which
 689      * gives client and server some useful parallelism).
 690      */
 691     private void serverKeyExchange(DH_ServerKeyExchange mesg)
 692             throws IOException {
 693         if (debug != null && Debug.isOn("handshake")) {
 694             mesg.print(System.out);
 695         }
 696         dh = new DHCrypt(mesg.getModulus(), mesg.getBase(),
 697                                             sslContext.getSecureRandom());
 698         serverDH = mesg.getServerPublicKey();
 699     }
 700 
 701     private void serverKeyExchange(ECDH_ServerKeyExchange mesg)
 702             throws IOException {
 703         if (debug != null && Debug.isOn("handshake")) {
 704             mesg.print(System.out);
 705         }
 706         ECPublicKey key = mesg.getPublicKey();
 707         ecdh = new ECDHCrypt(key.getParams(), sslContext.getSecureRandom());
 708         ephemeralServerKey = key;
 709     }
 710 
 711     /*
 712      * The server's "Hello Done" message is the client's sign that
 713      * it's time to do all the hard work.
 714      */
 715     private void serverHelloDone(ServerHelloDone mesg) throws IOException {
 716         if (debug != null && Debug.isOn("handshake")) {
 717             mesg.print(System.out);
 718         }
 719         /*
 720          * Always make sure the input has been digested before we
 721          * start emitting data, to ensure the hashes are correctly
 722          * computed for the Finished and CertificateVerify messages
 723          * which we send (here).
 724          */
 725         input.digestNow();
 726 
 727         /*
 728          * FIRST ... if requested, send an appropriate Certificate chain
 729          * to authenticate the client, and remember the associated private
 730          * key to sign the CertificateVerify message.
 731          */
 732         PrivateKey signingKey = null;
 733 
 734         if (certRequest != null) {
 735             X509ExtendedKeyManager km = sslContext.getX509KeyManager();
 736 
 737             ArrayList<String> keytypesTmp = new ArrayList<>(4);
 738 
 739             for (int i = 0; i < certRequest.types.length; i++) {
 740                 String typeName;
 741 
 742                 switch (certRequest.types[i]) {
 743                 case CertificateRequest.cct_rsa_sign:
 744                     typeName = "RSA";
 745                     break;
 746 
 747                 case CertificateRequest.cct_dss_sign:
 748                     typeName = "DSA";
 749                     break;
 750 
 751                 case CertificateRequest.cct_ecdsa_sign:
 752                     // ignore if we do not have EC crypto available
 753                     typeName = JsseJce.isEcAvailable() ? "EC" : null;
 754                     break;
 755 
 756                 // Fixed DH/ECDH client authentication not supported
 757                 case CertificateRequest.cct_rsa_fixed_dh:
 758                 case CertificateRequest.cct_dss_fixed_dh:
 759                 case CertificateRequest.cct_rsa_fixed_ecdh:
 760                 case CertificateRequest.cct_ecdsa_fixed_ecdh:
 761                 // Any other values (currently not used in TLS)
 762                 case CertificateRequest.cct_rsa_ephemeral_dh:
 763                 case CertificateRequest.cct_dss_ephemeral_dh:
 764                 default:
 765                     typeName = null;
 766                     break;
 767                 }
 768 
 769                 if ((typeName != null) && (!keytypesTmp.contains(typeName))) {
 770                     keytypesTmp.add(typeName);
 771                 }
 772             }
 773 
 774             String alias = null;
 775             int keytypesTmpSize = keytypesTmp.size();
 776             if (keytypesTmpSize != 0) {
 777                 String keytypes[] =
 778                         keytypesTmp.toArray(new String[keytypesTmpSize]);
 779 
 780                 if (conn != null) {
 781                     alias = km.chooseClientAlias(keytypes,
 782                         certRequest.getAuthorities(), conn);
 783                 } else {
 784                     alias = km.chooseEngineClientAlias(keytypes,
 785                         certRequest.getAuthorities(), engine);
 786                 }
 787             }
 788 
 789             CertificateMsg m1 = null;
 790             if (alias != null) {
 791                 X509Certificate[] certs = km.getCertificateChain(alias);
 792                 if ((certs != null) && (certs.length != 0)) {
 793                     PublicKey publicKey = certs[0].getPublicKey();
 794                     // for EC, make sure we use a supported named curve
 795                     if (publicKey instanceof ECPublicKey) {
 796                         ECParameterSpec params =
 797                             ((ECPublicKey)publicKey).getParams();
 798                         int index =
 799                             SupportedEllipticCurvesExtension.getCurveIndex(
 800                                 params);
 801                         if (!SupportedEllipticCurvesExtension.isSupported(
 802                                 index)) {
 803                             publicKey = null;
 804                         }
 805                     }
 806                     if (publicKey != null) {
 807                         m1 = new CertificateMsg(certs);
 808                         signingKey = km.getPrivateKey(alias);
 809                         session.setLocalPrivateKey(signingKey);
 810                         session.setLocalCertificates(certs);
 811                     }
 812                 }
 813             }
 814             if (m1 == null) {
 815                 //
 816                 // No appropriate cert was found ... report this to the
 817                 // server.  For SSLv3, send the no_certificate alert;
 818                 // TLS uses an empty cert chain instead.
 819                 //
 820                 if (protocolVersion.v >= ProtocolVersion.TLS10.v) {
 821                     m1 = new CertificateMsg(new X509Certificate [0]);
 822                 } else {
 823                     warningSE(Alerts.alert_no_certificate);
 824                 }
 825             }
 826 
 827             //
 828             // At last ... send any client certificate chain.
 829             //
 830             if (m1 != null) {
 831                 if (debug != null && Debug.isOn("handshake")) {
 832                     m1.print(System.out);
 833                 }
 834                 m1.write(output);
 835             }
 836         }
 837 
 838         /*
 839          * SECOND ... send the client key exchange message.  The
 840          * procedure used is a function of the cipher suite selected;
 841          * one is always needed.
 842          */
 843         HandshakeMessage m2;
 844 
 845         switch (keyExchange) {
 846 
 847         case K_RSA:
 848         case K_RSA_EXPORT:
 849             if (serverKey == null) {
 850                 throw new SSLProtocolException
 851                         ("Server did not send certificate message");
 852             }
 853 
 854             if (!(serverKey instanceof RSAPublicKey)) {
 855                 throw new SSLProtocolException
 856                         ("Server certificate does not include an RSA key");
 857             }
 858 
 859             /*
 860              * For RSA key exchange, we randomly generate a new
 861              * pre-master secret and encrypt it with the server's
 862              * public key.  Then we save that pre-master secret
 863              * so that we can calculate the keying data later;
 864              * it's a performance speedup not to do that until
 865              * the client's waiting for the server response, but
 866              * more of a speedup for the D-H case.
 867              *
 868              * If the RSA_EXPORT scheme is active, when the public
 869              * key in the server certificate is less than or equal
 870              * to 512 bits in length, use the cert's public key,
 871              * otherwise, the ephemeral one.
 872              */
 873             PublicKey key;
 874             if (keyExchange == K_RSA) {
 875                 key = serverKey;
 876             } else {    // K_RSA_EXPORT
 877                 if (JsseJce.getRSAKeyLength(serverKey) <= 512) {
 878                     // extraneous ephemeralServerKey check done
 879                     // above in processMessage()
 880                     key = serverKey;
 881                 } else {
 882                     if (ephemeralServerKey == null) {
 883                         throw new SSLProtocolException("Server did not send" +
 884                             " a RSA_EXPORT Server Key Exchange message");
 885                     }
 886                     key = ephemeralServerKey;
 887                 }
 888             }
 889 
 890             m2 = new RSAClientKeyExchange(protocolVersion, maxProtocolVersion,
 891                                 sslContext.getSecureRandom(), key);
 892             break;
 893         case K_DH_RSA:
 894         case K_DH_DSS:
 895             /*
 896              * For DH Key exchange, we only need to make sure the server
 897              * knows our public key, so we calculate the same pre-master
 898              * secret.
 899              *
 900              * For certs that had DH keys in them, we send an empty
 901              * handshake message (no key) ... we flag this case by
 902              * passing a null "dhPublic" value.
 903              *
 904              * Otherwise we send ephemeral DH keys, unsigned.
 905              */
 906             // if (useDH_RSA || useDH_DSS)
 907             m2 = new DHClientKeyExchange();
 908             break;
 909         case K_DHE_RSA:
 910         case K_DHE_DSS:
 911         case K_DH_ANON:
 912             if (dh == null) {
 913                 throw new SSLProtocolException
 914                     ("Server did not send a DH Server Key Exchange message");
 915             }
 916             m2 = new DHClientKeyExchange(dh.getPublicKey());
 917             break;
 918         case K_ECDHE_RSA:
 919         case K_ECDHE_ECDSA:
 920         case K_ECDH_ANON:
 921             if (ecdh == null) {
 922                 throw new SSLProtocolException
 923                     ("Server did not send a ECDH Server Key Exchange message");
 924             }
 925             m2 = new ECDHClientKeyExchange(ecdh.getPublicKey());
 926             break;
 927         case K_ECDH_RSA:
 928         case K_ECDH_ECDSA:
 929             if (serverKey == null) {
 930                 throw new SSLProtocolException
 931                         ("Server did not send certificate message");
 932             }
 933             if (serverKey instanceof ECPublicKey == false) {
 934                 throw new SSLProtocolException
 935                         ("Server certificate does not include an EC key");
 936             }
 937             ECParameterSpec params = ((ECPublicKey)serverKey).getParams();
 938             ecdh = new ECDHCrypt(params, sslContext.getSecureRandom());
 939             m2 = new ECDHClientKeyExchange(ecdh.getPublicKey());
 940             break;
 941         case K_KRB5:
 942         case K_KRB5_EXPORT:
 943             String sniHostname = null;
 944             for (SNIServerName serverName : requestedServerNames) {
 945                 if (serverName instanceof SNIHostName) {
 946                     sniHostname = ((SNIHostName) serverName).getAsciiName();
 947                     break;
 948                 }
 949             }
 950 
 951             KerberosClientKeyExchange kerberosMsg = null;
 952             if (sniHostname != null) {
 953                 // use first requested SNI hostname
 954                 try {
 955                     kerberosMsg = new KerberosClientKeyExchange(
 956                         sniHostname, getAccSE(), protocolVersion,
 957                         sslContext.getSecureRandom());
 958                 } catch(IOException e) {
 959                     if (serverNamesAccepted) {
 960                         // server accepted requested SNI hostname,
 961                         // so it must be used
 962                         throw e;
 963                     }
 964                     // fallback to using hostname
 965                     if (debug != null && Debug.isOn("handshake")) {
 966                         System.out.println(
 967                             "Warning, cannot use Server Name Indication: "
 968                                 + e.getMessage());
 969                     }
 970                 }
 971             }
 972 
 973             if (kerberosMsg == null) {
 974                 String hostname = getHostSE();
 975                 if (hostname == null) {
 976                     throw new IOException("Hostname is required" +
 977                         " to use Kerberos cipher suites");
 978                 }
 979                 kerberosMsg = new KerberosClientKeyExchange(
 980                      hostname, getAccSE(), protocolVersion,
 981                      sslContext.getSecureRandom());
 982             }
 983 
 984             // Record the principals involved in exchange
 985             session.setPeerPrincipal(kerberosMsg.getPeerPrincipal());
 986             session.setLocalPrincipal(kerberosMsg.getLocalPrincipal());
 987             m2 = kerberosMsg;
 988             break;
 989         default:
 990             // somethings very wrong
 991             throw new RuntimeException
 992                                 ("Unsupported key exchange: " + keyExchange);
 993         }
 994         if (debug != null && Debug.isOn("handshake")) {
 995             m2.print(System.out);
 996         }
 997         m2.write(output);
 998 
 999 
1000         /*
1001          * THIRD, send a "change_cipher_spec" record followed by the
1002          * "Finished" message.  We flush the messages we've queued up, to
1003          * get concurrency between client and server.  The concurrency is
1004          * useful as we calculate the master secret, which is needed both
1005          * to compute the "Finished" message, and to compute the keys used
1006          * to protect all records following the change_cipher_spec.
1007          */
1008 
1009         output.doHashes();
1010         output.flush();
1011 
1012         /*
1013          * We deferred calculating the master secret and this connection's
1014          * keying data; we do it now.  Deferring this calculation is good
1015          * from a performance point of view, since it lets us do it during
1016          * some time that network delays and the server's own calculations
1017          * would otherwise cause to be "dead" in the critical path.
1018          */
1019         SecretKey preMasterSecret;
1020         switch (keyExchange) {
1021         case K_RSA:
1022         case K_RSA_EXPORT:
1023             preMasterSecret = ((RSAClientKeyExchange)m2).preMaster;
1024             break;
1025         case K_KRB5:
1026         case K_KRB5_EXPORT:
1027             byte[] secretBytes =
1028                 ((KerberosClientKeyExchange)m2).getUnencryptedPreMasterSecret();
1029             preMasterSecret = new SecretKeySpec(secretBytes,
1030                 "TlsPremasterSecret");
1031             break;
1032         case K_DHE_RSA:
1033         case K_DHE_DSS:
1034         case K_DH_ANON:
1035             preMasterSecret = dh.getAgreedSecret(serverDH, true);
1036             break;
1037         case K_ECDHE_RSA:
1038         case K_ECDHE_ECDSA:
1039         case K_ECDH_ANON:
1040             preMasterSecret = ecdh.getAgreedSecret(ephemeralServerKey);
1041             break;
1042         case K_ECDH_RSA:
1043         case K_ECDH_ECDSA:
1044             preMasterSecret = ecdh.getAgreedSecret(serverKey);
1045             break;
1046         default:
1047             throw new IOException("Internal error: unknown key exchange "
1048                 + keyExchange);
1049         }
1050 
1051         calculateKeys(preMasterSecret, null);
1052 
1053         /*
1054          * FOURTH, if we sent a Certificate, we need to send a signed
1055          * CertificateVerify (unless the key in the client's certificate
1056          * was a Diffie-Hellman key).).
1057          *
1058          * This uses a hash of the previous handshake messages ... either
1059          * a nonfinal one (if the particular implementation supports it)
1060          * or else using the third element in the arrays of hashes being
1061          * computed.
1062          */
1063         if (signingKey != null) {
1064             CertificateVerify m3;
1065             try {
1066                 SignatureAndHashAlgorithm preferableSignatureAlgorithm = null;
1067                 if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
1068                     preferableSignatureAlgorithm =
1069                         SignatureAndHashAlgorithm.getPreferableAlgorithm(
1070                             peerSupportedSignAlgs, signingKey.getAlgorithm(),
1071                             signingKey);
1072 
1073                     if (preferableSignatureAlgorithm == null) {
1074                         throw new SSLHandshakeException(
1075                             "No supported signature algorithm");
1076                     }
1077 
1078                     String hashAlg =
1079                         SignatureAndHashAlgorithm.getHashAlgorithmName(
1080                                 preferableSignatureAlgorithm);
1081                     if (hashAlg == null || hashAlg.length() == 0) {
1082                         throw new SSLHandshakeException(
1083                                 "No supported hash algorithm");
1084                     }
1085                 }
1086 
1087                 m3 = new CertificateVerify(protocolVersion, handshakeHash,
1088                     signingKey, session.getMasterSecret(),
1089                     sslContext.getSecureRandom(),
1090                     preferableSignatureAlgorithm);
1091             } catch (GeneralSecurityException e) {
1092                 fatalSE(Alerts.alert_handshake_failure,
1093                     "Error signing certificate verify", e);
1094                 // NOTREACHED, make compiler happy
1095                 m3 = null;
1096             }
1097             if (debug != null && Debug.isOn("handshake")) {
1098                 m3.print(System.out);
1099             }
1100             m3.write(output);
1101             output.doHashes();
1102         }
1103 
1104         /*
1105          * OK, that's that!
1106          */
1107         sendChangeCipherAndFinish(false);
1108     }
1109 
1110 
1111     /*
1112      * "Finished" is the last handshake message sent.  If we got this
1113      * far, the MAC has been validated post-decryption.  We validate
1114      * the two hashes here as an additional sanity check, protecting
1115      * the handshake against various active attacks.
1116      */
1117     private void serverFinished(Finished mesg) throws IOException {
1118         if (debug != null && Debug.isOn("handshake")) {
1119             mesg.print(System.out);
1120         }
1121 
1122         boolean verified = mesg.verify(handshakeHash, Finished.SERVER,
1123             session.getMasterSecret());
1124 
1125         if (!verified) {
1126             fatalSE(Alerts.alert_illegal_parameter,
1127                        "server 'finished' message doesn't verify");
1128             // NOTREACHED
1129         }
1130 
1131         /*
1132          * save server verify data for secure renegotiation
1133          */
1134         if (secureRenegotiation) {
1135             serverVerifyData = mesg.getVerifyData();
1136         }
1137 
1138         /*
1139          * Reset the handshake state if this is not an initial handshake.
1140          */
1141         if (!isInitialHandshake) {
1142             session.setAsSessionResumption(false);
1143         }
1144 
1145         /*
1146          * OK, it verified.  If we're doing the fast handshake, add that
1147          * "Finished" message to the hash of handshake messages, then send
1148          * our own change_cipher_spec and Finished message for the server
1149          * to verify in turn.  These are the last handshake messages.
1150          *
1151          * In any case, update the session cache.  We're done handshaking,
1152          * so there are no threats any more associated with partially
1153          * completed handshakes.
1154          */
1155         if (resumingSession) {
1156             input.digestNow();
1157             sendChangeCipherAndFinish(true);
1158         }
1159         session.setLastAccessedTime(System.currentTimeMillis());
1160 
1161         if (!resumingSession) {
1162             if (session.isRejoinable()) {
1163                 ((SSLSessionContextImpl) sslContext
1164                         .engineGetClientSessionContext())
1165                         .put(session);
1166                 if (debug != null && Debug.isOn("session")) {
1167                     System.out.println("%% Cached client session: " + session);
1168                 }
1169             } else if (debug != null && Debug.isOn("session")) {
1170                 System.out.println(
1171                     "%% Didn't cache non-resumable client session: "
1172                     + session);
1173             }
1174         }
1175     }
1176 
1177 
1178     /*
1179      * Send my change-cipher-spec and Finished message ... done as the
1180      * last handshake act in either the short or long sequences.  In
1181      * the short one, we've already seen the server's Finished; in the
1182      * long one, we wait for it now.
1183      */
1184     private void sendChangeCipherAndFinish(boolean finishedTag)
1185             throws IOException {
1186         Finished mesg = new Finished(protocolVersion, handshakeHash,
1187             Finished.CLIENT, session.getMasterSecret(), cipherSuite);
1188 
1189         /*
1190          * Send the change_cipher_spec message, then the Finished message
1191          * which we just calculated (and protected using the keys we just
1192          * calculated).  Server responds with its Finished message, except
1193          * in the "fast handshake" (resume session) case.
1194          */
1195         sendChangeCipherSpec(mesg, finishedTag);
1196 
1197         /*
1198          * save client verify data for secure renegotiation
1199          */
1200         if (secureRenegotiation) {
1201             clientVerifyData = mesg.getVerifyData();
1202         }
1203 
1204         /*
1205          * Update state machine so server MUST send 'finished' next.
1206          * (In "long" handshake case; in short case, we're responding
1207          * to its message.)
1208          */
1209         state = HandshakeMessage.ht_finished - 1;
1210     }
1211 
1212 
1213     /*
1214      * Returns a ClientHello message to kickstart renegotiations
1215      */
1216     @Override
1217     HandshakeMessage getKickstartMessage() throws SSLException {
1218         // session ID of the ClientHello message
1219         SessionId sessionId = SSLSessionImpl.nullSession.getSessionId();
1220 
1221         // a list of cipher suites sent by the client
1222         CipherSuiteList cipherSuites = getActiveCipherSuites();
1223 
1224         // set the max protocol version this client is supporting.
1225         maxProtocolVersion = protocolVersion;
1226 
1227         //
1228         // Try to resume an existing session.  This might be mandatory,
1229         // given certain API options.
1230         //
1231         session = ((SSLSessionContextImpl)sslContext
1232                         .engineGetClientSessionContext())
1233                         .get(getHostSE(), getPortSE());
1234         if (debug != null && Debug.isOn("session")) {
1235             if (session != null) {
1236                 System.out.println("%% Client cached "
1237                     + session
1238                     + (session.isRejoinable() ? "" : " (not rejoinable)"));
1239             } else {
1240                 System.out.println("%% No cached client session");
1241             }
1242         }
1243         if (session != null) {
1244             // If unsafe server certificate change is not allowed, reserve
1245             // current server certificates if the previous handshake is a
1246             // session-resumption abbreviated initial handshake.
1247             if (!allowUnsafeServerCertChange && session.isSessionResumption()) {
1248                 try {
1249                     // If existing, peer certificate chain cannot be null.
1250                     reservedServerCerts =
1251                         (X509Certificate[])session.getPeerCertificates();
1252                 } catch (SSLPeerUnverifiedException puve) {
1253                     // Maybe not certificate-based, ignore the exception.
1254                 }
1255             }
1256 
1257             if (!session.isRejoinable()) {
1258                 session = null;
1259             }
1260         }
1261 
1262         if (session != null) {
1263             CipherSuite sessionSuite = session.getSuite();
1264             ProtocolVersion sessionVersion = session.getProtocolVersion();
1265             if (isNegotiable(sessionSuite) == false) {
1266                 if (debug != null && Debug.isOn("session")) {
1267                     System.out.println("%% can't resume, unavailable cipher");
1268                 }
1269                 session = null;
1270             }
1271 
1272             if ((session != null) && !isNegotiable(sessionVersion)) {
1273                 if (debug != null && Debug.isOn("session")) {
1274                     System.out.println("%% can't resume, protocol disabled");
1275                 }
1276                 session = null;
1277             }
1278 
1279             if (session != null) {
1280                 if (debug != null) {
1281                     if (Debug.isOn("handshake") || Debug.isOn("session")) {
1282                         System.out.println("%% Try resuming " + session
1283                             + " from port " + getLocalPortSE());
1284                     }
1285                 }
1286 
1287                 sessionId = session.getSessionId();
1288                 maxProtocolVersion = sessionVersion;
1289 
1290                 // Update SSL version number in underlying SSL socket and
1291                 // handshake output stream, so that the output records (at the
1292                 // record layer) have the correct version
1293                 setVersion(sessionVersion);
1294             }
1295 
1296             /*
1297              * Force use of the previous session ciphersuite, and
1298              * add the SCSV if enabled.
1299              */
1300             if (!enableNewSession) {
1301                 if (session == null) {
1302                     throw new SSLHandshakeException(
1303                         "Can't reuse existing SSL client session");
1304                 }
1305 
1306                 Collection<CipherSuite> cipherList = new ArrayList<>(2);
1307                 cipherList.add(sessionSuite);
1308                 if (!secureRenegotiation &&
1309                         cipherSuites.contains(CipherSuite.C_SCSV)) {
1310                     cipherList.add(CipherSuite.C_SCSV);
1311                 }   // otherwise, renegotiation_info extension will be used
1312 
1313                 cipherSuites = new CipherSuiteList(cipherList);
1314             }
1315         }
1316 
1317         if (session == null && !enableNewSession) {
1318             throw new SSLHandshakeException("No existing session to resume");
1319         }
1320 
1321         // exclude SCSV for secure renegotiation
1322         if (secureRenegotiation && cipherSuites.contains(CipherSuite.C_SCSV)) {
1323             Collection<CipherSuite> cipherList =
1324                         new ArrayList<>(cipherSuites.size() - 1);
1325             for (CipherSuite suite : cipherSuites.collection()) {
1326                 if (suite != CipherSuite.C_SCSV) {
1327                     cipherList.add(suite);
1328                 }
1329             }
1330 
1331             cipherSuites = new CipherSuiteList(cipherList);
1332         }
1333 
1334         // make sure there is a negotiable cipher suite.
1335         boolean negotiable = false;
1336         for (CipherSuite suite : cipherSuites.collection()) {
1337             if (isNegotiable(suite)) {
1338                 negotiable = true;
1339                 break;
1340             }
1341         }
1342 
1343         if (!negotiable) {
1344             throw new SSLHandshakeException("No negotiable cipher suite");
1345         }
1346 
1347         // Not a TLS1.2+ handshake
1348         // For SSLv2Hello, HandshakeHash.reset() will be called, so we
1349         // cannot call HandshakeHash.protocolDetermined() here. As it does
1350         // not follow the spec that HandshakeHash.reset() can be only be
1351         // called before protocolDetermined.
1352         // if (maxProtocolVersion.v < ProtocolVersion.TLS12.v) {
1353         //     handshakeHash.protocolDetermined(maxProtocolVersion);
1354         // }
1355 
1356         // create the ClientHello message
1357         ClientHello clientHelloMessage = new ClientHello(
1358                 sslContext.getSecureRandom(), maxProtocolVersion,
1359                 sessionId, cipherSuites);
1360 
1361         // add signature_algorithm extension
1362         if (maxProtocolVersion.v >= ProtocolVersion.TLS12.v) {
1363             // we will always send the signature_algorithm extension
1364             Collection<SignatureAndHashAlgorithm> localSignAlgs =
1365                                                 getLocalSupportedSignAlgs();
1366             if (localSignAlgs.isEmpty()) {
1367                 throw new SSLHandshakeException(
1368                             "No supported signature algorithm");
1369             }
1370 
1371             clientHelloMessage.addSignatureAlgorithmsExtension(localSignAlgs);
1372         }
1373 
1374         // add server_name extension
1375         if (enableSNIExtension) {
1376             if (session != null) {
1377                 requestedServerNames = session.getRequestedServerNames();
1378             } else {
1379                 requestedServerNames = serverNames;
1380             }
1381 
1382             if (!requestedServerNames.isEmpty()) {
1383                 clientHelloMessage.addSNIExtension(requestedServerNames);
1384             }
1385         }
1386 
1387         // reset the client random cookie
1388         clnt_random = clientHelloMessage.clnt_random;
1389 
1390         /*
1391          * need to set the renegotiation_info extension for:
1392          * 1: secure renegotiation
1393          * 2: initial handshake and no SCSV in the ClientHello
1394          * 3: insecure renegotiation and no SCSV in the ClientHello
1395          */
1396         if (secureRenegotiation ||
1397                 !cipherSuites.contains(CipherSuite.C_SCSV)) {
1398             clientHelloMessage.addRenegotiationInfoExtension(clientVerifyData);
1399         }
1400 
1401         return clientHelloMessage;
1402     }
1403 
1404     /*
1405      * Fault detected during handshake.
1406      */
1407     @Override
1408     void handshakeAlert(byte description) throws SSLProtocolException {
1409         String message = Alerts.alertDescription(description);
1410 
1411         if (debug != null && Debug.isOn("handshake")) {
1412             System.out.println("SSL - handshake alert: " + message);
1413         }
1414         throw new SSLProtocolException("handshake alert:  " + message);
1415     }
1416 
1417     /*
1418      * Unless we are using an anonymous ciphersuite, the server always
1419      * sends a certificate message (for the CipherSuites we currently
1420      * support). The trust manager verifies the chain for us.
1421      */
1422     private void serverCertificate(CertificateMsg mesg) throws IOException {
1423         if (debug != null && Debug.isOn("handshake")) {
1424             mesg.print(System.out);
1425         }
1426         X509Certificate[] peerCerts = mesg.getCertificateChain();
1427         if (peerCerts.length == 0) {
1428             fatalSE(Alerts.alert_bad_certificate, "empty certificate chain");
1429         }
1430 
1431         // Allow server certificate change in client side during renegotiation
1432         // after a session-resumption abbreviated initial handshake?
1433         //
1434         // DO NOT need to check allowUnsafeServerCertChange here. We only
1435         // reserve server certificates when allowUnsafeServerCertChange is
1436         // flase.
1437         if (reservedServerCerts != null) {
1438             // It is not necessary to check the certificate update if endpoint
1439             // identification is enabled.
1440             String identityAlg = getEndpointIdentificationAlgorithmSE();
1441             if ((identityAlg == null || identityAlg.length() == 0) &&
1442                 !isIdentityEquivalent(peerCerts[0], reservedServerCerts[0])) {
1443 
1444                 fatalSE(Alerts.alert_bad_certificate,
1445                         "server certificate change is restricted " +
1446                         "during renegotiation");
1447             }
1448         }
1449 
1450         // ask the trust manager to verify the chain
1451         X509TrustManager tm = sslContext.getX509TrustManager();
1452         try {
1453             // find out the key exchange algorithm used
1454             // use "RSA" for non-ephemeral "RSA_EXPORT"
1455             String keyExchangeString;
1456             if (keyExchange == K_RSA_EXPORT && !serverKeyExchangeReceived) {
1457                 keyExchangeString = K_RSA.name;
1458             } else {
1459                 keyExchangeString = keyExchange.name;
1460             }
1461 
1462             if (tm instanceof X509ExtendedTrustManager) {
1463                 if (conn != null) {
1464                     ((X509ExtendedTrustManager)tm).checkServerTrusted(
1465                         peerCerts.clone(),
1466                         keyExchangeString,
1467                         conn);
1468                 } else {
1469                     ((X509ExtendedTrustManager)tm).checkServerTrusted(
1470                         peerCerts.clone(),
1471                         keyExchangeString,
1472                         engine);
1473                 }
1474             } else {
1475                 // Unlikely to happen, because we have wrapped the old
1476                 // X509TrustManager with the new X509ExtendedTrustManager.
1477                 throw new CertificateException(
1478                     "Improper X509TrustManager implementation");
1479             }
1480         } catch (CertificateException e) {
1481             // This will throw an exception, so include the original error.
1482             fatalSE(Alerts.alert_certificate_unknown, e);
1483         }
1484         session.setPeerCertificates(peerCerts);
1485     }
1486 
1487     /*
1488      * Whether the certificates can represent the same identity?
1489      *
1490      * The certificates can be used to represent the same identity:
1491      *     1. If the subject alternative names of IP address are present in
1492      *        both certificates, they should be identical; otherwise,
1493      *     2. if the subject alternative names of DNS name are present in
1494      *        both certificates, they should be identical; otherwise,
1495      *     3. if the subject fields are present in both certificates, the
1496      *        certificate subjects and issuers should be identical.
1497      */
1498     private static boolean isIdentityEquivalent(X509Certificate thisCert,
1499             X509Certificate prevCert) {
1500         if (thisCert.equals(prevCert)) {
1501             return true;
1502         }
1503 
1504         // check subject alternative names
1505         Collection<List<?>> thisSubjectAltNames = null;
1506         try {
1507             thisSubjectAltNames = thisCert.getSubjectAlternativeNames();
1508         } catch (CertificateParsingException cpe) {
1509             if (debug != null && Debug.isOn("handshake")) {
1510                 System.out.println(
1511                         "Attempt to obtain subjectAltNames extension failed!");
1512             }
1513         }
1514 
1515         Collection<List<?>> prevSubjectAltNames = null;
1516         try {
1517             prevSubjectAltNames = prevCert.getSubjectAlternativeNames();
1518         } catch (CertificateParsingException cpe) {
1519             if (debug != null && Debug.isOn("handshake")) {
1520                 System.out.println(
1521                         "Attempt to obtain subjectAltNames extension failed!");
1522             }
1523         }
1524 
1525         if ((thisSubjectAltNames != null) && (prevSubjectAltNames != null)) {
1526             // check the iPAddress field in subjectAltName extension
1527             Collection<String> thisSubAltIPAddrs =
1528                         getSubjectAltNames(thisSubjectAltNames, ALTNAME_IP);
1529             Collection<String> prevSubAltIPAddrs =
1530                         getSubjectAltNames(prevSubjectAltNames, ALTNAME_IP);
1531             if ((thisSubAltIPAddrs != null) && (prevSubAltIPAddrs != null) &&
1532                 (isEquivalent(thisSubAltIPAddrs, prevSubAltIPAddrs))) {
1533 
1534                 return true;
1535             }
1536 
1537             // check the dNSName field in subjectAltName extension
1538             Collection<String> thisSubAltDnsNames =
1539                         getSubjectAltNames(thisSubjectAltNames, ALTNAME_DNS);
1540             Collection<String> prevSubAltDnsNames =
1541                         getSubjectAltNames(prevSubjectAltNames, ALTNAME_DNS);
1542             if ((thisSubAltDnsNames != null) && (prevSubAltDnsNames != null) &&
1543                 (isEquivalent(thisSubAltDnsNames, prevSubAltDnsNames))) {
1544 
1545                 return true;
1546             }
1547         }
1548 
1549         // check the certificate subject and issuer
1550         X500Principal thisSubject = thisCert.getSubjectX500Principal();
1551         X500Principal prevSubject = prevCert.getSubjectX500Principal();
1552         X500Principal thisIssuer = thisCert.getIssuerX500Principal();
1553         X500Principal prevIssuer = prevCert.getIssuerX500Principal();
1554         if (!thisSubject.getName().isEmpty() &&
1555                 !prevSubject.getName().isEmpty() &&
1556                 thisSubject.equals(prevSubject) &&
1557                 thisIssuer.equals(prevIssuer)) {
1558             return true;
1559         }
1560 
1561         return false;
1562     }
1563 
1564     /*
1565      * Returns the subject alternative name of the specified type in the
1566      * subjectAltNames extension of a certificate.
1567      *
1568      * Note that only those subjectAltName types that use String data
1569      * should be passed into this function.
1570      */
1571     private static Collection<String> getSubjectAltNames(
1572             Collection<List<?>> subjectAltNames, int type) {
1573 
1574         HashSet<String> subAltDnsNames = null;
1575         for (List<?> subjectAltName : subjectAltNames) {
1576             int subjectAltNameType = (Integer)subjectAltName.get(0);
1577             if (subjectAltNameType == type) {
1578                 String subAltDnsName = (String)subjectAltName.get(1);
1579                 if ((subAltDnsName != null) && !subAltDnsName.isEmpty()) {
1580                     if (subAltDnsNames == null) {
1581                         subAltDnsNames =
1582                                 new HashSet<>(subjectAltNames.size());
1583                     }
1584                     subAltDnsNames.add(subAltDnsName);
1585                 }
1586             }
1587         }
1588 
1589         return subAltDnsNames;
1590     }
1591 
1592     private static boolean isEquivalent(Collection<String> thisSubAltNames,
1593             Collection<String> prevSubAltNames) {
1594 
1595         for (String thisSubAltName : thisSubAltNames) {
1596             for (String prevSubAltName : prevSubAltNames) {
1597                 // Only allow the exactly match.  Check no wildcard character.
1598                 if (thisSubAltName.equalsIgnoreCase(prevSubAltName)) {
1599                     return true;
1600                 }
1601             }
1602         }
1603 
1604         return false;
1605     }
1606 }