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