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

Print this page




 124      * same (See isIdentityEquivalent()).
 125      *
 126      * Considering the compatibility impact and the actual requirements to
 127      * support server certificate change in practice, the system property,
 128      * jdk.tls.allowUnsafeServerCertChange, is used to define whether unsafe
 129      * server certificate change in renegotiation is allowed or not.  The
 130      * default value of the system property is "false".  To mitigate the
 131      * compactibility impact, applications may want to set the system
 132      * property to "true" at their own risk.
 133      *
 134      * If the value of the system property is "false", server certificate
 135      * change in renegotiation after a session-resumption abbreviated initial
 136      * handshake is restricted (See isIdentityEquivalent()).
 137      *
 138      * If the system property is set to "true" explicitly, the restriction on
 139      * server certificate change in renegotiation is disabled.
 140      */
 141     private final static boolean allowUnsafeServerCertChange =
 142         Debug.getBooleanProperty("jdk.tls.allowUnsafeServerCertChange", false);
 143 




 144     private List<SNIServerName> requestedServerNames =
 145             Collections.<SNIServerName>emptyList();
 146 



 147     private boolean serverNamesAccepted = false;
 148 


 149     /*
 150      * the reserved server certificate chain in previous handshaking
 151      *
 152      * The server certificate chain is only reserved if the previous
 153      * handshake is a session-resumption abbreviated initial handshake.
 154      */
 155     private X509Certificate[] reservedServerCerts = null;
 156 
 157     /*
 158      * Constructors
 159      */
 160     ClientHandshaker(SSLSocketImpl socket, SSLContextImpl context,
 161             ProtocolList enabledProtocols,
 162             ProtocolVersion activeProtocolVersion,
 163             boolean isInitialHandshake, boolean secureRenegotiation,
 164             byte[] clientVerifyData, byte[] serverVerifyData) {
 165 
 166         super(socket, context, enabledProtocols, true, true,
 167             activeProtocolVersion, isInitialHandshake, secureRenegotiation,
 168             clientVerifyData, serverVerifyData);
 169     }
 170 
 171     ClientHandshaker(SSLEngineImpl engine, SSLContextImpl context,
 172             ProtocolList enabledProtocols,
 173             ProtocolVersion activeProtocolVersion,
 174             boolean isInitialHandshake, boolean secureRenegotiation,
 175             byte[] clientVerifyData, byte[] serverVerifyData) {

 176 
 177         super(engine, context, enabledProtocols, true, true,
 178             activeProtocolVersion, isInitialHandshake, secureRenegotiation,
 179             clientVerifyData, serverVerifyData);
 180     }
 181 
 182     /*
 183      * This routine handles all the client side handshake messages, one at
 184      * a time.  Given the message type (and in some cases the pending cipher
 185      * spec) it parses the type-specific message.  Then it calls a function
 186      * that handles that specific message.
 187      *
 188      * It updates the state machine (need to verify it) as each message
 189      * is processed, and writes responses as needed using the connection
 190      * in the constructor.
 191      */
 192     @Override
 193     void processMessage(byte type, int messageLen) throws IOException {
 194         if (state >= type
 195                 && (type != HandshakeMessage.ht_hello_request)) {
 196             throw new SSLProtocolException(
 197                     "Handshake message sequence violation, " + type);
 198         }
 199 
 200         switch (type) {
 201         case HandshakeMessage.ht_hello_request:
 202             this.serverHelloRequest(new HelloRequest(input));


 203             break;
 204 












 205         case HandshakeMessage.ht_server_hello:
 206             this.serverHello(new ServerHello(input, messageLen));





 207             break;
 208 
 209         case HandshakeMessage.ht_certificate:
 210             if (keyExchange == K_DH_ANON || keyExchange == K_ECDH_ANON
 211                     || keyExchange == K_KRB5 || keyExchange == K_KRB5_EXPORT) {
 212                 fatalSE(Alerts.alert_unexpected_message,
 213                     "unexpected server cert chain");
 214                 // NOTREACHED
 215             }
 216             this.serverCertificate(new CertificateMsg(input));


 217             serverKey =
 218                 session.getPeerCertificates()[0].getPublicKey();
 219             break;
 220 
 221         case HandshakeMessage.ht_server_key_exchange:
 222             serverKeyExchangeReceived = true;
 223             switch (keyExchange) {
 224             case K_RSA_EXPORT:
 225                 /**
 226                  * The server key exchange message is sent by the server only
 227                  * when the server certificate message does not contain the
 228                  * proper amount of data to allow the client to exchange a
 229                  * premaster secret, such as when RSA_EXPORT is used and the
 230                  * public key in the server certificate is longer than 512 bits.
 231                  */
 232                 if (serverKey == null) {
 233                     throw new SSLProtocolException
 234                         ("Server did not send certificate message");
 235                 }
 236 
 237                 if (!(serverKey instanceof RSAPublicKey)) {
 238                     throw new SSLProtocolException("Protocol violation:" +
 239                         " the certificate type must be appropriate for the" +
 240                         " selected cipher suite's key exchange algorithm");
 241                 }
 242 
 243                 if (JsseJce.getRSAKeyLength(serverKey) <= 512) {
 244                     throw new SSLProtocolException("Protocol violation:" +
 245                         " server sent a server key exchange message for" +
 246                         " key exchange " + keyExchange +
 247                         " when the public key in the server certificate" +
 248                         " is less than or equal to 512 bits in length");
 249                 }
 250 
 251                 try {
 252                     this.serverKeyExchange(new RSA_ServerKeyExchange(input));



 253                 } catch (GeneralSecurityException e) {
 254                     throwSSLException("Server key", e);
 255                 }
 256                 break;
 257             case K_DH_ANON:
 258                 try {
 259                     this.serverKeyExchange(new DH_ServerKeyExchange(
 260                                                 input, protocolVersion));


 261                 } catch (GeneralSecurityException e) {
 262                     throwSSLException("Server key", e);
 263                 }
 264                 break;
 265             case K_DHE_DSS:
 266             case K_DHE_RSA:
 267                 try {
 268                     this.serverKeyExchange(new DH_ServerKeyExchange(

 269                         input, serverKey,
 270                         clnt_random.random_bytes, svr_random.random_bytes,
 271                         messageLen,
 272                         localSupportedSignAlgs, protocolVersion));


 273                 } catch (GeneralSecurityException e) {
 274                     throwSSLException("Server key", e);
 275                 }
 276                 break;
 277             case K_ECDHE_ECDSA:
 278             case K_ECDHE_RSA:
 279             case K_ECDH_ANON:
 280                 try {
 281                     this.serverKeyExchange(new ECDH_ServerKeyExchange

 282                         (input, serverKey, clnt_random.random_bytes,
 283                         svr_random.random_bytes,
 284                         localSupportedSignAlgs, protocolVersion));


 285                 } catch (GeneralSecurityException e) {
 286                     throwSSLException("Server key", e);
 287                 }
 288                 break;
 289             case K_RSA:
 290             case K_DH_RSA:
 291             case K_DH_DSS:
 292             case K_ECDH_ECDSA:
 293             case K_ECDH_RSA:
 294                 throw new SSLProtocolException(
 295                     "Protocol violation: server sent a server key exchange"
 296                     + " message for key exchange " + keyExchange);
 297             case K_KRB5:
 298             case K_KRB5_EXPORT:
 299                 throw new SSLProtocolException(
 300                     "unexpected receipt of server key exchange algorithm");
 301             default:
 302                 throw new SSLProtocolException(
 303                     "unsupported key exchange algorithm = "
 304                     + keyExchange);
 305             }
 306             break;
 307 
 308         case HandshakeMessage.ht_certificate_request:
 309             // save for later, it's handled by serverHelloDone
 310             if ((keyExchange == K_DH_ANON) || (keyExchange == K_ECDH_ANON)) {
 311                 throw new SSLHandshakeException(
 312                     "Client authentication requested for "+
 313                     "anonymous cipher suite.");
 314             } else if (keyExchange == K_KRB5 || keyExchange == K_KRB5_EXPORT) {
 315                 throw new SSLHandshakeException(
 316                     "Client certificate requested for "+
 317                     "kerberos cipher suite.");
 318             }
 319             certRequest = new CertificateRequest(input, protocolVersion);
 320             if (debug != null && Debug.isOn("handshake")) {
 321                 certRequest.print(System.out);
 322             }

 323 
 324             if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
 325                 Collection<SignatureAndHashAlgorithm> peerSignAlgs =
 326                                         certRequest.getSignAlgorithms();
 327                 if (peerSignAlgs == null || peerSignAlgs.isEmpty()) {
 328                     throw new SSLHandshakeException(
 329                         "No peer supported signature algorithms");
 330                 }
 331 
 332                 Collection<SignatureAndHashAlgorithm> supportedPeerSignAlgs =
 333                     SignatureAndHashAlgorithm.getSupportedAlgorithms(
 334                                                             peerSignAlgs);
 335                 if (supportedPeerSignAlgs.isEmpty()) {
 336                     throw new SSLHandshakeException(
 337                         "No supported signature and hash algorithm in common");
 338                 }
 339 
 340                 setPeerSupportedSignAlgs(supportedPeerSignAlgs);
 341                 session.setPeerSupportedSignatureAlgorithms(
 342                                                 supportedPeerSignAlgs);
 343             }
 344 
 345             break;
 346 
 347         case HandshakeMessage.ht_server_hello_done:
 348             this.serverHelloDone(new ServerHelloDone(input));



 349             break;
 350 
 351         case HandshakeMessage.ht_finished:
 352             // A ChangeCipherSpec record must have been received prior to
 353             // reception of the Finished message (RFC 5246, 7.4.9).
 354             if (!receivedChangeCipherSpec()) {
 355                 fatalSE(Alerts.alert_handshake_failure,
 356                     "Received Finished message before ChangeCipherSpec");
 357             }
 358 
 359             this.serverFinished(
 360                 new Finished(protocolVersion, input, cipherSuite));
 361             break;
 362 
 363         default:
 364             throw new SSLProtocolException(
 365                 "Illegal client handshake msg, " + type);
 366         }
 367 
 368         //
 369         // Move state machine forward if the message handling
 370         // code didn't already do so
 371         //
 372         if (state < type) {
 373             state = type;
 374         }
 375     }
 376 
 377     /*
 378      * Used by the server to kickstart negotiations -- this requests a
 379      * "client hello" to renegotiate current cipher specs (e.g. maybe lots
 380      * of data has been encrypted with the same keys, or the server needs
 381      * the client to present a certificate).
 382      */
 383     private void serverHelloRequest(HelloRequest mesg) throws IOException {
 384         if (debug != null && Debug.isOn("handshake")) {
 385             mesg.print(System.out);
 386         }
 387 
 388         //
 389         // Could be (e.g. at connection setup) that we already
 390         // sent the "client hello" but the server's not seen it.
 391         //
 392         if (state < HandshakeMessage.ht_client_hello) {
 393             if (!secureRenegotiation && !allowUnsafeRenegotiation) {
 394                 // renegotiation is not allowed.
 395                 if (activeProtocolVersion.v >= ProtocolVersion.TLS10.v) {
 396                     // response with a no_renegotiation warning,
 397                     warningSE(Alerts.alert_no_renegotiation);
 398 
 399                     // invalidate the handshake so that the caller can
 400                     // dispose this object.
 401                     invalidated = true;
 402 
 403                     // If there is still unread block in the handshake
 404                     // input stream, it would be truncated with the disposal
 405                     // and the next handshake message will become incomplete.
 406                     //
 407                     // However, according to SSL/TLS specifications, no more
 408                     // handshake message should immediately follow ClientHello
 409                     // or HelloRequest. So just let it be.
 410                 } else {
 411                     // For SSLv3, send the handshake_failure fatal error.
 412                     // Note that SSLv3 does not define a no_renegotiation
 413                     // alert like TLSv1. However we cannot ignore the message
 414                     // simply, otherwise the other side was waiting for a
 415                     // response that would never come.
 416                     fatalSE(Alerts.alert_handshake_failure,
 417                         "Renegotiation is not allowed");
 418                 }
 419             } else {
 420                 if (!secureRenegotiation) {
 421                     if (debug != null && Debug.isOn("handshake")) {
 422                         System.out.println(
 423                             "Warning: continue with insecure renegotiation");
 424                     }
 425                 }
 426                 kickstart();
 427             }
 428         }
 429     }
 430 


 431 





















 432     /*
 433      * Server chooses session parameters given options created by the
 434      * client -- basically, cipher options, session id, and someday a
 435      * set of compression options.
 436      *
 437      * There are two branches of the state machine, decided by the
 438      * details of this message.  One is the "fast" handshake, where we
 439      * can resume the pre-existing session we asked resume.  The other
 440      * is a more expensive "full" handshake, with key exchange and
 441      * probably authentication getting done.
 442      */
 443     private void serverHello(ServerHello mesg) throws IOException {



 444         serverKeyExchangeReceived = false;
 445         if (debug != null && Debug.isOn("handshake")) {
 446             mesg.print(System.out);
 447         }
 448 
 449         // check if the server selected protocol version is OK for us
 450         ProtocolVersion mesgVersion = mesg.protocolVersion;
 451         if (!isNegotiable(mesgVersion)) {
 452             throw new SSLHandshakeException(
 453                 "Server chose " + mesgVersion +
 454                 ", but that protocol version is not enabled or not supported " +
 455                 "by the client.");
 456         }
 457 
 458         handshakeHash.protocolDetermined(mesgVersion);
 459 
 460         // Set protocolVersion and propagate to SSLSocket and the
 461         // Handshake streams
 462         setVersion(mesgVersion);
 463 


 519                 }
 520 
 521                 // we have already allowed unsafe renegotation before request
 522                 // the renegotiation.
 523             }
 524         }
 525 
 526         //
 527         // Save server nonce, we always use it to compute connection
 528         // keys and it's also used to create the master secret if we're
 529         // creating a new session (i.e. in the full handshake).
 530         //
 531         svr_random = mesg.svr_random;
 532 
 533         if (isNegotiable(mesg.cipherSuite) == false) {
 534             fatalSE(Alerts.alert_illegal_parameter,
 535                 "Server selected improper ciphersuite " + mesg.cipherSuite);
 536         }
 537 
 538         setCipherSuite(mesg.cipherSuite);
 539         if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
 540             handshakeHash.setFinishedAlg(cipherSuite.prfAlg.getPRFHashAlg());
 541         }
 542 
 543         if (mesg.compression_method != 0) {
 544             fatalSE(Alerts.alert_illegal_parameter,
 545                 "compression type not supported, "
 546                 + mesg.compression_method);
 547             // NOTREACHED
 548         }
 549 
 550         // so far so good, let's look at the session
 551         if (session != null) {
 552             // we tried to resume, let's see what the server decided
 553             if (session.getSessionId().equals(mesg.sessionId)) {
 554                 // server resumed the session, let's make sure everything
 555                 // checks out
 556 
 557                 // Verify that the session ciphers are unchanged.
 558                 CipherSuite sessionSuite = session.getSuite();
 559                 if (cipherSuite != sessionSuite) {


 594                         Set<Principal> principals =
 595                             subject.getPrincipals(Principal.class);
 596                         if (!principals.contains(localPrincipal)) {
 597                             throw new SSLProtocolException("Server resumed" +
 598                                 " session with wrong subject identity");
 599                         } else {
 600                             if (debug != null && Debug.isOn("session"))
 601                                 System.out.println("Subject identity is same");
 602                         }
 603                     } else {
 604                         if (debug != null && Debug.isOn("session"))
 605                             System.out.println("Kerberos credentials are not" +
 606                                 " present in the current Subject; check if " +
 607                                 " javax.security.auth.useSubjectAsCreds" +
 608                                 " system property has been set to false");
 609                         throw new SSLProtocolException
 610                             ("Server resumed session with no subject");
 611                     }
 612                 }
 613 
 614                 // looks fine; resume it, and update the state machine.
 615                 resumingSession = true;
 616                 state = HandshakeMessage.ht_finished - 1;
 617                 calculateConnectionKeys(session.getMasterSecret());
 618                 if (debug != null && Debug.isOn("session")) {
 619                     System.out.println("%% Server resumed " + session);
 620                 }
 621             } else {
 622                 // we wanted to resume, but the server refused
 623                 session = null;
 624                 if (!enableNewSession) {
 625                     throw new SSLException("New session creation is disabled");
 626                 }
 627             }
 628         }
 629 


















 630         if (resumingSession && session != null) {
 631             setHandshakeSessionSE(session);
 632             // Reserve the handshake state if this is a session-resumption
 633             // abbreviated initial handshake.
 634             if (isInitialHandshake) {
 635                 session.setAsSessionResumption(true);
 636             }
 637 
 638             return;
 639         }
 640 
 641         // check extensions
 642         for (HelloExtension ext : mesg.extensions.list()) {
 643             ExtensionType type = ext.type;
 644             if (type == ExtensionType.EXT_SERVER_NAME) {
 645                 serverNamesAccepted = true;
 646             } else if ((type != ExtensionType.EXT_ELLIPTIC_CURVES)
 647                     && (type != ExtensionType.EXT_EC_POINT_FORMATS)
 648                     && (type != ExtensionType.EXT_SERVER_NAME)
 649                     && (type != ExtensionType.EXT_RENEGOTIATION_INFO)) {
 650                 fatalSE(Alerts.alert_unsupported_extension,
 651                     "Server sent an unsupported extension: " + type);
 652             }
 653         }
 654 
 655         // Create a new session, we need to do the full handshake
 656         session = new SSLSessionImpl(protocolVersion, cipherSuite,
 657                             getLocalSupportedSignAlgs(),
 658                             mesg.sessionId, getHostSE(), getPortSE());
 659         session.setRequestedServerNames(requestedServerNames);


 660         setHandshakeSessionSE(session);
 661         if (debug != null && Debug.isOn("handshake")) {
 662             System.out.println("** " + cipherSuite);
 663         }
 664     }
 665 
 666     /*
 667      * Server's own key was either a signing-only key, or was too
 668      * large for export rules ... this message holds an ephemeral
 669      * RSA key to use for key exchange.
 670      */
 671     private void serverKeyExchange(RSA_ServerKeyExchange mesg)
 672             throws IOException, GeneralSecurityException {
 673         if (debug != null && Debug.isOn("handshake")) {
 674             mesg.print(System.out);
 675         }
 676         if (!mesg.verify(serverKey, clnt_random, svr_random)) {
 677             fatalSE(Alerts.alert_handshake_failure,
 678                 "server key exchange invalid");
 679             // NOTREACHED
 680         }
 681         ephemeralServerKey = mesg.getPublicKey();
 682     }
 683 
 684 
 685     /*
 686      * Diffie-Hellman key exchange.  We save the server public key and
 687      * our own D-H algorithm object so we can defer key calculations
 688      * until after we've sent the client key exchange message (which
 689      * gives client and server some useful parallelism).
 690      */
 691     private void serverKeyExchange(DH_ServerKeyExchange mesg)
 692             throws IOException {
 693         if (debug != null && Debug.isOn("handshake")) {
 694             mesg.print(System.out);
 695         }
 696         dh = new DHCrypt(mesg.getModulus(), mesg.getBase(),
 697                                             sslContext.getSecureRandom());
 698         serverDH = mesg.getServerPublicKey();
 699     }
 700 
 701     private void serverKeyExchange(ECDH_ServerKeyExchange mesg)
 702             throws IOException {
 703         if (debug != null && Debug.isOn("handshake")) {
 704             mesg.print(System.out);
 705         }
 706         ECPublicKey key = mesg.getPublicKey();
 707         ecdh = new ECDHCrypt(key.getParams(), sslContext.getSecureRandom());
 708         ephemeralServerKey = key;
 709     }
 710 
 711     /*
 712      * The server's "Hello Done" message is the client's sign that
 713      * it's time to do all the hard work.
 714      */
 715     private void serverHelloDone(ServerHelloDone mesg) throws IOException {
 716         if (debug != null && Debug.isOn("handshake")) {
 717             mesg.print(System.out);
 718         }
 719         /*
 720          * Always make sure the input has been digested before we
 721          * start emitting data, to ensure the hashes are correctly
 722          * computed for the Finished and CertificateVerify messages
 723          * which we send (here).
 724          */
 725         input.digestNow();
 726 
 727         /*
 728          * FIRST ... if requested, send an appropriate Certificate chain
 729          * to authenticate the client, and remember the associated private
 730          * key to sign the CertificateVerify message.
 731          */
 732         PrivateKey signingKey = null;
 733 
 734         if (certRequest != null) {
 735             X509ExtendedKeyManager km = sslContext.getX509KeyManager();
 736 
 737             ArrayList<String> keytypesTmp = new ArrayList<>(4);
 738 
 739             for (int i = 0; i < certRequest.types.length; i++) {
 740                 String typeName;
 741 
 742                 switch (certRequest.types[i]) {
 743                 case CertificateRequest.cct_rsa_sign:
 744                     typeName = "RSA";
 745                     break;


 800                                 params);
 801                         if (!SupportedEllipticCurvesExtension.isSupported(
 802                                 index)) {
 803                             publicKey = null;
 804                         }
 805                     }
 806                     if (publicKey != null) {
 807                         m1 = new CertificateMsg(certs);
 808                         signingKey = km.getPrivateKey(alias);
 809                         session.setLocalPrivateKey(signingKey);
 810                         session.setLocalCertificates(certs);
 811                     }
 812                 }
 813             }
 814             if (m1 == null) {
 815                 //
 816                 // No appropriate cert was found ... report this to the
 817                 // server.  For SSLv3, send the no_certificate alert;
 818                 // TLS uses an empty cert chain instead.
 819                 //
 820                 if (protocolVersion.v >= ProtocolVersion.TLS10.v) {
 821                     m1 = new CertificateMsg(new X509Certificate [0]);
 822                 } else {
 823                     warningSE(Alerts.alert_no_certificate);
 824                 }
 825                 if (debug != null && Debug.isOn("handshake")) {
 826                     System.out.println(
 827                         "Warning: no suitable certificate found - " +
 828                         "continuing without client authentication");
 829                 }
 830             }
 831 
 832             //
 833             // At last ... send any client certificate chain.
 834             //
 835             if (m1 != null) {
 836                 if (debug != null && Debug.isOn("handshake")) {
 837                     m1.print(System.out);
 838                 }
 839                 m1.write(output);

 840             }
 841         }
 842 
 843         /*
 844          * SECOND ... send the client key exchange message.  The
 845          * procedure used is a function of the cipher suite selected;
 846          * one is always needed.
 847          */
 848         HandshakeMessage m2;
 849 
 850         switch (keyExchange) {
 851 
 852         case K_RSA:
 853         case K_RSA_EXPORT:
 854             if (serverKey == null) {
 855                 throw new SSLProtocolException
 856                         ("Server did not send certificate message");
 857             }
 858 
 859             if (!(serverKey instanceof RSAPublicKey)) {


 983                 }
 984                 kerberosMsg = new KerberosClientKeyExchange(
 985                      hostname, getAccSE(), protocolVersion,
 986                      sslContext.getSecureRandom());
 987             }
 988 
 989             // Record the principals involved in exchange
 990             session.setPeerPrincipal(kerberosMsg.getPeerPrincipal());
 991             session.setLocalPrincipal(kerberosMsg.getLocalPrincipal());
 992             m2 = kerberosMsg;
 993             break;
 994         default:
 995             // somethings very wrong
 996             throw new RuntimeException
 997                                 ("Unsupported key exchange: " + keyExchange);
 998         }
 999         if (debug != null && Debug.isOn("handshake")) {
1000             m2.print(System.out);
1001         }
1002         m2.write(output);

1003 
1004 
1005         /*
1006          * THIRD, send a "change_cipher_spec" record followed by the
1007          * "Finished" message.  We flush the messages we've queued up, to
1008          * get concurrency between client and server.  The concurrency is
1009          * useful as we calculate the master secret, which is needed both
1010          * to compute the "Finished" message, and to compute the keys used
1011          * to protect all records following the change_cipher_spec.
1012          */
1013 
1014         output.doHashes();
1015         output.flush();
1016 
1017         /*
1018          * We deferred calculating the master secret and this connection's
1019          * keying data; we do it now.  Deferring this calculation is good
1020          * from a performance point of view, since it lets us do it during
1021          * some time that network delays and the server's own calculations
1022          * would otherwise cause to be "dead" in the critical path.
1023          */
1024         SecretKey preMasterSecret;
1025         switch (keyExchange) {
1026         case K_RSA:
1027         case K_RSA_EXPORT:
1028             preMasterSecret = ((RSAClientKeyExchange)m2).preMaster;
1029             break;
1030         case K_KRB5:
1031         case K_KRB5_EXPORT:
1032             byte[] secretBytes =
1033                 ((KerberosClientKeyExchange)m2).getUnencryptedPreMasterSecret();
1034             preMasterSecret = new SecretKeySpec(secretBytes,


1052             throw new IOException("Internal error: unknown key exchange "
1053                 + keyExchange);
1054         }
1055 
1056         calculateKeys(preMasterSecret, null);
1057 
1058         /*
1059          * FOURTH, if we sent a Certificate, we need to send a signed
1060          * CertificateVerify (unless the key in the client's certificate
1061          * was a Diffie-Hellman key).).
1062          *
1063          * This uses a hash of the previous handshake messages ... either
1064          * a nonfinal one (if the particular implementation supports it)
1065          * or else using the third element in the arrays of hashes being
1066          * computed.
1067          */
1068         if (signingKey != null) {
1069             CertificateVerify m3;
1070             try {
1071                 SignatureAndHashAlgorithm preferableSignatureAlgorithm = null;
1072                 if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
1073                     preferableSignatureAlgorithm =
1074                         SignatureAndHashAlgorithm.getPreferableAlgorithm(
1075                             peerSupportedSignAlgs, signingKey.getAlgorithm(),
1076                             signingKey);
1077 
1078                     if (preferableSignatureAlgorithm == null) {
1079                         throw new SSLHandshakeException(
1080                             "No supported signature algorithm");
1081                     }
1082 
1083                     String hashAlg =
1084                         SignatureAndHashAlgorithm.getHashAlgorithmName(
1085                                 preferableSignatureAlgorithm);
1086                     if (hashAlg == null || hashAlg.length() == 0) {
1087                         throw new SSLHandshakeException(
1088                                 "No supported hash algorithm");
1089                     }
1090                 }
1091 
1092                 m3 = new CertificateVerify(protocolVersion, handshakeHash,
1093                     signingKey, session.getMasterSecret(),
1094                     sslContext.getSecureRandom(),
1095                     preferableSignatureAlgorithm);
1096             } catch (GeneralSecurityException e) {
1097                 fatalSE(Alerts.alert_handshake_failure,
1098                     "Error signing certificate verify", e);
1099                 // NOTREACHED, make compiler happy
1100                 m3 = null;
1101             }
1102             if (debug != null && Debug.isOn("handshake")) {
1103                 m3.print(System.out);
1104             }
1105             m3.write(output);
1106             output.doHashes();

1107         }
1108 
1109         /*
1110          * OK, that's that!
1111          */
1112         sendChangeCipherAndFinish(false);



1113     }
1114 
1115 
1116     /*
1117      * "Finished" is the last handshake message sent.  If we got this
1118      * far, the MAC has been validated post-decryption.  We validate
1119      * the two hashes here as an additional sanity check, protecting
1120      * the handshake against various active attacks.
1121      */
1122     private void serverFinished(Finished mesg) throws IOException {
1123         if (debug != null && Debug.isOn("handshake")) {
1124             mesg.print(System.out);
1125         }
1126 
1127         boolean verified = mesg.verify(handshakeHash, Finished.SERVER,
1128             session.getMasterSecret());
1129 
1130         if (!verified) {
1131             fatalSE(Alerts.alert_illegal_parameter,
1132                        "server 'finished' message doesn't verify");


1141         }
1142 
1143         /*
1144          * Reset the handshake state if this is not an initial handshake.
1145          */
1146         if (!isInitialHandshake) {
1147             session.setAsSessionResumption(false);
1148         }
1149 
1150         /*
1151          * OK, it verified.  If we're doing the fast handshake, add that
1152          * "Finished" message to the hash of handshake messages, then send
1153          * our own change_cipher_spec and Finished message for the server
1154          * to verify in turn.  These are the last handshake messages.
1155          *
1156          * In any case, update the session cache.  We're done handshaking,
1157          * so there are no threats any more associated with partially
1158          * completed handshakes.
1159          */
1160         if (resumingSession) {
1161             input.digestNow();
1162             sendChangeCipherAndFinish(true);


1163         }
1164         session.setLastAccessedTime(System.currentTimeMillis());
1165 
1166         if (!resumingSession) {
1167             if (session.isRejoinable()) {
1168                 ((SSLSessionContextImpl) sslContext
1169                         .engineGetClientSessionContext())
1170                         .put(session);
1171                 if (debug != null && Debug.isOn("session")) {
1172                     System.out.println("%% Cached client session: " + session);
1173                 }
1174             } else if (debug != null && Debug.isOn("session")) {
1175                 System.out.println(
1176                     "%% Didn't cache non-resumable client session: "
1177                     + session);
1178             }
1179         }
1180     }
1181 
1182 
1183     /*
1184      * Send my change-cipher-spec and Finished message ... done as the
1185      * last handshake act in either the short or long sequences.  In
1186      * the short one, we've already seen the server's Finished; in the
1187      * long one, we wait for it now.
1188      */
1189     private void sendChangeCipherAndFinish(boolean finishedTag)
1190             throws IOException {




1191         Finished mesg = new Finished(protocolVersion, handshakeHash,
1192             Finished.CLIENT, session.getMasterSecret(), cipherSuite);
1193 
1194         /*
1195          * Send the change_cipher_spec message, then the Finished message
1196          * which we just calculated (and protected using the keys we just
1197          * calculated).  Server responds with its Finished message, except
1198          * in the "fast handshake" (resume session) case.
1199          */
1200         sendChangeCipherSpec(mesg, finishedTag);
1201 
1202         /*
1203          * save client verify data for secure renegotiation
1204          */
1205         if (secureRenegotiation) {
1206             clientVerifyData = mesg.getVerifyData();
1207         }
1208 
1209         /*
1210          * Update state machine so server MUST send 'finished' next.
1211          * (In "long" handshake case; in short case, we're responding
1212          * to its message.)
1213          */
1214         state = HandshakeMessage.ht_finished - 1;
1215     }
1216 
1217 
1218     /*
1219      * Returns a ClientHello message to kickstart renegotiations
1220      */
1221     @Override
1222     HandshakeMessage getKickstartMessage() throws SSLException {
1223         // session ID of the ClientHello message
1224         SessionId sessionId = SSLSessionImpl.nullSession.getSessionId();
1225 
1226         // a list of cipher suites sent by the client
1227         CipherSuiteList cipherSuites = getActiveCipherSuites();
1228 
1229         // set the max protocol version this client is supporting.
1230         maxProtocolVersion = protocolVersion;
1231 
1232         //
1233         // Try to resume an existing session.  This might be mandatory,
1234         // given certain API options.


1344                 break;
1345             }
1346         }
1347 
1348         if (!negotiable) {
1349             throw new SSLHandshakeException("No negotiable cipher suite");
1350         }
1351 
1352         // Not a TLS1.2+ handshake
1353         // For SSLv2Hello, HandshakeHash.reset() will be called, so we
1354         // cannot call HandshakeHash.protocolDetermined() here. As it does
1355         // not follow the spec that HandshakeHash.reset() can be only be
1356         // called before protocolDetermined.
1357         // if (maxProtocolVersion.v < ProtocolVersion.TLS12.v) {
1358         //     handshakeHash.protocolDetermined(maxProtocolVersion);
1359         // }
1360 
1361         // create the ClientHello message
1362         ClientHello clientHelloMessage = new ClientHello(
1363                 sslContext.getSecureRandom(), maxProtocolVersion,
1364                 sessionId, cipherSuites);
1365 
1366         // add signature_algorithm extension
1367         if (maxProtocolVersion.v >= ProtocolVersion.TLS12.v) {
1368             // we will always send the signature_algorithm extension
1369             Collection<SignatureAndHashAlgorithm> localSignAlgs =
1370                                                 getLocalSupportedSignAlgs();
1371             if (localSignAlgs.isEmpty()) {
1372                 throw new SSLHandshakeException(
1373                             "No supported signature algorithm");
1374             }
1375 
1376             clientHelloMessage.addSignatureAlgorithmsExtension(localSignAlgs);
1377         }
1378 
1379         // add server_name extension
1380         if (enableSNIExtension) {
1381             if (session != null) {
1382                 requestedServerNames = session.getRequestedServerNames();
1383             } else {
1384                 requestedServerNames = serverNames;
1385             }
1386 
1387             if (!requestedServerNames.isEmpty()) {
1388                 clientHelloMessage.addSNIExtension(requestedServerNames);
1389             }
1390         }
1391 































1392         // reset the client random cookie
1393         clnt_random = clientHelloMessage.clnt_random;
1394 
1395         /*
1396          * need to set the renegotiation_info extension for:
1397          * 1: secure renegotiation
1398          * 2: initial handshake and no SCSV in the ClientHello
1399          * 3: insecure renegotiation and no SCSV in the ClientHello
1400          */
1401         if (secureRenegotiation ||
1402                 !cipherSuites.contains(CipherSuite.C_SCSV)) {
1403             clientHelloMessage.addRenegotiationInfoExtension(clientVerifyData);
1404         }
1405 





1406         return clientHelloMessage;
1407     }
1408 
1409     /*
1410      * Fault detected during handshake.
1411      */
1412     @Override
1413     void handshakeAlert(byte description) throws SSLProtocolException {
1414         String message = Alerts.alertDescription(description);
1415 
1416         if (debug != null && Debug.isOn("handshake")) {
1417             System.out.println("SSL - handshake alert: " + message);
1418         }
1419         throw new SSLProtocolException("handshake alert:  " + message);
1420     }
1421 
1422     /*
1423      * Unless we are using an anonymous ciphersuite, the server always
1424      * sends a certificate message (for the CipherSuites we currently
1425      * support). The trust manager verifies the chain for us.




 124      * same (See isIdentityEquivalent()).
 125      *
 126      * Considering the compatibility impact and the actual requirements to
 127      * support server certificate change in practice, the system property,
 128      * jdk.tls.allowUnsafeServerCertChange, is used to define whether unsafe
 129      * server certificate change in renegotiation is allowed or not.  The
 130      * default value of the system property is "false".  To mitigate the
 131      * compactibility impact, applications may want to set the system
 132      * property to "true" at their own risk.
 133      *
 134      * If the value of the system property is "false", server certificate
 135      * change in renegotiation after a session-resumption abbreviated initial
 136      * handshake is restricted (See isIdentityEquivalent()).
 137      *
 138      * If the system property is set to "true" explicitly, the restriction on
 139      * server certificate change in renegotiation is disabled.
 140      */
 141     private final static boolean allowUnsafeServerCertChange =
 142         Debug.getBooleanProperty("jdk.tls.allowUnsafeServerCertChange", false);
 143 
 144     // To switch off the max_fragment_length extension.
 145     private final static boolean enableMFLExtension =
 146             Debug.getBooleanProperty("jsse.enableMFLExtension", false);
 147 
 148     private List<SNIServerName> requestedServerNames =
 149             Collections.<SNIServerName>emptyList();
 150 
 151     // maximum fragment length
 152     private int requestedMFLength = -1;     // -1: no fragment length limit
 153 
 154     private boolean serverNamesAccepted = false;
 155 
 156     private ClientHello initialClientHelloMsg = null;   // DTLS only
 157 
 158     /*
 159      * the reserved server certificate chain in previous handshaking
 160      *
 161      * The server certificate chain is only reserved if the previous
 162      * handshake is a session-resumption abbreviated initial handshake.
 163      */
 164     private X509Certificate[] reservedServerCerts = null;
 165 
 166     /*
 167      * Constructors
 168      */
 169     ClientHandshaker(SSLSocketImpl socket, SSLContextImpl context,
 170             ProtocolList enabledProtocols,
 171             ProtocolVersion activeProtocolVersion,
 172             boolean isInitialHandshake, boolean secureRenegotiation,
 173             byte[] clientVerifyData, byte[] serverVerifyData) {
 174 
 175         super(socket, context, enabledProtocols, true, true,
 176             activeProtocolVersion, isInitialHandshake, secureRenegotiation,
 177             clientVerifyData, serverVerifyData);
 178     }
 179 
 180     ClientHandshaker(SSLEngineImpl engine, SSLContextImpl context,
 181             ProtocolList enabledProtocols,
 182             ProtocolVersion activeProtocolVersion,
 183             boolean isInitialHandshake, boolean secureRenegotiation,
 184             byte[] clientVerifyData, byte[] serverVerifyData,
 185             boolean isDTLS) {
 186 
 187         super(engine, context, enabledProtocols, true, true,
 188             activeProtocolVersion, isInitialHandshake, secureRenegotiation,
 189             clientVerifyData, serverVerifyData, isDTLS);
 190     }
 191 
 192     /*
 193      * This routine handles all the client side handshake messages, one at
 194      * a time.  Given the message type (and in some cases the pending cipher
 195      * spec) it parses the type-specific message.  Then it calls a function
 196      * that handles that specific message.
 197      *
 198      * It updates the state machine (need to verify it) as each message
 199      * is processed, and writes responses as needed using the connection
 200      * in the constructor.
 201      */
 202     @Override
 203     void processMessage(byte type, int messageLen) throws IOException {
 204         // check the handshake state
 205         handshakeState.check(type);



 206 
 207         switch (type) {
 208         case HandshakeMessage.ht_hello_request:
 209             HelloRequest helloRequest = new HelloRequest(input);
 210             handshakeState.update(helloRequest, resumingSession);
 211             this.serverHelloRequest(helloRequest);
 212             break;
 213 
 214         case HandshakeMessage.ht_hello_verify_request:
 215             if (!isDTLS) {
 216                 throw new SSLProtocolException(
 217                     "hello_verify_request is not a SSL/TLS handshake message");
 218             }
 219 
 220             HelloVerifyRequest helloVerifyRequest =
 221                         new HelloVerifyRequest(input, messageLen);
 222             handshakeState.update(helloVerifyRequest, resumingSession);
 223             this.helloVerifyRequest(helloVerifyRequest);
 224             break;
 225 
 226         case HandshakeMessage.ht_server_hello:
 227             ServerHello serverHello = new ServerHello(input, messageLen);
 228             this.serverHello(serverHello);
 229 
 230             // This handshake state update needs the resumingSession value
 231             // set by serverHello().
 232             handshakeState.update(serverHello, resumingSession);
 233             break;
 234 
 235         case HandshakeMessage.ht_certificate:
 236             if (keyExchange == K_DH_ANON || keyExchange == K_ECDH_ANON
 237                     || keyExchange == K_KRB5 || keyExchange == K_KRB5_EXPORT) {
 238                 fatalSE(Alerts.alert_unexpected_message,
 239                     "unexpected server cert chain");
 240                 // NOTREACHED
 241             }
 242             CertificateMsg certificateMsg = new CertificateMsg(input);
 243             handshakeState.update(certificateMsg, resumingSession);
 244             this.serverCertificate(certificateMsg);
 245             serverKey =
 246                 session.getPeerCertificates()[0].getPublicKey();
 247             break;
 248 
 249         case HandshakeMessage.ht_server_key_exchange:
 250             serverKeyExchangeReceived = true;
 251             switch (keyExchange) {
 252             case K_RSA_EXPORT:
 253                 /**
 254                  * The server key exchange message is sent by the server only
 255                  * when the server certificate message does not contain the
 256                  * proper amount of data to allow the client to exchange a
 257                  * premaster secret, such as when RSA_EXPORT is used and the
 258                  * public key in the server certificate is longer than 512 bits.
 259                  */
 260                 if (serverKey == null) {
 261                     throw new SSLProtocolException
 262                         ("Server did not send certificate message");
 263                 }
 264 
 265                 if (!(serverKey instanceof RSAPublicKey)) {
 266                     throw new SSLProtocolException("Protocol violation:" +
 267                         " the certificate type must be appropriate for the" +
 268                         " selected cipher suite's key exchange algorithm");
 269                 }
 270 
 271                 if (JsseJce.getRSAKeyLength(serverKey) <= 512) {
 272                     throw new SSLProtocolException("Protocol violation:" +
 273                         " server sent a server key exchange message for" +
 274                         " key exchange " + keyExchange +
 275                         " when the public key in the server certificate" +
 276                         " is less than or equal to 512 bits in length");
 277                 }
 278 
 279                 try {
 280                     RSA_ServerKeyExchange rsaSrvKeyExchange =
 281                                     new RSA_ServerKeyExchange(input);
 282                     handshakeState.update(rsaSrvKeyExchange, resumingSession);
 283                     this.serverKeyExchange(rsaSrvKeyExchange);
 284                 } catch (GeneralSecurityException e) {
 285                     throw new SSLException("Server key", e);
 286                 }
 287                 break;
 288             case K_DH_ANON:
 289                 try {
 290                     DH_ServerKeyExchange dhSrvKeyExchange =
 291                             new DH_ServerKeyExchange(input, protocolVersion);
 292                     handshakeState.update(dhSrvKeyExchange, resumingSession);
 293                     this.serverKeyExchange(dhSrvKeyExchange);
 294                 } catch (GeneralSecurityException e) {
 295                     throw new SSLException("Server key", e);
 296                 }
 297                 break;
 298             case K_DHE_DSS:
 299             case K_DHE_RSA:
 300                 try {
 301                     DH_ServerKeyExchange dhSrvKeyExchange =
 302                         new DH_ServerKeyExchange(
 303                             input, serverKey,
 304                             clnt_random.random_bytes, svr_random.random_bytes,
 305                             messageLen,
 306                             localSupportedSignAlgs, protocolVersion);
 307                     handshakeState.update(dhSrvKeyExchange, resumingSession);
 308                     this.serverKeyExchange(dhSrvKeyExchange);
 309                 } catch (GeneralSecurityException e) {
 310                     throw new SSLException("Server key", e);
 311                 }
 312                 break;
 313             case K_ECDHE_ECDSA:
 314             case K_ECDHE_RSA:
 315             case K_ECDH_ANON:
 316                 try {
 317                     ECDH_ServerKeyExchange ecdhSrvKeyExchange =
 318                         new ECDH_ServerKeyExchange
 319                             (input, serverKey, clnt_random.random_bytes,
 320                             svr_random.random_bytes,
 321                             localSupportedSignAlgs, protocolVersion);
 322                     handshakeState.update(ecdhSrvKeyExchange, resumingSession);
 323                     this.serverKeyExchange(ecdhSrvKeyExchange);
 324                 } catch (GeneralSecurityException e) {
 325                     throw new SSLException("Server key", e);
 326                 }
 327                 break;
 328             case K_RSA:
 329             case K_DH_RSA:
 330             case K_DH_DSS:
 331             case K_ECDH_ECDSA:
 332             case K_ECDH_RSA:
 333                 throw new SSLProtocolException(
 334                     "Protocol violation: server sent a server key exchange"
 335                     + " message for key exchange " + keyExchange);
 336             case K_KRB5:
 337             case K_KRB5_EXPORT:
 338                 throw new SSLProtocolException(
 339                     "unexpected receipt of server key exchange algorithm");
 340             default:
 341                 throw new SSLProtocolException(
 342                     "unsupported key exchange algorithm = "
 343                     + keyExchange);
 344             }
 345             break;
 346 
 347         case HandshakeMessage.ht_certificate_request:
 348             // save for later, it's handled by serverHelloDone
 349             if ((keyExchange == K_DH_ANON) || (keyExchange == K_ECDH_ANON)) {
 350                 throw new SSLHandshakeException(
 351                     "Client authentication requested for "+
 352                     "anonymous cipher suite.");
 353             } else if (keyExchange == K_KRB5 || keyExchange == K_KRB5_EXPORT) {
 354                 throw new SSLHandshakeException(
 355                     "Client certificate requested for "+
 356                     "kerberos cipher suite.");
 357             }
 358             certRequest = new CertificateRequest(input, protocolVersion);
 359             if (debug != null && Debug.isOn("handshake")) {
 360                 certRequest.print(System.out);
 361             }
 362             handshakeState.update(certRequest, resumingSession);
 363 
 364             if (protocolVersion.useTLS12PlusSpec()) {
 365                 Collection<SignatureAndHashAlgorithm> peerSignAlgs =
 366                                         certRequest.getSignAlgorithms();
 367                 if (peerSignAlgs == null || peerSignAlgs.isEmpty()) {
 368                     throw new SSLHandshakeException(
 369                         "No peer supported signature algorithms");
 370                 }
 371 
 372                 Collection<SignatureAndHashAlgorithm> supportedPeerSignAlgs =
 373                     SignatureAndHashAlgorithm.getSupportedAlgorithms(
 374                                                             peerSignAlgs);
 375                 if (supportedPeerSignAlgs.isEmpty()) {
 376                     throw new SSLHandshakeException(
 377                         "No supported signature and hash algorithm in common");
 378                 }
 379 
 380                 setPeerSupportedSignAlgs(supportedPeerSignAlgs);
 381                 session.setPeerSupportedSignatureAlgorithms(
 382                                                 supportedPeerSignAlgs);
 383             }
 384 
 385             break;
 386 
 387         case HandshakeMessage.ht_server_hello_done:
 388             ServerHelloDone serverHelloDone = new ServerHelloDone(input);
 389             handshakeState.update(serverHelloDone, resumingSession);
 390             this.serverHelloDone(serverHelloDone);
 391 
 392             break;
 393 
 394         case HandshakeMessage.ht_finished:
 395             Finished serverFinished =
 396                     new Finished(protocolVersion, input, cipherSuite);
 397             handshakeState.update(serverFinished, resumingSession);
 398             this.serverFinished(serverFinished);


 399 


 400             break;
 401 
 402         default:
 403             throw new SSLProtocolException(
 404                 "Illegal client handshake msg, " + type);
 405         }







 406     }

 407 
 408     /*
 409      * Used by the server to kickstart negotiations -- this requests a
 410      * "client hello" to renegotiate current cipher specs (e.g. maybe lots
 411      * of data has been encrypted with the same keys, or the server needs
 412      * the client to present a certificate).
 413      */
 414     private void serverHelloRequest(HelloRequest mesg) throws IOException {
 415         if (debug != null && Debug.isOn("handshake")) {
 416             mesg.print(System.out);
 417         }
 418 
 419         //
 420         // Could be (e.g. at connection setup) that we already
 421         // sent the "client hello" but the server's not seen it.
 422         //
 423         if (!clientHelloDelivered) {
 424             if (!secureRenegotiation && !allowUnsafeRenegotiation) {
 425                 // renegotiation is not allowed.
 426                 if (activeProtocolVersion.useTLS10PlusSpec()) {
 427                     // response with a no_renegotiation warning,
 428                     warningSE(Alerts.alert_no_renegotiation);
 429 
 430                     // invalidate the handshake so that the caller can
 431                     // dispose this object.
 432                     invalidated = true;
 433 
 434                     // If there is still unread block in the handshake
 435                     // input stream, it would be truncated with the disposal
 436                     // and the next handshake message will become incomplete.
 437                     //
 438                     // However, according to SSL/TLS specifications, no more
 439                     // handshake message should immediately follow ClientHello
 440                     // or HelloRequest. So just let it be.
 441                 } else {
 442                     // For SSLv3, send the handshake_failure fatal error.
 443                     // Note that SSLv3 does not define a no_renegotiation
 444                     // alert like TLSv1. However we cannot ignore the message
 445                     // simply, otherwise the other side was waiting for a
 446                     // response that would never come.
 447                     fatalSE(Alerts.alert_handshake_failure,
 448                         "Renegotiation is not allowed");
 449                 }
 450             } else {
 451                 if (!secureRenegotiation) {
 452                     if (debug != null && Debug.isOn("handshake")) {
 453                         System.out.println(
 454                             "Warning: continue with insecure renegotiation");
 455                     }
 456                 }
 457                 kickstart();
 458             }
 459         }
 460     }
 461 
 462     private void helloVerifyRequest(
 463             HelloVerifyRequest mesg) throws IOException {
 464 
 465         if (debug != null && Debug.isOn("handshake")) {
 466             mesg.print(System.out);
 467         }
 468 
 469         //
 470         // Note that HelloVerifyRequest.server_version is used solely to
 471         // indicate packet formatting, and not as part of version negotiation.
 472         // Need not to check version values match for HelloVerifyRequest
 473         // message.
 474         //
 475         initialClientHelloMsg.cookie = mesg.cookie.clone();
 476 
 477         if (debug != null && Debug.isOn("handshake")) {
 478             initialClientHelloMsg.print(System.out);
 479         }
 480 
 481         // deliver the ClientHello message with cookie
 482         initialClientHelloMsg.write(output);
 483         handshakeState.update(initialClientHelloMsg, resumingSession);
 484     }
 485 
 486     /*
 487      * Server chooses session parameters given options created by the
 488      * client -- basically, cipher options, session id, and someday a
 489      * set of compression options.
 490      *
 491      * There are two branches of the state machine, decided by the
 492      * details of this message.  One is the "fast" handshake, where we
 493      * can resume the pre-existing session we asked resume.  The other
 494      * is a more expensive "full" handshake, with key exchange and
 495      * probably authentication getting done.
 496      */
 497     private void serverHello(ServerHello mesg) throws IOException {
 498         // Dispose the reserved ClientHello message (if exists).
 499         initialClientHelloMsg = null;
 500 
 501         serverKeyExchangeReceived = false;
 502         if (debug != null && Debug.isOn("handshake")) {
 503             mesg.print(System.out);
 504         }
 505 
 506         // check if the server selected protocol version is OK for us
 507         ProtocolVersion mesgVersion = mesg.protocolVersion;
 508         if (!isNegotiable(mesgVersion)) {
 509             throw new SSLHandshakeException(
 510                 "Server chose " + mesgVersion +
 511                 ", but that protocol version is not enabled or not supported " +
 512                 "by the client.");
 513         }
 514 
 515         handshakeHash.protocolDetermined(mesgVersion);
 516 
 517         // Set protocolVersion and propagate to SSLSocket and the
 518         // Handshake streams
 519         setVersion(mesgVersion);
 520 


 576                 }
 577 
 578                 // we have already allowed unsafe renegotation before request
 579                 // the renegotiation.
 580             }
 581         }
 582 
 583         //
 584         // Save server nonce, we always use it to compute connection
 585         // keys and it's also used to create the master secret if we're
 586         // creating a new session (i.e. in the full handshake).
 587         //
 588         svr_random = mesg.svr_random;
 589 
 590         if (isNegotiable(mesg.cipherSuite) == false) {
 591             fatalSE(Alerts.alert_illegal_parameter,
 592                 "Server selected improper ciphersuite " + mesg.cipherSuite);
 593         }
 594 
 595         setCipherSuite(mesg.cipherSuite);
 596         if (protocolVersion.useTLS12PlusSpec()) {
 597             handshakeHash.setFinishedAlg(cipherSuite.prfAlg.getPRFHashAlg());
 598         }
 599 
 600         if (mesg.compression_method != 0) {
 601             fatalSE(Alerts.alert_illegal_parameter,
 602                 "compression type not supported, "
 603                 + mesg.compression_method);
 604             // NOTREACHED
 605         }
 606 
 607         // so far so good, let's look at the session
 608         if (session != null) {
 609             // we tried to resume, let's see what the server decided
 610             if (session.getSessionId().equals(mesg.sessionId)) {
 611                 // server resumed the session, let's make sure everything
 612                 // checks out
 613 
 614                 // Verify that the session ciphers are unchanged.
 615                 CipherSuite sessionSuite = session.getSuite();
 616                 if (cipherSuite != sessionSuite) {


 651                         Set<Principal> principals =
 652                             subject.getPrincipals(Principal.class);
 653                         if (!principals.contains(localPrincipal)) {
 654                             throw new SSLProtocolException("Server resumed" +
 655                                 " session with wrong subject identity");
 656                         } else {
 657                             if (debug != null && Debug.isOn("session"))
 658                                 System.out.println("Subject identity is same");
 659                         }
 660                     } else {
 661                         if (debug != null && Debug.isOn("session"))
 662                             System.out.println("Kerberos credentials are not" +
 663                                 " present in the current Subject; check if " +
 664                                 " javax.security.auth.useSubjectAsCreds" +
 665                                 " system property has been set to false");
 666                         throw new SSLProtocolException
 667                             ("Server resumed session with no subject");
 668                     }
 669                 }
 670 
 671                 // looks fine; resume it.
 672                 resumingSession = true;

 673                 calculateConnectionKeys(session.getMasterSecret());
 674                 if (debug != null && Debug.isOn("session")) {
 675                     System.out.println("%% Server resumed " + session);
 676                 }
 677             } else {
 678                 // we wanted to resume, but the server refused
 679                 session = null;
 680                 if (!enableNewSession) {
 681                     throw new SSLException("New session creation is disabled");
 682                 }
 683             }
 684         }
 685 
 686         // check the "max_fragment_length" extension
 687         MaxFragmentLengthExtension maxFragLenExt = (MaxFragmentLengthExtension)
 688                 mesg.extensions.get(ExtensionType.EXT_MAX_FRAGMENT_LENGTH);
 689         if (maxFragLenExt != null) {
 690             if ((requestedMFLength == -1) ||
 691                     maxFragLenExt.getMaxFragLen() != requestedMFLength) {
 692                 // If the client did not request this extension, or the
 693                 // response value is different from the length it requested,
 694                 // abort the handshake with a fatal illegal_parameter alert.
 695                 fatalSE(Alerts.alert_illegal_parameter,
 696                         "Failed to negotiate the max_fragment_length");
 697             }
 698         } else if (!resumingSession) {
 699             // no "max_fragment_length" extension
 700             requestedMFLength = -1;
 701         }   // Otherwise, using the value negotiated during the original
 702             // session initiation 
 703 
 704         if (resumingSession && session != null) {
 705             setHandshakeSessionSE(session);
 706             // Reserve the handshake state if this is a session-resumption
 707             // abbreviated initial handshake.
 708             if (isInitialHandshake) {
 709                 session.setAsSessionResumption(true);
 710             }
 711 
 712             return;
 713         }
 714 
 715         // check extensions
 716         for (HelloExtension ext : mesg.extensions.list()) {
 717             ExtensionType type = ext.type;
 718             if (type == ExtensionType.EXT_SERVER_NAME) {
 719                 serverNamesAccepted = true;
 720             } else if ((type != ExtensionType.EXT_ELLIPTIC_CURVES)
 721                     && (type != ExtensionType.EXT_EC_POINT_FORMATS)
 722                     && (type != ExtensionType.EXT_SERVER_NAME)
 723                     && (type != ExtensionType.EXT_RENEGOTIATION_INFO)) {
 724                 fatalSE(Alerts.alert_unsupported_extension,
 725                     "Server sent an unsupported extension: " + type);
 726             }
 727         }
 728 
 729         // Create a new session, we need to do the full handshake
 730         session = new SSLSessionImpl(protocolVersion, cipherSuite,
 731                             getLocalSupportedSignAlgs(),
 732                             mesg.sessionId, getHostSE(), getPortSE());
 733         session.setRequestedServerNames(requestedServerNames);
 734         session.setNegotiatedMaxFragSize(requestedMFLength);
 735         session.setMaximumPacketSize(maximumPacketSize);
 736         setHandshakeSessionSE(session);
 737         if (debug != null && Debug.isOn("handshake")) {
 738             System.out.println("** " + cipherSuite);
 739         }
 740     }
 741 
 742     /*
 743      * Server's own key was either a signing-only key, or was too
 744      * large for export rules ... this message holds an ephemeral
 745      * RSA key to use for key exchange.
 746      */
 747     private void serverKeyExchange(RSA_ServerKeyExchange mesg)
 748             throws IOException, GeneralSecurityException {
 749         if (debug != null && Debug.isOn("handshake")) {
 750             mesg.print(System.out);
 751         }
 752         if (!mesg.verify(serverKey, clnt_random, svr_random)) {
 753             fatalSE(Alerts.alert_handshake_failure,
 754                 "server key exchange invalid");
 755             // NOTREACHED
 756         }
 757         ephemeralServerKey = mesg.getPublicKey();
 758     }
 759 

 760     /*
 761      * Diffie-Hellman key exchange.  We save the server public key and
 762      * our own D-H algorithm object so we can defer key calculations
 763      * until after we've sent the client key exchange message (which
 764      * gives client and server some useful parallelism).
 765      */
 766     private void serverKeyExchange(DH_ServerKeyExchange mesg)
 767             throws IOException {
 768         if (debug != null && Debug.isOn("handshake")) {
 769             mesg.print(System.out);
 770         }
 771         dh = new DHCrypt(mesg.getModulus(), mesg.getBase(),
 772                                             sslContext.getSecureRandom());
 773         serverDH = mesg.getServerPublicKey();
 774     }
 775 
 776     private void serverKeyExchange(ECDH_ServerKeyExchange mesg)
 777             throws IOException {
 778         if (debug != null && Debug.isOn("handshake")) {
 779             mesg.print(System.out);
 780         }
 781         ECPublicKey key = mesg.getPublicKey();
 782         ecdh = new ECDHCrypt(key.getParams(), sslContext.getSecureRandom());
 783         ephemeralServerKey = key;
 784     }
 785 
 786     /*
 787      * The server's "Hello Done" message is the client's sign that
 788      * it's time to do all the hard work.
 789      */
 790     private void serverHelloDone(ServerHelloDone mesg) throws IOException {
 791         if (debug != null && Debug.isOn("handshake")) {
 792             mesg.print(System.out);
 793         }







 794 
 795         /*
 796          * FIRST ... if requested, send an appropriate Certificate chain
 797          * to authenticate the client, and remember the associated private
 798          * key to sign the CertificateVerify message.
 799          */
 800         PrivateKey signingKey = null;
 801 
 802         if (certRequest != null) {
 803             X509ExtendedKeyManager km = sslContext.getX509KeyManager();
 804 
 805             ArrayList<String> keytypesTmp = new ArrayList<>(4);
 806 
 807             for (int i = 0; i < certRequest.types.length; i++) {
 808                 String typeName;
 809 
 810                 switch (certRequest.types[i]) {
 811                 case CertificateRequest.cct_rsa_sign:
 812                     typeName = "RSA";
 813                     break;


 868                                 params);
 869                         if (!SupportedEllipticCurvesExtension.isSupported(
 870                                 index)) {
 871                             publicKey = null;
 872                         }
 873                     }
 874                     if (publicKey != null) {
 875                         m1 = new CertificateMsg(certs);
 876                         signingKey = km.getPrivateKey(alias);
 877                         session.setLocalPrivateKey(signingKey);
 878                         session.setLocalCertificates(certs);
 879                     }
 880                 }
 881             }
 882             if (m1 == null) {
 883                 //
 884                 // No appropriate cert was found ... report this to the
 885                 // server.  For SSLv3, send the no_certificate alert;
 886                 // TLS uses an empty cert chain instead.
 887                 //
 888                 if (protocolVersion.useTLS10PlusSpec()) {
 889                     m1 = new CertificateMsg(new X509Certificate [0]);
 890                 } else {
 891                     warningSE(Alerts.alert_no_certificate);
 892                 }
 893                 if (debug != null && Debug.isOn("handshake")) {
 894                     System.out.println(
 895                         "Warning: no suitable certificate found - " +
 896                         "continuing without client authentication");
 897                 }
 898             }
 899 
 900             //
 901             // At last ... send any client certificate chain.
 902             //
 903             if (m1 != null) {
 904                 if (debug != null && Debug.isOn("handshake")) {
 905                     m1.print(System.out);
 906                 }
 907                 m1.write(output);
 908                 handshakeState.update(m1, resumingSession);
 909             }
 910         }
 911 
 912         /*
 913          * SECOND ... send the client key exchange message.  The
 914          * procedure used is a function of the cipher suite selected;
 915          * one is always needed.
 916          */
 917         HandshakeMessage m2;
 918 
 919         switch (keyExchange) {
 920 
 921         case K_RSA:
 922         case K_RSA_EXPORT:
 923             if (serverKey == null) {
 924                 throw new SSLProtocolException
 925                         ("Server did not send certificate message");
 926             }
 927 
 928             if (!(serverKey instanceof RSAPublicKey)) {


1052                 }
1053                 kerberosMsg = new KerberosClientKeyExchange(
1054                      hostname, getAccSE(), protocolVersion,
1055                      sslContext.getSecureRandom());
1056             }
1057 
1058             // Record the principals involved in exchange
1059             session.setPeerPrincipal(kerberosMsg.getPeerPrincipal());
1060             session.setLocalPrincipal(kerberosMsg.getLocalPrincipal());
1061             m2 = kerberosMsg;
1062             break;
1063         default:
1064             // somethings very wrong
1065             throw new RuntimeException
1066                                 ("Unsupported key exchange: " + keyExchange);
1067         }
1068         if (debug != null && Debug.isOn("handshake")) {
1069             m2.print(System.out);
1070         }
1071         m2.write(output);
1072         handshakeState.update(m2, resumingSession);
1073 

1074         /*
1075          * THIRD, send a "change_cipher_spec" record followed by the
1076          * "Finished" message.  We flush the messages we've queued up, to
1077          * get concurrency between client and server.  The concurrency is
1078          * useful as we calculate the master secret, which is needed both
1079          * to compute the "Finished" message, and to compute the keys used
1080          * to protect all records following the change_cipher_spec.
1081          */


1082         output.flush();
1083 
1084         /*
1085          * We deferred calculating the master secret and this connection's
1086          * keying data; we do it now.  Deferring this calculation is good
1087          * from a performance point of view, since it lets us do it during
1088          * some time that network delays and the server's own calculations
1089          * would otherwise cause to be "dead" in the critical path.
1090          */
1091         SecretKey preMasterSecret;
1092         switch (keyExchange) {
1093         case K_RSA:
1094         case K_RSA_EXPORT:
1095             preMasterSecret = ((RSAClientKeyExchange)m2).preMaster;
1096             break;
1097         case K_KRB5:
1098         case K_KRB5_EXPORT:
1099             byte[] secretBytes =
1100                 ((KerberosClientKeyExchange)m2).getUnencryptedPreMasterSecret();
1101             preMasterSecret = new SecretKeySpec(secretBytes,


1119             throw new IOException("Internal error: unknown key exchange "
1120                 + keyExchange);
1121         }
1122 
1123         calculateKeys(preMasterSecret, null);
1124 
1125         /*
1126          * FOURTH, if we sent a Certificate, we need to send a signed
1127          * CertificateVerify (unless the key in the client's certificate
1128          * was a Diffie-Hellman key).).
1129          *
1130          * This uses a hash of the previous handshake messages ... either
1131          * a nonfinal one (if the particular implementation supports it)
1132          * or else using the third element in the arrays of hashes being
1133          * computed.
1134          */
1135         if (signingKey != null) {
1136             CertificateVerify m3;
1137             try {
1138                 SignatureAndHashAlgorithm preferableSignatureAlgorithm = null;
1139                 if (protocolVersion.useTLS12PlusSpec()) {
1140                     preferableSignatureAlgorithm =
1141                         SignatureAndHashAlgorithm.getPreferableAlgorithm(
1142                             peerSupportedSignAlgs, signingKey.getAlgorithm(),
1143                             signingKey);
1144 
1145                     if (preferableSignatureAlgorithm == null) {
1146                         throw new SSLHandshakeException(
1147                             "No supported signature algorithm");
1148                     }
1149 
1150                     String hashAlg =
1151                         SignatureAndHashAlgorithm.getHashAlgorithmName(
1152                                 preferableSignatureAlgorithm);
1153                     if (hashAlg == null || hashAlg.length() == 0) {
1154                         throw new SSLHandshakeException(
1155                                 "No supported hash algorithm");
1156                     }
1157                 }
1158 
1159                 m3 = new CertificateVerify(protocolVersion, handshakeHash,
1160                     signingKey, session.getMasterSecret(),
1161                     sslContext.getSecureRandom(),
1162                     preferableSignatureAlgorithm);
1163             } catch (GeneralSecurityException e) {
1164                 fatalSE(Alerts.alert_handshake_failure,
1165                     "Error signing certificate verify", e);
1166                 // NOTREACHED, make compiler happy
1167                 m3 = null;
1168             }
1169             if (debug != null && Debug.isOn("handshake")) {
1170                 m3.print(System.out);
1171             }
1172             m3.write(output);
1173             handshakeState.update(m3, resumingSession);
1174             output.flush();
1175         }
1176 
1177         /*
1178          * OK, that's that!
1179          */
1180         sendChangeCipherAndFinish(false);
1181 
1182         // expecting the final ChangeCipherSpec and Finished messages
1183         expectingFinishFlightSE();
1184     }
1185 
1186 
1187     /*
1188      * "Finished" is the last handshake message sent.  If we got this
1189      * far, the MAC has been validated post-decryption.  We validate
1190      * the two hashes here as an additional sanity check, protecting
1191      * the handshake against various active attacks.
1192      */
1193     private void serverFinished(Finished mesg) throws IOException {
1194         if (debug != null && Debug.isOn("handshake")) {
1195             mesg.print(System.out);
1196         }
1197 
1198         boolean verified = mesg.verify(handshakeHash, Finished.SERVER,
1199             session.getMasterSecret());
1200 
1201         if (!verified) {
1202             fatalSE(Alerts.alert_illegal_parameter,
1203                        "server 'finished' message doesn't verify");


1212         }
1213 
1214         /*
1215          * Reset the handshake state if this is not an initial handshake.
1216          */
1217         if (!isInitialHandshake) {
1218             session.setAsSessionResumption(false);
1219         }
1220 
1221         /*
1222          * OK, it verified.  If we're doing the fast handshake, add that
1223          * "Finished" message to the hash of handshake messages, then send
1224          * our own change_cipher_spec and Finished message for the server
1225          * to verify in turn.  These are the last handshake messages.
1226          *
1227          * In any case, update the session cache.  We're done handshaking,
1228          * so there are no threats any more associated with partially
1229          * completed handshakes.
1230          */
1231         if (resumingSession) {

1232             sendChangeCipherAndFinish(true);
1233         } else {
1234             handshakeFinished = true;
1235         }
1236         session.setLastAccessedTime(System.currentTimeMillis());
1237 
1238         if (!resumingSession) {
1239             if (session.isRejoinable()) {
1240                 ((SSLSessionContextImpl) sslContext
1241                         .engineGetClientSessionContext())
1242                         .put(session);
1243                 if (debug != null && Debug.isOn("session")) {
1244                     System.out.println("%% Cached client session: " + session);
1245                 }
1246             } else if (debug != null && Debug.isOn("session")) {
1247                 System.out.println(
1248                     "%% Didn't cache non-resumable client session: "
1249                     + session);
1250             }
1251         }
1252     }
1253 
1254 
1255     /*
1256      * Send my change-cipher-spec and Finished message ... done as the
1257      * last handshake act in either the short or long sequences.  In
1258      * the short one, we've already seen the server's Finished; in the
1259      * long one, we wait for it now.
1260      */
1261     private void sendChangeCipherAndFinish(boolean finishedTag)
1262             throws IOException {
1263 
1264         // Reload if this message has been reserved.
1265         handshakeHash.reload();
1266 
1267         Finished mesg = new Finished(protocolVersion, handshakeHash,
1268             Finished.CLIENT, session.getMasterSecret(), cipherSuite);
1269 
1270         /*
1271          * Send the change_cipher_spec message, then the Finished message
1272          * which we just calculated (and protected using the keys we just
1273          * calculated).  Server responds with its Finished message, except
1274          * in the "fast handshake" (resume session) case.
1275          */
1276         sendChangeCipherSpec(mesg, finishedTag);
1277 
1278         /*
1279          * save client verify data for secure renegotiation
1280          */
1281         if (secureRenegotiation) {
1282             clientVerifyData = mesg.getVerifyData();
1283         }







1284     }
1285 
1286 
1287     /*
1288      * Returns a ClientHello message to kickstart renegotiations
1289      */
1290     @Override
1291     HandshakeMessage getKickstartMessage() throws SSLException {
1292         // session ID of the ClientHello message
1293         SessionId sessionId = SSLSessionImpl.nullSession.getSessionId();
1294 
1295         // a list of cipher suites sent by the client
1296         CipherSuiteList cipherSuites = getActiveCipherSuites();
1297 
1298         // set the max protocol version this client is supporting.
1299         maxProtocolVersion = protocolVersion;
1300 
1301         //
1302         // Try to resume an existing session.  This might be mandatory,
1303         // given certain API options.


1413                 break;
1414             }
1415         }
1416 
1417         if (!negotiable) {
1418             throw new SSLHandshakeException("No negotiable cipher suite");
1419         }
1420 
1421         // Not a TLS1.2+ handshake
1422         // For SSLv2Hello, HandshakeHash.reset() will be called, so we
1423         // cannot call HandshakeHash.protocolDetermined() here. As it does
1424         // not follow the spec that HandshakeHash.reset() can be only be
1425         // called before protocolDetermined.
1426         // if (maxProtocolVersion.v < ProtocolVersion.TLS12.v) {
1427         //     handshakeHash.protocolDetermined(maxProtocolVersion);
1428         // }
1429 
1430         // create the ClientHello message
1431         ClientHello clientHelloMessage = new ClientHello(
1432                 sslContext.getSecureRandom(), maxProtocolVersion,
1433                 sessionId, cipherSuites, isDTLS);
1434 
1435         // add signature_algorithm extension
1436         if (maxProtocolVersion.useTLS12PlusSpec()) {
1437             // we will always send the signature_algorithm extension
1438             Collection<SignatureAndHashAlgorithm> localSignAlgs =
1439                                                 getLocalSupportedSignAlgs();
1440             if (localSignAlgs.isEmpty()) {
1441                 throw new SSLHandshakeException(
1442                             "No supported signature algorithm");
1443             }
1444 
1445             clientHelloMessage.addSignatureAlgorithmsExtension(localSignAlgs);
1446         }
1447 
1448         // add server_name extension
1449         if (enableSNIExtension) {
1450             if (session != null) {
1451                 requestedServerNames = session.getRequestedServerNames();
1452             } else {
1453                 requestedServerNames = serverNames;
1454             }
1455 
1456             if (!requestedServerNames.isEmpty()) {
1457                 clientHelloMessage.addSNIExtension(requestedServerNames);
1458             }
1459         }
1460 
1461         // add max_fragment_length extension
1462         if (enableMFLExtension) {
1463             if (session != null) {
1464                 // The same extension should be sent for resumption.
1465                 requestedMFLength = session.getNegotiatedMaxFragSize();
1466             } else if (maximumPacketSize != 0) {
1467                 // Maybe we can calculate the fragment size more accurate
1468                 // by condering the enabled cipher suites in the future.
1469                 requestedMFLength = maximumPacketSize;
1470                 if (isDTLS) {
1471                     requestedMFLength -= DTLSRecord.maxPlaintextPlusSize;
1472                 } else {
1473                     requestedMFLength -= SSLRecord.maxPlaintextPlusSize;
1474                 }
1475             } else {
1476                 // Need no max_fragment_length extension.
1477                 requestedMFLength = -1;
1478             }
1479 
1480             if ((requestedMFLength > 0) &&
1481                 MaxFragmentLengthExtension.needFragLenNego(requestedMFLength)) {
1482 
1483                 requestedMFLength =
1484                         MaxFragmentLengthExtension.getValidMaxFragLen(
1485                                                         requestedMFLength);
1486                 clientHelloMessage.addMFLExtension(requestedMFLength);
1487             } else {
1488                 requestedMFLength = -1;
1489             }
1490         }
1491 
1492         // reset the client random cookie
1493         clnt_random = clientHelloMessage.clnt_random;
1494 
1495         /*
1496          * need to set the renegotiation_info extension for:
1497          * 1: secure renegotiation
1498          * 2: initial handshake and no SCSV in the ClientHello
1499          * 3: insecure renegotiation and no SCSV in the ClientHello
1500          */
1501         if (secureRenegotiation ||
1502                 !cipherSuites.contains(CipherSuite.C_SCSV)) {
1503             clientHelloMessage.addRenegotiationInfoExtension(clientVerifyData);
1504         }
1505 
1506         if (isDTLS) {
1507             // Cookie exchange need to reserve the initial ClientHello message.
1508             initialClientHelloMsg = clientHelloMessage;
1509         }
1510 
1511         return clientHelloMessage;
1512     }
1513 
1514     /*
1515      * Fault detected during handshake.
1516      */
1517     @Override
1518     void handshakeAlert(byte description) throws SSLProtocolException {
1519         String message = Alerts.alertDescription(description);
1520 
1521         if (debug != null && Debug.isOn("handshake")) {
1522             System.out.println("SSL - handshake alert: " + message);
1523         }
1524         throw new SSLProtocolException("handshake alert:  " + message);
1525     }
1526 
1527     /*
1528      * Unless we are using an anonymous ciphersuite, the server always
1529      * sends a certificate message (for the CipherSuites we currently
1530      * support). The trust manager verifies the chain for us.