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 27 package sun.security.ssl; 28 29 import java.io.*; 30 import java.util.*; 31 import java.security.*; 32 import java.security.cert.*; 33 import java.security.interfaces.*; 34 import java.security.spec.ECParameterSpec; 35 36 import javax.crypto.SecretKey; 37 import javax.crypto.spec.SecretKeySpec; 38 39 import javax.net.ssl.*; 40 41 import javax.security.auth.Subject; 42 43 import sun.security.ssl.HandshakeMessage.*; 44 import sun.security.ssl.CipherSuite.*; 45 import sun.security.ssl.SignatureAndHashAlgorithm.*; 46 import static sun.security.ssl.CipherSuite.*; 47 import static sun.security.ssl.CipherSuite.KeyExchange.*; 48 49 /** 50 * ServerHandshaker does the protocol handshaking from the point 51 * of view of a server. It is driven asychronously by handshake messages 52 * as delivered by the parent Handshaker class, and also uses 53 * common functionality (e.g. key generation) that is provided there. 54 * 55 * @author David Brownell 56 */ 57 final class ServerHandshaker extends Handshaker { 58 59 // is the server going to require the client to authenticate? 60 private byte doClientAuth; 61 62 // our authentication info 63 private X509Certificate[] certs; 64 private PrivateKey privateKey; 65 66 private SecretKey[] kerberosKeys; 67 68 // flag to check for clientCertificateVerify message 69 private boolean needClientVerify = false; 70 71 /* 72 * For exportable ciphersuites using non-exportable key sizes, we use 73 * ephemeral RSA keys. We could also do anonymous RSA in the same way 74 * but there are no such ciphersuites currently defined. 75 */ 76 private PrivateKey tempPrivateKey; 77 private PublicKey tempPublicKey; 78 79 /* 80 * For anonymous and ephemeral Diffie-Hellman key exchange, we use 81 * ephemeral Diffie-Hellman keys. 82 */ 83 private DHCrypt dh; 84 85 // Helper for ECDH based key exchanges 86 private ECDHCrypt ecdh; 87 88 // version request by the client in its ClientHello 89 // we remember it for the RSA premaster secret version check 90 private ProtocolVersion clientRequestedVersion; 91 92 private SupportedEllipticCurvesExtension supportedCurves; 93 94 // the preferable signature algorithm used by ServerKeyExchange message 95 SignatureAndHashAlgorithm preferableSignatureAlgorithm; 96 97 /* 98 * Constructor ... use the keys found in the auth context. 99 */ ServerHandshaker(SSLSocketImpl socket, SSLContextImpl context, ProtocolList enabledProtocols, byte clientAuth, ProtocolVersion activeProtocolVersion, boolean isInitialHandshake, boolean secureRenegotiation, byte[] clientVerifyData, byte[] serverVerifyData)100 ServerHandshaker(SSLSocketImpl socket, SSLContextImpl context, 101 ProtocolList enabledProtocols, byte clientAuth, 102 ProtocolVersion activeProtocolVersion, boolean isInitialHandshake, 103 boolean secureRenegotiation, 104 byte[] clientVerifyData, byte[] serverVerifyData) { 105 106 super(socket, context, enabledProtocols, 107 (clientAuth != SSLEngineImpl.clauth_none), false, 108 activeProtocolVersion, isInitialHandshake, secureRenegotiation, 109 clientVerifyData, serverVerifyData); 110 doClientAuth = clientAuth; 111 } 112 113 /* 114 * Constructor ... use the keys found in the auth context. 115 */ ServerHandshaker(SSLEngineImpl engine, SSLContextImpl context, ProtocolList enabledProtocols, byte clientAuth, ProtocolVersion activeProtocolVersion, boolean isInitialHandshake, boolean secureRenegotiation, byte[] clientVerifyData, byte[] serverVerifyData)116 ServerHandshaker(SSLEngineImpl engine, SSLContextImpl context, 117 ProtocolList enabledProtocols, byte clientAuth, 118 ProtocolVersion activeProtocolVersion, 119 boolean isInitialHandshake, boolean secureRenegotiation, 120 byte[] clientVerifyData, byte[] serverVerifyData) { 121 122 super(engine, context, enabledProtocols, 123 (clientAuth != SSLEngineImpl.clauth_none), false, 124 activeProtocolVersion, isInitialHandshake, secureRenegotiation, 125 clientVerifyData, serverVerifyData); 126 doClientAuth = clientAuth; 127 } 128 129 /* 130 * As long as handshaking has not started, we can change 131 * whether client authentication is required. Otherwise, 132 * we will need to wait for the next handshake. 133 */ setClientAuth(byte clientAuth)134 void setClientAuth(byte clientAuth) { 135 doClientAuth = clientAuth; 136 } 137 138 /* 139 * This routine handles all the server side handshake messages, one at 140 * a time. Given the message type (and in some cases the pending cipher 141 * spec) it parses the type-specific message. Then it calls a function 142 * that handles that specific message. 143 * 144 * It updates the state machine as each message is processed, and writes 145 * responses as needed using the connection in the constructor. 146 */ processMessage(byte type, int message_len)147 void processMessage(byte type, int message_len) 148 throws IOException { 149 // 150 // In SSLv3 and TLS, messages follow strictly increasing 151 // numerical order _except_ for one annoying special case. 152 // 153 if ((state >= type) 154 && (state != HandshakeMessage.ht_client_key_exchange 155 && type != HandshakeMessage.ht_certificate_verify)) { 156 throw new SSLProtocolException( 157 "Handshake message sequence violation, state = " + state 158 + ", type = " + type); 159 } 160 161 switch (type) { 162 case HandshakeMessage.ht_client_hello: 163 ClientHello ch = new ClientHello(input, message_len); 164 /* 165 * send it off for processing. 166 */ 167 this.clientHello(ch); 168 break; 169 170 case HandshakeMessage.ht_certificate: 171 if (doClientAuth == SSLEngineImpl.clauth_none) { 172 fatalSE(Alerts.alert_unexpected_message, 173 "client sent unsolicited cert chain"); 174 // NOTREACHED 175 } 176 this.clientCertificate(new CertificateMsg(input)); 177 break; 178 179 case HandshakeMessage.ht_client_key_exchange: 180 SecretKey preMasterSecret; 181 switch (keyExchange) { 182 case K_RSA: 183 case K_RSA_EXPORT: 184 /* 185 * The client's pre-master secret is decrypted using 186 * either the server's normal private RSA key, or the 187 * temporary one used for non-export or signing-only 188 * certificates/keys. 189 */ 190 RSAClientKeyExchange pms = new RSAClientKeyExchange( 191 protocolVersion, clientRequestedVersion, 192 sslContext.getSecureRandom(), input, 193 message_len, privateKey); 194 preMasterSecret = this.clientKeyExchange(pms); 195 break; 196 case K_KRB5: 197 case K_KRB5_EXPORT: 198 preMasterSecret = this.clientKeyExchange( 199 new KerberosClientKeyExchange(protocolVersion, 200 clientRequestedVersion, 201 sslContext.getSecureRandom(), 202 input, 203 kerberosKeys)); 204 break; 205 case K_DHE_RSA: 206 case K_DHE_DSS: 207 case K_DH_ANON: 208 /* 209 * The pre-master secret is derived using the normal 210 * Diffie-Hellman calculation. Note that the main 211 * protocol difference in these five flavors is in how 212 * the ServerKeyExchange message was constructed! 213 */ 214 preMasterSecret = this.clientKeyExchange( 215 new DHClientKeyExchange(input)); 216 break; 217 case K_ECDH_RSA: 218 case K_ECDH_ECDSA: 219 case K_ECDHE_RSA: 220 case K_ECDHE_ECDSA: 221 case K_ECDH_ANON: 222 preMasterSecret = this.clientKeyExchange 223 (new ECDHClientKeyExchange(input)); 224 break; 225 default: 226 throw new SSLProtocolException 227 ("Unrecognized key exchange: " + keyExchange); 228 } 229 230 // 231 // All keys are calculated from the premaster secret 232 // and the exchanged nonces in the same way. 233 // 234 calculateKeys(preMasterSecret, clientRequestedVersion); 235 break; 236 237 case HandshakeMessage.ht_certificate_verify: 238 this.clientCertificateVerify(new CertificateVerify(input, 239 localSupportedSignAlgs, protocolVersion)); 240 break; 241 242 case HandshakeMessage.ht_finished: 243 this.clientFinished( 244 new Finished(protocolVersion, input, cipherSuite)); 245 break; 246 247 default: 248 throw new SSLProtocolException( 249 "Illegal server handshake msg, " + type); 250 } 251 252 // 253 // Move state machine forward if the message handling 254 // code didn't already do so 255 // 256 if (state < type) { 257 if(type == HandshakeMessage.ht_certificate_verify) { 258 state = type + 2; // an annoying special case 259 } else { 260 state = type; 261 } 262 } 263 } 264 265 266 /* 267 * ClientHello presents the server with a bunch of options, to which the 268 * server replies with a ServerHello listing the ones which this session 269 * will use. If needed, it also writes its Certificate plus in some cases 270 * a ServerKeyExchange message. It may also write a CertificateRequest, 271 * to elicit a client certificate. 272 * 273 * All these messages are terminated by a ServerHelloDone message. In 274 * most cases, all this can be sent in a single Record. 275 */ clientHello(ClientHello mesg)276 private void clientHello(ClientHello mesg) throws IOException { 277 if (debug != null && Debug.isOn("handshake")) { 278 mesg.print(System.out); 279 } 280 281 // Does the message include security renegotiation indication? 282 boolean renegotiationIndicated = false; 283 284 // check the TLS_EMPTY_RENEGOTIATION_INFO_SCSV 285 CipherSuiteList cipherSuites = mesg.getCipherSuites(); 286 if (cipherSuites.contains(CipherSuite.C_SCSV)) { 287 renegotiationIndicated = true; 288 if (isInitialHandshake) { 289 secureRenegotiation = true; 290 } else { 291 // abort the handshake with a fatal handshake_failure alert 292 if (secureRenegotiation) { 293 fatalSE(Alerts.alert_handshake_failure, 294 "The SCSV is present in a secure renegotiation"); 295 } else { 296 fatalSE(Alerts.alert_handshake_failure, 297 "The SCSV is present in a insecure renegotiation"); 298 } 299 } 300 } 301 302 // check the "renegotiation_info" extension 303 RenegotiationInfoExtension clientHelloRI = (RenegotiationInfoExtension) 304 mesg.extensions.get(ExtensionType.EXT_RENEGOTIATION_INFO); 305 if (clientHelloRI != null) { 306 renegotiationIndicated = true; 307 if (isInitialHandshake) { 308 // verify the length of the "renegotiated_connection" field 309 if (!clientHelloRI.isEmpty()) { 310 // abort the handshake with a fatal handshake_failure alert 311 fatalSE(Alerts.alert_handshake_failure, 312 "The renegotiation_info field is not empty"); 313 } 314 315 secureRenegotiation = true; 316 } else { 317 if (!secureRenegotiation) { 318 // unexpected RI extension for insecure renegotiation, 319 // abort the handshake with a fatal handshake_failure alert 320 fatalSE(Alerts.alert_handshake_failure, 321 "The renegotiation_info is present in a insecure " + 322 "renegotiation"); 323 } 324 325 // verify the client_verify_data value 326 if (!Arrays.equals(clientVerifyData, 327 clientHelloRI.getRenegotiatedConnection())) { 328 fatalSE(Alerts.alert_handshake_failure, 329 "Incorrect verify data in ClientHello " + 330 "renegotiation_info message"); 331 } 332 } 333 } else if (!isInitialHandshake && secureRenegotiation) { 334 // if the connection's "secure_renegotiation" flag is set to TRUE 335 // and the "renegotiation_info" extension is not present, abort 336 // the handshake. 337 fatalSE(Alerts.alert_handshake_failure, 338 "Inconsistent secure renegotiation indication"); 339 } 340 341 // if there is no security renegotiation indication or the previous 342 // handshake is insecure. 343 if (!renegotiationIndicated || !secureRenegotiation) { 344 if (isInitialHandshake) { 345 if (!allowLegacyHelloMessages) { 346 // abort the handshake with a fatal handshake_failure alert 347 fatalSE(Alerts.alert_handshake_failure, 348 "Failed to negotiate the use of secure renegotiation"); 349 } 350 351 // continue with legacy ClientHello 352 if (debug != null && Debug.isOn("handshake")) { 353 System.out.println("Warning: No renegotiation " + 354 "indication in ClientHello, allow legacy ClientHello"); 355 } 356 } else if (!allowUnsafeRenegotiation) { 357 // abort the handshake 358 if (activeProtocolVersion.v >= ProtocolVersion.TLS10.v) { 359 // response with a no_renegotiation warning, 360 warningSE(Alerts.alert_no_renegotiation); 361 362 // invalidate the handshake so that the caller can 363 // dispose this object. 364 invalidated = true; 365 366 // If there is still unread block in the handshake 367 // input stream, it would be truncated with the disposal 368 // and the next handshake message will become incomplete. 369 // 370 // However, according to SSL/TLS specifications, no more 371 // handshake message could immediately follow ClientHello 372 // or HelloRequest. But in case of any improper messages, 373 // we'd better check to ensure there is no remaining bytes 374 // in the handshake input stream. 375 if (input.available() > 0) { 376 fatalSE(Alerts.alert_unexpected_message, 377 "ClientHello followed by an unexpected " + 378 "handshake message"); 379 } 380 381 return; 382 } else { 383 // For SSLv3, send the handshake_failure fatal error. 384 // Note that SSLv3 does not define a no_renegotiation 385 // alert like TLSv1. However we cannot ignore the message 386 // simply, otherwise the other side was waiting for a 387 // response that would never come. 388 fatalSE(Alerts.alert_handshake_failure, 389 "Renegotiation is not allowed"); 390 } 391 } else { // !isInitialHandshake && allowUnsafeRenegotiation 392 // continue with unsafe renegotiation. 393 if (debug != null && Debug.isOn("handshake")) { 394 System.out.println( 395 "Warning: continue with insecure renegotiation"); 396 } 397 } 398 } 399 400 /* 401 * Always make sure this entire record has been digested before we 402 * start emitting output, to ensure correct digesting order. 403 */ 404 input.digestNow(); 405 406 /* 407 * FIRST, construct the ServerHello using the options and priorities 408 * from the ClientHello. Update the (pending) cipher spec as we do 409 * so, and save the client's version to protect against rollback 410 * attacks. 411 * 412 * There are a bunch of minor tasks here, and one major one: deciding 413 * if the short or the full handshake sequence will be used. 414 */ 415 ServerHello m1 = new ServerHello(); 416 417 clientRequestedVersion = mesg.protocolVersion; 418 419 // select a proper protocol version. 420 ProtocolVersion selectedVersion = 421 selectProtocolVersion(clientRequestedVersion); 422 if (selectedVersion == null || 423 selectedVersion.v == ProtocolVersion.SSL20Hello.v) { 424 fatalSE(Alerts.alert_handshake_failure, 425 "Client requested protocol " + clientRequestedVersion + 426 " not enabled or not supported"); 427 } 428 429 handshakeHash.protocolDetermined(selectedVersion); 430 setVersion(selectedVersion); 431 432 m1.protocolVersion = protocolVersion; 433 434 // 435 // random ... save client and server values for later use 436 // in computing the master secret (from pre-master secret) 437 // and thence the other crypto keys. 438 // 439 // NOTE: this use of three inputs to generating _each_ set 440 // of ciphers slows things down, but it does increase the 441 // security since each connection in the session can hold 442 // its own authenticated (and strong) keys. One could make 443 // creation of a session a rare thing... 444 // 445 clnt_random = mesg.clnt_random; 446 svr_random = new RandomCookie(sslContext.getSecureRandom()); 447 m1.svr_random = svr_random; 448 449 session = null; // forget about the current session 450 // 451 // Here we go down either of two paths: (a) the fast one, where 452 // the client's asked to rejoin an existing session, and the server 453 // permits this; (b) the other one, where a new session is created. 454 // 455 if (mesg.sessionId.length() != 0) { 456 // client is trying to resume a session, let's see... 457 458 SSLSessionImpl previous = ((SSLSessionContextImpl)sslContext 459 .engineGetServerSessionContext()) 460 .get(mesg.sessionId.getId()); 461 // 462 // Check if we can use the fast path, resuming a session. We 463 // can do so iff we have a valid record for that session, and 464 // the cipher suite for that session was on the list which the 465 // client requested, and if we're not forgetting any needed 466 // authentication on the part of the client. 467 // 468 if (previous != null) { 469 resumingSession = previous.isRejoinable(); 470 471 if (resumingSession) { 472 ProtocolVersion oldVersion = previous.getProtocolVersion(); 473 // cannot resume session with different version 474 if (oldVersion != protocolVersion) { 475 resumingSession = false; 476 } 477 } 478 479 if (resumingSession && 480 (doClientAuth == SSLEngineImpl.clauth_required)) { 481 try { 482 previous.getPeerPrincipal(); 483 } catch (SSLPeerUnverifiedException e) { 484 resumingSession = false; 485 } 486 } 487 488 // validate subject identity 489 if (resumingSession) { 490 CipherSuite suite = previous.getSuite(); 491 if (suite.keyExchange == K_KRB5 || 492 suite.keyExchange == K_KRB5_EXPORT) { 493 Principal localPrincipal = previous.getLocalPrincipal(); 494 495 Subject subject = null; 496 try { 497 subject = AccessController.doPrivileged( 498 new PrivilegedExceptionAction<Subject>() { 499 public Subject run() throws Exception { 500 return 501 Krb5Helper.getServerSubject(getAccSE()); 502 }}); 503 } catch (PrivilegedActionException e) { 504 subject = null; 505 if (debug != null && Debug.isOn("session")) { 506 System.out.println("Attempt to obtain" + 507 " subject failed!"); 508 } 509 } 510 511 if (subject != null) { 512 // Eliminate dependency on KerberosPrincipal 513 Set<Principal> principals = 514 subject.getPrincipals(Principal.class); 515 if (!principals.contains(localPrincipal)) { 516 resumingSession = false; 517 if (debug != null && Debug.isOn("session")) { 518 System.out.println("Subject identity" + 519 " is not the same"); 520 } 521 } else { 522 if (debug != null && Debug.isOn("session")) 523 System.out.println("Subject identity" + 524 " is same"); 525 } 526 } else { 527 resumingSession = false; 528 if (debug != null && Debug.isOn("session")) 529 System.out.println("Kerberos credentials are" + 530 " not present in the current Subject;" + 531 " check if " + 532 " javax.security.auth.useSubjectAsCreds" + 533 " system property has been set to false"); 534 } 535 } 536 } 537 538 if (resumingSession) { 539 CipherSuite suite = previous.getSuite(); 540 // verify that the ciphersuite from the cached session 541 // is in the list of client requested ciphersuites and 542 // we have it enabled 543 if ((isNegotiable(suite) == false) || 544 (mesg.getCipherSuites().contains(suite) == false)) { 545 resumingSession = false; 546 } else { 547 // everything looks ok, set the ciphersuite 548 // this should be done last when we are sure we 549 // will resume 550 setCipherSuite(suite); 551 } 552 } 553 554 if (resumingSession) { 555 session = previous; 556 if (debug != null && 557 (Debug.isOn("handshake") || Debug.isOn("session"))) { 558 System.out.println("%% Resuming " + session); 559 } 560 } 561 } 562 } // else client did not try to resume 563 564 // 565 // If client hasn't specified a session we can resume, start a 566 // new one and choose its cipher suite and compression options. 567 // Unless new session creation is disabled for this connection! 568 // 569 if (session == null) { 570 if (!enableNewSession) { 571 throw new SSLException("Client did not resume a session"); 572 } 573 574 supportedCurves = (SupportedEllipticCurvesExtension) 575 mesg.extensions.get(ExtensionType.EXT_ELLIPTIC_CURVES); 576 577 // We only need to handle the "signature_algorithm" extension 578 // for full handshakes and TLS 1.2 or later. 579 if (protocolVersion.v >= ProtocolVersion.TLS12.v) { 580 SignatureAlgorithmsExtension signAlgs = 581 (SignatureAlgorithmsExtension)mesg.extensions.get( 582 ExtensionType.EXT_SIGNATURE_ALGORITHMS); 583 if (signAlgs != null) { 584 Collection<SignatureAndHashAlgorithm> peerSignAlgs = 585 signAlgs.getSignAlgorithms(); 586 if (peerSignAlgs == null || peerSignAlgs.isEmpty()) { 587 throw new SSLHandshakeException( 588 "No peer supported signature algorithms"); 589 } 590 591 Collection<SignatureAndHashAlgorithm> 592 supportedPeerSignAlgs = 593 SignatureAndHashAlgorithm.getSupportedAlgorithms( 594 peerSignAlgs); 595 if (supportedPeerSignAlgs.isEmpty()) { 596 throw new SSLHandshakeException( 597 "No supported signature and hash algorithm " + 598 "in common"); 599 } 600 601 setPeerSupportedSignAlgs(supportedPeerSignAlgs); 602 } // else, need to use peer implicit supported signature algs 603 } 604 605 session = new SSLSessionImpl(protocolVersion, CipherSuite.C_NULL, 606 getLocalSupportedSignAlgs(), 607 sslContext.getSecureRandom(), 608 getHostAddressSE(), getPortSE()); 609 610 if (protocolVersion.v >= ProtocolVersion.TLS12.v) { 611 if (peerSupportedSignAlgs != null) { 612 session.setPeerSupportedSignatureAlgorithms( 613 peerSupportedSignAlgs); 614 } // else, we will set the implicit peer supported signature 615 // algorithms in chooseCipherSuite() 616 } 617 618 // set the handshake session 619 setHandshakeSessionSE(session); 620 621 // choose cipher suite and corresponding private key 622 chooseCipherSuite(mesg); 623 624 session.setSuite(cipherSuite); 625 session.setLocalPrivateKey(privateKey); 626 627 // chooseCompression(mesg); 628 } else { 629 // set the handshake session 630 setHandshakeSessionSE(session); 631 } 632 633 if (protocolVersion.v >= ProtocolVersion.TLS12.v) { 634 if (resumingSession) { 635 handshakeHash.setCertificateVerifyAlg(null); 636 } 637 handshakeHash.setFinishedAlg(cipherSuite.prfAlg.getPRFHashAlg()); 638 } 639 640 m1.cipherSuite = cipherSuite; 641 m1.sessionId = session.getSessionId(); 642 m1.compression_method = session.getCompression(); 643 644 if (secureRenegotiation) { 645 // For ServerHellos that are initial handshakes, then the 646 // "renegotiated_connection" field in "renegotiation_info" 647 // extension is of zero length. 648 // 649 // For ServerHellos that are renegotiating, this field contains 650 // the concatenation of client_verify_data and server_verify_data. 651 // 652 // Note that for initial handshakes, both the clientVerifyData 653 // variable and serverVerifyData variable are of zero length. 654 HelloExtension serverHelloRI = new RenegotiationInfoExtension( 655 clientVerifyData, serverVerifyData); 656 m1.extensions.add(serverHelloRI); 657 } 658 659 if (debug != null && Debug.isOn("handshake")) { 660 m1.print(System.out); 661 System.out.println("Cipher suite: " + session.getSuite()); 662 } 663 m1.write(output); 664 665 // 666 // If we are resuming a session, we finish writing handshake 667 // messages right now and then finish. 668 // 669 if (resumingSession) { 670 calculateConnectionKeys(session.getMasterSecret()); 671 sendChangeCipherAndFinish(false); 672 return; 673 } 674 675 676 /* 677 * SECOND, write the server Certificate(s) if we need to. 678 * 679 * NOTE: while an "anonymous RSA" mode is explicitly allowed by 680 * the protocol, we can't support it since all of the SSL flavors 681 * defined in the protocol spec are explicitly stated to require 682 * using RSA certificates. 683 */ 684 if (keyExchange == K_KRB5 || keyExchange == K_KRB5_EXPORT) { 685 // Server certificates are omitted for Kerberos ciphers 686 687 } else if ((keyExchange != K_DH_ANON) && (keyExchange != K_ECDH_ANON)) { 688 if (certs == null) { 689 throw new RuntimeException("no certificates"); 690 } 691 692 CertificateMsg m2 = new CertificateMsg(certs); 693 694 /* 695 * Set local certs in the SSLSession, output 696 * debug info, and then actually write to the client. 697 */ 698 session.setLocalCertificates(certs); 699 if (debug != null && Debug.isOn("handshake")) { 700 m2.print(System.out); 701 } 702 m2.write(output); 703 704 // XXX has some side effects with OS TCP buffering, 705 // leave it out for now 706 707 // let client verify chain in the meantime... 708 // output.flush(); 709 } else { 710 if (certs != null) { 711 throw new RuntimeException("anonymous keyexchange with certs"); 712 } 713 } 714 715 /* 716 * THIRD, the ServerKeyExchange message ... iff it's needed. 717 * 718 * It's usually needed unless there's an encryption-capable 719 * RSA cert, or a D-H cert. The notable exception is that 720 * exportable ciphers used with big RSA keys need to downgrade 721 * to use short RSA keys, even when the key/cert encrypts OK. 722 */ 723 724 ServerKeyExchange m3; 725 switch (keyExchange) { 726 case K_RSA: 727 case K_KRB5: 728 case K_KRB5_EXPORT: 729 // no server key exchange for RSA or KRB5 ciphersuites 730 m3 = null; 731 break; 732 case K_RSA_EXPORT: 733 if (JsseJce.getRSAKeyLength(certs[0].getPublicKey()) > 512) { 734 try { 735 m3 = new RSA_ServerKeyExchange( 736 tempPublicKey, privateKey, 737 clnt_random, svr_random, 738 sslContext.getSecureRandom()); 739 privateKey = tempPrivateKey; 740 } catch (GeneralSecurityException e) { 741 throwSSLException 742 ("Error generating RSA server key exchange", e); 743 m3 = null; // make compiler happy 744 } 745 } else { 746 // RSA_EXPORT with short key, don't need ServerKeyExchange 747 m3 = null; 748 } 749 break; 750 case K_DHE_RSA: 751 case K_DHE_DSS: 752 try { 753 m3 = new DH_ServerKeyExchange(dh, 754 privateKey, 755 clnt_random.random_bytes, 756 svr_random.random_bytes, 757 sslContext.getSecureRandom(), 758 preferableSignatureAlgorithm, 759 protocolVersion); 760 } catch (GeneralSecurityException e) { 761 throwSSLException("Error generating DH server key exchange", e); 762 m3 = null; // make compiler happy 763 } 764 break; 765 case K_DH_ANON: 766 m3 = new DH_ServerKeyExchange(dh, protocolVersion); 767 break; 768 case K_ECDHE_RSA: 769 case K_ECDHE_ECDSA: 770 case K_ECDH_ANON: 771 try { 772 m3 = new ECDH_ServerKeyExchange(ecdh, 773 privateKey, 774 clnt_random.random_bytes, 775 svr_random.random_bytes, 776 sslContext.getSecureRandom(), 777 preferableSignatureAlgorithm, 778 protocolVersion); 779 } catch (GeneralSecurityException e) { 780 throwSSLException( 781 "Error generating ECDH server key exchange", e); 782 m3 = null; // make compiler happy 783 } 784 break; 785 case K_ECDH_RSA: 786 case K_ECDH_ECDSA: 787 // ServerKeyExchange not used for fixed ECDH 788 m3 = null; 789 break; 790 default: 791 throw new RuntimeException("internal error: " + keyExchange); 792 } 793 if (m3 != null) { 794 if (debug != null && Debug.isOn("handshake")) { 795 m3.print(System.out); 796 } 797 m3.write(output); 798 } 799 800 // 801 // FOURTH, the CertificateRequest message. The details of 802 // the message can be affected by the key exchange algorithm 803 // in use. For example, certs with fixed Diffie-Hellman keys 804 // are only useful with the DH_DSS and DH_RSA key exchange 805 // algorithms. 806 // 807 // Needed only if server requires client to authenticate self. 808 // Illegal for anonymous flavors, so we need to check that. 809 // 810 // CertificateRequest is omitted for Kerberos ciphers 811 if (doClientAuth != SSLEngineImpl.clauth_none && 812 keyExchange != K_DH_ANON && keyExchange != K_ECDH_ANON && 813 keyExchange != K_KRB5 && keyExchange != K_KRB5_EXPORT) { 814 815 CertificateRequest m4; 816 X509Certificate caCerts[]; 817 818 Collection<SignatureAndHashAlgorithm> localSignAlgs = null; 819 if (protocolVersion.v >= ProtocolVersion.TLS12.v) { 820 // We currently use all local upported signature and hash 821 // algorithms. However, to minimize the computation cost 822 // of requested hash algorithms, we may use a restricted 823 // set of signature algorithms in the future. 824 localSignAlgs = getLocalSupportedSignAlgs(); 825 if (localSignAlgs.isEmpty()) { 826 throw new SSLHandshakeException( 827 "No supported signature algorithm"); 828 } 829 830 Set<String> localHashAlgs = 831 SignatureAndHashAlgorithm.getHashAlgorithmNames( 832 localSignAlgs); 833 if (localHashAlgs.isEmpty()) { 834 throw new SSLHandshakeException( 835 "No supported signature algorithm"); 836 } 837 handshakeHash.restrictCertificateVerifyAlgs(localHashAlgs); 838 } 839 840 caCerts = sslContext.getX509TrustManager().getAcceptedIssuers(); 841 m4 = new CertificateRequest(caCerts, keyExchange, 842 localSignAlgs, protocolVersion); 843 844 if (debug != null && Debug.isOn("handshake")) { 845 m4.print(System.out); 846 } 847 m4.write(output); 848 } else { 849 if (protocolVersion.v >= ProtocolVersion.TLS12.v) { 850 handshakeHash.setCertificateVerifyAlg(null); 851 } 852 } 853 854 /* 855 * FIFTH, say ServerHelloDone. 856 */ 857 ServerHelloDone m5 = new ServerHelloDone(); 858 859 if (debug != null && Debug.isOn("handshake")) { 860 m5.print(System.out); 861 } 862 m5.write(output); 863 864 /* 865 * Flush any buffered messages so the client will see them. 866 * Ideally, all the messages above go in a single network level 867 * message to the client. Without big Certificate chains, it's 868 * going to be the common case. 869 */ 870 output.flush(); 871 } 872 873 /* 874 * Choose cipher suite from among those supported by client. Sets 875 * the cipherSuite and keyExchange variables. 876 */ chooseCipherSuite(ClientHello mesg)877 private void chooseCipherSuite(ClientHello mesg) throws IOException { 878 for (CipherSuite suite : mesg.getCipherSuites().collection()) { 879 if (isNegotiable(suite) == false) { 880 continue; 881 } 882 883 if (doClientAuth == SSLEngineImpl.clauth_required) { 884 if ((suite.keyExchange == K_DH_ANON) || 885 (suite.keyExchange == K_ECDH_ANON)) { 886 continue; 887 } 888 } 889 if (trySetCipherSuite(suite) == false) { 890 continue; 891 } 892 return; 893 } 894 fatalSE(Alerts.alert_handshake_failure, 895 "no cipher suites in common"); 896 } 897 898 /** 899 * Set the given CipherSuite, if possible. Return the result. 900 * The call succeeds if the CipherSuite is available and we have 901 * the necessary certificates to complete the handshake. We don't 902 * check if the CipherSuite is actually enabled. 903 * 904 * If successful, this method also generates ephemeral keys if 905 * required for this ciphersuite. This may take some time, so this 906 * method should only be called if you really want to use the 907 * CipherSuite. 908 * 909 * This method is called from chooseCipherSuite() in this class. 910 */ trySetCipherSuite(CipherSuite suite)911 boolean trySetCipherSuite(CipherSuite suite) { 912 /* 913 * If we're resuming a session we know we can 914 * support this key exchange algorithm and in fact 915 * have already cached the result of it in 916 * the session state. 917 */ 918 if (resumingSession) { 919 return true; 920 } 921 922 if (suite.isNegotiable() == false) { 923 return false; 924 } 925 926 // must not negotiate the obsoleted weak cipher suites. 927 if (protocolVersion.v >= suite.obsoleted) { 928 return false; 929 } 930 931 // must not negotiate unsupported cipher suites. 932 if (protocolVersion.v < suite.supported) { 933 return false; 934 } 935 936 KeyExchange keyExchange = suite.keyExchange; 937 938 // null out any existing references 939 privateKey = null; 940 certs = null; 941 dh = null; 942 tempPrivateKey = null; 943 tempPublicKey = null; 944 945 Collection<SignatureAndHashAlgorithm> supportedSignAlgs = null; 946 if (protocolVersion.v >= ProtocolVersion.TLS12.v) { 947 if (peerSupportedSignAlgs != null) { 948 supportedSignAlgs = peerSupportedSignAlgs; 949 } else { 950 SignatureAndHashAlgorithm algorithm = null; 951 952 // we may optimize the performance 953 switch (keyExchange) { 954 // If the negotiated key exchange algorithm is one of 955 // (RSA, DHE_RSA, DH_RSA, RSA_PSK, ECDH_RSA, ECDHE_RSA), 956 // behave as if client had sent the value {sha1,rsa}. 957 case K_RSA: 958 case K_DHE_RSA: 959 case K_DH_RSA: 960 // case K_RSA_PSK: 961 case K_ECDH_RSA: 962 case K_ECDHE_RSA: 963 algorithm = SignatureAndHashAlgorithm.valueOf( 964 HashAlgorithm.SHA1.value, 965 SignatureAlgorithm.RSA.value, 0); 966 break; 967 // If the negotiated key exchange algorithm is one of 968 // (DHE_DSS, DH_DSS), behave as if the client had 969 // sent the value {sha1,dsa}. 970 case K_DHE_DSS: 971 case K_DH_DSS: 972 algorithm = SignatureAndHashAlgorithm.valueOf( 973 HashAlgorithm.SHA1.value, 974 SignatureAlgorithm.DSA.value, 0); 975 break; 976 // If the negotiated key exchange algorithm is one of 977 // (ECDH_ECDSA, ECDHE_ECDSA), behave as if the client 978 // had sent value {sha1,ecdsa}. 979 case K_ECDH_ECDSA: 980 case K_ECDHE_ECDSA: 981 algorithm = SignatureAndHashAlgorithm.valueOf( 982 HashAlgorithm.SHA1.value, 983 SignatureAlgorithm.ECDSA.value, 0); 984 break; 985 default: 986 // no peer supported signature algorithms 987 } 988 989 if (algorithm == null) { 990 supportedSignAlgs = 991 Collections.<SignatureAndHashAlgorithm>emptySet(); 992 } else { 993 supportedSignAlgs = 994 new ArrayList<SignatureAndHashAlgorithm>(1); 995 supportedSignAlgs.add(algorithm); 996 } 997 998 // Sets the peer supported signature algorithm to use in KM 999 // temporarily. 1000 session.setPeerSupportedSignatureAlgorithms(supportedSignAlgs); 1001 } 1002 } 1003 1004 switch (keyExchange) { 1005 case K_RSA: 1006 // need RSA certs for authentication 1007 if (setupPrivateKeyAndChain("RSA") == false) { 1008 return false; 1009 } 1010 break; 1011 case K_RSA_EXPORT: 1012 // need RSA certs for authentication 1013 if (setupPrivateKeyAndChain("RSA") == false) { 1014 return false; 1015 } 1016 1017 try { 1018 if (JsseJce.getRSAKeyLength(certs[0].getPublicKey()) > 512) { 1019 if (!setupEphemeralRSAKeys(suite.exportable)) { 1020 return false; 1021 } 1022 } 1023 } catch (RuntimeException e) { 1024 // could not determine keylength, ignore key 1025 return false; 1026 } 1027 break; 1028 case K_DHE_RSA: 1029 // need RSA certs for authentication 1030 if (setupPrivateKeyAndChain("RSA") == false) { 1031 return false; 1032 } 1033 1034 // get preferable peer signature algorithm for server key exchange 1035 if (protocolVersion.v >= ProtocolVersion.TLS12.v) { 1036 preferableSignatureAlgorithm = 1037 SignatureAndHashAlgorithm.getPreferableAlgorithm( 1038 supportedSignAlgs, "RSA", privateKey); 1039 if (preferableSignatureAlgorithm == null) { 1040 return false; 1041 } 1042 } 1043 1044 setupEphemeralDHKeys(suite.exportable); 1045 break; 1046 case K_ECDHE_RSA: 1047 // need RSA certs for authentication 1048 if (setupPrivateKeyAndChain("RSA") == false) { 1049 return false; 1050 } 1051 1052 // get preferable peer signature algorithm for server key exchange 1053 if (protocolVersion.v >= ProtocolVersion.TLS12.v) { 1054 preferableSignatureAlgorithm = 1055 SignatureAndHashAlgorithm.getPreferableAlgorithm( 1056 supportedSignAlgs, "RSA", privateKey); 1057 if (preferableSignatureAlgorithm == null) { 1058 return false; 1059 } 1060 } 1061 1062 if (setupEphemeralECDHKeys() == false) { 1063 return false; 1064 } 1065 break; 1066 case K_DHE_DSS: 1067 // get preferable peer signature algorithm for server key exchange 1068 if (protocolVersion.v >= ProtocolVersion.TLS12.v) { 1069 preferableSignatureAlgorithm = 1070 SignatureAndHashAlgorithm.getPreferableAlgorithm( 1071 supportedSignAlgs, "DSA"); 1072 if (preferableSignatureAlgorithm == null) { 1073 return false; 1074 } 1075 } 1076 1077 // need DSS certs for authentication 1078 if (setupPrivateKeyAndChain("DSA") == false) { 1079 return false; 1080 } 1081 setupEphemeralDHKeys(suite.exportable); 1082 break; 1083 case K_ECDHE_ECDSA: 1084 // get preferable peer signature algorithm for server key exchange 1085 if (protocolVersion.v >= ProtocolVersion.TLS12.v) { 1086 preferableSignatureAlgorithm = 1087 SignatureAndHashAlgorithm.getPreferableAlgorithm( 1088 supportedSignAlgs, "ECDSA"); 1089 if (preferableSignatureAlgorithm == null) { 1090 return false; 1091 } 1092 } 1093 1094 // need EC cert signed using EC 1095 if (setupPrivateKeyAndChain("EC_EC") == false) { 1096 return false; 1097 } 1098 if (setupEphemeralECDHKeys() == false) { 1099 return false; 1100 } 1101 break; 1102 case K_ECDH_RSA: 1103 // need EC cert signed using RSA 1104 if (setupPrivateKeyAndChain("EC_RSA") == false) { 1105 return false; 1106 } 1107 setupStaticECDHKeys(); 1108 break; 1109 case K_ECDH_ECDSA: 1110 // need EC cert signed using EC 1111 if (setupPrivateKeyAndChain("EC_EC") == false) { 1112 return false; 1113 } 1114 setupStaticECDHKeys(); 1115 break; 1116 case K_KRB5: 1117 case K_KRB5_EXPORT: 1118 // need Kerberos Key 1119 if (!setupKerberosKeys()) { 1120 return false; 1121 } 1122 break; 1123 case K_DH_ANON: 1124 // no certs needed for anonymous 1125 setupEphemeralDHKeys(suite.exportable); 1126 break; 1127 case K_ECDH_ANON: 1128 // no certs needed for anonymous 1129 if (setupEphemeralECDHKeys() == false) { 1130 return false; 1131 } 1132 break; 1133 default: 1134 // internal error, unknown key exchange 1135 throw new RuntimeException("Unrecognized cipherSuite: " + suite); 1136 } 1137 setCipherSuite(suite); 1138 1139 // set the peer implicit supported signature algorithms 1140 if (protocolVersion.v >= ProtocolVersion.TLS12.v) { 1141 if (peerSupportedSignAlgs == null) { 1142 setPeerSupportedSignAlgs(supportedSignAlgs); 1143 // we had alreay update the session 1144 } 1145 } 1146 return true; 1147 } 1148 1149 /* 1150 * Get some "ephemeral" RSA keys for this context. This means 1151 * generating them if it's not already been done. 1152 * 1153 * Note that we currently do not implement any ciphersuites that use 1154 * strong ephemeral RSA. (We do not support the EXPORT1024 ciphersuites 1155 * and standard RSA ciphersuites prohibit ephemeral mode for some reason) 1156 * This means that export is always true and 512 bit keys are generated. 1157 */ setupEphemeralRSAKeys(boolean export)1158 private boolean setupEphemeralRSAKeys(boolean export) { 1159 KeyPair kp = sslContext.getEphemeralKeyManager(). 1160 getRSAKeyPair(export, sslContext.getSecureRandom()); 1161 if (kp == null) { 1162 return false; 1163 } else { 1164 tempPublicKey = kp.getPublic(); 1165 tempPrivateKey = kp.getPrivate(); 1166 return true; 1167 } 1168 } 1169 1170 /* 1171 * Acquire some "ephemeral" Diffie-Hellman keys for this handshake. 1172 * We don't reuse these, for improved forward secrecy. 1173 */ setupEphemeralDHKeys(boolean export)1174 private void setupEphemeralDHKeys(boolean export) { 1175 /* 1176 * Diffie-Hellman keys ... we use 768 bit private keys due 1177 * to the "use twice as many key bits as bits you want secret" 1178 * rule of thumb, assuming we want the same size premaster 1179 * secret with Diffie-Hellman and RSA key exchanges. Except 1180 * that exportable ciphers max out at 512 bits modulus values. 1181 */ 1182 dh = new DHCrypt((export ? 512 : 768), sslContext.getSecureRandom()); 1183 } 1184 1185 // Setup the ephemeral ECDH parameters. 1186 // If we cannot continue because we do not support any of the curves that 1187 // the client requested, return false. Otherwise (all is well), return true. setupEphemeralECDHKeys()1188 private boolean setupEphemeralECDHKeys() { 1189 int index = -1; 1190 if (supportedCurves != null) { 1191 // if the client sent the supported curves extension, pick the 1192 // first one that we support; 1193 for (int curveId : supportedCurves.curveIds()) { 1194 if (SupportedEllipticCurvesExtension.isSupported(curveId)) { 1195 index = curveId; 1196 break; 1197 } 1198 } 1199 if (index < 0) { 1200 // no match found, cannot use this ciphersuite 1201 return false; 1202 } 1203 } else { 1204 // pick our preference 1205 index = SupportedEllipticCurvesExtension.DEFAULT.curveIds()[0]; 1206 } 1207 String oid = SupportedEllipticCurvesExtension.getCurveOid(index); 1208 ecdh = new ECDHCrypt(oid, sslContext.getSecureRandom()); 1209 return true; 1210 } 1211 setupStaticECDHKeys()1212 private void setupStaticECDHKeys() { 1213 // don't need to check whether the curve is supported, already done 1214 // in setupPrivateKeyAndChain(). 1215 ecdh = new ECDHCrypt(privateKey, certs[0].getPublicKey()); 1216 } 1217 1218 /** 1219 * Retrieve the server key and certificate for the specified algorithm 1220 * from the KeyManager and set the instance variables. 1221 * 1222 * @return true if successful, false if not available or invalid 1223 */ setupPrivateKeyAndChain(String algorithm)1224 private boolean setupPrivateKeyAndChain(String algorithm) { 1225 X509ExtendedKeyManager km = sslContext.getX509KeyManager(); 1226 String alias; 1227 if (conn != null) { 1228 alias = km.chooseServerAlias(algorithm, null, conn); 1229 } else { 1230 alias = km.chooseEngineServerAlias(algorithm, null, engine); 1231 } 1232 if (alias == null) { 1233 return false; 1234 } 1235 PrivateKey tempPrivateKey = km.getPrivateKey(alias); 1236 if (tempPrivateKey == null) { 1237 return false; 1238 } 1239 X509Certificate[] tempCerts = km.getCertificateChain(alias); 1240 if ((tempCerts == null) || (tempCerts.length == 0)) { 1241 return false; 1242 } 1243 String keyAlgorithm = algorithm.split("_")[0]; 1244 PublicKey publicKey = tempCerts[0].getPublicKey(); 1245 if ((tempPrivateKey.getAlgorithm().equals(keyAlgorithm) == false) 1246 || (publicKey.getAlgorithm().equals(keyAlgorithm) == false)) { 1247 return false; 1248 } 1249 // For ECC certs, check whether we support the EC domain parameters. 1250 // If the client sent a SupportedEllipticCurves ClientHello extension, 1251 // check against that too. 1252 if (keyAlgorithm.equals("EC")) { 1253 if (publicKey instanceof ECPublicKey == false) { 1254 return false; 1255 } 1256 ECParameterSpec params = ((ECPublicKey)publicKey).getParams(); 1257 int index = SupportedEllipticCurvesExtension.getCurveIndex(params); 1258 if (SupportedEllipticCurvesExtension.isSupported(index) == false) { 1259 return false; 1260 } 1261 if ((supportedCurves != null) && !supportedCurves.contains(index)) { 1262 return false; 1263 } 1264 } 1265 this.privateKey = tempPrivateKey; 1266 this.certs = tempCerts; 1267 return true; 1268 } 1269 1270 /** 1271 * Retrieve the Kerberos key for the specified server principal 1272 * from the JAAS configuration file. 1273 * 1274 * @return true if successful, false if not available or invalid 1275 */ setupKerberosKeys()1276 private boolean setupKerberosKeys() { 1277 if (kerberosKeys != null) { 1278 return true; 1279 } 1280 try { 1281 final AccessControlContext acc = getAccSE(); 1282 kerberosKeys = AccessController.doPrivileged( 1283 // Eliminate dependency on KerberosKey 1284 new PrivilegedExceptionAction<SecretKey[]>() { 1285 public SecretKey[] run() throws Exception { 1286 // get kerberos key for the default principal 1287 return Krb5Helper.getServerKeys(acc); 1288 }}); 1289 1290 // check permission to access and use the secret key of the 1291 // Kerberized "host" service 1292 if (kerberosKeys != null && kerberosKeys.length > 0) { 1293 if (debug != null && Debug.isOn("handshake")) { 1294 for (SecretKey k: kerberosKeys) { 1295 System.out.println("Using Kerberos key: " + 1296 k); 1297 } 1298 } 1299 1300 String serverPrincipal = 1301 Krb5Helper.getServerPrincipalName(kerberosKeys[0]); 1302 SecurityManager sm = System.getSecurityManager(); 1303 try { 1304 if (sm != null) { 1305 // Eliminate dependency on ServicePermission 1306 sm.checkPermission(Krb5Helper.getServicePermission( 1307 serverPrincipal, "accept"), acc); 1308 } 1309 } catch (SecurityException se) { 1310 kerberosKeys = null; 1311 // %%% destroy keys? or will that affect Subject? 1312 if (debug != null && Debug.isOn("handshake")) 1313 System.out.println("Permission to access Kerberos" 1314 + " secret key denied"); 1315 return false; 1316 } 1317 } 1318 return (kerberosKeys != null && kerberosKeys.length > 0); 1319 } catch (PrivilegedActionException e) { 1320 // Likely exception here is LoginExceptin 1321 if (debug != null && Debug.isOn("handshake")) { 1322 System.out.println("Attempt to obtain Kerberos key failed: " 1323 + e.toString()); 1324 } 1325 return false; 1326 } 1327 } 1328 1329 /* 1330 * For Kerberos ciphers, the premaster secret is encrypted using 1331 * the session key. See RFC 2712. 1332 */ clientKeyExchange(KerberosClientKeyExchange mesg)1333 private SecretKey clientKeyExchange(KerberosClientKeyExchange mesg) 1334 throws IOException { 1335 1336 if (debug != null && Debug.isOn("handshake")) { 1337 mesg.print(System.out); 1338 } 1339 1340 // Record the principals involved in exchange 1341 session.setPeerPrincipal(mesg.getPeerPrincipal()); 1342 session.setLocalPrincipal(mesg.getLocalPrincipal()); 1343 1344 byte[] b = mesg.getUnencryptedPreMasterSecret(); 1345 return new SecretKeySpec(b, "TlsPremasterSecret"); 1346 } 1347 1348 /* 1349 * Diffie Hellman key exchange is used when the server presented 1350 * D-H parameters in its certificate (signed using RSA or DSS/DSA), 1351 * or else the server presented no certificate but sent D-H params 1352 * in a ServerKeyExchange message. Use of D-H is specified by the 1353 * cipher suite chosen. 1354 * 1355 * The message optionally contains the client's D-H public key (if 1356 * it wasn't not sent in a client certificate). As always with D-H, 1357 * if a client and a server have each other's D-H public keys and 1358 * they use common algorithm parameters, they have a shared key 1359 * that's derived via the D-H calculation. That key becomes the 1360 * pre-master secret. 1361 */ clientKeyExchange(DHClientKeyExchange mesg)1362 private SecretKey clientKeyExchange(DHClientKeyExchange mesg) 1363 throws IOException { 1364 1365 if (debug != null && Debug.isOn("handshake")) { 1366 mesg.print(System.out); 1367 } 1368 return dh.getAgreedSecret(mesg.getClientPublicKey(), false); 1369 } 1370 clientKeyExchange(ECDHClientKeyExchange mesg)1371 private SecretKey clientKeyExchange(ECDHClientKeyExchange mesg) 1372 throws IOException { 1373 1374 if (debug != null && Debug.isOn("handshake")) { 1375 mesg.print(System.out); 1376 } 1377 return ecdh.getAgreedSecret(mesg.getEncodedPoint()); 1378 } 1379 1380 /* 1381 * Client wrote a message to verify the certificate it sent earlier. 1382 * 1383 * Note that this certificate isn't involved in key exchange. Client 1384 * authentication messages are included in the checksums used to 1385 * validate the handshake (e.g. Finished messages). Other than that, 1386 * the _exact_ identity of the client is less fundamental to protocol 1387 * security than its role in selecting keys via the pre-master secret. 1388 */ clientCertificateVerify(CertificateVerify mesg)1389 private void clientCertificateVerify(CertificateVerify mesg) 1390 throws IOException { 1391 1392 if (debug != null && Debug.isOn("handshake")) { 1393 mesg.print(System.out); 1394 } 1395 1396 if (protocolVersion.v >= ProtocolVersion.TLS12.v) { 1397 SignatureAndHashAlgorithm signAlg = 1398 mesg.getPreferableSignatureAlgorithm(); 1399 if (signAlg == null) { 1400 throw new SSLHandshakeException( 1401 "Illegal CertificateVerify message"); 1402 } 1403 1404 String hashAlg = 1405 SignatureAndHashAlgorithm.getHashAlgorithmName(signAlg); 1406 if (hashAlg == null || hashAlg.length() == 0) { 1407 throw new SSLHandshakeException( 1408 "No supported hash algorithm"); 1409 } 1410 1411 handshakeHash.setCertificateVerifyAlg(hashAlg); 1412 } 1413 1414 try { 1415 PublicKey publicKey = 1416 session.getPeerCertificates()[0].getPublicKey(); 1417 1418 boolean valid = mesg.verify(protocolVersion, handshakeHash, 1419 publicKey, session.getMasterSecret()); 1420 if (valid == false) { 1421 fatalSE(Alerts.alert_bad_certificate, 1422 "certificate verify message signature error"); 1423 } 1424 } catch (GeneralSecurityException e) { 1425 fatalSE(Alerts.alert_bad_certificate, 1426 "certificate verify format error", e); 1427 } 1428 1429 // reset the flag for clientCertificateVerify message 1430 needClientVerify = false; 1431 } 1432 1433 1434 /* 1435 * Client writes "finished" at the end of its handshake, after cipher 1436 * spec is changed. We verify it and then send ours. 1437 * 1438 * When we're resuming a session, we'll have already sent our own 1439 * Finished message so just the verification is needed. 1440 */ clientFinished(Finished mesg)1441 private void clientFinished(Finished mesg) throws IOException { 1442 if (debug != null && Debug.isOn("handshake")) { 1443 mesg.print(System.out); 1444 } 1445 1446 /* 1447 * Verify if client did send the certificate when client 1448 * authentication was required, otherwise server should not proceed 1449 */ 1450 if (doClientAuth == SSLEngineImpl.clauth_required) { 1451 // get X500Principal of the end-entity certificate for X509-based 1452 // ciphersuites, or Kerberos principal for Kerberos ciphersuites 1453 session.getPeerPrincipal(); 1454 } 1455 1456 /* 1457 * Verify if client did send clientCertificateVerify message following 1458 * the client Certificate, otherwise server should not proceed 1459 */ 1460 if (needClientVerify) { 1461 fatalSE(Alerts.alert_handshake_failure, 1462 "client did not send certificate verify message"); 1463 } 1464 1465 /* 1466 * Verify the client's message with the "before" digest of messages, 1467 * and forget about continuing to use that digest. 1468 */ 1469 boolean verified = mesg.verify(handshakeHash, Finished.CLIENT, 1470 session.getMasterSecret()); 1471 1472 if (!verified) { 1473 fatalSE(Alerts.alert_handshake_failure, 1474 "client 'finished' message doesn't verify"); 1475 // NOTREACHED 1476 } 1477 1478 /* 1479 * save client verify data for secure renegotiation 1480 */ 1481 if (secureRenegotiation) { 1482 clientVerifyData = mesg.getVerifyData(); 1483 } 1484 1485 /* 1486 * OK, it verified. If we're doing the full handshake, add that 1487 * "Finished" message to the hash of handshake messages, then send 1488 * the change_cipher_spec and Finished message. 1489 */ 1490 if (!resumingSession) { 1491 input.digestNow(); 1492 sendChangeCipherAndFinish(true); 1493 } 1494 1495 /* 1496 * Update the session cache only after the handshake completed, else 1497 * we're open to an attack against a partially completed handshake. 1498 */ 1499 session.setLastAccessedTime(System.currentTimeMillis()); 1500 if (!resumingSession && session.isRejoinable()) { 1501 ((SSLSessionContextImpl)sslContext.engineGetServerSessionContext()) 1502 .put(session); 1503 if (debug != null && Debug.isOn("session")) { 1504 System.out.println( 1505 "%% Cached server session: " + session); 1506 } 1507 } else if (!resumingSession && 1508 debug != null && Debug.isOn("session")) { 1509 System.out.println( 1510 "%% Didn't cache non-resumable server session: " 1511 + session); 1512 } 1513 } 1514 1515 /* 1516 * Compute finished message with the "server" digest (and then forget 1517 * about that digest, it can't be used again). 1518 */ sendChangeCipherAndFinish(boolean finishedTag)1519 private void sendChangeCipherAndFinish(boolean finishedTag) 1520 throws IOException { 1521 1522 output.flush(); 1523 1524 Finished mesg = new Finished(protocolVersion, handshakeHash, 1525 Finished.SERVER, session.getMasterSecret(), cipherSuite); 1526 1527 /* 1528 * Send the change_cipher_spec record; then our Finished handshake 1529 * message will be the last handshake message. Flush, and now we 1530 * are ready for application data!! 1531 */ 1532 sendChangeCipherSpec(mesg, finishedTag); 1533 1534 /* 1535 * save server verify data for secure renegotiation 1536 */ 1537 if (secureRenegotiation) { 1538 serverVerifyData = mesg.getVerifyData(); 1539 } 1540 1541 /* 1542 * Update state machine so client MUST send 'finished' next 1543 * The update should only take place if it is not in the fast 1544 * handshake mode since the server has to wait for a finished 1545 * message from the client. 1546 */ 1547 if (finishedTag) { 1548 state = HandshakeMessage.ht_finished; 1549 } 1550 } 1551 1552 1553 /* 1554 * Returns a HelloRequest message to kickstart renegotiations 1555 */ getKickstartMessage()1556 HandshakeMessage getKickstartMessage() { 1557 return new HelloRequest(); 1558 } 1559 1560 1561 /* 1562 * Fault detected during handshake. 1563 */ handshakeAlert(byte description)1564 void handshakeAlert(byte description) throws SSLProtocolException { 1565 1566 String message = Alerts.alertDescription(description); 1567 1568 if (debug != null && Debug.isOn("handshake")) { 1569 System.out.println("SSL -- handshake alert: " 1570 + message); 1571 } 1572 1573 /* 1574 * It's ok to get a no_certificate alert from a client of which 1575 * we *requested* authentication information. 1576 * However, if we *required* it, then this is not acceptable. 1577 * 1578 * Anyone calling getPeerCertificates() on the 1579 * session will get an SSLPeerUnverifiedException. 1580 */ 1581 if ((description == Alerts.alert_no_certificate) && 1582 (doClientAuth == SSLEngineImpl.clauth_requested)) { 1583 return; 1584 } 1585 1586 throw new SSLProtocolException("handshake alert: " + message); 1587 } 1588 1589 /* 1590 * RSA key exchange is normally used. The client encrypts a "pre-master 1591 * secret" with the server's public key, from the Certificate (or else 1592 * ServerKeyExchange) message that was sent to it by the server. That's 1593 * decrypted using the private key before we get here. 1594 */ clientKeyExchange(RSAClientKeyExchange mesg)1595 private SecretKey clientKeyExchange(RSAClientKeyExchange mesg) 1596 throws IOException { 1597 1598 if (debug != null && Debug.isOn("handshake")) { 1599 mesg.print(System.out); 1600 } 1601 return mesg.preMaster; 1602 } 1603 1604 /* 1605 * Verify the certificate sent by the client. We'll only get one if we 1606 * sent a CertificateRequest to request client authentication. If we 1607 * are in TLS mode, the client may send a message with no certificates 1608 * to indicate it does not have an appropriate chain. (In SSLv3 mode, 1609 * it would send a no certificate alert). 1610 */ clientCertificate(CertificateMsg mesg)1611 private void clientCertificate(CertificateMsg mesg) throws IOException { 1612 if (debug != null && Debug.isOn("handshake")) { 1613 mesg.print(System.out); 1614 } 1615 1616 X509Certificate[] peerCerts = mesg.getCertificateChain(); 1617 1618 if (peerCerts.length == 0) { 1619 /* 1620 * If the client authentication is only *REQUESTED* (e.g. 1621 * not *REQUIRED*, this is an acceptable condition.) 1622 */ 1623 if (doClientAuth == SSLEngineImpl.clauth_requested) { 1624 // Smart (aka stupid) to forecast that no CertificateVerify 1625 // message will be received. 1626 if (protocolVersion.v >= ProtocolVersion.TLS12.v) { 1627 handshakeHash.setCertificateVerifyAlg(null); 1628 } 1629 return; 1630 } else { 1631 fatalSE(Alerts.alert_bad_certificate, 1632 "null cert chain"); 1633 } 1634 } 1635 1636 // ask the trust manager to verify the chain 1637 X509TrustManager tm = sslContext.getX509TrustManager(); 1638 1639 try { 1640 // find out the types of client authentication used 1641 PublicKey key = peerCerts[0].getPublicKey(); 1642 String keyAlgorithm = key.getAlgorithm(); 1643 String authType; 1644 if (keyAlgorithm.equals("RSA")) { 1645 authType = "RSA"; 1646 } else if (keyAlgorithm.equals("DSA")) { 1647 authType = "DSA"; 1648 } else if (keyAlgorithm.equals("EC")) { 1649 authType = "EC"; 1650 } else { 1651 // unknown public key type 1652 authType = "UNKNOWN"; 1653 } 1654 1655 if (tm instanceof X509ExtendedTrustManager) { 1656 if (conn != null) { 1657 ((X509ExtendedTrustManager)tm).checkClientTrusted( 1658 peerCerts.clone(), 1659 authType, 1660 conn); 1661 } else { 1662 ((X509ExtendedTrustManager)tm).checkClientTrusted( 1663 peerCerts.clone(), 1664 authType, 1665 engine); 1666 } 1667 } else { 1668 // Unlikely to happen, because we have wrapped the old 1669 // X509TrustManager with the new X509ExtendedTrustManager. 1670 throw new CertificateException( 1671 "Improper X509TrustManager implementation"); 1672 } 1673 } catch (CertificateException e) { 1674 // This will throw an exception, so include the original error. 1675 fatalSE(Alerts.alert_certificate_unknown, e); 1676 } 1677 // set the flag for clientCertificateVerify message 1678 needClientVerify = true; 1679 1680 session.setPeerCertificates(peerCerts); 1681 } 1682 } 1683