1 /* 2 * Copyright 1996-2007 Sun Microsystems, Inc. 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. Sun designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 22 * CA 95054 USA or visit www.sun.com if you need additional information or 23 * have any questions. 24 */ 25 26 27 package sun.security.ssl; 28 29 import java.io.*; 30 import java.math.BigInteger; 31 import java.security.*; 32 import java.security.interfaces.*; 33 import java.security.spec.*; 34 import java.security.cert.*; 35 import java.security.cert.Certificate; 36 import java.util.*; 37 import java.util.concurrent.ConcurrentHashMap; 38 39 import java.lang.reflect.*; 40 41 import javax.security.auth.x500.X500Principal; 42 43 import javax.crypto.KeyGenerator; 44 import javax.crypto.SecretKey; 45 import javax.crypto.spec.SecretKeySpec; 46 47 import javax.net.ssl.*; 48 49 import sun.security.action.GetPropertyAction; 50 51 import sun.security.internal.spec.TlsPrfParameterSpec; 52 53 import sun.security.ssl.CipherSuite.*; 54 55 /** 56 * Many data structures are involved in the handshake messages. These 57 * classes are used as structures, with public data members. They are 58 * not visible outside the SSL package. 59 * 60 * Handshake messages all have a common header format, and they are all 61 * encoded in a "handshake data" SSL record substream. The base class 62 * here (HandshakeMessage) provides a common framework and records the 63 * SSL record type of the particular handshake message. 64 * 65 * This file contains subclasses for all the basic handshake messages. 66 * All handshake messages know how to encode and decode themselves on 67 * SSL streams; this facilitates using the same code on SSL client and 68 * server sides, although they don't send and receive the same messages. 69 * 70 * Messages also know how to print themselves, which is quite handy 71 * for debugging. They always identify their type, and can optionally 72 * dump all of their content. 73 * 74 * @author David Brownell 75 */ 76 abstract class HandshakeMessage { 77 78 HandshakeMessage() { } 79 80 // enum HandshakeType: 81 static final byte ht_hello_request = 0; 82 static final byte ht_client_hello = 1; 83 static final byte ht_server_hello = 2; 84 85 static final byte ht_certificate = 11; 86 static final byte ht_server_key_exchange = 12; 87 static final byte ht_certificate_request = 13; 88 static final byte ht_server_hello_done = 14; 89 static final byte ht_certificate_verify = 15; 90 static final byte ht_client_key_exchange = 16; 91 92 static final byte ht_finished = 20; 93 94 /* Class and subclass dynamic debugging support */ 95 static final Debug debug = Debug.getInstance("ssl"); 96 97 /** 98 * Utility method to convert a BigInteger to a byte array in unsigned 99 * format as needed in the handshake messages. BigInteger uses 100 * 2's complement format, i.e. it prepends an extra zero if the MSB 101 * is set. We remove that. 102 */ 103 static byte[] toByteArray(BigInteger bi) { 104 byte[] b = bi.toByteArray(); 105 if ((b.length > 1) && (b[0] == 0)) { 106 int n = b.length - 1; 107 byte[] newarray = new byte[n]; 108 System.arraycopy(b, 1, newarray, 0, n); 109 b = newarray; 110 } 111 return b; 112 } 113 114 /* 115 * SSL 3.0 MAC padding constants. 116 * Also used by CertificateVerify and Finished during the handshake. 117 */ 118 static final byte[] MD5_pad1 = genPad(0x36, 48); 119 static final byte[] MD5_pad2 = genPad(0x5c, 48); 120 121 static final byte[] SHA_pad1 = genPad(0x36, 40); 122 static final byte[] SHA_pad2 = genPad(0x5c, 40); 123 124 private static byte[] genPad(int b, int count) { 125 byte[] padding = new byte[count]; 126 Arrays.fill(padding, (byte)b); 127 return padding; 128 } 129 130 /* 131 * Write a handshake message on the (handshake) output stream. 132 * This is just a four byte header followed by the data. 133 * 134 * NOTE that huge messages -- notably, ones with huge cert 135 * chains -- are handled correctly. 136 */ 137 final void write(HandshakeOutStream s) throws IOException { 138 int len = messageLength(); 139 if (len > (1 << 24)) { 140 throw new SSLException("Handshake message too big" 141 + ", type = " + messageType() + ", len = " + len); 142 } 143 s.write(messageType()); 144 s.putInt24(len); 145 send(s); 146 } 147 148 /* 149 * Subclasses implement these methods so those kinds of 150 * messages can be emitted. Base class delegates to subclass. 151 */ 152 abstract int messageType(); 153 abstract int messageLength(); 154 abstract void send(HandshakeOutStream s) throws IOException; 155 156 /* 157 * Write a descriptive message on the output stream; for debugging. 158 */ 159 abstract void print(PrintStream p) throws IOException; 160 161 // 162 // NOTE: the rest of these classes are nested within this one, and are 163 // imported by other classes in this package. There are a few other 164 // handshake message classes, not neatly nested here because of current 165 // licensing requirement for native (RSA) methods. They belong here, 166 // but those native methods complicate things a lot! 167 // 168 169 170 /* 171 * HelloRequest ... SERVER --> CLIENT 172 * 173 * Server can ask the client to initiate a new handshake, e.g. to change 174 * session parameters after a connection has been (re)established. 175 */ 176 static final 177 class HelloRequest extends HandshakeMessage 178 { 179 int messageType() { return ht_hello_request; } 180 181 HelloRequest() { } 182 183 HelloRequest(HandshakeInStream in) throws IOException 184 { 185 // nothing in this message 186 } 187 188 int messageLength() { return 0; } 189 190 void send(HandshakeOutStream out) throws IOException 191 { 192 // nothing in this messaage 193 } 194 195 void print(PrintStream out) throws IOException 196 { 197 out.println("*** HelloRequest (empty)"); 198 } 199 200 } 201 202 203 /* 204 * ClientHello ... CLIENT --> SERVER 205 * 206 * Client initiates handshake by telling server what it wants, and what it 207 * can support (prioritized by what's first in the ciphe suite list). 208 * 209 * By RFC2246:7.4.1.2 it's explicitly anticipated that this message 210 * will have more data added at the end ... e.g. what CAs the client trusts. 211 * Until we know how to parse it, we will just read what we know 212 * about, and let our caller handle the jumps over unknown data. 213 */ 214 static final 215 class ClientHello extends HandshakeMessage 216 { 217 int messageType() { return ht_client_hello; } 218 219 ProtocolVersion protocolVersion; 220 RandomCookie clnt_random; 221 SessionId sessionId; 222 private CipherSuiteList cipherSuites; 223 byte[] compression_methods; 224 225 HelloExtensions extensions = new HelloExtensions(); 226 227 private final static byte[] NULL_COMPRESSION = new byte[] {0}; 228 229 ClientHello(SecureRandom generator, ProtocolVersion protocolVersion) { 230 this.protocolVersion = protocolVersion; 231 clnt_random = new RandomCookie(generator); 232 compression_methods = NULL_COMPRESSION; 233 // sessionId, cipher_suites TBS later 234 } 235 236 CipherSuiteList getCipherSuites() { 237 return cipherSuites; 238 } 239 240 // Set the ciphersuites. 241 // This method may only be called once. 242 void setCipherSuites(CipherSuiteList cipherSuites) { 243 this.cipherSuites = cipherSuites; 244 if (cipherSuites.containsEC()) { 245 extensions.add(SupportedEllipticCurvesExtension.DEFAULT); 246 extensions.add(SupportedEllipticPointFormatsExtension.DEFAULT); 247 } 248 } 249 250 int messageLength() { 251 /* 252 * Add fixed size parts of each field... 253 * version + random + session + cipher + compress 254 */ 255 return (2 + 32 + 1 + 2 + 1 256 + sessionId.length() /* ... + variable parts */ 257 + (cipherSuites.size() * 2) 258 + compression_methods.length) 259 + extensions.length(); 260 } 261 262 ClientHello(HandshakeInStream s, int messageLength) throws IOException { 263 protocolVersion = ProtocolVersion.valueOf(s.getInt8(), s.getInt8()); 264 clnt_random = new RandomCookie(s); 265 sessionId = new SessionId(s.getBytes8()); 266 cipherSuites = new CipherSuiteList(s); 267 compression_methods = s.getBytes8(); 268 if (messageLength() != messageLength) { 269 extensions = new HelloExtensions(s); 270 } 271 } 272 273 void send(HandshakeOutStream s) throws IOException { 274 s.putInt8(protocolVersion.major); 275 s.putInt8(protocolVersion.minor); 276 clnt_random.send(s); 277 s.putBytes8(sessionId.getId()); 278 cipherSuites.send(s); 279 s.putBytes8(compression_methods); 280 extensions.send(s); 281 } 282 283 void print(PrintStream s) throws IOException { 284 s.println("*** ClientHello, " + protocolVersion); 285 286 if (debug != null && Debug.isOn("verbose")) { 287 s.print ("RandomCookie: "); clnt_random.print(s); 288 289 s.print("Session ID: "); 290 s.println(sessionId); 291 292 s.println("Cipher Suites: " + cipherSuites); 293 294 Debug.println(s, "Compression Methods", compression_methods); 295 extensions.print(s); 296 s.println("***"); 297 } 298 } 299 } 300 301 /* 302 * ServerHello ... SERVER --> CLIENT 303 * 304 * Server chooses protocol options from among those it supports and the 305 * client supports. Then it sends the basic session descriptive parameters 306 * back to the client. 307 */ 308 static final 309 class ServerHello extends HandshakeMessage 310 { 311 int messageType() { return ht_server_hello; } 312 313 ProtocolVersion protocolVersion; 314 RandomCookie svr_random; 315 SessionId sessionId; 316 CipherSuite cipherSuite; 317 byte compression_method; 318 HelloExtensions extensions = new HelloExtensions(); 319 int extensionLength; 320 321 ServerHello() { 322 // empty 323 } 324 325 ServerHello(HandshakeInStream input, int messageLength) throws IOException { 326 protocolVersion = ProtocolVersion.valueOf(input.getInt8(), 327 input.getInt8()); 328 svr_random = new RandomCookie(input); 329 sessionId = new SessionId(input.getBytes8()); 330 cipherSuite = CipherSuite.valueOf(input.getInt8(), input.getInt8()); 331 compression_method = (byte)input.getInt8(); 332 if (messageLength() != messageLength) { 333 extensions = new HelloExtensions(input); 334 } 335 } 336 337 int messageLength() 338 { 339 // almost fixed size, except session ID and extensions: 340 // major + minor = 2 341 // random = 32 342 // session ID len field = 1 343 // cipher suite + compression = 3 344 // extensions: if present, 2 + length of extensions 345 return 38 + sessionId.length() + extensions.length(); 346 } 347 348 void send(HandshakeOutStream s) throws IOException 349 { 350 s.putInt8(protocolVersion.major); 351 s.putInt8(protocolVersion.minor); 352 svr_random.send(s); 353 s.putBytes8(sessionId.getId()); 354 s.putInt8(cipherSuite.id >> 8); 355 s.putInt8(cipherSuite.id & 0xff); 356 s.putInt8(compression_method); 357 extensions.send(s); 358 } 359 360 void print(PrintStream s) throws IOException 361 { 362 s.println("*** ServerHello, " + protocolVersion); 363 364 if (debug != null && Debug.isOn("verbose")) { 365 s.print ("RandomCookie: "); svr_random.print(s); 366 367 int i; 368 369 s.print("Session ID: "); 370 s.println(sessionId); 371 372 s.println("Cipher Suite: " + cipherSuite); 373 s.println("Compression Method: " + compression_method); 374 extensions.print(s); 375 s.println("***"); 376 } 377 } 378 } 379 380 381 /* 382 * CertificateMsg ... send by both CLIENT and SERVER 383 * 384 * Each end of a connection may need to pass its certificate chain to 385 * the other end. Such chains are intended to validate an identity with 386 * reference to some certifying authority. Examples include companies 387 * like Verisign, or financial institutions. There's some control over 388 * the certifying authorities which are sent. 389 * 390 * NOTE: that these messages might be huge, taking many handshake records. 391 * Up to 2^48 bytes of certificate may be sent, in records of at most 2^14 392 * bytes each ... up to 2^32 records sent on the output stream. 393 */ 394 static final 395 class CertificateMsg extends HandshakeMessage 396 { 397 int messageType() { return ht_certificate; } 398 399 private X509Certificate[] chain; 400 401 private List<byte[]> encodedChain; 402 403 private int messageLength; 404 405 CertificateMsg(X509Certificate[] certs) { 406 chain = certs; 407 } 408 409 CertificateMsg(HandshakeInStream input) throws IOException { 410 int chainLen = input.getInt24(); 411 List<Certificate> v = new ArrayList<Certificate>(4); 412 413 CertificateFactory cf = null; 414 while (chainLen > 0) { 415 byte[] cert = input.getBytes24(); 416 chainLen -= (3 + cert.length); 417 try { 418 if (cf == null) { 419 cf = CertificateFactory.getInstance("X.509"); 420 } 421 v.add(cf.generateCertificate(new ByteArrayInputStream(cert))); 422 } catch (CertificateException e) { 423 throw (SSLProtocolException)new SSLProtocolException 424 (e.getMessage()).initCause(e); 425 } 426 } 427 428 chain = v.toArray(new X509Certificate[v.size()]); 429 } 430 431 int messageLength() { 432 if (encodedChain == null) { 433 messageLength = 3; 434 encodedChain = new ArrayList<byte[]>(chain.length); 435 try { 436 for (X509Certificate cert : chain) { 437 byte[] b = cert.getEncoded(); 438 encodedChain.add(b); 439 messageLength += b.length + 3; 440 } 441 } catch (CertificateEncodingException e) { 442 encodedChain = null; 443 throw new RuntimeException("Could not encode certificates", e); 444 } 445 } 446 return messageLength; 447 } 448 449 void send(HandshakeOutStream s) throws IOException { 450 s.putInt24(messageLength() - 3); 451 for (byte[] b : encodedChain) { 452 s.putBytes24(b); 453 } 454 } 455 456 void print(PrintStream s) throws IOException { 457 s.println("*** Certificate chain"); 458 459 if (debug != null && Debug.isOn("verbose")) { 460 for (int i = 0; i < chain.length; i++) 461 s.println("chain [" + i + "] = " + chain[i]); 462 s.println("***"); 463 } 464 } 465 466 X509Certificate[] getCertificateChain() { 467 return chain; 468 } 469 } 470 471 472 /* 473 * ServerKeyExchange ... SERVER --> CLIENT 474 * 475 * The cipher suite selected, when combined with the certificate exchanged, 476 * implies one of several different kinds of key exchange. Most current 477 * cipher suites require the server to send more than its certificate. 478 * 479 * The primary exceptions are when a server sends an encryption-capable 480 * RSA public key in its cert, to be used with RSA (or RSA_export) key 481 * exchange; and when a server sends its Diffie-Hellman cert. Those kinds 482 * of key exchange do not require a ServerKeyExchange message. 483 * 484 * Key exchange can be viewed as having three modes, which are explicit 485 * for the Diffie-Hellman flavors and poorly specified for RSA ones: 486 * 487 * - "Ephemeral" keys. Here, a "temporary" key is allocated by the 488 * server, and signed. Diffie-Hellman keys signed using RSA or 489 * DSS are ephemeral (DHE flavor). RSA keys get used to do the same 490 * thing, to cut the key size down to 512 bits (export restrictions) 491 * or for signing-only RSA certificates. 492 * 493 * - Anonymity. Here no server certificate is sent, only the public 494 * key of the server. This case is subject to man-in-the-middle 495 * attacks. This can be done with Diffie-Hellman keys (DH_anon) or 496 * with RSA keys, but is only used in SSLv3 for DH_anon. 497 * 498 * - "Normal" case. Here a server certificate is sent, and the public 499 * key there is used directly in exchanging the premaster secret. 500 * For example, Diffie-Hellman "DH" flavor, and any RSA flavor with 501 * only 512 bit keys. 502 * 503 * If a server certificate is sent, there is no anonymity. However, 504 * when a certificate is sent, ephemeral keys may still be used to 505 * exchange the premaster secret. That's how RSA_EXPORT often works, 506 * as well as how the DHE_* flavors work. 507 */ 508 static abstract class ServerKeyExchange extends HandshakeMessage 509 { 510 int messageType() { return ht_server_key_exchange; } 511 } 512 513 514 /* 515 * Using RSA for Key Exchange: exchange a session key that's not as big 516 * as the signing-only key. Used for export applications, since exported 517 * RSA encryption keys can't be bigger than 512 bytes. 518 * 519 * This is never used when keys are 512 bits or smaller, and isn't used 520 * on "US Domestic" ciphers in any case. 521 */ 522 static final 523 class RSA_ServerKeyExchange extends ServerKeyExchange 524 { 525 private byte rsa_modulus[]; // 1 to 2^16 - 1 bytes 526 private byte rsa_exponent[]; // 1 to 2^16 - 1 bytes 527 528 private Signature signature; 529 private byte[] signatureBytes; 530 531 /* 532 * Hash the nonces and the ephemeral RSA public key. 533 */ 534 private void updateSignature(byte clntNonce[], byte svrNonce[]) 535 throws SignatureException { 536 int tmp; 537 538 signature.update(clntNonce); 539 signature.update(svrNonce); 540 541 tmp = rsa_modulus.length; 542 signature.update((byte)(tmp >> 8)); 543 signature.update((byte)(tmp & 0x0ff)); 544 signature.update(rsa_modulus); 545 546 tmp = rsa_exponent.length; 547 signature.update((byte)(tmp >> 8)); 548 signature.update((byte)(tmp & 0x0ff)); 549 signature.update(rsa_exponent); 550 } 551 552 553 /* 554 * Construct an RSA server key exchange message, using data 555 * known _only_ to the server. 556 * 557 * The client knows the public key corresponding to this private 558 * key, from the Certificate message sent previously. To comply 559 * with US export regulations we use short RSA keys ... either 560 * long term ones in the server's X509 cert, or else ephemeral 561 * ones sent using this message. 562 */ 563 RSA_ServerKeyExchange(PublicKey ephemeralKey, PrivateKey privateKey, 564 RandomCookie clntNonce, RandomCookie svrNonce, SecureRandom sr) 565 throws GeneralSecurityException { 566 RSAPublicKeySpec rsaKey = JsseJce.getRSAPublicKeySpec(ephemeralKey); 567 rsa_modulus = toByteArray(rsaKey.getModulus()); 568 rsa_exponent = toByteArray(rsaKey.getPublicExponent()); 569 signature = RSASignature.getInstance(); 570 signature.initSign(privateKey, sr); 571 updateSignature(clntNonce.random_bytes, svrNonce.random_bytes); 572 signatureBytes = signature.sign(); 573 } 574 575 576 /* 577 * Parse an RSA server key exchange message, using data known 578 * to the client (and, in some situations, eavesdroppers). 579 */ 580 RSA_ServerKeyExchange(HandshakeInStream input) 581 throws IOException, NoSuchAlgorithmException { 582 signature = RSASignature.getInstance(); 583 rsa_modulus = input.getBytes16(); 584 rsa_exponent = input.getBytes16(); 585 signatureBytes = input.getBytes16(); 586 } 587 588 /* 589 * Get the ephemeral RSA public key that will be used in this 590 * SSL connection. 591 */ 592 PublicKey getPublicKey() { 593 try { 594 KeyFactory kfac = JsseJce.getKeyFactory("RSA"); 595 // modulus and exponent are always positive 596 RSAPublicKeySpec kspec = new RSAPublicKeySpec 597 (new BigInteger(1, rsa_modulus), 598 new BigInteger(1, rsa_exponent)); 599 return kfac.generatePublic(kspec); 600 } catch (Exception e) { 601 throw new RuntimeException(e); 602 } 603 } 604 605 /* 606 * Verify the signed temporary key using the hashes computed 607 * from it and the two nonces. This is called by clients 608 * with "exportable" RSA flavors. 609 */ 610 boolean verify(PublicKey certifiedKey, RandomCookie clntNonce, 611 RandomCookie svrNonce) throws GeneralSecurityException { 612 signature.initVerify(certifiedKey); 613 updateSignature(clntNonce.random_bytes, svrNonce.random_bytes); 614 return signature.verify(signatureBytes); 615 } 616 617 int messageLength() { 618 return 6 + rsa_modulus.length + rsa_exponent.length 619 + signatureBytes.length; 620 } 621 622 void send(HandshakeOutStream s) throws IOException { 623 s.putBytes16(rsa_modulus); 624 s.putBytes16(rsa_exponent); 625 s.putBytes16(signatureBytes); 626 } 627 628 void print(PrintStream s) throws IOException { 629 s.println("*** RSA ServerKeyExchange"); 630 631 if (debug != null && Debug.isOn("verbose")) { 632 Debug.println(s, "RSA Modulus", rsa_modulus); 633 Debug.println(s, "RSA Public Exponent", rsa_exponent); 634 } 635 } 636 } 637 638 639 /* 640 * Using Diffie-Hellman algorithm for key exchange. All we really need to 641 * do is securely get Diffie-Hellman keys (using the same P, G parameters) 642 * to our peer, then we automatically have a shared secret without need 643 * to exchange any more data. (D-H only solutions, such as SKIP, could 644 * eliminate key exchange negotiations and get faster connection setup. 645 * But they still need a signature algorithm like DSS/DSA to support the 646 * trusted distribution of keys without relying on unscalable physical 647 * key distribution systems.) 648 * 649 * This class supports several DH-based key exchange algorithms, though 650 * perhaps eventually each deserves its own class. Notably, this has 651 * basic support for DH_anon and its DHE_DSS and DHE_RSA signed variants. 652 */ 653 static final 654 class DH_ServerKeyExchange extends ServerKeyExchange 655 { 656 // Fix message encoding, see 4348279 657 private final static boolean dhKeyExchangeFix = 658 Debug.getBooleanProperty("com.sun.net.ssl.dhKeyExchangeFix", true); 659 660 private byte dh_p []; // 1 to 2^16 - 1 bytes 661 private byte dh_g []; // 1 to 2^16 - 1 bytes 662 private byte dh_Ys []; // 1 to 2^16 - 1 bytes 663 664 private byte signature []; 665 666 /* Return the Diffie-Hellman modulus */ 667 BigInteger getModulus() { 668 return new BigInteger(1, dh_p); 669 } 670 671 /* Return the Diffie-Hellman base/generator */ 672 BigInteger getBase() { 673 return new BigInteger(1, dh_g); 674 } 675 676 /* Return the server's Diffie-Hellman public key */ 677 BigInteger getServerPublicKey() { 678 return new BigInteger(1, dh_Ys); 679 } 680 681 /* 682 * Update sig with nonces and Diffie-Hellman public key. 683 */ 684 private void updateSignature(Signature sig, byte clntNonce[], 685 byte svrNonce[]) throws SignatureException { 686 int tmp; 687 688 sig.update(clntNonce); 689 sig.update(svrNonce); 690 691 tmp = dh_p.length; 692 sig.update((byte)(tmp >> 8)); 693 sig.update((byte)(tmp & 0x0ff)); 694 sig.update(dh_p); 695 696 tmp = dh_g.length; 697 sig.update((byte)(tmp >> 8)); 698 sig.update((byte)(tmp & 0x0ff)); 699 sig.update(dh_g); 700 701 tmp = dh_Ys.length; 702 sig.update((byte)(tmp >> 8)); 703 sig.update((byte)(tmp & 0x0ff)); 704 sig.update(dh_Ys); 705 } 706 707 /* 708 * Construct from initialized DH key object, for DH_anon 709 * key exchange. 710 */ 711 DH_ServerKeyExchange(DHCrypt obj) { 712 getValues(obj); 713 signature = null; 714 } 715 716 /* 717 * Construct from initialized DH key object and the key associated 718 * with the cert chain which was sent ... for DHE_DSS and DHE_RSA 719 * key exchange. (Constructor called by server.) 720 */ 721 DH_ServerKeyExchange(DHCrypt obj, PrivateKey key, byte clntNonce[], 722 byte svrNonce[], SecureRandom sr) throws GeneralSecurityException { 723 724 getValues(obj); 725 726 Signature sig; 727 if (key.getAlgorithm().equals("DSA")) { 728 sig = JsseJce.getSignature(JsseJce.SIGNATURE_DSA); 729 } else { 730 sig = RSASignature.getInstance(); 731 } 732 sig.initSign(key, sr); 733 updateSignature(sig, clntNonce, svrNonce); 734 signature = sig.sign(); 735 } 736 737 private void getValues(DHCrypt obj) { 738 dh_p = toByteArray(obj.getModulus()); 739 dh_g = toByteArray(obj.getBase()); 740 dh_Ys = toByteArray(obj.getPublicKey()); 741 } 742 743 /* 744 * Construct a DH_ServerKeyExchange message from an input 745 * stream, as if sent from server to client for use with 746 * DH_anon key exchange 747 */ 748 DH_ServerKeyExchange(HandshakeInStream input) throws IOException { 749 dh_p = input.getBytes16(); 750 dh_g = input.getBytes16(); 751 dh_Ys = input.getBytes16(); 752 signature = null; 753 } 754 755 /* 756 * Construct a DH_ServerKeyExchange message from an input stream 757 * and a certificate, as if sent from server to client for use with 758 * DHE_DSS or DHE_RSA key exchange. (Called by client.) 759 */ 760 DH_ServerKeyExchange(HandshakeInStream input, PublicKey publicKey, 761 byte clntNonce[], byte svrNonce[], int messageSize) 762 throws IOException, GeneralSecurityException { 763 764 dh_p = input.getBytes16(); 765 dh_g = input.getBytes16(); 766 dh_Ys = input.getBytes16(); 767 768 byte signature[]; 769 if (dhKeyExchangeFix) { 770 signature = input.getBytes16(); 771 } else { 772 messageSize -= (dh_p.length + 2); 773 messageSize -= (dh_g.length + 2); 774 messageSize -= (dh_Ys.length + 2); 775 776 signature = new byte[messageSize]; 777 input.read(signature); 778 } 779 780 Signature sig; 781 String algorithm = publicKey.getAlgorithm(); 782 if (algorithm.equals("DSA")) { 783 sig = JsseJce.getSignature(JsseJce.SIGNATURE_DSA); 784 } else if (algorithm.equals("RSA")) { 785 sig = RSASignature.getInstance(); 786 } else { 787 throw new SSLKeyException("neither an RSA or a DSA key"); 788 } 789 790 sig.initVerify(publicKey); 791 updateSignature(sig, clntNonce, svrNonce); 792 793 if (sig.verify(signature) == false ) { 794 throw new SSLKeyException("Server D-H key verification failed"); 795 } 796 } 797 798 int messageLength() { 799 int temp = 6; // overhead for p, g, y(s) values. 800 801 temp += dh_p.length; 802 temp += dh_g.length; 803 temp += dh_Ys.length; 804 if (signature != null) { 805 temp += signature.length; 806 if (dhKeyExchangeFix) { 807 temp += 2; 808 } 809 } 810 return temp; 811 } 812 813 void send(HandshakeOutStream s) throws IOException { 814 s.putBytes16(dh_p); 815 s.putBytes16(dh_g); 816 s.putBytes16(dh_Ys); 817 if (signature != null) { 818 if (dhKeyExchangeFix) { 819 s.putBytes16(signature); 820 } else { 821 s.write(signature); 822 } 823 } 824 } 825 826 void print(PrintStream s) throws IOException { 827 s.println("*** Diffie-Hellman ServerKeyExchange"); 828 829 if (debug != null && Debug.isOn("verbose")) { 830 Debug.println(s, "DH Modulus", dh_p); 831 Debug.println(s, "DH Base", dh_g); 832 Debug.println(s, "Server DH Public Key", dh_Ys); 833 834 if (signature == null) { 835 s.println("Anonymous"); 836 } else { 837 s.println("Signed with a DSA or RSA public key"); 838 } 839 } 840 } 841 } 842 843 /* 844 * ECDH server key exchange message. Sent by the server for ECDHE and ECDH_anon 845 * ciphersuites to communicate its ephemeral public key (including the 846 * EC domain parameters). 847 * 848 * We support named curves only, no explicitly encoded curves. 849 */ 850 static final 851 class ECDH_ServerKeyExchange extends ServerKeyExchange 852 { 853 854 // constants for ECCurveType 855 private final static int CURVE_EXPLICIT_PRIME = 1; 856 private final static int CURVE_EXPLICIT_CHAR2 = 2; 857 private final static int CURVE_NAMED_CURVE = 3; 858 859 // id of the curve we are using 860 private int curveId; 861 // encoded public point 862 private byte[] pointBytes; 863 864 // signature bytes (or null if anonymous) 865 private byte[] signatureBytes; 866 867 // public key object encapsulated in this message 868 private ECPublicKey publicKey; 869 870 ECDH_ServerKeyExchange(ECDHCrypt obj, PrivateKey privateKey, 871 byte[] clntNonce, byte[] svrNonce, SecureRandom sr) 872 throws GeneralSecurityException { 873 publicKey = (ECPublicKey)obj.getPublicKey(); 874 ECParameterSpec params = publicKey.getParams(); 875 ECPoint point = publicKey.getW(); 876 pointBytes = JsseJce.encodePoint(point, params.getCurve()); 877 curveId = SupportedEllipticCurvesExtension.getCurveIndex(params); 878 879 if (privateKey == null) { 880 // ECDH_anon 881 return; 882 } 883 884 Signature sig = getSignature(privateKey.getAlgorithm()); 885 sig.initSign(privateKey); 886 887 updateSignature(sig, clntNonce, svrNonce); 888 signatureBytes = sig.sign(); 889 } 890 891 /* 892 * Parse an ECDH server key exchange message. 893 */ 894 ECDH_ServerKeyExchange(HandshakeInStream input, PublicKey signingKey, 895 byte[] clntNonce, byte[] svrNonce) 896 throws IOException, GeneralSecurityException { 897 int curveType = input.getInt8(); 898 ECParameterSpec parameters; 899 // These parsing errors should never occur as we negotiated 900 // the supported curves during the exchange of the Hello messages. 901 if (curveType == CURVE_NAMED_CURVE) { 902 curveId = input.getInt16(); 903 if (SupportedEllipticCurvesExtension.isSupported(curveId) == false) { 904 throw new SSLHandshakeException("Unsupported curveId: " + curveId); 905 } 906 String curveOid = SupportedEllipticCurvesExtension.getCurveOid(curveId); 907 if (curveOid == null) { 908 throw new SSLHandshakeException("Unknown named curve: " + curveId); 909 } 910 parameters = JsseJce.getECParameterSpec(curveOid); 911 if (parameters == null) { 912 throw new SSLHandshakeException("Unsupported curve: " + curveOid); 913 } 914 } else { 915 throw new SSLHandshakeException("Unsupported ECCurveType: " + curveType); 916 } 917 pointBytes = input.getBytes8(); 918 919 ECPoint point = JsseJce.decodePoint(pointBytes, parameters.getCurve()); 920 KeyFactory factory = JsseJce.getKeyFactory("EC"); 921 publicKey = (ECPublicKey)factory.generatePublic(new ECPublicKeySpec(point, parameters)); 922 923 if (signingKey == null) { 924 // ECDH_anon 925 return; 926 } 927 928 // verify the signature 929 signatureBytes = input.getBytes16(); 930 Signature sig = getSignature(signingKey.getAlgorithm()); 931 sig.initVerify(signingKey); 932 933 updateSignature(sig, clntNonce, svrNonce); 934 935 if (sig.verify(signatureBytes) == false ) { 936 throw new SSLKeyException 937 ("Invalid signature on ECDH server key exchange message"); 938 } 939 } 940 941 /* 942 * Get the ephemeral EC public key encapsulated in this message. 943 */ 944 ECPublicKey getPublicKey() { 945 return publicKey; 946 } 947 948 private static Signature getSignature(String keyAlgorithm) throws NoSuchAlgorithmException { 949 if (keyAlgorithm.equals("EC")) { 950 return JsseJce.getSignature(JsseJce.SIGNATURE_ECDSA); 951 } else if (keyAlgorithm.equals("RSA")) { 952 return RSASignature.getInstance(); 953 } else { 954 throw new NoSuchAlgorithmException("neither an RSA or a EC key"); 955 } 956 } 957 958 private void updateSignature(Signature sig, byte clntNonce[], 959 byte svrNonce[]) throws SignatureException { 960 sig.update(clntNonce); 961 sig.update(svrNonce); 962 963 sig.update((byte)CURVE_NAMED_CURVE); 964 sig.update((byte)(curveId >> 8)); 965 sig.update((byte)curveId); 966 sig.update((byte)pointBytes.length); 967 sig.update(pointBytes); 968 } 969 970 int messageLength() { 971 int sigLen = (signatureBytes == null) ? 0 : 2 + signatureBytes.length; 972 return 4 + pointBytes.length + sigLen; 973 } 974 975 void send(HandshakeOutStream s) throws IOException { 976 s.putInt8(CURVE_NAMED_CURVE); 977 s.putInt16(curveId); 978 s.putBytes8(pointBytes); 979 if (signatureBytes != null) { 980 s.putBytes16(signatureBytes); 981 } 982 } 983 984 void print(PrintStream s) throws IOException { 985 s.println("*** ECDH ServerKeyExchange"); 986 987 if (debug != null && Debug.isOn("verbose")) { 988 s.println("Server key: " + publicKey); 989 } 990 } 991 } 992 993 static final class DistinguishedName { 994 995 /* 996 * DER encoded distinguished name. 997 * TLS requires that its not longer than 65535 bytes. 998 */ 999 byte name[]; 1000 1001 DistinguishedName(HandshakeInStream input) throws IOException { 1002 name = input.getBytes16(); 1003 } 1004 1005 DistinguishedName(X500Principal dn) { 1006 name = dn.getEncoded(); 1007 } 1008 1009 X500Principal getX500Principal() throws IOException { 1010 try { 1011 return new X500Principal(name); 1012 } catch (IllegalArgumentException e) { 1013 throw (SSLProtocolException)new SSLProtocolException 1014 (e.getMessage()).initCause(e); 1015 } 1016 } 1017 1018 int length() { 1019 return 2 + name.length; 1020 } 1021 1022 void send(HandshakeOutStream output) throws IOException { 1023 output.putBytes16(name); 1024 } 1025 1026 void print(PrintStream output) throws IOException { 1027 X500Principal principal = new X500Principal(name); 1028 output.println("<" + principal.toString() + ">"); 1029 } 1030 } 1031 1032 /* 1033 * CertificateRequest ... SERVER --> CLIENT 1034 * 1035 * Authenticated servers may ask clients to authenticate themselves 1036 * in turn, using this message. 1037 */ 1038 static final 1039 class CertificateRequest extends HandshakeMessage 1040 { 1041 int messageType() { return ht_certificate_request; } 1042 1043 // enum ClientCertificateType 1044 static final int cct_rsa_sign = 1; 1045 static final int cct_dss_sign = 2; 1046 static final int cct_rsa_fixed_dh = 3; 1047 static final int cct_dss_fixed_dh = 4; 1048 1049 // The existance of these two values is a bug in the SSL specification. 1050 // They are never used in the protocol. 1051 static final int cct_rsa_ephemeral_dh = 5; 1052 static final int cct_dss_ephemeral_dh = 6; 1053 1054 // From RFC 4492 (ECC) 1055 static final int cct_ecdsa_sign = 64; 1056 static final int cct_rsa_fixed_ecdh = 65; 1057 static final int cct_ecdsa_fixed_ecdh = 66; 1058 1059 private final static byte[] TYPES_NO_ECC = { cct_rsa_sign, cct_dss_sign }; 1060 private final static byte[] TYPES_ECC = 1061 { cct_rsa_sign, cct_dss_sign, cct_ecdsa_sign }; 1062 1063 byte types []; // 1 to 255 types 1064 DistinguishedName authorities []; // 3 to 2^16 - 1 1065 // ... "3" because that's the smallest DER-encoded X500 DN 1066 1067 CertificateRequest(X509Certificate ca[], KeyExchange keyExchange) 1068 throws IOException { 1069 // always use X500Principal 1070 authorities = new DistinguishedName[ca.length]; 1071 for (int i = 0; i < ca.length; i++) { 1072 X500Principal x500Principal = ca[i].getSubjectX500Principal(); 1073 authorities[i] = new DistinguishedName(x500Principal); 1074 } 1075 // we support RSA, DSS, and ECDSA client authentication and they 1076 // can be used with all ciphersuites. If this changes, the code 1077 // needs to be adapted to take keyExchange into account. 1078 // We only request ECDSA client auth if we have ECC crypto available. 1079 this.types = JsseJce.isEcAvailable() ? TYPES_ECC : TYPES_NO_ECC; 1080 } 1081 1082 CertificateRequest(HandshakeInStream input) throws IOException { 1083 types = input.getBytes8(); 1084 int len = input.getInt16(); 1085 ArrayList<DistinguishedName> v = new ArrayList<DistinguishedName>(); 1086 while (len >= 3) { 1087 DistinguishedName dn = new DistinguishedName(input); 1088 v.add(dn); 1089 len -= dn.length(); 1090 } 1091 1092 if (len != 0) { 1093 throw new SSLProtocolException("Bad CertificateRequest DN length"); 1094 } 1095 1096 authorities = v.toArray(new DistinguishedName[v.size()]); 1097 } 1098 1099 X500Principal[] getAuthorities() throws IOException { 1100 X500Principal[] ret = new X500Principal[authorities.length]; 1101 for (int i = 0; i < authorities.length; i++) { 1102 ret[i] = authorities[i].getX500Principal(); 1103 } 1104 return ret; 1105 } 1106 1107 int messageLength() 1108 { 1109 int len; 1110 1111 len = 1 + types.length + 2; 1112 for (int i = 0; i < authorities.length; i++) 1113 len += authorities[i].length(); 1114 return len; 1115 } 1116 1117 void send(HandshakeOutStream output) throws IOException 1118 { 1119 int len = 0; 1120 1121 for (int i = 0; i < authorities.length; i++) 1122 len += authorities[i].length(); 1123 1124 output.putBytes8(types); 1125 output.putInt16(len); 1126 for (int i = 0; i < authorities.length; i++) 1127 authorities[i].send(output); 1128 } 1129 1130 void print(PrintStream s) throws IOException 1131 { 1132 s.println("*** CertificateRequest"); 1133 1134 if (debug != null && Debug.isOn("verbose")) { 1135 s.print("Cert Types: "); 1136 for (int i = 0; i < types.length; i++) { 1137 switch (types[i]) { 1138 case cct_rsa_sign: 1139 s.print("RSA"); break; 1140 case cct_dss_sign: 1141 s.print("DSS"); break; 1142 case cct_rsa_fixed_dh: 1143 s.print("Fixed DH (RSA sig)"); break; 1144 case cct_dss_fixed_dh: 1145 s.print("Fixed DH (DSS sig)"); break; 1146 case cct_rsa_ephemeral_dh: 1147 s.print("Ephemeral DH (RSA sig)"); break; 1148 case cct_dss_ephemeral_dh: 1149 s.print("Ephemeral DH (DSS sig)"); break; 1150 case cct_ecdsa_sign: 1151 s.print("ECDSA"); break; 1152 case cct_rsa_fixed_ecdh: 1153 s.print("Fixed ECDH (RSA sig)"); break; 1154 case cct_ecdsa_fixed_ecdh: 1155 s.print("Fixed ECDH (ECDSA sig)"); break; 1156 default: 1157 s.print("Type-" + (types[i] & 0xff)); break; 1158 } 1159 if (i != types.length - 1) { 1160 s.print(", "); 1161 } 1162 } 1163 s.println(); 1164 1165 s.println("Cert Authorities:"); 1166 for (int i = 0; i < authorities.length; i++) 1167 authorities[i].print(s); 1168 } 1169 } 1170 } 1171 1172 1173 /* 1174 * ServerHelloDone ... SERVER --> CLIENT 1175 * 1176 * When server's done sending its messages in response to the client's 1177 * "hello" (e.g. its own hello, certificate, key exchange message, perhaps 1178 * client certificate request) it sends this message to flag that it's 1179 * done that part of the handshake. 1180 */ 1181 static final 1182 class ServerHelloDone extends HandshakeMessage 1183 { 1184 int messageType() { return ht_server_hello_done; } 1185 1186 ServerHelloDone() { } 1187 1188 ServerHelloDone(HandshakeInStream input) 1189 { 1190 // nothing to do 1191 } 1192 1193 int messageLength() 1194 { 1195 return 0; 1196 } 1197 1198 void send(HandshakeOutStream s) throws IOException 1199 { 1200 // nothing to send 1201 } 1202 1203 void print(PrintStream s) throws IOException 1204 { 1205 s.println("*** ServerHelloDone"); 1206 } 1207 } 1208 1209 1210 /* 1211 * CertificateVerify ... CLIENT --> SERVER 1212 * 1213 * Sent after client sends signature-capable certificates (e.g. not 1214 * Diffie-Hellman) to verify. 1215 */ 1216 static final class CertificateVerify extends HandshakeMessage { 1217 1218 int messageType() { return ht_certificate_verify; } 1219 1220 private byte[] signature; 1221 1222 /* 1223 * Create an RSA or DSA signed certificate verify message. 1224 */ 1225 CertificateVerify(ProtocolVersion protocolVersion, HandshakeHash 1226 handshakeHash, PrivateKey privateKey, SecretKey masterSecret, 1227 SecureRandom sr) throws GeneralSecurityException { 1228 String algorithm = privateKey.getAlgorithm(); 1229 Signature sig = getSignature(protocolVersion, algorithm); 1230 sig.initSign(privateKey, sr); 1231 updateSignature(sig, protocolVersion, handshakeHash, algorithm, 1232 masterSecret); 1233 signature = sig.sign(); 1234 } 1235 1236 // 1237 // Unmarshal the signed data from the input stream. 1238 // 1239 CertificateVerify(HandshakeInStream input) throws IOException { 1240 signature = input.getBytes16(); 1241 } 1242 1243 /* 1244 * Verify a certificate verify message. Return the result of verification, 1245 * if there is a problem throw a GeneralSecurityException. 1246 */ 1247 boolean verify(ProtocolVersion protocolVersion, 1248 HandshakeHash handshakeHash, PublicKey publicKey, 1249 SecretKey masterSecret) throws GeneralSecurityException { 1250 String algorithm = publicKey.getAlgorithm(); 1251 Signature sig = getSignature(protocolVersion, algorithm); 1252 sig.initVerify(publicKey); 1253 updateSignature(sig, protocolVersion, handshakeHash, algorithm, 1254 masterSecret); 1255 return sig.verify(signature); 1256 } 1257 1258 /* 1259 * Get the Signature object appropriate for verification using the 1260 * given signature algorithm and protocol version. 1261 */ 1262 private static Signature getSignature(ProtocolVersion protocolVersion, 1263 String algorithm) throws GeneralSecurityException { 1264 if (algorithm.equals("RSA")) { 1265 return RSASignature.getInternalInstance(); 1266 } else if (algorithm.equals("DSA")) { 1267 return JsseJce.getSignature(JsseJce.SIGNATURE_RAWDSA); 1268 } else if (algorithm.equals("EC")) { 1269 return JsseJce.getSignature(JsseJce.SIGNATURE_RAWECDSA); 1270 } else { 1271 throw new SignatureException("Unrecognized algorithm: " 1272 + algorithm); 1273 } 1274 } 1275 1276 /* 1277 * Update the Signature with the data appropriate for the given 1278 * signature algorithm and protocol version so that the object is 1279 * ready for signing or verifying. 1280 */ 1281 private static void updateSignature(Signature sig, 1282 ProtocolVersion protocolVersion, 1283 HandshakeHash handshakeHash, String algorithm, SecretKey masterKey) 1284 throws SignatureException { 1285 MessageDigest md5Clone = handshakeHash.getMD5Clone(); 1286 MessageDigest shaClone = handshakeHash.getSHAClone(); 1287 boolean tls = protocolVersion.v >= ProtocolVersion.TLS10.v; 1288 if (algorithm.equals("RSA")) { 1289 if (tls) { 1290 // nothing to do 1291 } else { // SSLv3 1292 updateDigest(md5Clone, MD5_pad1, MD5_pad2, masterKey); 1293 updateDigest(shaClone, SHA_pad1, SHA_pad2, masterKey); 1294 } 1295 // need to use these hashes directly 1296 RSASignature.setHashes(sig, md5Clone, shaClone); 1297 } else { // DSA, ECDSA 1298 if (tls) { 1299 // nothing to do 1300 } else { // SSLv3 1301 updateDigest(shaClone, SHA_pad1, SHA_pad2, masterKey); 1302 } 1303 sig.update(shaClone.digest()); 1304 } 1305 } 1306 1307 /* 1308 * Update the MessageDigest for SSLv3 certificate verify or finished 1309 * message calculation. The digest must already have been updated with 1310 * all preceding handshake messages. 1311 * Used by the Finished class as well. 1312 */ 1313 static void updateDigest(MessageDigest md, byte[] pad1, byte[] pad2, 1314 SecretKey masterSecret) { 1315 // Digest the key bytes if available. 1316 // Otherwise (sensitive key), try digesting the key directly. 1317 // That is currently only implemented in SunPKCS11 using a private 1318 // reflection API, so we avoid that if possible. 1319 byte[] keyBytes = "RAW".equals(masterSecret.getFormat()) 1320 ? masterSecret.getEncoded() : null; 1321 if (keyBytes != null) { 1322 md.update(keyBytes); 1323 } else { 1324 digestKey(md, masterSecret); 1325 } 1326 md.update(pad1); 1327 byte[] temp = md.digest(); 1328 1329 if (keyBytes != null) { 1330 md.update(keyBytes); 1331 } else { 1332 digestKey(md, masterSecret); 1333 } 1334 md.update(pad2); 1335 md.update(temp); 1336 } 1337 1338 private final static Class delegate; 1339 private final static Field spiField; 1340 1341 static { 1342 try { 1343 delegate = Class.forName("java.security.MessageDigest$Delegate"); 1344 spiField = delegate.getDeclaredField("digestSpi"); 1345 } catch (Exception e) { 1346 throw new RuntimeException("Reflection failed", e); 1347 } 1348 makeAccessible(spiField); 1349 } 1350 1351 private static void makeAccessible(final AccessibleObject o) { 1352 AccessController.doPrivileged(new PrivilegedAction<Object>() { 1353 public Object run() { 1354 o.setAccessible(true); 1355 return null; 1356 } 1357 }); 1358 } 1359 1360 // ConcurrentHashMap does not allow null values, use this marker object 1361 private final static Object NULL_OBJECT = new Object(); 1362 1363 // cache Method objects per Spi class 1364 // Note that this will prevent the Spi classes from being GC'd. We assume 1365 // that is not a problem. 1366 private final static Map<Class,Object> methodCache = 1367 new ConcurrentHashMap<Class,Object>(); 1368 1369 private static void digestKey(MessageDigest md, SecretKey key) { 1370 try { 1371 // Verify that md is implemented via MessageDigestSpi, not 1372 // via JDK 1.1 style MessageDigest subclassing. 1373 if (md.getClass() != delegate) { 1374 throw new Exception("Digest is not a MessageDigestSpi"); 1375 } 1376 MessageDigestSpi spi = (MessageDigestSpi)spiField.get(md); 1377 Class<?> clazz = spi.getClass(); 1378 Object r = methodCache.get(clazz); 1379 if (r == null) { 1380 try { 1381 r = clazz.getDeclaredMethod("implUpdate", SecretKey.class); 1382 makeAccessible((Method)r); 1383 } catch (NoSuchMethodException e) { 1384 r = NULL_OBJECT; 1385 } 1386 methodCache.put(clazz, r); 1387 } 1388 if (r == NULL_OBJECT) { 1389 throw new Exception("Digest does not support implUpdate(SecretKey)"); 1390 } 1391 Method update = (Method)r; 1392 update.invoke(spi, key); 1393 } catch (Exception e) { 1394 throw new RuntimeException 1395 ("Could not obtain encoded key and MessageDigest cannot digest key", e); 1396 } 1397 } 1398 1399 int messageLength() { 1400 return 2 + signature.length; 1401 } 1402 1403 void send(HandshakeOutStream s) throws IOException { 1404 s.putBytes16(signature); 1405 } 1406 1407 void print(PrintStream s) throws IOException { 1408 s.println("*** CertificateVerify"); 1409 } 1410 } 1411 1412 1413 /* 1414 * FINISHED ... sent by both CLIENT and SERVER 1415 * 1416 * This is the FINISHED message as defined in the SSL and TLS protocols. 1417 * Both protocols define this handshake message slightly differently. 1418 * This class supports both formats. 1419 * 1420 * When handshaking is finished, each side sends a "change_cipher_spec" 1421 * record, then immediately sends a "finished" handshake message prepared 1422 * according to the newly adopted cipher spec. 1423 * 1424 * NOTE that until this is sent, no application data may be passed, unless 1425 * some non-default cipher suite has already been set up on this connection 1426 * connection (e.g. a previous handshake arranged one). 1427 */ 1428 static final class Finished extends HandshakeMessage { 1429 1430 int messageType() { return ht_finished; } 1431 1432 // constant for a Finished message sent by the client 1433 final static int CLIENT = 1; 1434 1435 // constant for a Finished message sent by the server 1436 final static int SERVER = 2; 1437 1438 // enum Sender: "CLNT" and "SRVR" 1439 private static final byte[] SSL_CLIENT = { 0x43, 0x4C, 0x4E, 0x54 }; 1440 private static final byte[] SSL_SERVER = { 0x53, 0x52, 0x56, 0x52 }; 1441 1442 /* 1443 * Contents of the finished message ("checksum"). For TLS, it 1444 * is 12 bytes long, for SSLv3 36 bytes. 1445 */ 1446 private byte[] verifyData; 1447 1448 /* 1449 * Create a finished message to send to the remote peer. 1450 */ 1451 Finished(ProtocolVersion protocolVersion, HandshakeHash handshakeHash, 1452 int sender, SecretKey master) { 1453 verifyData = getFinished(protocolVersion, handshakeHash, sender, 1454 master); 1455 } 1456 1457 /* 1458 * Constructor that reads FINISHED message from stream. 1459 */ 1460 Finished(ProtocolVersion protocolVersion, HandshakeInStream input) 1461 throws IOException { 1462 int msgLen = (protocolVersion.v >= ProtocolVersion.TLS10.v) ? 12 : 36; 1463 verifyData = new byte[msgLen]; 1464 input.read(verifyData); 1465 } 1466 1467 /* 1468 * Verify that the hashes here are what would have been produced 1469 * according to a given set of inputs. This is used to ensure that 1470 * both client and server are fully in sync, and that the handshake 1471 * computations have been successful. 1472 */ 1473 boolean verify(ProtocolVersion protocolVersion, 1474 HandshakeHash handshakeHash, int sender, SecretKey master) { 1475 byte[] myFinished = getFinished(protocolVersion, handshakeHash, 1476 sender, master); 1477 return Arrays.equals(myFinished, verifyData); 1478 } 1479 1480 /* 1481 * Perform the actual finished message calculation. 1482 */ 1483 private static byte[] getFinished(ProtocolVersion protocolVersion, 1484 HandshakeHash handshakeHash, int sender, SecretKey masterKey) { 1485 byte[] sslLabel; 1486 String tlsLabel; 1487 if (sender == CLIENT) { 1488 sslLabel = SSL_CLIENT; 1489 tlsLabel = "client finished"; 1490 } else if (sender == SERVER) { 1491 sslLabel = SSL_SERVER; 1492 tlsLabel = "server finished"; 1493 } else { 1494 throw new RuntimeException("Invalid sender: " + sender); 1495 } 1496 MessageDigest md5Clone = handshakeHash.getMD5Clone(); 1497 MessageDigest shaClone = handshakeHash.getSHAClone(); 1498 if (protocolVersion.v >= ProtocolVersion.TLS10.v) { 1499 // TLS 1500 try { 1501 byte[] seed = new byte[36]; 1502 md5Clone.digest(seed, 0, 16); 1503 shaClone.digest(seed, 16, 20); 1504 1505 TlsPrfParameterSpec spec = new TlsPrfParameterSpec 1506 (masterKey, tlsLabel, seed, 12); 1507 KeyGenerator prf = JsseJce.getKeyGenerator("SunTlsPrf"); 1508 prf.init(spec); 1509 SecretKey prfKey = prf.generateKey(); 1510 if ("RAW".equals(prfKey.getFormat()) == false) { 1511 throw new ProviderException 1512 ("Invalid PRF output, format must be RAW"); 1513 } 1514 byte[] finished = prfKey.getEncoded(); 1515 return finished; 1516 } catch (GeneralSecurityException e) { 1517 throw new RuntimeException("PRF failed", e); 1518 } 1519 } else { 1520 // SSLv3 1521 updateDigest(md5Clone, sslLabel, MD5_pad1, MD5_pad2, masterKey); 1522 updateDigest(shaClone, sslLabel, SHA_pad1, SHA_pad2, masterKey); 1523 byte[] finished = new byte[36]; 1524 try { 1525 md5Clone.digest(finished, 0, 16); 1526 shaClone.digest(finished, 16, 20); 1527 } catch (DigestException e) { 1528 // cannot occur 1529 throw new RuntimeException("Digest failed", e); 1530 } 1531 return finished; 1532 } 1533 } 1534 1535 /* 1536 * Update the MessageDigest for SSLv3 finished message calculation. 1537 * The digest must already have been updated with all preceding handshake 1538 * messages. This operation is almost identical to the certificate verify 1539 * hash, reuse that code. 1540 */ 1541 private static void updateDigest(MessageDigest md, byte[] sender, 1542 byte[] pad1, byte[] pad2, SecretKey masterSecret) { 1543 md.update(sender); 1544 CertificateVerify.updateDigest(md, pad1, pad2, masterSecret); 1545 } 1546 1547 int messageLength() { 1548 return verifyData.length; 1549 } 1550 1551 void send(HandshakeOutStream out) throws IOException { 1552 out.write(verifyData); 1553 } 1554 1555 void print(PrintStream s) throws IOException { 1556 s.println("*** Finished"); 1557 if (debug != null && Debug.isOn("verbose")) { 1558 Debug.println(s, "verify_data", verifyData); 1559 s.println("***"); 1560 } 1561 } 1562 1563 } 1564 1565 // 1566 // END of nested classes 1567 // 1568 1569 }