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