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