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 }