1 /* 2 * Copyright (c) 1996, 2012, 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 40 import javax.crypto.SecretKey; 41 import javax.crypto.spec.SecretKeySpec; 42 43 import javax.net.ssl.*; 44 45 import javax.security.auth.Subject; 46 47 import sun.security.ssl.HandshakeMessage.*; 48 import sun.security.ssl.CipherSuite.*; 49 import static sun.security.ssl.CipherSuite.KeyExchange.*; 50 51 import sun.net.util.IPAddressUtil; 52 53 /** 54 * ClientHandshaker does the protocol handshaking from the point 55 * of view of a client. It is driven asychronously by handshake messages 56 * as delivered by the parent Handshaker class, and also uses 57 * common functionality (e.g. key generation) that is provided there. 58 * 59 * @author David Brownell 60 */ 61 final class ClientHandshaker extends Handshaker { 62 63 // the server's public key from its certificate. 64 private PublicKey serverKey; 65 66 // the server's ephemeral public key from the server key exchange message 67 // for ECDHE/ECDH_anon and RSA_EXPORT. 68 private PublicKey ephemeralServerKey; 69 70 // server's ephemeral public value for DHE/DH_anon key exchanges 71 private BigInteger serverDH; 72 73 private DHCrypt dh; 74 75 private ECDHCrypt ecdh; 76 77 private CertificateRequest certRequest; 78 79 private boolean serverKeyExchangeReceived; 80 81 /* 82 * The RSA PreMasterSecret needs to know the version of 83 * ClientHello that was used on this handshake. This represents 84 * the "max version" this client is supporting. In the 85 * case of an initial handshake, it's the max version enabled, 86 * but in the case of a resumption attempt, it's the version 87 * of the session we're trying to resume. 88 */ 89 private ProtocolVersion maxProtocolVersion; 90 91 // To switch off the SNI extension. 92 private final static boolean enableSNIExtension = 93 Debug.getBooleanProperty("jsse.enableSNIExtension", true); 94 95 /* 96 * Constructors 97 */ 98 ClientHandshaker(SSLSocketImpl socket, SSLContextImpl context, 99 ProtocolList enabledProtocols, 100 ProtocolVersion activeProtocolVersion, 101 boolean isInitialHandshake, boolean secureRenegotiation, 102 byte[] clientVerifyData, byte[] serverVerifyData) { 103 104 super(socket, context, enabledProtocols, true, true, 105 activeProtocolVersion, isInitialHandshake, secureRenegotiation, 106 clientVerifyData, serverVerifyData); 107 } 108 109 ClientHandshaker(SSLEngineImpl engine, SSLContextImpl context, 110 ProtocolList enabledProtocols, 111 ProtocolVersion activeProtocolVersion, 112 boolean isInitialHandshake, boolean secureRenegotiation, 113 byte[] clientVerifyData, byte[] serverVerifyData) { 114 115 super(engine, context, enabledProtocols, true, true, 116 activeProtocolVersion, isInitialHandshake, secureRenegotiation, 117 clientVerifyData, serverVerifyData); 118 } 119 120 /* 121 * This routine handles all the client side handshake messages, one at 122 * a time. Given the message type (and in some cases the pending cipher 123 * spec) it parses the type-specific message. Then it calls a function 124 * that handles that specific message. 125 * 126 * It updates the state machine (need to verify it) as each message 127 * is processed, and writes responses as needed using the connection 128 * in the constructor. 129 */ 130 void processMessage(byte type, int messageLen) throws IOException { 131 if (state >= type 132 && (type != HandshakeMessage.ht_hello_request)) { 133 throw new SSLProtocolException( 134 "Handshake message sequence violation, " + type); 135 } 136 137 switch (type) { 138 case HandshakeMessage.ht_hello_request: 139 this.serverHelloRequest(new HelloRequest(input)); 140 break; 141 142 case HandshakeMessage.ht_server_hello: 143 this.serverHello(new ServerHello(input, messageLen)); 144 break; 145 146 case HandshakeMessage.ht_certificate: 147 if (keyExchange == K_DH_ANON || keyExchange == K_ECDH_ANON 148 || keyExchange == K_KRB5 || keyExchange == K_KRB5_EXPORT) { 149 fatalSE(Alerts.alert_unexpected_message, 150 "unexpected server cert chain"); 151 // NOTREACHED 152 } 153 this.serverCertificate(new CertificateMsg(input)); 154 serverKey = 155 session.getPeerCertificates()[0].getPublicKey(); 156 break; 157 158 case HandshakeMessage.ht_server_key_exchange: 159 serverKeyExchangeReceived = true; 160 switch (keyExchange) { 161 case K_RSA_EXPORT: 162 /** 163 * The server key exchange message is sent by the server only 164 * when the server certificate message does not contain the 165 * proper amount of data to allow the client to exchange a 166 * premaster secret, such as when RSA_EXPORT is used and the 167 * public key in the server certificate is longer than 512 bits. 168 */ 169 if (serverKey == null) { 170 throw new SSLProtocolException 171 ("Server did not send certificate message"); 172 } 173 174 if (!(serverKey instanceof RSAPublicKey)) { 175 throw new SSLProtocolException("Protocol violation:" + 176 " the certificate type must be appropriate for the" + 177 " selected cipher suite's key exchange algorithm"); 178 } 179 180 if (JsseJce.getRSAKeyLength(serverKey) <= 512) { 181 throw new SSLProtocolException("Protocol violation:" + 182 " server sent a server key exchange message for" + 183 " key exchange " + keyExchange + 184 " when the public key in the server certificate" + 185 " is less than or equal to 512 bits in length"); 186 } 187 188 try { 189 this.serverKeyExchange(new RSA_ServerKeyExchange(input)); 190 } catch (GeneralSecurityException e) { 191 throwSSLException("Server key", e); 192 } 193 break; 194 case K_DH_ANON: 195 try { 196 this.serverKeyExchange(new DH_ServerKeyExchange( 197 input, protocolVersion)); 198 } catch (GeneralSecurityException e) { 199 throwSSLException("Server key", e); 200 } 201 break; 202 case K_DHE_DSS: 203 case K_DHE_RSA: 204 try { 205 this.serverKeyExchange(new DH_ServerKeyExchange( 206 input, serverKey, 207 clnt_random.random_bytes, svr_random.random_bytes, 208 messageLen, 209 localSupportedSignAlgs, protocolVersion)); 210 } catch (GeneralSecurityException e) { 211 throwSSLException("Server key", e); 212 } 213 break; 214 case K_ECDHE_ECDSA: 215 case K_ECDHE_RSA: 216 case K_ECDH_ANON: 217 try { 218 this.serverKeyExchange(new ECDH_ServerKeyExchange 219 (input, serverKey, clnt_random.random_bytes, 220 svr_random.random_bytes, 221 localSupportedSignAlgs, protocolVersion)); 222 } catch (GeneralSecurityException e) { 223 throwSSLException("Server key", e); 224 } 225 break; 226 case K_RSA: 227 case K_DH_RSA: 228 case K_DH_DSS: 229 case K_ECDH_ECDSA: 230 case K_ECDH_RSA: 231 throw new SSLProtocolException( 232 "Protocol violation: server sent a server key exchange" 233 + "message for key exchange " + keyExchange); 234 case K_KRB5: 235 case K_KRB5_EXPORT: 236 throw new SSLProtocolException( 237 "unexpected receipt of server key exchange algorithm"); 238 default: 239 throw new SSLProtocolException( 240 "unsupported key exchange algorithm = " 241 + keyExchange); 242 } 243 break; 244 245 case HandshakeMessage.ht_certificate_request: 246 // save for later, it's handled by serverHelloDone 247 if ((keyExchange == K_DH_ANON) || (keyExchange == K_ECDH_ANON)) { 248 throw new SSLHandshakeException( 249 "Client authentication requested for "+ 250 "anonymous cipher suite."); 251 } else if (keyExchange == K_KRB5 || keyExchange == K_KRB5_EXPORT) { 252 throw new SSLHandshakeException( 253 "Client certificate requested for "+ 254 "kerberos cipher suite."); 255 } 256 certRequest = new CertificateRequest(input, protocolVersion); 257 if (debug != null && Debug.isOn("handshake")) { 258 certRequest.print(System.out); 259 } 260 261 if (protocolVersion.v >= ProtocolVersion.TLS12.v) { 262 Collection<SignatureAndHashAlgorithm> peerSignAlgs = 263 certRequest.getSignAlgorithms(); 264 if (peerSignAlgs == null || peerSignAlgs.isEmpty()) { 265 throw new SSLHandshakeException( 266 "No peer supported signature algorithms"); 267 } 268 269 Collection<SignatureAndHashAlgorithm> supportedPeerSignAlgs = 270 SignatureAndHashAlgorithm.getSupportedAlgorithms( 271 peerSignAlgs); 272 if (supportedPeerSignAlgs.isEmpty()) { 273 throw new SSLHandshakeException( 274 "No supported signature and hash algorithm in common"); 275 } 276 277 setPeerSupportedSignAlgs(supportedPeerSignAlgs); 278 session.setPeerSupportedSignatureAlgorithms( 279 supportedPeerSignAlgs); 280 } 281 282 break; 283 284 case HandshakeMessage.ht_server_hello_done: 285 this.serverHelloDone(new ServerHelloDone(input)); 286 break; 287 288 case HandshakeMessage.ht_finished: 289 this.serverFinished( 290 new Finished(protocolVersion, input, cipherSuite)); 291 break; 292 293 default: 294 throw new SSLProtocolException( 295 "Illegal client handshake msg, " + type); 296 } 297 298 // 299 // Move state machine forward if the message handling 300 // code didn't already do so 301 // 302 if (state < type) { 303 state = type; 304 } 305 } 306 307 /* 308 * Used by the server to kickstart negotiations -- this requests a 309 * "client hello" to renegotiate current cipher specs (e.g. maybe lots 310 * of data has been encrypted with the same keys, or the server needs 311 * the client to present a certificate). 312 */ 313 private void serverHelloRequest(HelloRequest mesg) throws IOException { 314 if (debug != null && Debug.isOn("handshake")) { 315 mesg.print(System.out); 316 } 317 318 // 319 // Could be (e.g. at connection setup) that we already 320 // sent the "client hello" but the server's not seen it. 321 // 322 if (state < HandshakeMessage.ht_client_hello) { 323 if (!secureRenegotiation && !allowUnsafeRenegotiation) { 324 // renegotiation is not allowed. 325 if (activeProtocolVersion.v >= ProtocolVersion.TLS10.v) { 326 // response with a no_renegotiation warning, 327 warningSE(Alerts.alert_no_renegotiation); 328 329 // invalidate the handshake so that the caller can 330 // dispose this object. 331 invalidated = true; 332 333 // If there is still unread block in the handshake 334 // input stream, it would be truncated with the disposal 335 // and the next handshake message will become incomplete. 336 // 337 // However, according to SSL/TLS specifications, no more 338 // handshake message should immediately follow ClientHello 339 // or HelloRequest. So just let it be. 340 } else { 341 // For SSLv3, send the handshake_failure fatal error. 342 // Note that SSLv3 does not define a no_renegotiation 343 // alert like TLSv1. However we cannot ignore the message 344 // simply, otherwise the other side was waiting for a 345 // response that would never come. 346 fatalSE(Alerts.alert_handshake_failure, 347 "Renegotiation is not allowed"); 348 } 349 } else { 350 if (!secureRenegotiation) { 351 if (debug != null && Debug.isOn("handshake")) { 352 System.out.println( 353 "Warning: continue with insecure renegotiation"); 354 } 355 } 356 kickstart(); 357 } 358 } 359 } 360 361 362 /* 363 * Server chooses session parameters given options created by the 364 * client -- basically, cipher options, session id, and someday a 365 * set of compression options. 366 * 367 * There are two branches of the state machine, decided by the 368 * details of this message. One is the "fast" handshake, where we 369 * can resume the pre-existing session we asked resume. The other 370 * is a more expensive "full" handshake, with key exchange and 371 * probably authentication getting done. 372 */ 373 private void serverHello(ServerHello mesg) throws IOException { 374 serverKeyExchangeReceived = false; 375 if (debug != null && Debug.isOn("handshake")) { 376 mesg.print(System.out); 377 } 378 379 // check if the server selected protocol version is OK for us 380 ProtocolVersion mesgVersion = mesg.protocolVersion; 381 if (!isNegotiable(mesgVersion)) { 382 throw new SSLHandshakeException( 383 "Server chose " + mesgVersion + 384 ", but that protocol version is not enabled or not supported " + 385 "by the client."); 386 } 387 388 handshakeHash.protocolDetermined(mesgVersion); 389 390 // Set protocolVersion and propagate to SSLSocket and the 391 // Handshake streams 392 setVersion(mesgVersion); 393 394 // check the "renegotiation_info" extension 395 RenegotiationInfoExtension serverHelloRI = (RenegotiationInfoExtension) 396 mesg.extensions.get(ExtensionType.EXT_RENEGOTIATION_INFO); 397 if (serverHelloRI != null) { 398 if (isInitialHandshake) { 399 // verify the length of the "renegotiated_connection" field 400 if (!serverHelloRI.isEmpty()) { 401 // abort the handshake with a fatal handshake_failure alert 402 fatalSE(Alerts.alert_handshake_failure, 403 "The renegotiation_info field is not empty"); 404 } 405 406 secureRenegotiation = true; 407 } else { 408 // For a legacy renegotiation, the client MUST verify that 409 // it does not contain the "renegotiation_info" extension. 410 if (!secureRenegotiation) { 411 fatalSE(Alerts.alert_handshake_failure, 412 "Unexpected renegotiation indication extension"); 413 } 414 415 // verify the client_verify_data and server_verify_data values 416 byte[] verifyData = 417 new byte[clientVerifyData.length + serverVerifyData.length]; 418 System.arraycopy(clientVerifyData, 0, verifyData, 419 0, clientVerifyData.length); 420 System.arraycopy(serverVerifyData, 0, verifyData, 421 clientVerifyData.length, serverVerifyData.length); 422 if (!Arrays.equals(verifyData, 423 serverHelloRI.getRenegotiatedConnection())) { 424 fatalSE(Alerts.alert_handshake_failure, 425 "Incorrect verify data in ServerHello " + 426 "renegotiation_info message"); 427 } 428 } 429 } else { 430 // no renegotiation indication extension 431 if (isInitialHandshake) { 432 if (!allowLegacyHelloMessages) { 433 // abort the handshake with a fatal handshake_failure alert 434 fatalSE(Alerts.alert_handshake_failure, 435 "Failed to negotiate the use of secure renegotiation"); 436 } 437 438 secureRenegotiation = false; 439 if (debug != null && Debug.isOn("handshake")) { 440 System.out.println("Warning: No renegotiation " + 441 "indication extension in ServerHello"); 442 } 443 } else { 444 // For a secure renegotiation, the client must abort the 445 // handshake if no "renegotiation_info" extension is present. 446 if (secureRenegotiation) { 447 fatalSE(Alerts.alert_handshake_failure, 448 "No renegotiation indication extension"); 449 } 450 451 // we have already allowed unsafe renegotation before request 452 // the renegotiation. 453 } 454 } 455 456 // 457 // Save server nonce, we always use it to compute connection 458 // keys and it's also used to create the master secret if we're 459 // creating a new session (i.e. in the full handshake). 460 // 461 svr_random = mesg.svr_random; 462 463 if (isNegotiable(mesg.cipherSuite) == false) { 464 fatalSE(Alerts.alert_illegal_parameter, 465 "Server selected improper ciphersuite " + mesg.cipherSuite); 466 } 467 468 setCipherSuite(mesg.cipherSuite); 469 if (protocolVersion.v >= ProtocolVersion.TLS12.v) { 470 handshakeHash.setFinishedAlg(cipherSuite.prfAlg.getPRFHashAlg()); 471 } 472 473 if (mesg.compression_method != 0) { 474 fatalSE(Alerts.alert_illegal_parameter, 475 "compression type not supported, " 476 + mesg.compression_method); 477 // NOTREACHED 478 } 479 480 // so far so good, let's look at the session 481 if (session != null) { 482 // we tried to resume, let's see what the server decided 483 if (session.getSessionId().equals(mesg.sessionId)) { 484 // server resumed the session, let's make sure everything 485 // checks out 486 487 // Verify that the session ciphers are unchanged. 488 CipherSuite sessionSuite = session.getSuite(); 489 if (cipherSuite != sessionSuite) { 490 throw new SSLProtocolException 491 ("Server returned wrong cipher suite for session"); 492 } 493 494 // verify protocol version match 495 ProtocolVersion sessionVersion = session.getProtocolVersion(); 496 if (protocolVersion != sessionVersion) { 497 throw new SSLProtocolException 498 ("Server resumed session with wrong protocol version"); 499 } 500 501 // validate subject identity 502 if (sessionSuite.keyExchange == K_KRB5 || 503 sessionSuite.keyExchange == K_KRB5_EXPORT) { 504 Principal localPrincipal = session.getLocalPrincipal(); 505 506 Subject subject = null; 507 try { 508 subject = AccessController.doPrivileged( 509 new PrivilegedExceptionAction<Subject>() { 510 public Subject run() throws Exception { 511 return Krb5Helper.getClientSubject(getAccSE()); 512 }}); 513 } catch (PrivilegedActionException e) { 514 subject = null; 515 if (debug != null && Debug.isOn("session")) { 516 System.out.println("Attempt to obtain" + 517 " subject failed!"); 518 } 519 } 520 521 if (subject != null) { 522 // Eliminate dependency on KerberosPrincipal 523 Set<Principal> principals = 524 subject.getPrincipals(Principal.class); 525 if (!principals.contains(localPrincipal)) { 526 throw new SSLProtocolException("Server resumed" + 527 " session with wrong subject identity"); 528 } else { 529 if (debug != null && Debug.isOn("session")) 530 System.out.println("Subject identity is same"); 531 } 532 } else { 533 if (debug != null && Debug.isOn("session")) 534 System.out.println("Kerberos credentials are not" + 535 " present in the current Subject; check if " + 536 " javax.security.auth.useSubjectAsCreds" + 537 " system property has been set to false"); 538 throw new SSLProtocolException 539 ("Server resumed session with no subject"); 540 } 541 } 542 543 // looks fine; resume it, and update the state machine. 544 resumingSession = true; 545 state = HandshakeMessage.ht_finished - 1; 546 calculateConnectionKeys(session.getMasterSecret()); 547 if (debug != null && Debug.isOn("session")) { 548 System.out.println("%% Server resumed " + session); 549 } 550 } else { 551 // we wanted to resume, but the server refused 552 session = null; 553 if (!enableNewSession) { 554 throw new SSLException 555 ("New session creation is disabled"); 556 } 557 } 558 } 559 560 if (resumingSession && session != null) { 561 if (protocolVersion.v >= ProtocolVersion.TLS12.v) { 562 handshakeHash.setCertificateVerifyAlg(null); 563 } 564 565 setHandshakeSessionSE(session); 566 return; 567 } 568 569 // check extensions 570 for (HelloExtension ext : mesg.extensions.list()) { 571 ExtensionType type = ext.type; 572 if ((type != ExtensionType.EXT_ELLIPTIC_CURVES) 573 && (type != ExtensionType.EXT_EC_POINT_FORMATS) 574 && (type != ExtensionType.EXT_SERVER_NAME) 575 && (type != ExtensionType.EXT_RENEGOTIATION_INFO)) { 576 fatalSE(Alerts.alert_unsupported_extension, 577 "Server sent an unsupported extension: " + type); 578 } 579 } 580 581 // Create a new session, we need to do the full handshake 582 session = new SSLSessionImpl(protocolVersion, cipherSuite, 583 getLocalSupportedSignAlgs(), 584 mesg.sessionId, getHostSE(), getPortSE()); 585 setHandshakeSessionSE(session); 586 if (debug != null && Debug.isOn("handshake")) { 587 System.out.println("** " + cipherSuite); 588 } 589 } 590 591 /* 592 * Server's own key was either a signing-only key, or was too 593 * large for export rules ... this message holds an ephemeral 594 * RSA key to use for key exchange. 595 */ 596 private void serverKeyExchange(RSA_ServerKeyExchange mesg) 597 throws IOException, GeneralSecurityException { 598 if (debug != null && Debug.isOn("handshake")) { 599 mesg.print(System.out); 600 } 601 if (!mesg.verify(serverKey, clnt_random, svr_random)) { 602 fatalSE(Alerts.alert_handshake_failure, 603 "server key exchange invalid"); 604 // NOTREACHED 605 } 606 ephemeralServerKey = mesg.getPublicKey(); 607 } 608 609 610 /* 611 * Diffie-Hellman key exchange. We save the server public key and 612 * our own D-H algorithm object so we can defer key calculations 613 * until after we've sent the client key exchange message (which 614 * gives client and server some useful parallelism). 615 */ 616 private void serverKeyExchange(DH_ServerKeyExchange mesg) 617 throws IOException { 618 if (debug != null && Debug.isOn("handshake")) { 619 mesg.print(System.out); 620 } 621 dh = new DHCrypt(mesg.getModulus(), mesg.getBase(), 622 sslContext.getSecureRandom()); 623 serverDH = mesg.getServerPublicKey(); 624 } 625 626 private void serverKeyExchange(ECDH_ServerKeyExchange mesg) 627 throws IOException { 628 if (debug != null && Debug.isOn("handshake")) { 629 mesg.print(System.out); 630 } 631 ECPublicKey key = mesg.getPublicKey(); 632 ecdh = new ECDHCrypt(key.getParams(), sslContext.getSecureRandom()); 633 ephemeralServerKey = key; 634 } 635 636 /* 637 * The server's "Hello Done" message is the client's sign that 638 * it's time to do all the hard work. 639 */ 640 private void serverHelloDone(ServerHelloDone mesg) throws IOException { 641 if (debug != null && Debug.isOn("handshake")) { 642 mesg.print(System.out); 643 } 644 /* 645 * Always make sure the input has been digested before we 646 * start emitting data, to ensure the hashes are correctly 647 * computed for the Finished and CertificateVerify messages 648 * which we send (here). 649 */ 650 input.digestNow(); 651 652 /* 653 * FIRST ... if requested, send an appropriate Certificate chain 654 * to authenticate the client, and remember the associated private 655 * key to sign the CertificateVerify message. 656 */ 657 PrivateKey signingKey = null; 658 659 if (certRequest != null) { 660 X509ExtendedKeyManager km = sslContext.getX509KeyManager(); 661 662 ArrayList<String> keytypesTmp = new ArrayList<>(4); 663 664 for (int i = 0; i < certRequest.types.length; i++) { 665 String typeName; 666 667 switch (certRequest.types[i]) { 668 case CertificateRequest.cct_rsa_sign: 669 typeName = "RSA"; 670 break; 671 672 case CertificateRequest.cct_dss_sign: 673 typeName = "DSA"; 674 break; 675 676 case CertificateRequest.cct_ecdsa_sign: 677 // ignore if we do not have EC crypto available 678 typeName = JsseJce.isEcAvailable() ? "EC" : null; 679 break; 680 681 // Fixed DH/ECDH client authentication not supported 682 case CertificateRequest.cct_rsa_fixed_dh: 683 case CertificateRequest.cct_dss_fixed_dh: 684 case CertificateRequest.cct_rsa_fixed_ecdh: 685 case CertificateRequest.cct_ecdsa_fixed_ecdh: 686 // Any other values (currently not used in TLS) 687 case CertificateRequest.cct_rsa_ephemeral_dh: 688 case CertificateRequest.cct_dss_ephemeral_dh: 689 default: 690 typeName = null; 691 break; 692 } 693 694 if ((typeName != null) && (!keytypesTmp.contains(typeName))) { 695 keytypesTmp.add(typeName); 696 } 697 } 698 699 String alias = null; 700 int keytypesTmpSize = keytypesTmp.size(); 701 if (keytypesTmpSize != 0) { 702 String keytypes[] = 703 keytypesTmp.toArray(new String[keytypesTmpSize]); 704 705 if (conn != null) { 706 alias = km.chooseClientAlias(keytypes, 707 certRequest.getAuthorities(), conn); 708 } else { 709 alias = km.chooseEngineClientAlias(keytypes, 710 certRequest.getAuthorities(), engine); 711 } 712 } 713 714 CertificateMsg m1 = null; 715 if (alias != null) { 716 X509Certificate[] certs = km.getCertificateChain(alias); 717 if ((certs != null) && (certs.length != 0)) { 718 PublicKey publicKey = certs[0].getPublicKey(); 719 // for EC, make sure we use a supported named curve 720 if (publicKey instanceof ECPublicKey) { 721 ECParameterSpec params = 722 ((ECPublicKey)publicKey).getParams(); 723 int index = 724 SupportedEllipticCurvesExtension.getCurveIndex( 725 params); 726 if (!SupportedEllipticCurvesExtension.isSupported( 727 index)) { 728 publicKey = null; 729 } 730 } 731 if (publicKey != null) { 732 m1 = new CertificateMsg(certs); 733 signingKey = km.getPrivateKey(alias); 734 session.setLocalPrivateKey(signingKey); 735 session.setLocalCertificates(certs); 736 } 737 } 738 } 739 if (m1 == null) { 740 // 741 // No appropriate cert was found ... report this to the 742 // server. For SSLv3, send the no_certificate alert; 743 // TLS uses an empty cert chain instead. 744 // 745 if (protocolVersion.v >= ProtocolVersion.TLS10.v) { 746 m1 = new CertificateMsg(new X509Certificate [0]); 747 } else { 748 warningSE(Alerts.alert_no_certificate); 749 } 750 } 751 752 // 753 // At last ... send any client certificate chain. 754 // 755 if (m1 != null) { 756 if (debug != null && Debug.isOn("handshake")) { 757 m1.print(System.out); 758 } 759 m1.write(output); 760 } 761 } 762 763 /* 764 * SECOND ... send the client key exchange message. The 765 * procedure used is a function of the cipher suite selected; 766 * one is always needed. 767 */ 768 HandshakeMessage m2; 769 770 switch (keyExchange) { 771 772 case K_RSA: 773 case K_RSA_EXPORT: 774 if (serverKey == null) { 775 throw new SSLProtocolException 776 ("Server did not send certificate message"); 777 } 778 779 if (!(serverKey instanceof RSAPublicKey)) { 780 throw new SSLProtocolException 781 ("Server certificate does not include an RSA key"); 782 } 783 784 /* 785 * For RSA key exchange, we randomly generate a new 786 * pre-master secret and encrypt it with the server's 787 * public key. Then we save that pre-master secret 788 * so that we can calculate the keying data later; 789 * it's a performance speedup not to do that until 790 * the client's waiting for the server response, but 791 * more of a speedup for the D-H case. 792 * 793 * If the RSA_EXPORT scheme is active, when the public 794 * key in the server certificate is less than or equal 795 * to 512 bits in length, use the cert's public key, 796 * otherwise, the ephemeral one. 797 */ 798 PublicKey key; 799 if (keyExchange == K_RSA) { 800 key = serverKey; 801 } else { // K_RSA_EXPORT 802 if (JsseJce.getRSAKeyLength(serverKey) <= 512) { 803 // extraneous ephemeralServerKey check done 804 // above in processMessage() 805 key = serverKey; 806 } else { 807 if (ephemeralServerKey == null) { 808 throw new SSLProtocolException("Server did not send" + 809 " a RSA_EXPORT Server Key Exchange message"); 810 } 811 key = ephemeralServerKey; 812 } 813 } 814 815 m2 = new RSAClientKeyExchange(protocolVersion, maxProtocolVersion, 816 sslContext.getSecureRandom(), key); 817 break; 818 case K_DH_RSA: 819 case K_DH_DSS: 820 /* 821 * For DH Key exchange, we only need to make sure the server 822 * knows our public key, so we calculate the same pre-master 823 * secret. 824 * 825 * For certs that had DH keys in them, we send an empty 826 * handshake message (no key) ... we flag this case by 827 * passing a null "dhPublic" value. 828 * 829 * Otherwise we send ephemeral DH keys, unsigned. 830 */ 831 // if (useDH_RSA || useDH_DSS) 832 m2 = new DHClientKeyExchange(); 833 break; 834 case K_DHE_RSA: 835 case K_DHE_DSS: 836 case K_DH_ANON: 837 if (dh == null) { 838 throw new SSLProtocolException 839 ("Server did not send a DH Server Key Exchange message"); 840 } 841 m2 = new DHClientKeyExchange(dh.getPublicKey()); 842 break; 843 case K_ECDHE_RSA: 844 case K_ECDHE_ECDSA: 845 case K_ECDH_ANON: 846 if (ecdh == null) { 847 throw new SSLProtocolException 848 ("Server did not send a ECDH Server Key Exchange message"); 849 } 850 m2 = new ECDHClientKeyExchange(ecdh.getPublicKey()); 851 break; 852 case K_ECDH_RSA: 853 case K_ECDH_ECDSA: 854 if (serverKey == null) { 855 throw new SSLProtocolException 856 ("Server did not send certificate message"); 857 } 858 if (serverKey instanceof ECPublicKey == false) { 859 throw new SSLProtocolException 860 ("Server certificate does not include an EC key"); 861 } 862 ECParameterSpec params = ((ECPublicKey)serverKey).getParams(); 863 ecdh = new ECDHCrypt(params, sslContext.getSecureRandom()); 864 m2 = new ECDHClientKeyExchange(ecdh.getPublicKey()); 865 break; 866 case K_KRB5: 867 case K_KRB5_EXPORT: 868 String hostname = getHostSE(); 869 if (hostname == null) { 870 throw new IOException("Hostname is required" + 871 " to use Kerberos cipher suites"); 872 } 873 KerberosClientKeyExchange kerberosMsg = 874 new KerberosClientKeyExchange( 875 hostname, isLoopbackSE(), getAccSE(), protocolVersion, 876 sslContext.getSecureRandom()); 877 // Record the principals involved in exchange 878 session.setPeerPrincipal(kerberosMsg.getPeerPrincipal()); 879 session.setLocalPrincipal(kerberosMsg.getLocalPrincipal()); 880 m2 = kerberosMsg; 881 break; 882 default: 883 // somethings very wrong 884 throw new RuntimeException 885 ("Unsupported key exchange: " + keyExchange); 886 } 887 if (debug != null && Debug.isOn("handshake")) { 888 m2.print(System.out); 889 } 890 m2.write(output); 891 892 893 /* 894 * THIRD, send a "change_cipher_spec" record followed by the 895 * "Finished" message. We flush the messages we've queued up, to 896 * get concurrency between client and server. The concurrency is 897 * useful as we calculate the master secret, which is needed both 898 * to compute the "Finished" message, and to compute the keys used 899 * to protect all records following the change_cipher_spec. 900 */ 901 902 output.doHashes(); 903 output.flush(); 904 905 /* 906 * We deferred calculating the master secret and this connection's 907 * keying data; we do it now. Deferring this calculation is good 908 * from a performance point of view, since it lets us do it during 909 * some time that network delays and the server's own calculations 910 * would otherwise cause to be "dead" in the critical path. 911 */ 912 SecretKey preMasterSecret; 913 switch (keyExchange) { 914 case K_RSA: 915 case K_RSA_EXPORT: 916 preMasterSecret = ((RSAClientKeyExchange)m2).preMaster; 917 break; 918 case K_KRB5: 919 case K_KRB5_EXPORT: 920 byte[] secretBytes = 921 ((KerberosClientKeyExchange)m2).getUnencryptedPreMasterSecret(); 922 preMasterSecret = new SecretKeySpec(secretBytes, 923 "TlsPremasterSecret"); 924 break; 925 case K_DHE_RSA: 926 case K_DHE_DSS: 927 case K_DH_ANON: 928 preMasterSecret = dh.getAgreedSecret(serverDH, true); 929 break; 930 case K_ECDHE_RSA: 931 case K_ECDHE_ECDSA: 932 case K_ECDH_ANON: 933 preMasterSecret = ecdh.getAgreedSecret(ephemeralServerKey); 934 break; 935 case K_ECDH_RSA: 936 case K_ECDH_ECDSA: 937 preMasterSecret = ecdh.getAgreedSecret(serverKey); 938 break; 939 default: 940 throw new IOException("Internal error: unknown key exchange " 941 + keyExchange); 942 } 943 944 calculateKeys(preMasterSecret, null); 945 946 /* 947 * FOURTH, if we sent a Certificate, we need to send a signed 948 * CertificateVerify (unless the key in the client's certificate 949 * was a Diffie-Hellman key).). 950 * 951 * This uses a hash of the previous handshake messages ... either 952 * a nonfinal one (if the particular implementation supports it) 953 * or else using the third element in the arrays of hashes being 954 * computed. 955 */ 956 if (signingKey != null) { 957 CertificateVerify m3; 958 try { 959 SignatureAndHashAlgorithm preferableSignatureAlgorithm = null; 960 if (protocolVersion.v >= ProtocolVersion.TLS12.v) { 961 preferableSignatureAlgorithm = 962 SignatureAndHashAlgorithm.getPreferableAlgorithm( 963 peerSupportedSignAlgs, signingKey.getAlgorithm(), 964 signingKey); 965 966 if (preferableSignatureAlgorithm == null) { 967 throw new SSLHandshakeException( 968 "No supported signature algorithm"); 969 } 970 971 String hashAlg = 972 SignatureAndHashAlgorithm.getHashAlgorithmName( 973 preferableSignatureAlgorithm); 974 if (hashAlg == null || hashAlg.length() == 0) { 975 throw new SSLHandshakeException( 976 "No supported hash algorithm"); 977 } 978 979 handshakeHash.setCertificateVerifyAlg(hashAlg); 980 } 981 982 m3 = new CertificateVerify(protocolVersion, handshakeHash, 983 signingKey, session.getMasterSecret(), 984 sslContext.getSecureRandom(), 985 preferableSignatureAlgorithm); 986 } catch (GeneralSecurityException e) { 987 fatalSE(Alerts.alert_handshake_failure, 988 "Error signing certificate verify", e); 989 // NOTREACHED, make compiler happy 990 m3 = null; 991 } 992 if (debug != null && Debug.isOn("handshake")) { 993 m3.print(System.out); 994 } 995 m3.write(output); 996 output.doHashes(); 997 } else { 998 if (protocolVersion.v >= ProtocolVersion.TLS12.v) { 999 handshakeHash.setCertificateVerifyAlg(null); 1000 } 1001 } 1002 1003 /* 1004 * OK, that's that! 1005 */ 1006 sendChangeCipherAndFinish(false); 1007 } 1008 1009 1010 /* 1011 * "Finished" is the last handshake message sent. If we got this 1012 * far, the MAC has been validated post-decryption. We validate 1013 * the two hashes here as an additional sanity check, protecting 1014 * the handshake against various active attacks. 1015 */ 1016 private void serverFinished(Finished mesg) throws IOException { 1017 if (debug != null && Debug.isOn("handshake")) { 1018 mesg.print(System.out); 1019 } 1020 1021 boolean verified = mesg.verify(handshakeHash, Finished.SERVER, 1022 session.getMasterSecret()); 1023 1024 if (!verified) { 1025 fatalSE(Alerts.alert_illegal_parameter, 1026 "server 'finished' message doesn't verify"); 1027 // NOTREACHED 1028 } 1029 1030 /* 1031 * save server verify data for secure renegotiation 1032 */ 1033 if (secureRenegotiation) { 1034 serverVerifyData = mesg.getVerifyData(); 1035 } 1036 1037 /* 1038 * OK, it verified. If we're doing the fast handshake, add that 1039 * "Finished" message to the hash of handshake messages, then send 1040 * our own change_cipher_spec and Finished message for the server 1041 * to verify in turn. These are the last handshake messages. 1042 * 1043 * In any case, update the session cache. We're done handshaking, 1044 * so there are no threats any more associated with partially 1045 * completed handshakes. 1046 */ 1047 if (resumingSession) { 1048 input.digestNow(); 1049 sendChangeCipherAndFinish(true); 1050 } 1051 session.setLastAccessedTime(System.currentTimeMillis()); 1052 1053 if (!resumingSession) { 1054 if (session.isRejoinable()) { 1055 ((SSLSessionContextImpl) sslContext 1056 .engineGetClientSessionContext()) 1057 .put(session); 1058 if (debug != null && Debug.isOn("session")) { 1059 System.out.println("%% Cached client session: " + session); 1060 } 1061 } else if (debug != null && Debug.isOn("session")) { 1062 System.out.println( 1063 "%% Didn't cache non-resumable client session: " 1064 + session); 1065 } 1066 } 1067 } 1068 1069 1070 /* 1071 * Send my change-cipher-spec and Finished message ... done as the 1072 * last handshake act in either the short or long sequences. In 1073 * the short one, we've already seen the server's Finished; in the 1074 * long one, we wait for it now. 1075 */ 1076 private void sendChangeCipherAndFinish(boolean finishedTag) 1077 throws IOException { 1078 Finished mesg = new Finished(protocolVersion, handshakeHash, 1079 Finished.CLIENT, session.getMasterSecret(), cipherSuite); 1080 1081 /* 1082 * Send the change_cipher_spec message, then the Finished message 1083 * which we just calculated (and protected using the keys we just 1084 * calculated). Server responds with its Finished message, except 1085 * in the "fast handshake" (resume session) case. 1086 */ 1087 sendChangeCipherSpec(mesg, finishedTag); 1088 1089 /* 1090 * save client verify data for secure renegotiation 1091 */ 1092 if (secureRenegotiation) { 1093 clientVerifyData = mesg.getVerifyData(); 1094 } 1095 1096 /* 1097 * Update state machine so server MUST send 'finished' next. 1098 * (In "long" handshake case; in short case, we're responding 1099 * to its message.) 1100 */ 1101 state = HandshakeMessage.ht_finished - 1; 1102 } 1103 1104 1105 /* 1106 * Returns a ClientHello message to kickstart renegotiations 1107 */ 1108 HandshakeMessage getKickstartMessage() throws SSLException { 1109 // session ID of the ClientHello message 1110 SessionId sessionId = SSLSessionImpl.nullSession.getSessionId(); 1111 1112 // a list of cipher suites sent by the client 1113 CipherSuiteList cipherSuites = getActiveCipherSuites(); 1114 1115 // set the max protocol version this client is supporting. 1116 maxProtocolVersion = protocolVersion; 1117 1118 // 1119 // Try to resume an existing session. This might be mandatory, 1120 // given certain API options. 1121 // 1122 session = ((SSLSessionContextImpl)sslContext 1123 .engineGetClientSessionContext()) 1124 .get(getHostSE(), getPortSE()); 1125 if (debug != null && Debug.isOn("session")) { 1126 if (session != null) { 1127 System.out.println("%% Client cached " 1128 + session 1129 + (session.isRejoinable() ? "" : " (not rejoinable)")); 1130 } else { 1131 System.out.println("%% No cached client session"); 1132 } 1133 } 1134 if ((session != null) && (session.isRejoinable() == false)) { 1135 session = null; 1136 } 1137 1138 if (session != null) { 1139 CipherSuite sessionSuite = session.getSuite(); 1140 ProtocolVersion sessionVersion = session.getProtocolVersion(); 1141 if (isNegotiable(sessionSuite) == false) { 1142 if (debug != null && Debug.isOn("session")) { 1143 System.out.println("%% can't resume, unavailable cipher"); 1144 } 1145 session = null; 1146 } 1147 1148 if ((session != null) && !isNegotiable(sessionVersion)) { 1149 if (debug != null && Debug.isOn("session")) { 1150 System.out.println("%% can't resume, protocol disabled"); 1151 } 1152 session = null; 1153 } 1154 1155 if (session != null) { 1156 if (debug != null) { 1157 if (Debug.isOn("handshake") || Debug.isOn("session")) { 1158 System.out.println("%% Try resuming " + session 1159 + " from port " + getLocalPortSE()); 1160 } 1161 } 1162 1163 sessionId = session.getSessionId(); 1164 maxProtocolVersion = sessionVersion; 1165 1166 // Update SSL version number in underlying SSL socket and 1167 // handshake output stream, so that the output records (at the 1168 // record layer) have the correct version 1169 setVersion(sessionVersion); 1170 } 1171 1172 /* 1173 * Force use of the previous session ciphersuite, and 1174 * add the SCSV if enabled. 1175 */ 1176 if (!enableNewSession) { 1177 if (session == null) { 1178 throw new SSLHandshakeException( 1179 "Can't reuse existing SSL client session"); 1180 } 1181 1182 Collection<CipherSuite> cipherList = new ArrayList<>(2); 1183 cipherList.add(sessionSuite); 1184 if (!secureRenegotiation && 1185 cipherSuites.contains(CipherSuite.C_SCSV)) { 1186 cipherList.add(CipherSuite.C_SCSV); 1187 } // otherwise, renegotiation_info extension will be used 1188 1189 cipherSuites = new CipherSuiteList(cipherList); 1190 } 1191 } 1192 1193 if (session == null && !enableNewSession) { 1194 throw new SSLHandshakeException("No existing session to resume"); 1195 } 1196 1197 // exclude SCSV for secure renegotiation 1198 if (secureRenegotiation && cipherSuites.contains(CipherSuite.C_SCSV)) { 1199 Collection<CipherSuite> cipherList = 1200 new ArrayList<>(cipherSuites.size() - 1); 1201 for (CipherSuite suite : cipherSuites.collection()) { 1202 if (suite != CipherSuite.C_SCSV) { 1203 cipherList.add(suite); 1204 } 1205 } 1206 1207 cipherSuites = new CipherSuiteList(cipherList); 1208 } 1209 1210 // make sure there is a negotiable cipher suite. 1211 boolean negotiable = false; 1212 for (CipherSuite suite : cipherSuites.collection()) { 1213 if (isNegotiable(suite)) { 1214 negotiable = true; 1215 break; 1216 } 1217 } 1218 1219 if (!negotiable) { 1220 throw new SSLHandshakeException("No negotiable cipher suite"); 1221 } 1222 1223 // Not a TLS1.2+ handshake 1224 // For SSLv2Hello, HandshakeHash.reset() will be called, so we 1225 // cannot call HandshakeHash.protocolDetermined() here. As it does 1226 // not follow the spec that HandshakeHash.reset() can be only be 1227 // called before protocolDetermined. 1228 // if (maxProtocolVersion.v < ProtocolVersion.TLS12.v) { 1229 // handshakeHash.protocolDetermined(maxProtocolVersion); 1230 // } 1231 1232 // create the ClientHello message 1233 ClientHello clientHelloMessage = new ClientHello( 1234 sslContext.getSecureRandom(), maxProtocolVersion, 1235 sessionId, cipherSuites); 1236 1237 // add signature_algorithm extension 1238 if (maxProtocolVersion.v >= ProtocolVersion.TLS12.v) { 1239 // we will always send the signature_algorithm extension 1240 Collection<SignatureAndHashAlgorithm> localSignAlgs = 1241 getLocalSupportedSignAlgs(); 1242 if (localSignAlgs.isEmpty()) { 1243 throw new SSLHandshakeException( 1244 "No supported signature algorithm"); 1245 } 1246 1247 clientHelloMessage.addSignatureAlgorithmsExtension(localSignAlgs); 1248 } 1249 1250 // add server_name extension 1251 if (enableSNIExtension) { 1252 // We cannot use the hostname resolved from name services. For 1253 // virtual hosting, multiple hostnames may be bound to the same IP 1254 // address, so the hostname resolved from name services is not 1255 // reliable. 1256 String hostname = getRawHostnameSE(); 1257 1258 // we only allow FQDN 1259 if (hostname != null && hostname.indexOf('.') > 0 && 1260 !IPAddressUtil.isIPv4LiteralAddress(hostname) && 1261 !IPAddressUtil.isIPv6LiteralAddress(hostname)) { 1262 clientHelloMessage.addServerNameIndicationExtension(hostname); 1263 } 1264 } 1265 1266 // reset the client random cookie 1267 clnt_random = clientHelloMessage.clnt_random; 1268 1269 /* 1270 * need to set the renegotiation_info extension for: 1271 * 1: secure renegotiation 1272 * 2: initial handshake and no SCSV in the ClientHello 1273 * 3: insecure renegotiation and no SCSV in the ClientHello 1274 */ 1275 if (secureRenegotiation || 1276 !cipherSuites.contains(CipherSuite.C_SCSV)) { 1277 clientHelloMessage.addRenegotiationInfoExtension(clientVerifyData); 1278 } 1279 1280 return clientHelloMessage; 1281 } 1282 1283 /* 1284 * Fault detected during handshake. 1285 */ 1286 void handshakeAlert(byte description) throws SSLProtocolException { 1287 String message = Alerts.alertDescription(description); 1288 1289 if (debug != null && Debug.isOn("handshake")) { 1290 System.out.println("SSL - handshake alert: " + message); 1291 } 1292 throw new SSLProtocolException("handshake alert: " + message); 1293 } 1294 1295 /* 1296 * Unless we are using an anonymous ciphersuite, the server always 1297 * sends a certificate message (for the CipherSuites we currently 1298 * support). The trust manager verifies the chain for us. 1299 */ 1300 private void serverCertificate(CertificateMsg mesg) throws IOException { 1301 if (debug != null && Debug.isOn("handshake")) { 1302 mesg.print(System.out); 1303 } 1304 X509Certificate[] peerCerts = mesg.getCertificateChain(); 1305 if (peerCerts.length == 0) { 1306 fatalSE(Alerts.alert_bad_certificate, 1307 "empty certificate chain"); 1308 } 1309 // ask the trust manager to verify the chain 1310 X509TrustManager tm = sslContext.getX509TrustManager(); 1311 try { 1312 // find out the key exchange algorithm used 1313 // use "RSA" for non-ephemeral "RSA_EXPORT" 1314 String keyExchangeString; 1315 if (keyExchange == K_RSA_EXPORT && !serverKeyExchangeReceived) { 1316 keyExchangeString = K_RSA.name; 1317 } else { 1318 keyExchangeString = keyExchange.name; 1319 } 1320 1321 if (tm instanceof X509ExtendedTrustManager) { 1322 if (conn != null) { 1323 ((X509ExtendedTrustManager)tm).checkServerTrusted( 1324 peerCerts.clone(), 1325 keyExchangeString, 1326 conn); 1327 } else { 1328 ((X509ExtendedTrustManager)tm).checkServerTrusted( 1329 peerCerts.clone(), 1330 keyExchangeString, 1331 engine); 1332 } 1333 } else { 1334 // Unlikely to happen, because we have wrapped the old 1335 // X509TrustManager with the new X509ExtendedTrustManager. 1336 throw new CertificateException( 1337 "Improper X509TrustManager implementation"); 1338 } 1339 } catch (CertificateException e) { 1340 // This will throw an exception, so include the original error. 1341 fatalSE(Alerts.alert_certificate_unknown, e); 1342 } 1343 session.setPeerCertificates(peerCerts); 1344 } 1345 } 1346