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