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