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