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