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