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