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