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(sessionSuite.keyExchange.name); 659 if (p != null) { 660 Principal localPrincipal = session.getLocalPrincipal(); 661 662 if (p.isRelated(true, getAccSE(), localPrincipal)) { 663 if (debug != null && Debug.isOn("session")) 664 System.out.println("Subject identity is same"); 665 } else { 666 throw new SSLProtocolException("Server resumed" + 667 " session with wrong subject identity or 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 // 680 // Invalidate the session for initial handshake in case 681 // of reusing next time. 682 if (isInitialHandshake) { 683 session.invalidate(); 684 } 685 session = null; 686 if (!enableNewSession) { 687 throw new SSLException("New session creation is disabled"); 688 } 689 } 690 } 691 692 // check the "max_fragment_length" extension 693 MaxFragmentLengthExtension maxFragLenExt = (MaxFragmentLengthExtension) 694 mesg.extensions.get(ExtensionType.EXT_MAX_FRAGMENT_LENGTH); 695 if (maxFragLenExt != null) { 696 if ((requestedMFLength == -1) || 697 maxFragLenExt.getMaxFragLen() != requestedMFLength) { 698 // If the client did not request this extension, or the 699 // response value is different from the length it requested, 700 // abort the handshake with a fatal illegal_parameter alert. 701 fatalSE(Alerts.alert_illegal_parameter, 702 "Failed to negotiate the max_fragment_length"); 703 } 704 } else if (!resumingSession) { 705 // no "max_fragment_length" extension 706 requestedMFLength = -1; 707 } // Otherwise, using the value negotiated during the original 708 // session initiation 709 710 // check the ALPN extension 711 ALPNExtension serverHelloALPN = 712 (ALPNExtension) mesg.extensions.get(ExtensionType.EXT_ALPN); 713 714 if (serverHelloALPN != null) { 715 // Check whether an ALPN extension was sent in ClientHello message 716 if (!alpnActive) { 717 fatalSE(Alerts.alert_unsupported_extension, 718 "Server sent " + ExtensionType.EXT_ALPN + 719 " extension when not requested by client"); 720 } 721 722 List<String> protocols = serverHelloALPN.getPeerAPs(); 723 // Only one application protocol name should be present 724 String p; 725 if ((protocols.size() == 1) && 726 !((p = protocols.get(0)).isEmpty())) { 727 int i; 728 for (i = 0; i < localApl.length; i++) { 729 if (localApl[i].equals(p)) { 730 break; 731 } 732 } 733 if (i == localApl.length) { 734 fatalSE(Alerts.alert_handshake_failure, 735 "Server has selected an application protocol name " + 736 "which was not offered by the client: " + p); 737 } 738 applicationProtocol = p; 739 } else { 740 fatalSE(Alerts.alert_handshake_failure, 741 "Incorrect data in ServerHello " + ExtensionType.EXT_ALPN + 742 " message"); 743 } 744 } else { 745 applicationProtocol = ""; 746 } 747 748 if (resumingSession && session != null) { 749 setHandshakeSessionSE(session); 750 // Reserve the handshake state if this is a session-resumption 751 // abbreviated initial handshake. 752 if (isInitialHandshake) { 753 session.setAsSessionResumption(true); 754 } 755 756 return; 757 } 758 759 // check extensions 760 for (HelloExtension ext : mesg.extensions.list()) { 761 ExtensionType type = ext.type; 762 if (type == ExtensionType.EXT_SERVER_NAME) { 763 serverNamesAccepted = true; 764 } else if (type == ExtensionType.EXT_STATUS_REQUEST || 765 type == ExtensionType.EXT_STATUS_REQUEST_V2) { 766 // Only enable the stapling feature if the client asserted 767 // these extensions. 768 if (sslContext.isStaplingEnabled(true)) { 769 staplingActive = true; 770 } else { 771 fatalSE(Alerts.alert_unexpected_message, "Server set " + 772 type + " extension when not requested by client"); 773 } 774 } else if ((type != ExtensionType.EXT_SUPPORTED_GROUPS) 775 && (type != ExtensionType.EXT_EC_POINT_FORMATS) 776 && (type != ExtensionType.EXT_SERVER_NAME) 777 && (type != ExtensionType.EXT_ALPN) 778 && (type != ExtensionType.EXT_RENEGOTIATION_INFO) 779 && (type != ExtensionType.EXT_STATUS_REQUEST) 780 && (type != ExtensionType.EXT_STATUS_REQUEST_V2)) { 781 // Note: Better to check client requested extensions rather 782 // than all supported extensions. 783 fatalSE(Alerts.alert_unsupported_extension, 784 "Server sent an unsupported extension: " + type); 785 } 786 } 787 788 // Create a new session, we need to do the full handshake 789 session = new SSLSessionImpl(protocolVersion, cipherSuite, 790 getLocalSupportedSignAlgs(), 791 mesg.sessionId, getHostSE(), getPortSE()); 792 session.setRequestedServerNames(requestedServerNames); 793 session.setNegotiatedMaxFragSize(requestedMFLength); 794 session.setMaximumPacketSize(maximumPacketSize); 795 setHandshakeSessionSE(session); 796 if (debug != null && Debug.isOn("handshake")) { 797 System.out.println("** " + cipherSuite); 798 } 799 } 800 801 /* 802 * Server's own key was either a signing-only key, or was too 803 * large for export rules ... this message holds an ephemeral 804 * RSA key to use for key exchange. 805 */ 806 private void serverKeyExchange(RSA_ServerKeyExchange mesg) 807 throws IOException, GeneralSecurityException { 808 if (debug != null && Debug.isOn("handshake")) { 809 mesg.print(System.out); 810 } 811 if (!mesg.verify(serverKey, clnt_random, svr_random)) { 812 fatalSE(Alerts.alert_handshake_failure, 813 "server key exchange invalid"); 814 // NOTREACHED 815 } 816 ephemeralServerKey = mesg.getPublicKey(); 817 818 // check constraints of RSA PublicKey 819 if (!algorithmConstraints.permits( 820 EnumSet.of(CryptoPrimitive.KEY_AGREEMENT), ephemeralServerKey)) { 821 822 throw new SSLHandshakeException("RSA ServerKeyExchange " + 823 "does not comply to algorithm constraints"); 824 } 825 } 826 827 /* 828 * Diffie-Hellman key exchange. We save the server public key and 829 * our own D-H algorithm object so we can defer key calculations 830 * until after we've sent the client key exchange message (which 831 * gives client and server some useful parallelism). 832 * 833 * Note per section 3 of RFC 7919, if the server is not compatible with 834 * FFDHE specification, the client MAY decide to continue the connection 835 * if the selected DHE group is acceptable under local policy, or it MAY 836 * decide to terminate the connection with a fatal insufficient_security 837 * (71) alert. The algorithm constraints mechanism is JDK local policy 838 * used for additional DHE parameters checking. So this implementation 839 * does not check the server compatibility and just pass to the local 840 * algorithm constraints checking. The client will continue the 841 * connection if the server selected DHE group is acceptable by the 842 * specified algorithm constraints. 843 */ 844 private void serverKeyExchange(DH_ServerKeyExchange mesg) 845 throws IOException { 846 if (debug != null && Debug.isOn("handshake")) { 847 mesg.print(System.out); 848 } 849 dh = new DHCrypt(mesg.getModulus(), mesg.getBase(), 850 sslContext.getSecureRandom()); 851 serverDH = mesg.getServerPublicKey(); 852 853 // check algorithm constraints 854 dh.checkConstraints(algorithmConstraints, serverDH); 855 } 856 857 private void serverKeyExchange(ECDH_ServerKeyExchange mesg) 858 throws IOException { 859 if (debug != null && Debug.isOn("handshake")) { 860 mesg.print(System.out); 861 } 862 ECPublicKey key = mesg.getPublicKey(); 863 ecdh = new ECDHCrypt(key.getParams(), sslContext.getSecureRandom()); 864 ephemeralServerKey = key; 865 866 // check constraints of EC PublicKey 867 if (!algorithmConstraints.permits( 868 EnumSet.of(CryptoPrimitive.KEY_AGREEMENT), ephemeralServerKey)) { 869 870 throw new SSLHandshakeException("ECDH ServerKeyExchange " + 871 "does not comply to algorithm constraints"); 872 } 873 } 874 875 /* 876 * The server's "Hello Done" message is the client's sign that 877 * it's time to do all the hard work. 878 */ 879 private void serverHelloDone(ServerHelloDone mesg) throws IOException { 880 if (debug != null && Debug.isOn("handshake")) { 881 mesg.print(System.out); 882 } 883 884 /* 885 * FIRST ... if requested, send an appropriate Certificate chain 886 * to authenticate the client, and remember the associated private 887 * key to sign the CertificateVerify message. 888 */ 889 PrivateKey signingKey = null; 890 891 if (certRequest != null) { 892 X509ExtendedKeyManager km = sslContext.getX509KeyManager(); 893 894 ArrayList<String> keytypesTmp = new ArrayList<>(4); 895 896 for (int i = 0; i < certRequest.types.length; i++) { 897 String typeName; 898 899 switch (certRequest.types[i]) { 900 case CertificateRequest.cct_rsa_sign: 901 typeName = "RSA"; 902 break; 903 904 case CertificateRequest.cct_dss_sign: 905 typeName = "DSA"; 906 break; 907 908 case CertificateRequest.cct_ecdsa_sign: 909 // ignore if we do not have EC crypto available 910 typeName = JsseJce.isEcAvailable() ? "EC" : null; 911 break; 912 913 // Fixed DH/ECDH client authentication not supported 914 // 915 // case CertificateRequest.cct_rsa_fixed_dh: 916 // case CertificateRequest.cct_dss_fixed_dh: 917 // case CertificateRequest.cct_rsa_fixed_ecdh: 918 // case CertificateRequest.cct_ecdsa_fixed_ecdh: 919 // 920 // Any other values (currently not used in TLS) 921 // 922 // case CertificateRequest.cct_rsa_ephemeral_dh: 923 // case CertificateRequest.cct_dss_ephemeral_dh: 924 default: 925 typeName = null; 926 break; 927 } 928 929 if ((typeName != null) && (!keytypesTmp.contains(typeName))) { 930 keytypesTmp.add(typeName); 931 } 932 } 933 934 String alias = null; 935 int keytypesTmpSize = keytypesTmp.size(); 936 if (keytypesTmpSize != 0) { 937 String[] keytypes = 938 keytypesTmp.toArray(new String[keytypesTmpSize]); 939 940 if (conn != null) { 941 alias = km.chooseClientAlias(keytypes, 942 certRequest.getAuthorities(), conn); 943 } else { 944 alias = km.chooseEngineClientAlias(keytypes, 945 certRequest.getAuthorities(), engine); 946 } 947 } 948 949 CertificateMsg m1 = null; 950 if (alias != null) { 951 X509Certificate[] certs = km.getCertificateChain(alias); 952 if ((certs != null) && (certs.length != 0)) { 953 PublicKey publicKey = certs[0].getPublicKey(); 954 if (publicKey != null) { 955 m1 = new CertificateMsg(certs); 956 signingKey = km.getPrivateKey(alias); 957 session.setLocalPrivateKey(signingKey); 958 session.setLocalCertificates(certs); 959 } 960 } 961 } 962 if (m1 == null) { 963 // 964 // No appropriate cert was found ... report this to the 965 // server. For SSLv3, send the no_certificate alert; 966 // TLS uses an empty cert chain instead. 967 // 968 if (protocolVersion.useTLS10PlusSpec()) { 969 m1 = new CertificateMsg(new X509Certificate [0]); 970 } else { 971 warningSE(Alerts.alert_no_certificate); 972 } 973 if (debug != null && Debug.isOn("handshake")) { 974 System.out.println( 975 "Warning: no suitable certificate found - " + 976 "continuing without client authentication"); 977 } 978 } 979 980 // 981 // At last ... send any client certificate chain. 982 // 983 if (m1 != null) { 984 if (debug != null && Debug.isOn("handshake")) { 985 m1.print(System.out); 986 } 987 m1.write(output); 988 handshakeState.update(m1, resumingSession); 989 } 990 } 991 992 /* 993 * SECOND ... send the client key exchange message. The 994 * procedure used is a function of the cipher suite selected; 995 * one is always needed. 996 */ 997 HandshakeMessage m2; 998 999 switch (keyExchange) { 1000 1001 case K_RSA: 1002 case K_RSA_EXPORT: 1003 if (serverKey == null) { 1004 throw new SSLProtocolException 1005 ("Server did not send certificate message"); 1006 } 1007 1008 if (!(serverKey instanceof RSAPublicKey)) { 1009 throw new SSLProtocolException 1010 ("Server certificate does not include an RSA key"); 1011 } 1012 1013 /* 1014 * For RSA key exchange, we randomly generate a new 1015 * pre-master secret and encrypt it with the server's 1016 * public key. Then we save that pre-master secret 1017 * so that we can calculate the keying data later; 1018 * it's a performance speedup not to do that until 1019 * the client's waiting for the server response, but 1020 * more of a speedup for the D-H case. 1021 * 1022 * If the RSA_EXPORT scheme is active, when the public 1023 * key in the server certificate is less than or equal 1024 * to 512 bits in length, use the cert's public key, 1025 * otherwise, the ephemeral one. 1026 */ 1027 PublicKey key; 1028 if (keyExchange == K_RSA) { 1029 key = serverKey; 1030 } else { // K_RSA_EXPORT 1031 if (JsseJce.getRSAKeyLength(serverKey) <= 512) { 1032 // extraneous ephemeralServerKey check done 1033 // above in processMessage() 1034 key = serverKey; 1035 } else { 1036 if (ephemeralServerKey == null) { 1037 throw new SSLProtocolException("Server did not send" + 1038 " a RSA_EXPORT Server Key Exchange message"); 1039 } 1040 key = ephemeralServerKey; 1041 } 1042 } 1043 1044 m2 = new RSAClientKeyExchange(protocolVersion, maxProtocolVersion, 1045 sslContext.getSecureRandom(), key); 1046 break; 1047 case K_DH_RSA: 1048 case K_DH_DSS: 1049 /* 1050 * For DH Key exchange, we only need to make sure the server 1051 * knows our public key, so we calculate the same pre-master 1052 * secret. 1053 * 1054 * For certs that had DH keys in them, we send an empty 1055 * handshake message (no key) ... we flag this case by 1056 * passing a null "dhPublic" value. 1057 * 1058 * Otherwise we send ephemeral DH keys, unsigned. 1059 */ 1060 // if (useDH_RSA || useDH_DSS) 1061 m2 = new DHClientKeyExchange(); 1062 break; 1063 case K_DHE_RSA: 1064 case K_DHE_DSS: 1065 case K_DH_ANON: 1066 if (dh == null) { 1067 throw new SSLProtocolException 1068 ("Server did not send a DH Server Key Exchange message"); 1069 } 1070 m2 = new DHClientKeyExchange(dh.getPublicKey()); 1071 break; 1072 case K_ECDHE_RSA: 1073 case K_ECDHE_ECDSA: 1074 case K_ECDH_ANON: 1075 if (ecdh == null) { 1076 throw new SSLProtocolException 1077 ("Server did not send a ECDH Server Key Exchange message"); 1078 } 1079 m2 = new ECDHClientKeyExchange(ecdh.getPublicKey()); 1080 break; 1081 case K_ECDH_RSA: 1082 case K_ECDH_ECDSA: 1083 if (serverKey == null) { 1084 throw new SSLProtocolException 1085 ("Server did not send certificate message"); 1086 } 1087 if (serverKey instanceof ECPublicKey == false) { 1088 throw new SSLProtocolException 1089 ("Server certificate does not include an EC key"); 1090 } 1091 ECParameterSpec params = ((ECPublicKey)serverKey).getParams(); 1092 ecdh = new ECDHCrypt(params, sslContext.getSecureRandom()); 1093 m2 = new ECDHClientKeyExchange(ecdh.getPublicKey()); 1094 break; 1095 default: 1096 ClientKeyExchangeService p = 1097 ClientKeyExchangeService.find(keyExchange.name); 1098 if (p == null) { 1099 // somethings very wrong 1100 throw new RuntimeException 1101 ("Unsupported key exchange: " + keyExchange); 1102 } 1103 String sniHostname = null; 1104 for (SNIServerName serverName : requestedServerNames) { 1105 if (serverName instanceof SNIHostName) { 1106 sniHostname = ((SNIHostName) serverName).getAsciiName(); 1107 break; 1108 } 1109 } 1110 1111 ClientKeyExchange exMsg = null; 1112 if (sniHostname != null) { 1113 // use first requested SNI hostname 1114 try { 1115 exMsg = p.createClientExchange( 1116 sniHostname, getAccSE(), protocolVersion, 1117 sslContext.getSecureRandom()); 1118 } catch(IOException e) { 1119 if (serverNamesAccepted) { 1120 // server accepted requested SNI hostname, 1121 // so it must be used 1122 throw e; 1123 } 1124 // fallback to using hostname 1125 if (debug != null && Debug.isOn("handshake")) { 1126 System.out.println( 1127 "Warning, cannot use Server Name Indication: " 1128 + e.getMessage()); 1129 } 1130 } 1131 } 1132 1133 if (exMsg == null) { 1134 String hostname = getHostSE(); 1135 if (hostname == null) { 1136 throw new IOException("Hostname is required" + 1137 " to use " + keyExchange + " key exchange"); 1138 } 1139 exMsg = p.createClientExchange( 1140 hostname, getAccSE(), protocolVersion, 1141 sslContext.getSecureRandom()); 1142 } 1143 1144 // Record the principals involved in exchange 1145 session.setPeerPrincipal(exMsg.getPeerPrincipal()); 1146 session.setLocalPrincipal(exMsg.getLocalPrincipal()); 1147 m2 = exMsg; 1148 break; 1149 } 1150 if (debug != null && Debug.isOn("handshake")) { 1151 m2.print(System.out); 1152 } 1153 m2.write(output); 1154 handshakeState.update(m2, resumingSession); 1155 1156 /* 1157 * THIRD, send a "change_cipher_spec" record followed by the 1158 * "Finished" message. We flush the messages we've queued up, to 1159 * get concurrency between client and server. The concurrency is 1160 * useful as we calculate the master secret, which is needed both 1161 * to compute the "Finished" message, and to compute the keys used 1162 * to protect all records following the change_cipher_spec. 1163 */ 1164 output.flush(); 1165 1166 /* 1167 * We deferred calculating the master secret and this connection's 1168 * keying data; we do it now. Deferring this calculation is good 1169 * from a performance point of view, since it lets us do it during 1170 * some time that network delays and the server's own calculations 1171 * would otherwise cause to be "dead" in the critical path. 1172 */ 1173 SecretKey preMasterSecret; 1174 switch (keyExchange) { 1175 case K_RSA: 1176 case K_RSA_EXPORT: 1177 preMasterSecret = ((RSAClientKeyExchange)m2).preMaster; 1178 break; 1179 case K_DHE_RSA: 1180 case K_DHE_DSS: 1181 case K_DH_ANON: 1182 preMasterSecret = dh.getAgreedSecret(serverDH, true); 1183 break; 1184 case K_ECDHE_RSA: 1185 case K_ECDHE_ECDSA: 1186 case K_ECDH_ANON: 1187 preMasterSecret = ecdh.getAgreedSecret(ephemeralServerKey); 1188 break; 1189 case K_ECDH_RSA: 1190 case K_ECDH_ECDSA: 1191 preMasterSecret = ecdh.getAgreedSecret(serverKey); 1192 break; 1193 default: 1194 if (ClientKeyExchangeService.find(keyExchange.name) != null) { 1195 preMasterSecret = 1196 ((ClientKeyExchange) m2).clientKeyExchange(); 1197 } else { 1198 throw new IOException("Internal error: unknown key exchange " 1199 + keyExchange); 1200 } 1201 } 1202 1203 calculateKeys(preMasterSecret, null); 1204 1205 /* 1206 * FOURTH, if we sent a Certificate, we need to send a signed 1207 * CertificateVerify (unless the key in the client's certificate 1208 * was a Diffie-Hellman key). 1209 * 1210 * This uses a hash of the previous handshake messages ... either 1211 * a nonfinal one (if the particular implementation supports it) 1212 * or else using the third element in the arrays of hashes being 1213 * computed. 1214 */ 1215 if (signingKey != null) { 1216 CertificateVerify m3; 1217 try { 1218 SignatureAndHashAlgorithm preferableSignatureAlgorithm = null; 1219 if (protocolVersion.useTLS12PlusSpec()) { 1220 preferableSignatureAlgorithm = 1221 SignatureAndHashAlgorithm.getPreferableAlgorithm( 1222 getPeerSupportedSignAlgs(), 1223 signingKey.getAlgorithm(), signingKey); 1224 1225 if (preferableSignatureAlgorithm == null) { 1226 throw new SSLHandshakeException( 1227 "No supported signature algorithm"); 1228 } 1229 1230 String hashAlg = 1231 SignatureAndHashAlgorithm.getHashAlgorithmName( 1232 preferableSignatureAlgorithm); 1233 if (hashAlg == null || hashAlg.length() == 0) { 1234 throw new SSLHandshakeException( 1235 "No supported hash algorithm"); 1236 } 1237 } 1238 1239 m3 = new CertificateVerify(protocolVersion, handshakeHash, 1240 signingKey, session.getMasterSecret(), 1241 sslContext.getSecureRandom(), 1242 preferableSignatureAlgorithm); 1243 } catch (GeneralSecurityException e) { 1244 fatalSE(Alerts.alert_handshake_failure, 1245 "Error signing certificate verify", e); 1246 // NOTREACHED, make compiler happy 1247 m3 = null; 1248 } 1249 if (debug != null && Debug.isOn("handshake")) { 1250 m3.print(System.out); 1251 } 1252 m3.write(output); 1253 handshakeState.update(m3, resumingSession); 1254 output.flush(); 1255 } 1256 1257 /* 1258 * OK, that's that! 1259 */ 1260 sendChangeCipherAndFinish(false); 1261 1262 // expecting the final ChangeCipherSpec and Finished messages 1263 expectingFinishFlightSE(); 1264 } 1265 1266 1267 /* 1268 * "Finished" is the last handshake message sent. If we got this 1269 * far, the MAC has been validated post-decryption. We validate 1270 * the two hashes here as an additional sanity check, protecting 1271 * the handshake against various active attacks. 1272 */ 1273 private void serverFinished(Finished mesg) throws IOException { 1274 if (debug != null && Debug.isOn("handshake")) { 1275 mesg.print(System.out); 1276 } 1277 1278 boolean verified = mesg.verify(handshakeHash, Finished.SERVER, 1279 session.getMasterSecret()); 1280 1281 if (!verified) { 1282 fatalSE(Alerts.alert_illegal_parameter, 1283 "server 'finished' message doesn't verify"); 1284 // NOTREACHED 1285 } 1286 1287 /* 1288 * save server verify data for secure renegotiation and TLS channel binding 1289 */ 1290 serverVerifyData = mesg.getVerifyData(); 1291 1292 /* 1293 * Reset the handshake state if this is not an initial handshake. 1294 */ 1295 if (!isInitialHandshake) { 1296 session.setAsSessionResumption(false); 1297 } 1298 1299 /* 1300 * OK, it verified. If we're doing the fast handshake, add that 1301 * "Finished" message to the hash of handshake messages, then send 1302 * our own change_cipher_spec and Finished message for the server 1303 * to verify in turn. These are the last handshake messages. 1304 * 1305 * In any case, update the session cache. We're done handshaking, 1306 * so there are no threats any more associated with partially 1307 * completed handshakes. 1308 */ 1309 if (resumingSession) { 1310 sendChangeCipherAndFinish(true); 1311 } else { 1312 handshakeFinished = true; 1313 } 1314 session.setLastAccessedTime(System.currentTimeMillis()); 1315 1316 if (!resumingSession) { 1317 if (session.isRejoinable()) { 1318 ((SSLSessionContextImpl) sslContext 1319 .engineGetClientSessionContext()) 1320 .put(session); 1321 if (debug != null && Debug.isOn("session")) { 1322 System.out.println("%% Cached client session: " + session); 1323 } 1324 } else if (debug != null && Debug.isOn("session")) { 1325 System.out.println( 1326 "%% Didn't cache non-resumable client session: " 1327 + session); 1328 } 1329 } 1330 } 1331 1332 1333 /* 1334 * Send my change-cipher-spec and Finished message ... done as the 1335 * last handshake act in either the short or long sequences. In 1336 * the short one, we've already seen the server's Finished; in the 1337 * long one, we wait for it now. 1338 */ 1339 private void sendChangeCipherAndFinish(boolean finishedTag) 1340 throws IOException { 1341 1342 // Reload if this message has been reserved. 1343 handshakeHash.reload(); 1344 1345 Finished mesg = new Finished(protocolVersion, handshakeHash, 1346 Finished.CLIENT, session.getMasterSecret(), cipherSuite); 1347 1348 /* 1349 * Send the change_cipher_spec message, then the Finished message 1350 * which we just calculated (and protected using the keys we just 1351 * calculated). Server responds with its Finished message, except 1352 * in the "fast handshake" (resume session) case. 1353 */ 1354 sendChangeCipherSpec(mesg, finishedTag); 1355 1356 /* 1357 * save client verify data for secure renegotiation and TLS channel binding 1358 */ 1359 clientVerifyData = mesg.getVerifyData(); 1360 } 1361 1362 1363 /* 1364 * Returns a ClientHello message to kickstart renegotiations 1365 */ 1366 @Override 1367 HandshakeMessage getKickstartMessage() throws SSLException { 1368 // session ID of the ClientHello message 1369 SessionId sessionId = SSLSessionImpl.nullSession.getSessionId(); 1370 1371 // a list of cipher suites sent by the client 1372 CipherSuiteList cipherSuites = getActiveCipherSuites(); 1373 1374 // set the max protocol version this client is supporting. 1375 maxProtocolVersion = protocolVersion; 1376 1377 // 1378 // Try to resume an existing session. This might be mandatory, 1379 // given certain API options. 1380 // 1381 session = ((SSLSessionContextImpl)sslContext 1382 .engineGetClientSessionContext()) 1383 .get(getHostSE(), getPortSE()); 1384 if (debug != null && Debug.isOn("session")) { 1385 if (session != null) { 1386 System.out.println("%% Client cached " 1387 + session 1388 + (session.isRejoinable() ? "" : " (not rejoinable)")); 1389 } else { 1390 System.out.println("%% No cached client session"); 1391 } 1392 } 1393 if (session != null) { 1394 // If unsafe server certificate change is not allowed, reserve 1395 // current server certificates if the previous handshake is a 1396 // session-resumption abbreviated initial handshake. 1397 if (!allowUnsafeServerCertChange && session.isSessionResumption()) { 1398 try { 1399 // If existing, peer certificate chain cannot be null. 1400 reservedServerCerts = 1401 (X509Certificate[])session.getPeerCertificates(); 1402 } catch (SSLPeerUnverifiedException puve) { 1403 // Maybe not certificate-based, ignore the exception. 1404 } 1405 } 1406 1407 if (!session.isRejoinable()) { 1408 session = null; 1409 } 1410 } 1411 1412 if (session != null) { 1413 CipherSuite sessionSuite = session.getSuite(); 1414 ProtocolVersion sessionVersion = session.getProtocolVersion(); 1415 if (isNegotiable(sessionSuite) == false) { 1416 if (debug != null && Debug.isOn("session")) { 1417 System.out.println("%% can't resume, unavailable cipher"); 1418 } 1419 session = null; 1420 } 1421 1422 if ((session != null) && !isNegotiable(sessionVersion)) { 1423 if (debug != null && Debug.isOn("session")) { 1424 System.out.println("%% can't resume, protocol disabled"); 1425 } 1426 session = null; 1427 } 1428 1429 if (session != null) { 1430 if (debug != null) { 1431 if (Debug.isOn("handshake") || Debug.isOn("session")) { 1432 System.out.println("%% Try resuming " + session 1433 + " from port " + getLocalPortSE()); 1434 } 1435 } 1436 1437 sessionId = session.getSessionId(); 1438 maxProtocolVersion = sessionVersion; 1439 1440 // Update SSL version number in underlying SSL socket and 1441 // handshake output stream, so that the output records (at the 1442 // record layer) have the correct version 1443 setVersion(sessionVersion); 1444 } 1445 1446 /* 1447 * Force use of the previous session ciphersuite, and 1448 * add the SCSV if enabled. 1449 */ 1450 if (!enableNewSession) { 1451 if (session == null) { 1452 throw new SSLHandshakeException( 1453 "Can't reuse existing SSL client session"); 1454 } 1455 1456 Collection<CipherSuite> cipherList = new ArrayList<>(2); 1457 cipherList.add(sessionSuite); 1458 if (!secureRenegotiation && 1459 cipherSuites.contains(CipherSuite.C_SCSV)) { 1460 cipherList.add(CipherSuite.C_SCSV); 1461 } // otherwise, renegotiation_info extension will be used 1462 1463 cipherSuites = new CipherSuiteList(cipherList); 1464 } 1465 } 1466 1467 if (session == null && !enableNewSession) { 1468 throw new SSLHandshakeException("No existing session to resume"); 1469 } 1470 1471 // exclude SCSV for secure renegotiation 1472 if (secureRenegotiation && cipherSuites.contains(CipherSuite.C_SCSV)) { 1473 Collection<CipherSuite> cipherList = 1474 new ArrayList<>(cipherSuites.size() - 1); 1475 for (CipherSuite suite : cipherSuites.collection()) { 1476 if (suite != CipherSuite.C_SCSV) { 1477 cipherList.add(suite); 1478 } 1479 } 1480 1481 cipherSuites = new CipherSuiteList(cipherList); 1482 } 1483 1484 // make sure there is a negotiable cipher suite. 1485 boolean negotiable = false; 1486 for (CipherSuite suite : cipherSuites.collection()) { 1487 if (isNegotiable(suite)) { 1488 negotiable = true; 1489 break; 1490 } 1491 } 1492 1493 if (!negotiable) { 1494 throw new SSLHandshakeException("No negotiable cipher suite"); 1495 } 1496 1497 // Not a TLS1.2+ handshake 1498 // For SSLv2Hello, HandshakeHash.reset() will be called, so we 1499 // cannot call HandshakeHash.protocolDetermined() here. As it does 1500 // not follow the spec that HandshakeHash.reset() can be only be 1501 // called before protocolDetermined. 1502 // if (maxProtocolVersion.v < ProtocolVersion.TLS12.v) { 1503 // handshakeHash.protocolDetermined(maxProtocolVersion); 1504 // } 1505 1506 // create the ClientHello message 1507 ClientHello clientHelloMessage = new ClientHello( 1508 sslContext.getSecureRandom(), maxProtocolVersion, 1509 sessionId, cipherSuites, isDTLS); 1510 1511 // Add named groups extension for ECDHE and FFDHE if necessary. 1512 SupportedGroupsExtension sge = 1513 SupportedGroupsExtension.createExtension( 1514 algorithmConstraints, 1515 cipherSuites, enableFFDHE); 1516 if (sge != null) { 1517 clientHelloMessage.extensions.add(sge); 1518 // Add elliptic point format extensions 1519 if (cipherSuites.contains(NamedGroupType.NAMED_GROUP_ECDHE)) { 1520 clientHelloMessage.extensions.add( 1521 EllipticPointFormatsExtension.DEFAULT); 1522 } 1523 } 1524 1525 // add signature_algorithm extension 1526 if (maxProtocolVersion.useTLS12PlusSpec()) { 1527 // we will always send the signature_algorithm extension 1528 Collection<SignatureAndHashAlgorithm> localSignAlgs = 1529 getLocalSupportedSignAlgs(); 1530 if (localSignAlgs.isEmpty()) { 1531 throw new SSLHandshakeException( 1532 "No supported signature algorithm"); 1533 } 1534 1535 clientHelloMessage.addSignatureAlgorithmsExtension(localSignAlgs); 1536 } 1537 1538 // add server_name extension 1539 if (enableSNIExtension) { 1540 if (session != null) { 1541 requestedServerNames = session.getRequestedServerNames(); 1542 } else { 1543 requestedServerNames = serverNames; 1544 } 1545 1546 if (!requestedServerNames.isEmpty()) { 1547 clientHelloMessage.addSNIExtension(requestedServerNames); 1548 } 1549 } 1550 1551 // add max_fragment_length extension 1552 if (enableMFLExtension) { 1553 if (session != null) { 1554 // The same extension should be sent for resumption. 1555 requestedMFLength = session.getNegotiatedMaxFragSize(); 1556 } else if (maximumPacketSize != 0) { 1557 // Maybe we can calculate the fragment size more accurate 1558 // by condering the enabled cipher suites in the future. 1559 requestedMFLength = maximumPacketSize; 1560 if (isDTLS) { 1561 requestedMFLength -= DTLSRecord.maxPlaintextPlusSize; 1562 } else { 1563 requestedMFLength -= SSLRecord.maxPlaintextPlusSize; 1564 } 1565 } else { 1566 // Need no max_fragment_length extension. 1567 requestedMFLength = -1; 1568 } 1569 1570 if ((requestedMFLength > 0) && 1571 MaxFragmentLengthExtension.needFragLenNego(requestedMFLength)) { 1572 1573 requestedMFLength = 1574 MaxFragmentLengthExtension.getValidMaxFragLen( 1575 requestedMFLength); 1576 clientHelloMessage.addMFLExtension(requestedMFLength); 1577 } else { 1578 requestedMFLength = -1; 1579 } 1580 } 1581 1582 // Add status_request and status_request_v2 extensions 1583 if (sslContext.isStaplingEnabled(true)) { 1584 clientHelloMessage.addCertStatusReqListV2Extension(); 1585 clientHelloMessage.addCertStatusRequestExtension(); 1586 } 1587 1588 // Add ALPN extension 1589 if (localApl != null && localApl.length > 0) { 1590 clientHelloMessage.addALPNExtension(localApl); 1591 alpnActive = true; 1592 } 1593 1594 // reset the client random cookie 1595 clnt_random = clientHelloMessage.clnt_random; 1596 1597 /* 1598 * need to set the renegotiation_info extension for: 1599 * 1: secure renegotiation 1600 * 2: initial handshake and no SCSV in the ClientHello 1601 * 3: insecure renegotiation and no SCSV in the ClientHello 1602 */ 1603 if (secureRenegotiation || 1604 !cipherSuites.contains(CipherSuite.C_SCSV)) { 1605 clientHelloMessage.addRenegotiationInfoExtension(clientVerifyData); 1606 } 1607 1608 if (isDTLS) { 1609 // Cookie exchange need to reserve the initial ClientHello message. 1610 initialClientHelloMsg = clientHelloMessage; 1611 } 1612 1613 return clientHelloMessage; 1614 } 1615 1616 /* 1617 * Fault detected during handshake. 1618 */ 1619 @Override 1620 void handshakeAlert(byte description) throws SSLProtocolException { 1621 String message = Alerts.alertDescription(description); 1622 1623 if (debug != null && Debug.isOn("handshake")) { 1624 System.out.println("SSL - handshake alert: " + message); 1625 } 1626 throw new SSLProtocolException("handshake alert: " + message); 1627 } 1628 1629 /* 1630 * Unless we are using an anonymous ciphersuite, the server always 1631 * sends a certificate message (for the CipherSuites we currently 1632 * support). The trust manager verifies the chain for us. 1633 */ 1634 private void serverCertificate(CertificateMsg mesg) throws IOException { 1635 if (debug != null && Debug.isOn("handshake")) { 1636 mesg.print(System.out); 1637 } 1638 X509Certificate[] peerCerts = mesg.getCertificateChain(); 1639 if (peerCerts.length == 0) { 1640 fatalSE(Alerts.alert_bad_certificate, "empty certificate chain"); 1641 } 1642 1643 // Allow server certificate change in client side during renegotiation 1644 // after a session-resumption abbreviated initial handshake? 1645 // 1646 // DO NOT need to check allowUnsafeServerCertChange here. We only 1647 // reserve server certificates when allowUnsafeServerCertChange is 1648 // flase. 1649 if (reservedServerCerts != null) { 1650 // It is not necessary to check the certificate update if endpoint 1651 // identification is enabled. 1652 String identityAlg = getEndpointIdentificationAlgorithmSE(); 1653 if ((identityAlg == null || identityAlg.length() == 0) && 1654 !isIdentityEquivalent(peerCerts[0], reservedServerCerts[0])) { 1655 1656 fatalSE(Alerts.alert_bad_certificate, 1657 "server certificate change is restricted " + 1658 "during renegotiation"); 1659 } 1660 } 1661 1662 // ask the trust manager to verify the chain 1663 if (staplingActive) { 1664 // Defer the certificate check until after we've received the 1665 // CertificateStatus message. If that message doesn't come in 1666 // immediately following this message we will execute the check 1667 // directly from processMessage before any other SSL/TLS processing. 1668 deferredCerts = peerCerts; 1669 } else { 1670 // We're not doing stapling, so perform the check right now 1671 checkServerCerts(peerCerts); 1672 } 1673 } 1674 1675 /** 1676 * If certificate status stapling has been enabled, the server will send 1677 * one or more status messages to the client. 1678 * 1679 * @param mesg a {@code CertificateStatus} object built from the data 1680 * sent by the server. 1681 * 1682 * @throws IOException if any parsing errors occur. 1683 */ 1684 private void certificateStatus(CertificateStatus mesg) throws IOException { 1685 if (debug != null && Debug.isOn("handshake")) { 1686 mesg.print(System.out); 1687 } 1688 1689 // Perform the certificate check using the deferred certificates 1690 // and responses that we have obtained. 1691 session.setStatusResponses(mesg.getResponses()); 1692 checkServerCerts(deferredCerts); 1693 } 1694 1695 /* 1696 * Whether the certificates can represent the same identity? 1697 * 1698 * The certificates can be used to represent the same identity: 1699 * 1. If the subject alternative names of IP address are present in 1700 * both certificates, they should be identical; otherwise, 1701 * 2. if the subject alternative names of DNS name are present in 1702 * both certificates, they should be identical; otherwise, 1703 * 3. if the subject fields are present in both certificates, the 1704 * certificate subjects and issuers should be identical. 1705 */ 1706 private static boolean isIdentityEquivalent(X509Certificate thisCert, 1707 X509Certificate prevCert) { 1708 if (thisCert.equals(prevCert)) { 1709 return true; 1710 } 1711 1712 // check subject alternative names 1713 Collection<List<?>> thisSubjectAltNames = null; 1714 try { 1715 thisSubjectAltNames = thisCert.getSubjectAlternativeNames(); 1716 } catch (CertificateParsingException cpe) { 1717 if (debug != null && Debug.isOn("handshake")) { 1718 System.out.println( 1719 "Attempt to obtain subjectAltNames extension failed!"); 1720 } 1721 } 1722 1723 Collection<List<?>> prevSubjectAltNames = null; 1724 try { 1725 prevSubjectAltNames = prevCert.getSubjectAlternativeNames(); 1726 } catch (CertificateParsingException cpe) { 1727 if (debug != null && Debug.isOn("handshake")) { 1728 System.out.println( 1729 "Attempt to obtain subjectAltNames extension failed!"); 1730 } 1731 } 1732 1733 if ((thisSubjectAltNames != null) && (prevSubjectAltNames != null)) { 1734 // check the iPAddress field in subjectAltName extension 1735 Collection<String> thisSubAltIPAddrs = 1736 getSubjectAltNames(thisSubjectAltNames, ALTNAME_IP); 1737 Collection<String> prevSubAltIPAddrs = 1738 getSubjectAltNames(prevSubjectAltNames, ALTNAME_IP); 1739 if ((thisSubAltIPAddrs != null) && (prevSubAltIPAddrs != null) && 1740 (isEquivalent(thisSubAltIPAddrs, prevSubAltIPAddrs))) { 1741 1742 return true; 1743 } 1744 1745 // check the dNSName field in subjectAltName extension 1746 Collection<String> thisSubAltDnsNames = 1747 getSubjectAltNames(thisSubjectAltNames, ALTNAME_DNS); 1748 Collection<String> prevSubAltDnsNames = 1749 getSubjectAltNames(prevSubjectAltNames, ALTNAME_DNS); 1750 if ((thisSubAltDnsNames != null) && (prevSubAltDnsNames != null) && 1751 (isEquivalent(thisSubAltDnsNames, prevSubAltDnsNames))) { 1752 1753 return true; 1754 } 1755 } 1756 1757 // check the certificate subject and issuer 1758 X500Principal thisSubject = thisCert.getSubjectX500Principal(); 1759 X500Principal prevSubject = prevCert.getSubjectX500Principal(); 1760 X500Principal thisIssuer = thisCert.getIssuerX500Principal(); 1761 X500Principal prevIssuer = prevCert.getIssuerX500Principal(); 1762 if (!thisSubject.getName().isEmpty() && 1763 !prevSubject.getName().isEmpty() && 1764 thisSubject.equals(prevSubject) && 1765 thisIssuer.equals(prevIssuer)) { 1766 return true; 1767 } 1768 1769 return false; 1770 } 1771 1772 /* 1773 * Returns the subject alternative name of the specified type in the 1774 * subjectAltNames extension of a certificate. 1775 * 1776 * Note that only those subjectAltName types that use String data 1777 * should be passed into this function. 1778 */ 1779 private static Collection<String> getSubjectAltNames( 1780 Collection<List<?>> subjectAltNames, int type) { 1781 1782 HashSet<String> subAltDnsNames = null; 1783 for (List<?> subjectAltName : subjectAltNames) { 1784 int subjectAltNameType = (Integer)subjectAltName.get(0); 1785 if (subjectAltNameType == type) { 1786 String subAltDnsName = (String)subjectAltName.get(1); 1787 if ((subAltDnsName != null) && !subAltDnsName.isEmpty()) { 1788 if (subAltDnsNames == null) { 1789 subAltDnsNames = 1790 new HashSet<>(subjectAltNames.size()); 1791 } 1792 subAltDnsNames.add(subAltDnsName); 1793 } 1794 } 1795 } 1796 1797 return subAltDnsNames; 1798 } 1799 1800 private static boolean isEquivalent(Collection<String> thisSubAltNames, 1801 Collection<String> prevSubAltNames) { 1802 1803 for (String thisSubAltName : thisSubAltNames) { 1804 for (String prevSubAltName : prevSubAltNames) { 1805 // Only allow the exactly match. Check no wildcard character. 1806 if (thisSubAltName.equalsIgnoreCase(prevSubAltName)) { 1807 return true; 1808 } 1809 } 1810 } 1811 1812 return false; 1813 } 1814 1815 /** 1816 * Perform client-side checking of server certificates. 1817 * 1818 * @param certs an array of {@code X509Certificate} objects presented 1819 * by the server in the ServerCertificate message. 1820 * 1821 * @throws IOException if a failure occurs during validation or 1822 * the trust manager associated with the {@code SSLContext} is not 1823 * an {@code X509ExtendedTrustManager}. 1824 */ 1825 private void checkServerCerts(X509Certificate[] certs) 1826 throws IOException { 1827 X509TrustManager tm = sslContext.getX509TrustManager(); 1828 1829 // find out the key exchange algorithm used 1830 // use "RSA" for non-ephemeral "RSA_EXPORT" 1831 String keyExchangeString; 1832 if (keyExchange == K_RSA_EXPORT && !serverKeyExchangeReceived) { 1833 keyExchangeString = K_RSA.name; 1834 } else { 1835 keyExchangeString = keyExchange.name; 1836 } 1837 1838 try { 1839 if (tm instanceof X509ExtendedTrustManager) { 1840 if (conn != null) { 1841 ((X509ExtendedTrustManager)tm).checkServerTrusted( 1842 certs.clone(), 1843 keyExchangeString, 1844 conn); 1845 } else { 1846 ((X509ExtendedTrustManager)tm).checkServerTrusted( 1847 certs.clone(), 1848 keyExchangeString, 1849 engine); 1850 } 1851 } else { 1852 // Unlikely to happen, because we have wrapped the old 1853 // X509TrustManager with the new X509ExtendedTrustManager. 1854 throw new CertificateException( 1855 "Improper X509TrustManager implementation"); 1856 } 1857 1858 // Once the server certificate chain has been validated, set 1859 // the certificate chain in the TLS session. 1860 session.setPeerCertificates(certs); 1861 } catch (CertificateException ce) { 1862 fatalSE(getCertificateAlert(ce), ce); 1863 } 1864 } 1865 1866 /** 1867 * When a failure happens during certificate checking from an 1868 * {@link X509TrustManager}, determine what TLS alert description to use. 1869 * 1870 * @param cexc The exception thrown by the {@link X509TrustManager} 1871 * 1872 * @return A byte value corresponding to a TLS alert description number. 1873 */ 1874 private byte getCertificateAlert(CertificateException cexc) { 1875 // The specific reason for the failure will determine how to 1876 // set the alert description value 1877 byte alertDesc = Alerts.alert_certificate_unknown; 1878 1879 Throwable baseCause = cexc.getCause(); 1880 if (baseCause instanceof CertPathValidatorException) { 1881 CertPathValidatorException cpve = 1882 (CertPathValidatorException)baseCause; 1883 Reason reason = cpve.getReason(); 1884 if (reason == BasicReason.REVOKED) { 1885 alertDesc = staplingActive ? 1886 Alerts.alert_bad_certificate_status_response : 1887 Alerts.alert_certificate_revoked; 1888 } else if (reason == BasicReason.UNDETERMINED_REVOCATION_STATUS) { 1889 alertDesc = staplingActive ? 1890 Alerts.alert_bad_certificate_status_response : 1891 Alerts.alert_certificate_unknown; 1892 } 1893 } 1894 1895 return alertDesc; 1896 } 1897 } 1898