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