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