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