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