< prev index next >

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

Print this page


   1 /*
   2  * Copyright (c) 1996, 2017, 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 java.security.cert.CertPathValidatorException;
  41 import java.security.cert.CertPathValidatorException.Reason;
  42 import java.security.cert.CertPathValidatorException.BasicReason;
  43 import javax.security.auth.x500.X500Principal;
  44 
  45 import javax.crypto.SecretKey;
  46 
  47 import javax.net.ssl.*;
  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 static final int ALTNAME_DNS = 2;
  64     private static final 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     private boolean staplingActive = false;
  85     private X509Certificate[] deferredCerts;
  86 
  87     /*
  88      * The RSA PreMasterSecret needs to know the version of
  89      * ClientHello that was used on this handshake.  This represents
  90      * the "max version" this client is supporting.  In the
  91      * case of an initial handshake, it's the max version enabled,
  92      * but in the case of a resumption attempt, it's the version
  93      * of the session we're trying to resume.
  94      */
  95     private ProtocolVersion maxProtocolVersion;
  96 
  97     // To switch off the SNI extension.
  98     private static final boolean enableSNIExtension =
  99             Debug.getBooleanProperty("jsse.enableSNIExtension", true);
 100 

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








  29 import java.security.cert.X509Certificate;













































  30 
  31 import sun.security.ssl.ClientHello.ClientHelloMessage;















  32 
  33 class ClientHandshakeContext extends HandshakeContext {
  34     /*
  35      * Allow unsafe server certificate change?
  36      *
  37      * Server certificate change during SSL/TLS renegotiation may be considered
  38      * unsafe, as described in the Triple Handshake attacks:
  39      *
  40      *     https://secure-resumption.com/tlsauth.pdf
  41      *
  42      * Endpoint identification (See
  43      * SSLParameters.getEndpointIdentificationAlgorithm()) is a pretty nice
  44      * guarantee that the server certificate change in renegotiation is legal.
  45      * However, endpoing identification is only enabled for HTTPS and LDAP
  46      * over SSL/TLS by default.  It is not enough to protect SSL/TLS
  47      * connections other than HTTPS and LDAP.
  48      *
  49      * The renegotiation indication extension (See RFC 5746) is a pretty
  50      * strong guarantee that the endpoints on both client and server sides
  51      * are identical on the same connection.  However, the Triple Handshake
  52      * attacks can bypass this guarantee if there is a session-resumption
  53      * handshake between the initial full handshake and the renegotiation
  54      * full handshake.
  55      *
  56      * Server certificate change may be unsafe and should be restricted if
  57      * endpoint identification is not enabled and the previous handshake is
  58      * a session-resumption abbreviated initial handshake, unless the
  59      * identities represented by both certificates can be regraded as the
  60      * same (See isIdentityEquivalent()).
  61      *
  62      * Considering the compatibility impact and the actual requirements to
  63      * support server certificate change in practice, the system property,
  64      * jdk.tls.allowUnsafeServerCertChange, is used to define whether unsafe
  65      * server certificate change in renegotiation is allowed or not.  The
  66      * default value of the system property is "false".  To mitigate the
  67      * compactibility impact, applications may want to set the system
  68      * property to "true" at their own risk.
  69      *
  70      * If the value of the system property is "false", server certificate
  71      * change in renegotiation after a session-resumption abbreviated initial
  72      * handshake is restricted (See isIdentityEquivalent()).
  73      *
  74      * If the system property is set to "true" explicitly, the restriction on
  75      * server certificate change in renegotiation is disabled.
  76      */
  77     static final boolean allowUnsafeServerCertChange =
  78             Utilities.getBooleanProperty(
  79                     "jdk.tls.allowUnsafeServerCertChange", false);




















  80 
  81     /*
  82      * the reserved server certificate chain in previous handshaking
  83      *
  84      * The server certificate chain is only reserved if the previous
  85      * handshake is a session-resumption abbreviated initial handshake.
  86      */
  87     X509Certificate[] reservedServerCerts = null;









  88 
  89     X509Certificate[] deferredCerts;



  90 
  91     ClientHelloMessage initialClientHelloMsg = null;





  92 
  93     ClientHandshakeContext(SSLContextImpl sslContext,
  94             TransportContext conContext) throws IOException {
  95         super(sslContext, conContext);
  96     }
  97 










  98     @Override
  99     void kickstart() throws IOException {
 100         if (kickstartMessageDelivered) {















































































































































































































































































































































































































































































































































































































 101             return;
 102         }
 103 
 104         SSLHandshake.kickstart(this);
 105         kickstartMessageDelivered = true;







































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































 106     }
 107 }

< prev index next >