1 /*
   2  * Copyright (c) 1996, 2016, 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 import sun.security.util.MessageDigestSpi2;
  53 import sun.security.provider.certpath.OCSPResponse;
  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 public abstract class HandshakeMessage {
  77 
  78     /* Class and subclass dynamic debugging support */
  79     public static final Debug debug = Debug.getInstance("ssl");
  80 
  81     // enum HandshakeType:
  82     static final byte   ht_hello_request          = 0;      // RFC 5246
  83     static final byte   ht_client_hello           = 1;      // RFC 5246
  84     static final byte   ht_server_hello           = 2;      // RFC 5246
  85     static final byte   ht_hello_verify_request   = 3;      // RFC 6347
  86     static final byte   ht_new_session_ticket     = 4;      // RFC 4507
  87 
  88     static final byte   ht_certificate            = 11;     // RFC 5246
  89     static final byte   ht_server_key_exchange    = 12;     // RFC 5246
  90     static final byte   ht_certificate_request    = 13;     // RFC 5246
  91     static final byte   ht_server_hello_done      = 14;     // RFC 5246
  92     static final byte   ht_certificate_verify     = 15;     // RFC 5246
  93     static final byte   ht_client_key_exchange    = 16;     // RFC 5246
  94 
  95     static final byte   ht_finished               = 20;     // RFC 5246
  96     static final byte   ht_certificate_url        = 21;     // RFC 6066
  97     static final byte   ht_certificate_status     = 22;     // RFC 6066
  98     static final byte   ht_supplemental_data      = 23;     // RFC 4680
  99 
 100     static final byte   ht_not_applicable         = -1;     // N/A
 101 
 102     /*
 103      * SSL 3.0 MAC padding constants.
 104      * Also used by CertificateVerify and Finished during the handshake.
 105      */
 106     static final byte[] MD5_pad1 = genPad(0x36, 48);
 107     static final byte[] MD5_pad2 = genPad(0x5c, 48);
 108 
 109     static final byte[] SHA_pad1 = genPad(0x36, 40);
 110     static final byte[] SHA_pad2 = genPad(0x5c, 40);
 111 
 112     // default constructor
 113     HandshakeMessage() {
 114     }
 115 
 116     /**
 117      * Utility method to convert a BigInteger to a byte array in unsigned
 118      * format as needed in the handshake messages. BigInteger uses
 119      * 2's complement format, i.e. it prepends an extra zero if the MSB
 120      * is set. We remove that.
 121      */
 122     static byte[] toByteArray(BigInteger bi) {
 123         byte[] b = bi.toByteArray();
 124         if ((b.length > 1) && (b[0] == 0)) {
 125             int n = b.length - 1;
 126             byte[] newarray = new byte[n];
 127             System.arraycopy(b, 1, newarray, 0, n);
 128             b = newarray;
 129         }
 130         return b;
 131     }
 132 
 133     private static byte[] genPad(int b, int count) {
 134         byte[] padding = new byte[count];
 135         Arrays.fill(padding, (byte)b);
 136         return padding;
 137     }
 138 
 139     /*
 140      * Write a handshake message on the (handshake) output stream.
 141      * This is just a four byte header followed by the data.
 142      *
 143      * NOTE that huge messages -- notably, ones with huge cert
 144      * chains -- are handled correctly.
 145      */
 146     final void write(HandshakeOutStream s) throws IOException {
 147         int len = messageLength();
 148         if (len >= Record.OVERFLOW_OF_INT24) {
 149             throw new SSLException("Handshake message too big"
 150                 + ", type = " + messageType() + ", len = " + len);
 151         }
 152         s.write(messageType());
 153         s.putInt24(len);
 154         send(s);
 155         s.complete();
 156     }
 157 
 158     /*
 159      * Subclasses implement these methods so those kinds of
 160      * messages can be emitted.  Base class delegates to subclass.
 161      */
 162     abstract int  messageType();
 163     abstract int  messageLength();
 164     abstract void send(HandshakeOutStream s) throws IOException;
 165 
 166     /*
 167      * Write a descriptive message on the output stream; for debugging.
 168      */
 169     abstract void print(PrintStream p) throws IOException;
 170 
 171 //
 172 // NOTE:  the rest of these classes are nested within this one, and are
 173 // imported by other classes in this package.  There are a few other
 174 // handshake message classes, not neatly nested here because of current
 175 // licensing requirement for native (RSA) methods.  They belong here,
 176 // but those native methods complicate things a lot!
 177 //
 178 
 179 
 180 /*
 181  * HelloRequest ... SERVER --> CLIENT
 182  *
 183  * Server can ask the client to initiate a new handshake, e.g. to change
 184  * session parameters after a connection has been (re)established.
 185  */
 186 static final class HelloRequest extends HandshakeMessage {
 187     @Override
 188     int messageType() { return ht_hello_request; }
 189 
 190     HelloRequest() { }
 191 
 192     HelloRequest(HandshakeInStream in) throws IOException
 193     {
 194         // nothing in this message
 195     }
 196 
 197     @Override
 198     int messageLength() { return 0; }
 199 
 200     @Override
 201     void send(HandshakeOutStream out) throws IOException
 202     {
 203         // nothing in this messaage
 204     }
 205 
 206     @Override
 207     void print(PrintStream out) throws IOException
 208     {
 209         out.println("*** HelloRequest (empty)");
 210     }
 211 
 212 }
 213 
 214 /*
 215  * HelloVerifyRequest ... SERVER --> CLIENT  [DTLS only]
 216  *
 217  * The definition of HelloVerifyRequest is as follows:
 218  *
 219  *     struct {
 220  *       ProtocolVersion server_version;
 221  *       opaque cookie<0..2^8-1>;
 222  *     } HelloVerifyRequest;
 223  *
 224  * For DTLS protocols, once the client has transmitted the ClientHello message,
 225  * it expects to see a HelloVerifyRequest from the server.  However, if the
 226  * server's message is lost, the client knows that either the ClientHello or
 227  * the HelloVerifyRequest has been lost and retransmits. [RFC 6347]
 228  */
 229 static final class HelloVerifyRequest extends HandshakeMessage {
 230     ProtocolVersion     protocolVersion;
 231     byte[]              cookie;         // 1 to 2^8 - 1 bytes
 232 
 233     HelloVerifyRequest(HelloCookieManager helloCookieManager,
 234             ClientHello clientHelloMsg) {
 235 
 236         this.protocolVersion = clientHelloMsg.protocolVersion;
 237         this.cookie = helloCookieManager.getCookie(clientHelloMsg);
 238     }
 239 
 240     HelloVerifyRequest(
 241             HandshakeInStream input, int messageLength) throws IOException {
 242 
 243         this.protocolVersion =
 244                 ProtocolVersion.valueOf(input.getInt8(), input.getInt8());
 245         this.cookie = input.getBytes8();
 246 
 247         // Is it a valid cookie?
 248         HelloCookieManager.checkCookie(protocolVersion, cookie);
 249     }
 250 
 251     @Override
 252     int messageType() {
 253         return ht_hello_verify_request;
 254     }
 255 
 256     @Override
 257     int messageLength() {
 258         return 2 + cookie.length;       // 2: the length of protocolVersion
 259     }
 260 
 261     @Override
 262     void send(HandshakeOutStream hos) throws IOException {
 263         hos.putInt8(protocolVersion.major);
 264         hos.putInt8(protocolVersion.minor);
 265         hos.putBytes8(cookie);
 266     }
 267 
 268     @Override
 269     void print(PrintStream out) throws IOException {
 270         out.println("*** HelloVerifyRequest");
 271         if (debug != null && Debug.isOn("verbose")) {
 272             out.println("server_version: " + protocolVersion);
 273             Debug.println(out, "cookie", cookie);
 274         }
 275     }
 276 }
 277 
 278 /*
 279  * ClientHello ... CLIENT --> SERVER
 280  *
 281  * Client initiates handshake by telling server what it wants, and what it
 282  * can support (prioritized by what's first in the ciphe suite list).
 283  *
 284  * By RFC2246:7.4.1.2 it's explicitly anticipated that this message
 285  * will have more data added at the end ... e.g. what CAs the client trusts.
 286  * Until we know how to parse it, we will just read what we know
 287  * about, and let our caller handle the jumps over unknown data.
 288  */
 289 static final class ClientHello extends HandshakeMessage {
 290 
 291     ProtocolVersion             protocolVersion;
 292     RandomCookie                clnt_random;
 293     SessionId                   sessionId;
 294     byte[]                      cookie;                     // DTLS only
 295     private CipherSuiteList     cipherSuites;
 296     private final boolean       isDTLS;
 297     byte[]                      compression_methods;
 298 
 299     HelloExtensions extensions = new HelloExtensions();
 300 
 301     private static final byte[]  NULL_COMPRESSION = new byte[] {0};
 302 
 303     ClientHello(SecureRandom generator, ProtocolVersion protocolVersion,
 304             SessionId sessionId, CipherSuiteList cipherSuites,
 305             boolean isDTLS) {
 306 
 307         this.isDTLS = isDTLS;
 308         this.protocolVersion = protocolVersion;
 309         this.sessionId = sessionId;
 310         this.cipherSuites = cipherSuites;
 311         if (isDTLS) {
 312             this.cookie = new byte[0];
 313         } else {
 314             this.cookie = null;
 315         }
 316 
 317         clnt_random = new RandomCookie(generator);
 318         compression_methods = NULL_COMPRESSION;
 319     }
 320 
 321     ClientHello(HandshakeInStream s,
 322             int messageLength, boolean isDTLS) throws IOException {
 323 
 324         this.isDTLS = isDTLS;
 325 
 326         protocolVersion = ProtocolVersion.valueOf(s.getInt8(), s.getInt8());
 327         clnt_random = new RandomCookie(s);
 328         sessionId = new SessionId(s.getBytes8());
 329         sessionId.checkLength(protocolVersion);
 330         if (isDTLS) {
 331             cookie = s.getBytes8();
 332         } else {
 333             cookie = null;
 334         }
 335 
 336         cipherSuites = new CipherSuiteList(s);
 337         compression_methods = s.getBytes8();
 338         if (messageLength() != messageLength) {
 339             extensions = new HelloExtensions(s);
 340         }
 341     }
 342 
 343     CipherSuiteList getCipherSuites() {
 344         return cipherSuites;
 345     }
 346 
 347     // add renegotiation_info extension
 348     void addRenegotiationInfoExtension(byte[] clientVerifyData) {
 349         HelloExtension renegotiationInfo = new RenegotiationInfoExtension(
 350                     clientVerifyData, new byte[0]);
 351         extensions.add(renegotiationInfo);
 352     }
 353 
 354     // add server_name extension
 355     void addSNIExtension(List<SNIServerName> serverNames) {
 356         try {
 357             extensions.add(new ServerNameExtension(serverNames));
 358         } catch (IOException ioe) {
 359             // ignore the exception and return
 360         }
 361     }
 362 
 363     // add signature_algorithm extension
 364     void addSignatureAlgorithmsExtension(
 365             Collection<SignatureAndHashAlgorithm> algorithms) {
 366         HelloExtension signatureAlgorithm =
 367                 new SignatureAlgorithmsExtension(algorithms);
 368         extensions.add(signatureAlgorithm);
 369     }
 370 
 371     void addMFLExtension(int maximumPacketSize) {
 372         HelloExtension maxFragmentLength =
 373                 new MaxFragmentLengthExtension(maximumPacketSize);
 374         extensions.add(maxFragmentLength);
 375     }
 376 
 377     void updateHelloCookie(MessageDigest cookieDigest) {
 378         //
 379         // Just use HandshakeOutStream to compute the hello verify cookie.
 380         // Not actually used to output handshake message records.
 381         //
 382         HandshakeOutStream hos = new HandshakeOutStream(null);
 383 
 384         try {
 385             send(hos, false);    // Do not count hello verify cookie.
 386         } catch (IOException ioe) {
 387             // unlikely to happen
 388         }
 389 
 390         cookieDigest.update(hos.toByteArray());
 391     }
 392 
 393     // Add status_request extension type
 394     void addCertStatusRequestExtension() {
 395         extensions.add(new CertStatusReqExtension(StatusRequestType.OCSP,
 396                 new OCSPStatusRequest()));
 397     }
 398 
 399     // Add status_request_v2 extension type
 400     void addCertStatusReqListV2Extension() {
 401         // Create a default OCSPStatusRequest that we can use for both
 402         // OCSP_MULTI and OCSP request list items.
 403         OCSPStatusRequest osr = new OCSPStatusRequest();
 404         List<CertStatusReqItemV2> itemList = new ArrayList<>(2);
 405         itemList.add(new CertStatusReqItemV2(StatusRequestType.OCSP_MULTI,
 406                 osr));
 407         itemList.add(new CertStatusReqItemV2(StatusRequestType.OCSP, osr));
 408         extensions.add(new CertStatusReqListV2Extension(itemList));
 409     }
 410 
 411     // add application_layer_protocol_negotiation extension
 412     void addALPNExtension(String[] applicationProtocols) throws SSLException {
 413         extensions.add(new ALPNExtension(applicationProtocols));
 414     }
 415 
 416     @Override
 417     int messageType() { return ht_client_hello; }
 418 
 419     @Override
 420     int messageLength() {
 421         /*
 422          * Add fixed size parts of each field...
 423          * version + random + session + cipher + compress
 424          */
 425         return (2 + 32 + 1 + 2 + 1
 426             + sessionId.length()                /* ... + variable parts */
 427             + (isDTLS ? (1 + cookie.length) : 0)
 428             + (cipherSuites.size() * 2)
 429             + compression_methods.length)
 430             + extensions.length();
 431     }
 432 
 433     @Override
 434     void send(HandshakeOutStream s) throws IOException {
 435         send(s, true);  // Count hello verify cookie.
 436     }
 437 
 438     @Override
 439     void print(PrintStream s) throws IOException {
 440         s.println("*** ClientHello, " + protocolVersion);
 441 
 442         if (debug != null && Debug.isOn("verbose")) {
 443             s.print("RandomCookie:  ");
 444             clnt_random.print(s);
 445 
 446             s.print("Session ID:  ");
 447             s.println(sessionId);
 448 
 449             if (isDTLS) {
 450                 Debug.println(s, "cookie", cookie);
 451             }
 452 
 453             s.println("Cipher Suites: " + cipherSuites);
 454 
 455             Debug.println(s, "Compression Methods", compression_methods);
 456             extensions.print(s);
 457             s.println("***");
 458         }
 459     }
 460 
 461     private void send(HandshakeOutStream s,
 462             boolean computeCookie) throws IOException {
 463         s.putInt8(protocolVersion.major);
 464         s.putInt8(protocolVersion.minor);
 465         clnt_random.send(s);
 466         s.putBytes8(sessionId.getId());
 467         if (isDTLS && computeCookie) {
 468             s.putBytes8(cookie);
 469         }
 470         cipherSuites.send(s);
 471         s.putBytes8(compression_methods);
 472         extensions.send(s);
 473     }
 474 
 475 }
 476 
 477 /*
 478  * ServerHello ... SERVER --> CLIENT
 479  *
 480  * Server chooses protocol options from among those it supports and the
 481  * client supports.  Then it sends the basic session descriptive parameters
 482  * back to the client.
 483  */
 484 static final
 485 class ServerHello extends HandshakeMessage
 486 {
 487     @Override
 488     int messageType() { return ht_server_hello; }
 489 
 490     ProtocolVersion     protocolVersion;
 491     RandomCookie        svr_random;
 492     SessionId           sessionId;
 493     CipherSuite         cipherSuite;
 494     byte                compression_method;
 495     HelloExtensions extensions = new HelloExtensions();
 496 
 497     ServerHello() {
 498         // empty
 499     }
 500 
 501     ServerHello(HandshakeInStream input, int messageLength)
 502             throws IOException {
 503         protocolVersion = ProtocolVersion.valueOf(input.getInt8(),
 504                                                   input.getInt8());
 505         svr_random = new RandomCookie(input);
 506         sessionId = new SessionId(input.getBytes8());
 507         sessionId.checkLength(protocolVersion);
 508         cipherSuite = CipherSuite.valueOf(input.getInt8(), input.getInt8());
 509         compression_method = (byte)input.getInt8();
 510         if (messageLength() != messageLength) {
 511             extensions = new HelloExtensions(input);
 512         }
 513     }
 514 
 515     @Override
 516     int messageLength()
 517     {
 518         // almost fixed size, except session ID and extensions:
 519         //      major + minor = 2
 520         //      random = 32
 521         //      session ID len field = 1
 522         //      cipher suite + compression = 3
 523         //      extensions: if present, 2 + length of extensions
 524         return 38 + sessionId.length() + extensions.length();
 525     }
 526 
 527     @Override
 528     void send(HandshakeOutStream s) throws IOException
 529     {
 530         s.putInt8(protocolVersion.major);
 531         s.putInt8(protocolVersion.minor);
 532         svr_random.send(s);
 533         s.putBytes8(sessionId.getId());
 534         s.putInt8(cipherSuite.id >> 8);
 535         s.putInt8(cipherSuite.id & 0xff);
 536         s.putInt8(compression_method);
 537         extensions.send(s);
 538     }
 539 
 540     @Override
 541     void print(PrintStream s) throws IOException
 542     {
 543         s.println("*** ServerHello, " + protocolVersion);
 544 
 545         if (debug != null && Debug.isOn("verbose")) {
 546             s.print("RandomCookie:  ");
 547             svr_random.print(s);
 548 
 549             s.print("Session ID:  ");
 550             s.println(sessionId);
 551 
 552             s.println("Cipher Suite: " + cipherSuite);
 553             s.println("Compression Method: " + compression_method);
 554             extensions.print(s);
 555             s.println("***");
 556         }
 557     }
 558 }
 559 
 560 
 561 /*
 562  * CertificateMsg ... send by both CLIENT and SERVER
 563  *
 564  * Each end of a connection may need to pass its certificate chain to
 565  * the other end.  Such chains are intended to validate an identity with
 566  * reference to some certifying authority.  Examples include companies
 567  * like Verisign, or financial institutions.  There's some control over
 568  * the certifying authorities which are sent.
 569  *
 570  * NOTE: that these messages might be huge, taking many handshake records.
 571  * Up to 2^48 bytes of certificate may be sent, in records of at most 2^14
 572  * bytes each ... up to 2^32 records sent on the output stream.
 573  */
 574 static final
 575 class CertificateMsg extends HandshakeMessage
 576 {
 577     @Override
 578     int messageType() { return ht_certificate; }
 579 
 580     private X509Certificate[] chain;
 581 
 582     private List<byte[]> encodedChain;
 583 
 584     private int messageLength;
 585 
 586     CertificateMsg(X509Certificate[] certs) {
 587         chain = certs;
 588     }
 589 
 590     CertificateMsg(HandshakeInStream input) throws IOException {
 591         int chainLen = input.getInt24();
 592         List<Certificate> v = new ArrayList<>(4);
 593 
 594         CertificateFactory cf = null;
 595         while (chainLen > 0) {
 596             byte[] cert = input.getBytes24();
 597             chainLen -= (3 + cert.length);
 598             try {
 599                 if (cf == null) {
 600                     cf = CertificateFactory.getInstance("X.509");
 601                 }
 602                 v.add(cf.generateCertificate(new ByteArrayInputStream(cert)));
 603             } catch (CertificateException e) {
 604                 throw (SSLProtocolException)new SSLProtocolException(
 605                     e.getMessage()).initCause(e);
 606             }
 607         }
 608 
 609         chain = v.toArray(new X509Certificate[v.size()]);
 610     }
 611 
 612     @Override
 613     int messageLength() {
 614         if (encodedChain == null) {
 615             messageLength = 3;
 616             encodedChain = new ArrayList<byte[]>(chain.length);
 617             try {
 618                 for (X509Certificate cert : chain) {
 619                     byte[] b = cert.getEncoded();
 620                     encodedChain.add(b);
 621                     messageLength += b.length + 3;
 622                 }
 623             } catch (CertificateEncodingException e) {
 624                 encodedChain = null;
 625                 throw new RuntimeException("Could not encode certificates", e);
 626             }
 627         }
 628         return messageLength;
 629     }
 630 
 631     @Override
 632     void send(HandshakeOutStream s) throws IOException {
 633         s.putInt24(messageLength() - 3);
 634         for (byte[] b : encodedChain) {
 635             s.putBytes24(b);
 636         }
 637     }
 638 
 639     @Override
 640     void print(PrintStream s) throws IOException {
 641         s.println("*** Certificate chain");
 642 
 643         if (chain.length == 0) {
 644             s.println("<Empty>");
 645         } else if (debug != null && Debug.isOn("verbose")) {
 646             for (int i = 0; i < chain.length; i++) {
 647                 s.println("chain [" + i + "] = " + chain[i]);
 648             }
 649         }
 650         s.println("***");
 651     }
 652 
 653     X509Certificate[] getCertificateChain() {
 654         return chain.clone();
 655     }
 656 }
 657 
 658 /*
 659  * CertificateStatus ... SERVER --> CLIENT
 660  *
 661  * When a ClientHello asserting the status_request or status_request_v2
 662  * extensions is accepted by the server, it will fetch and return one
 663  * or more status responses in this handshake message.
 664  *
 665  * NOTE: Like the Certificate handshake message, this can potentially
 666  * be a very large message both due to the size of multiple status
 667  * responses and the certificate chains that are often attached to them.
 668  * Up to 2^24 bytes of status responses may be sent, possibly fragmented
 669  * over multiple TLS records.
 670  */
 671 static final class CertificateStatus extends HandshakeMessage
 672 {
 673     private final StatusRequestType statusType;
 674     private int encodedResponsesLen;
 675     private int messageLength = -1;
 676     private List<byte[]> encodedResponses;
 677 
 678     @Override
 679     int messageType() { return ht_certificate_status; }
 680 
 681     /**
 682      * Create a CertificateStatus message from the certificates and their
 683      * respective OCSP responses
 684      *
 685      * @param type an indication of the type of response (OCSP or OCSP_MULTI)
 686      * @param responses a {@code List} of OCSP responses in DER-encoded form.
 687      *      For the OCSP type, only the first entry in the response list is
 688      *      used, and must correspond to the end-entity certificate sent to the
 689      *      peer.  Zero-length or null values for the response data are not
 690      *      allowed for the OCSP type.  For the OCSP_MULTI type, each entry in
 691      *      the list should match its corresponding certificate sent in the
 692      *      Server Certificate message.  Where an OCSP response does not exist,
 693      *      either a zero-length array or a null value should be used.
 694      *
 695      * @throws SSLException if an unsupported StatusRequestType or invalid
 696      *      OCSP response data is provided.
 697      */
 698     CertificateStatus(StatusRequestType type, X509Certificate[] chain,
 699             Map<X509Certificate, byte[]> responses) {
 700         statusType = type;
 701         encodedResponsesLen = 0;
 702         encodedResponses = new ArrayList<>(chain.length);
 703 
 704         Objects.requireNonNull(chain, "Null chain not allowed");
 705         Objects.requireNonNull(responses, "Null responses not allowed");
 706 
 707         if (statusType == StatusRequestType.OCSP) {
 708             // Just get the response for the end-entity certificate
 709             byte[] respDER = responses.get(chain[0]);
 710             if (respDER != null && respDER.length > 0) {
 711                 encodedResponses.add(respDER);
 712                 encodedResponsesLen = 3 + respDER.length;
 713             } else {
 714                 throw new IllegalArgumentException("Zero-length or null " +
 715                         "OCSP Response");
 716             }
 717         } else if (statusType == StatusRequestType.OCSP_MULTI) {
 718             for (X509Certificate cert : chain) {
 719                 byte[] respDER = responses.get(cert);
 720                 if (respDER != null) {
 721                     encodedResponses.add(respDER);
 722                     encodedResponsesLen += (respDER.length + 3);
 723                 } else {
 724                     // If we cannot find a response for a given certificate
 725                     // then use a zero-length placeholder.
 726                     encodedResponses.add(new byte[0]);
 727                     encodedResponsesLen += 3;
 728                 }
 729             }
 730         } else {
 731             throw new IllegalArgumentException(
 732                     "Unsupported StatusResponseType: " + statusType);
 733         }
 734     }
 735 
 736     /**
 737      * Decode the CertificateStatus handshake message coming from a
 738      * {@code HandshakeInputStream}.
 739      *
 740      * @param input the {@code HandshakeInputStream} containing the
 741      * CertificateStatus message bytes.
 742      *
 743      * @throws SSLHandshakeException if a zero-length response is found in the
 744      * OCSP response type, or an unsupported response type is detected.
 745      * @throws IOException if a decoding error occurs.
 746      */
 747     CertificateStatus(HandshakeInStream input) throws IOException {
 748         encodedResponsesLen = 0;
 749         encodedResponses = new ArrayList<>();
 750 
 751         statusType = StatusRequestType.get(input.getInt8());
 752         if (statusType == StatusRequestType.OCSP) {
 753             byte[] respDER = input.getBytes24();
 754             // Convert the incoming bytes to a OCSPResponse strucutre
 755             if (respDER.length > 0) {
 756                 encodedResponses.add(respDER);
 757                 encodedResponsesLen = 3 + respDER.length;
 758             } else {
 759                 throw new SSLHandshakeException("Zero-length OCSP Response");
 760             }
 761         } else if (statusType == StatusRequestType.OCSP_MULTI) {
 762             int respListLen = input.getInt24();
 763             encodedResponsesLen = respListLen;
 764 
 765             // Add each OCSP reponse into the array list in the order
 766             // we receive them off the wire.  A zero-length array is
 767             // allowed for ocsp_multi, and means that a response for
 768             // a given certificate is not available.
 769             while (respListLen > 0) {
 770                 byte[] respDER = input.getBytes24();
 771                 encodedResponses.add(respDER);
 772                 respListLen -= (respDER.length + 3);
 773             }
 774 
 775             if (respListLen != 0) {
 776                 throw new SSLHandshakeException(
 777                         "Bad OCSP response list length");
 778             }
 779         } else {
 780             throw new SSLHandshakeException("Unsupported StatusResponseType: " +
 781                     statusType);
 782         }
 783     }
 784 
 785     /**
 786      * Get the length of the CertificateStatus message.
 787      *
 788      * @return the length of the message in bytes.
 789      */
 790     @Override
 791     int messageLength() {
 792         int len = 1;            // Length + Status type
 793 
 794         if (messageLength == -1) {
 795             if (statusType == StatusRequestType.OCSP) {
 796                 len += encodedResponsesLen;
 797             } else if (statusType == StatusRequestType.OCSP_MULTI) {
 798                 len += 3 + encodedResponsesLen;
 799             }
 800             messageLength = len;
 801         }
 802 
 803         return messageLength;
 804     }
 805 
 806     /**
 807      * Encode the CertificateStatus handshake message and place it on a
 808      * {@code HandshakeOutputStream}.
 809      *
 810      * @param s the HandshakeOutputStream that will the message bytes.
 811      *
 812      * @throws IOException if an encoding error occurs.
 813      */
 814     @Override
 815     void send(HandshakeOutStream s) throws IOException {
 816         s.putInt8(statusType.id);
 817         if (statusType == StatusRequestType.OCSP) {
 818             s.putBytes24(encodedResponses.get(0));
 819         } else if (statusType == StatusRequestType.OCSP_MULTI) {
 820             s.putInt24(encodedResponsesLen);
 821             for (byte[] respBytes : encodedResponses) {
 822                 if (respBytes != null) {
 823                     s.putBytes24(respBytes);
 824                 } else {
 825                     s.putBytes24(null);
 826                 }
 827             }
 828         } else {
 829             // It is highly unlikely that we will fall into this section of
 830             // the code.
 831             throw new SSLHandshakeException("Unsupported status_type: " +
 832                     statusType.id);
 833         }
 834     }
 835 
 836     /**
 837      * Display a human-readable representation of the CertificateStatus message.
 838      *
 839      * @param s the PrintStream used to display the message data.
 840      *
 841      * @throws IOException if any errors occur while parsing the OCSP response
 842      * bytes into a readable form.
 843      */
 844     @Override
 845     void print(PrintStream s) throws IOException {
 846         s.println("*** CertificateStatus");
 847         if (debug != null && Debug.isOn("verbose")) {
 848             s.println("Type: " + statusType);
 849             if (statusType == StatusRequestType.OCSP) {
 850                 OCSPResponse oResp = new OCSPResponse(encodedResponses.get(0));
 851                 s.println(oResp);
 852             } else if (statusType == StatusRequestType.OCSP_MULTI) {
 853                 int numResponses = encodedResponses.size();
 854                 s.println(numResponses +
 855                         (numResponses == 1 ? " entry:" : " entries:"));
 856                 for (byte[] respDER : encodedResponses) {
 857                     if (respDER.length > 0) {
 858                         OCSPResponse oResp = new OCSPResponse(respDER);
 859                         s.println(oResp);
 860                     } else {
 861                         s.println("<Zero-length entry>");
 862                     }
 863                 }
 864             }
 865         }
 866     }
 867 
 868     /**
 869      * Get the type of CertificateStatus message
 870      *
 871      * @return the {@code StatusRequestType} for this CertificateStatus
 872      *      message.
 873      */
 874     StatusRequestType getType() {
 875         return statusType;
 876     }
 877 
 878     /**
 879      * Get the list of non-zero length OCSP responses.
 880      * The responses returned in this list can be used to map to
 881      * {@code X509Certificate} objects provided by the peer and
 882      * provided to a {@code PKIXRevocationChecker}.
 883      *
 884      * @return an unmodifiable List of zero or more byte arrays, each one
 885      *      consisting of a single status response.
 886      */
 887     List<byte[]> getResponses() {
 888         return Collections.unmodifiableList(encodedResponses);
 889     }
 890 }
 891 
 892 /*
 893  * ServerKeyExchange ... SERVER --> CLIENT
 894  *
 895  * The cipher suite selected, when combined with the certificate exchanged,
 896  * implies one of several different kinds of key exchange.  Most current
 897  * cipher suites require the server to send more than its certificate.
 898  *
 899  * The primary exceptions are when a server sends an encryption-capable
 900  * RSA public key in its cert, to be used with RSA (or RSA_export) key
 901  * exchange; and when a server sends its Diffie-Hellman cert.  Those kinds
 902  * of key exchange do not require a ServerKeyExchange message.
 903  *
 904  * Key exchange can be viewed as having three modes, which are explicit
 905  * for the Diffie-Hellman flavors and poorly specified for RSA ones:
 906  *
 907  *      - "Ephemeral" keys.  Here, a "temporary" key is allocated by the
 908  *        server, and signed.  Diffie-Hellman keys signed using RSA or
 909  *        DSS are ephemeral (DHE flavor).  RSA keys get used to do the same
 910  *        thing, to cut the key size down to 512 bits (export restrictions)
 911  *        or for signing-only RSA certificates.
 912  *
 913  *      - Anonymity.  Here no server certificate is sent, only the public
 914  *        key of the server.  This case is subject to man-in-the-middle
 915  *        attacks.  This can be done with Diffie-Hellman keys (DH_anon) or
 916  *        with RSA keys, but is only used in SSLv3 for DH_anon.
 917  *
 918  *      - "Normal" case.  Here a server certificate is sent, and the public
 919  *        key there is used directly in exchanging the premaster secret.
 920  *        For example, Diffie-Hellman "DH" flavor, and any RSA flavor with
 921  *        only 512 bit keys.
 922  *
 923  * If a server certificate is sent, there is no anonymity.  However,
 924  * when a certificate is sent, ephemeral keys may still be used to
 925  * exchange the premaster secret.  That's how RSA_EXPORT often works,
 926  * as well as how the DHE_* flavors work.
 927  */
 928 abstract static class ServerKeyExchange extends HandshakeMessage
 929 {
 930     @Override
 931     int messageType() { return ht_server_key_exchange; }
 932 }
 933 
 934 
 935 /*
 936  * Using RSA for Key Exchange:  exchange a session key that's not as big
 937  * as the signing-only key.  Used for export applications, since exported
 938  * RSA encryption keys can't be bigger than 512 bytes.
 939  *
 940  * This is never used when keys are 512 bits or smaller, and isn't used
 941  * on "US Domestic" ciphers in any case.
 942  */
 943 static final
 944 class RSA_ServerKeyExchange extends ServerKeyExchange
 945 {
 946     private byte[] rsa_modulus;     // 1 to 2^16 - 1 bytes
 947     private byte[] rsa_exponent;    // 1 to 2^16 - 1 bytes
 948 
 949     private Signature signature;
 950     private byte[] signatureBytes;
 951 
 952     /*
 953      * Hash the nonces and the ephemeral RSA public key.
 954      */
 955     private void updateSignature(byte[] clntNonce, byte[] svrNonce)
 956             throws SignatureException {
 957         int tmp;
 958 
 959         signature.update(clntNonce);
 960         signature.update(svrNonce);
 961 
 962         tmp = rsa_modulus.length;
 963         signature.update((byte)(tmp >> 8));
 964         signature.update((byte)(tmp & 0x0ff));
 965         signature.update(rsa_modulus);
 966 
 967         tmp = rsa_exponent.length;
 968         signature.update((byte)(tmp >> 8));
 969         signature.update((byte)(tmp & 0x0ff));
 970         signature.update(rsa_exponent);
 971     }
 972 
 973 
 974     /*
 975      * Construct an RSA server key exchange message, using data
 976      * known _only_ to the server.
 977      *
 978      * The client knows the public key corresponding to this private
 979      * key, from the Certificate message sent previously.  To comply
 980      * with US export regulations we use short RSA keys ... either
 981      * long term ones in the server's X509 cert, or else ephemeral
 982      * ones sent using this message.
 983      */
 984     RSA_ServerKeyExchange(PublicKey ephemeralKey, PrivateKey privateKey,
 985             RandomCookie clntNonce, RandomCookie svrNonce, SecureRandom sr)
 986             throws GeneralSecurityException {
 987         RSAPublicKeySpec rsaKey = JsseJce.getRSAPublicKeySpec(ephemeralKey);
 988         rsa_modulus = toByteArray(rsaKey.getModulus());
 989         rsa_exponent = toByteArray(rsaKey.getPublicExponent());
 990         signature = RSASignature.getInstance();
 991         signature.initSign(privateKey, sr);
 992         updateSignature(clntNonce.random_bytes, svrNonce.random_bytes);
 993         signatureBytes = signature.sign();
 994     }
 995 
 996 
 997     /*
 998      * Parse an RSA server key exchange message, using data known
 999      * to the client (and, in some situations, eavesdroppers).
1000      */
1001     RSA_ServerKeyExchange(HandshakeInStream input)
1002             throws IOException, NoSuchAlgorithmException {
1003         signature = RSASignature.getInstance();
1004         rsa_modulus = input.getBytes16();
1005         rsa_exponent = input.getBytes16();
1006         signatureBytes = input.getBytes16();
1007     }
1008 
1009     /*
1010      * Get the ephemeral RSA public key that will be used in this
1011      * SSL connection.
1012      */
1013     PublicKey getPublicKey() {
1014         try {
1015             KeyFactory kfac = JsseJce.getKeyFactory("RSA");
1016             // modulus and exponent are always positive
1017             RSAPublicKeySpec kspec = new RSAPublicKeySpec(
1018                 new BigInteger(1, rsa_modulus),
1019                 new BigInteger(1, rsa_exponent));
1020             return kfac.generatePublic(kspec);
1021         } catch (Exception e) {
1022             throw new RuntimeException(e);
1023         }
1024     }
1025 
1026     /*
1027      * Verify the signed temporary key using the hashes computed
1028      * from it and the two nonces.  This is called by clients
1029      * with "exportable" RSA flavors.
1030      */
1031     boolean verify(PublicKey certifiedKey, RandomCookie clntNonce,
1032             RandomCookie svrNonce) throws GeneralSecurityException {
1033         signature.initVerify(certifiedKey);
1034         updateSignature(clntNonce.random_bytes, svrNonce.random_bytes);
1035         return signature.verify(signatureBytes);
1036     }
1037 
1038     @Override
1039     int messageLength() {
1040         return 6 + rsa_modulus.length + rsa_exponent.length
1041                + signatureBytes.length;
1042     }
1043 
1044     @Override
1045     void send(HandshakeOutStream s) throws IOException {
1046         s.putBytes16(rsa_modulus);
1047         s.putBytes16(rsa_exponent);
1048         s.putBytes16(signatureBytes);
1049     }
1050 
1051     @Override
1052     void print(PrintStream s) throws IOException {
1053         s.println("*** RSA ServerKeyExchange");
1054 
1055         if (debug != null && Debug.isOn("verbose")) {
1056             Debug.println(s, "RSA Modulus", rsa_modulus);
1057             Debug.println(s, "RSA Public Exponent", rsa_exponent);
1058         }
1059     }
1060 }
1061 
1062 
1063 /*
1064  * Using Diffie-Hellman algorithm for key exchange.  All we really need to
1065  * do is securely get Diffie-Hellman keys (using the same P, G parameters)
1066  * to our peer, then we automatically have a shared secret without need
1067  * to exchange any more data.  (D-H only solutions, such as SKIP, could
1068  * eliminate key exchange negotiations and get faster connection setup.
1069  * But they still need a signature algorithm like DSS/DSA to support the
1070  * trusted distribution of keys without relying on unscalable physical
1071  * key distribution systems.)
1072  *
1073  * This class supports several DH-based key exchange algorithms, though
1074  * perhaps eventually each deserves its own class.  Notably, this has
1075  * basic support for DH_anon and its DHE_DSS and DHE_RSA signed variants.
1076  */
1077 static final
1078 class DH_ServerKeyExchange extends ServerKeyExchange
1079 {
1080     // Fix message encoding, see 4348279
1081     private static final boolean dhKeyExchangeFix =
1082         Debug.getBooleanProperty("com.sun.net.ssl.dhKeyExchangeFix", true);
1083 
1084     private byte[]                dh_p;        // 1 to 2^16 - 1 bytes
1085     private byte[]                dh_g;        // 1 to 2^16 - 1 bytes
1086     private byte[]                dh_Ys;       // 1 to 2^16 - 1 bytes
1087 
1088     private byte[]                signature;
1089 
1090     // protocol version being established using this ServerKeyExchange message
1091     ProtocolVersion protocolVersion;
1092 
1093     // the preferable signature algorithm used by this ServerKeyExchange message
1094     private SignatureAndHashAlgorithm preferableSignatureAlgorithm;
1095 
1096     /*
1097      * Construct from initialized DH key object, for DH_anon
1098      * key exchange.
1099      */
1100     DH_ServerKeyExchange(DHCrypt obj, ProtocolVersion protocolVersion) {
1101         this.protocolVersion = protocolVersion;
1102         this.preferableSignatureAlgorithm = null;
1103 
1104         // The DH key has been validated in the constructor of DHCrypt.
1105         setValues(obj);
1106         signature = null;
1107     }
1108 
1109     /*
1110      * Construct from initialized DH key object and the key associated
1111      * with the cert chain which was sent ... for DHE_DSS and DHE_RSA
1112      * key exchange.  (Constructor called by server.)
1113      */
1114     DH_ServerKeyExchange(DHCrypt obj, PrivateKey key, byte[] clntNonce,
1115             byte[] svrNonce, SecureRandom sr,
1116             SignatureAndHashAlgorithm signAlgorithm,
1117             ProtocolVersion protocolVersion) throws GeneralSecurityException {
1118 
1119         this.protocolVersion = protocolVersion;
1120 
1121         // The DH key has been validated in the constructor of DHCrypt.
1122         setValues(obj);
1123 
1124         Signature sig;
1125         if (protocolVersion.useTLS12PlusSpec()) {
1126             this.preferableSignatureAlgorithm = signAlgorithm;
1127             sig = JsseJce.getSignature(signAlgorithm.getAlgorithmName());
1128         } else {
1129             this.preferableSignatureAlgorithm = null;
1130             if (key.getAlgorithm().equals("DSA")) {
1131                 sig = JsseJce.getSignature(JsseJce.SIGNATURE_DSA);
1132             } else {
1133                 sig = RSASignature.getInstance();
1134             }
1135         }
1136 
1137         sig.initSign(key, sr);
1138         updateSignature(sig, clntNonce, svrNonce);
1139         signature = sig.sign();
1140     }
1141 
1142     /*
1143      * Construct a DH_ServerKeyExchange message from an input
1144      * stream, as if sent from server to client for use with
1145      * DH_anon key exchange
1146      */
1147     DH_ServerKeyExchange(HandshakeInStream input,
1148             ProtocolVersion protocolVersion)
1149             throws IOException, GeneralSecurityException {
1150 
1151         this.protocolVersion = protocolVersion;
1152         this.preferableSignatureAlgorithm = null;
1153 
1154         dh_p = input.getBytes16();
1155         dh_g = input.getBytes16();
1156         dh_Ys = input.getBytes16();
1157         KeyUtil.validate(new DHPublicKeySpec(new BigInteger(1, dh_Ys),
1158                                              new BigInteger(1, dh_p),
1159                                              new BigInteger(1, dh_g)));
1160 
1161         signature = null;
1162     }
1163 
1164     /*
1165      * Construct a DH_ServerKeyExchange message from an input stream
1166      * and a certificate, as if sent from server to client for use with
1167      * DHE_DSS or DHE_RSA key exchange.  (Called by client.)
1168      */
1169     DH_ServerKeyExchange(HandshakeInStream input, PublicKey publicKey,
1170             byte[] clntNonce, byte[] svrNonce, int messageSize,
1171             Collection<SignatureAndHashAlgorithm> localSupportedSignAlgs,
1172             ProtocolVersion protocolVersion)
1173             throws IOException, GeneralSecurityException {
1174 
1175         this.protocolVersion = protocolVersion;
1176 
1177         // read params: ServerDHParams
1178         dh_p = input.getBytes16();
1179         dh_g = input.getBytes16();
1180         dh_Ys = input.getBytes16();
1181         KeyUtil.validate(new DHPublicKeySpec(new BigInteger(1, dh_Ys),
1182                                              new BigInteger(1, dh_p),
1183                                              new BigInteger(1, dh_g)));
1184 
1185         // read the signature and hash algorithm
1186         if (protocolVersion.useTLS12PlusSpec()) {
1187             int hash = input.getInt8();         // hash algorithm
1188             int signature = input.getInt8();    // signature algorithm
1189 
1190             preferableSignatureAlgorithm =
1191                 SignatureAndHashAlgorithm.valueOf(hash, signature, 0);
1192 
1193             // Is it a local supported signature algorithm?
1194             if (!localSupportedSignAlgs.contains(
1195                     preferableSignatureAlgorithm)) {
1196                 throw new SSLHandshakeException(
1197                     "Unsupported SignatureAndHashAlgorithm in " +
1198                     "ServerKeyExchange message: " +
1199                     preferableSignatureAlgorithm);
1200             }
1201         } else {
1202             this.preferableSignatureAlgorithm = null;
1203         }
1204 
1205         // read the signature
1206         byte[] signature;
1207         if (dhKeyExchangeFix) {
1208             signature = input.getBytes16();
1209         } else {
1210             messageSize -= (dh_p.length + 2);
1211             messageSize -= (dh_g.length + 2);
1212             messageSize -= (dh_Ys.length + 2);
1213 
1214             signature = new byte[messageSize];
1215             input.read(signature);
1216         }
1217 
1218         Signature sig;
1219         String algorithm = publicKey.getAlgorithm();
1220         if (protocolVersion.useTLS12PlusSpec()) {
1221             sig = JsseJce.getSignature(
1222                         preferableSignatureAlgorithm.getAlgorithmName());
1223         } else {
1224                 switch (algorithm) {
1225                     case "DSA":
1226                         sig = JsseJce.getSignature(JsseJce.SIGNATURE_DSA);
1227                         break;
1228                     case "RSA":
1229                         sig = RSASignature.getInstance();
1230                         break;
1231                     default:
1232                         throw new SSLKeyException(
1233                             "neither an RSA or a DSA key: " + algorithm);
1234                 }
1235         }
1236 
1237         sig.initVerify(publicKey);
1238         updateSignature(sig, clntNonce, svrNonce);
1239 
1240         if (sig.verify(signature) == false ) {
1241             throw new SSLKeyException("Server D-H key verification failed");
1242         }
1243     }
1244 
1245     /* Return the Diffie-Hellman modulus */
1246     BigInteger getModulus() {
1247         return new BigInteger(1, dh_p);
1248     }
1249 
1250     /* Return the Diffie-Hellman base/generator */
1251     BigInteger getBase() {
1252         return new BigInteger(1, dh_g);
1253     }
1254 
1255     /* Return the server's Diffie-Hellman public key */
1256     BigInteger getServerPublicKey() {
1257         return new BigInteger(1, dh_Ys);
1258     }
1259 
1260     /*
1261      * Update sig with nonces and Diffie-Hellman public key.
1262      */
1263     private void updateSignature(Signature sig, byte[] clntNonce,
1264             byte[] svrNonce) throws SignatureException {
1265         int tmp;
1266 
1267         sig.update(clntNonce);
1268         sig.update(svrNonce);
1269 
1270         tmp = dh_p.length;
1271         sig.update((byte)(tmp >> 8));
1272         sig.update((byte)(tmp & 0x0ff));
1273         sig.update(dh_p);
1274 
1275         tmp = dh_g.length;
1276         sig.update((byte)(tmp >> 8));
1277         sig.update((byte)(tmp & 0x0ff));
1278         sig.update(dh_g);
1279 
1280         tmp = dh_Ys.length;
1281         sig.update((byte)(tmp >> 8));
1282         sig.update((byte)(tmp & 0x0ff));
1283         sig.update(dh_Ys);
1284     }
1285 
1286     private void setValues(DHCrypt obj) {
1287         dh_p = toByteArray(obj.getModulus());
1288         dh_g = toByteArray(obj.getBase());
1289         dh_Ys = toByteArray(obj.getPublicKey());
1290     }
1291 
1292     @Override
1293     int messageLength() {
1294         int temp = 6;   // overhead for p, g, y(s) values.
1295 
1296         temp += dh_p.length;
1297         temp += dh_g.length;
1298         temp += dh_Ys.length;
1299 
1300         if (signature != null) {
1301             if (protocolVersion.useTLS12PlusSpec()) {
1302                 temp += SignatureAndHashAlgorithm.sizeInRecord();
1303             }
1304 
1305             temp += signature.length;
1306             if (dhKeyExchangeFix) {
1307                 temp += 2;
1308             }
1309         }
1310 
1311         return temp;
1312     }
1313 
1314     @Override
1315     void send(HandshakeOutStream s) throws IOException {
1316         s.putBytes16(dh_p);
1317         s.putBytes16(dh_g);
1318         s.putBytes16(dh_Ys);
1319 
1320         if (signature != null) {
1321             if (protocolVersion.useTLS12PlusSpec()) {
1322                 s.putInt8(preferableSignatureAlgorithm.getHashValue());
1323                 s.putInt8(preferableSignatureAlgorithm.getSignatureValue());
1324             }
1325 
1326             if (dhKeyExchangeFix) {
1327                 s.putBytes16(signature);
1328             } else {
1329                 s.write(signature);
1330             }
1331         }
1332     }
1333 
1334     @Override
1335     void print(PrintStream s) throws IOException {
1336         s.println("*** Diffie-Hellman ServerKeyExchange");
1337 
1338         if (debug != null && Debug.isOn("verbose")) {
1339             Debug.println(s, "DH Modulus", dh_p);
1340             Debug.println(s, "DH Base", dh_g);
1341             Debug.println(s, "Server DH Public Key", dh_Ys);
1342 
1343             if (signature == null) {
1344                 s.println("Anonymous");
1345             } else {
1346                 if (protocolVersion.useTLS12PlusSpec()) {
1347                     s.println("Signature Algorithm " +
1348                         preferableSignatureAlgorithm.getAlgorithmName());
1349                 }
1350 
1351                 s.println("Signed with a DSA or RSA public key");
1352             }
1353         }
1354     }
1355 }
1356 
1357 /*
1358  * ECDH server key exchange message. Sent by the server for ECDHE and ECDH_anon
1359  * ciphersuites to communicate its ephemeral public key (including the
1360  * EC domain parameters).
1361  *
1362  * We support named curves only, no explicitly encoded curves.
1363  */
1364 static final
1365 class ECDH_ServerKeyExchange extends ServerKeyExchange {
1366 
1367     // constants for ECCurveType
1368     private static final int CURVE_EXPLICIT_PRIME = 1;
1369     private static final int CURVE_EXPLICIT_CHAR2 = 2;
1370     private static final int CURVE_NAMED_CURVE    = 3;
1371 
1372     // id of the curve we are using
1373     private int curveId;
1374     // encoded public point
1375     private byte[] pointBytes;
1376 
1377     // signature bytes (or null if anonymous)
1378     private byte[] signatureBytes;
1379 
1380     // public key object encapsulated in this message
1381     private ECPublicKey publicKey;
1382 
1383     // protocol version being established using this ServerKeyExchange message
1384     ProtocolVersion protocolVersion;
1385 
1386     // the preferable signature algorithm used by this ServerKeyExchange message
1387     private SignatureAndHashAlgorithm preferableSignatureAlgorithm;
1388 
1389     ECDH_ServerKeyExchange(ECDHCrypt obj, PrivateKey privateKey,
1390             byte[] clntNonce, byte[] svrNonce, SecureRandom sr,
1391             SignatureAndHashAlgorithm signAlgorithm,
1392             ProtocolVersion protocolVersion) throws GeneralSecurityException {
1393 
1394         this.protocolVersion = protocolVersion;
1395 
1396         publicKey = (ECPublicKey)obj.getPublicKey();
1397         ECParameterSpec params = publicKey.getParams();
1398         ECPoint point = publicKey.getW();
1399         pointBytes = JsseJce.encodePoint(point, params.getCurve());
1400         curveId = EllipticCurvesExtension.getCurveIndex(params);
1401 
1402         if (privateKey == null) {
1403             // ECDH_anon
1404             return;
1405         }
1406 
1407         Signature sig;
1408         if (protocolVersion.useTLS12PlusSpec()) {
1409             this.preferableSignatureAlgorithm = signAlgorithm;
1410             sig = JsseJce.getSignature(signAlgorithm.getAlgorithmName());
1411         } else {
1412             sig = getSignature(privateKey.getAlgorithm());
1413         }
1414         sig.initSign(privateKey);  // where is the SecureRandom?
1415 
1416         updateSignature(sig, clntNonce, svrNonce);
1417         signatureBytes = sig.sign();
1418     }
1419 
1420     /*
1421      * Parse an ECDH server key exchange message.
1422      */
1423     ECDH_ServerKeyExchange(HandshakeInStream input, PublicKey signingKey,
1424             byte[] clntNonce, byte[] svrNonce,
1425             Collection<SignatureAndHashAlgorithm> localSupportedSignAlgs,
1426             ProtocolVersion protocolVersion)
1427             throws IOException, GeneralSecurityException {
1428 
1429         this.protocolVersion = protocolVersion;
1430 
1431         // read params: ServerECDHParams
1432         int curveType = input.getInt8();
1433         ECParameterSpec parameters;
1434         // These parsing errors should never occur as we negotiated
1435         // the supported curves during the exchange of the Hello messages.
1436         if (curveType == CURVE_NAMED_CURVE) {
1437             curveId = input.getInt16();
1438             if (!EllipticCurvesExtension.isSupported(curveId)) {
1439                 throw new SSLHandshakeException(
1440                     "Unsupported curveId: " + curveId);
1441             }
1442             String curveOid = EllipticCurvesExtension.getCurveOid(curveId);
1443             if (curveOid == null) {
1444                 throw new SSLHandshakeException(
1445                     "Unknown named curve: " + curveId);
1446             }
1447             parameters = JsseJce.getECParameterSpec(curveOid);
1448             if (parameters == null) {
1449                 throw new SSLHandshakeException(
1450                     "Unsupported curve: " + curveOid);
1451             }
1452         } else {
1453             throw new SSLHandshakeException(
1454                 "Unsupported ECCurveType: " + curveType);
1455         }
1456         pointBytes = input.getBytes8();
1457 
1458         ECPoint point = JsseJce.decodePoint(pointBytes, parameters.getCurve());
1459         KeyFactory factory = JsseJce.getKeyFactory("EC");
1460         publicKey = (ECPublicKey)factory.generatePublic(
1461             new ECPublicKeySpec(point, parameters));
1462 
1463         if (signingKey == null) {
1464             // ECDH_anon
1465             return;
1466         }
1467 
1468         // read the signature and hash algorithm
1469         if (protocolVersion.useTLS12PlusSpec()) {
1470             int hash = input.getInt8();         // hash algorithm
1471             int signature = input.getInt8();    // signature algorithm
1472 
1473             preferableSignatureAlgorithm =
1474                 SignatureAndHashAlgorithm.valueOf(hash, signature, 0);
1475 
1476             // Is it a local supported signature algorithm?
1477             if (!localSupportedSignAlgs.contains(
1478                     preferableSignatureAlgorithm)) {
1479                 throw new SSLHandshakeException(
1480                         "Unsupported SignatureAndHashAlgorithm in " +
1481                         "ServerKeyExchange message: " +
1482                         preferableSignatureAlgorithm);
1483             }
1484         }
1485 
1486         // read the signature
1487         signatureBytes = input.getBytes16();
1488 
1489         // verify the signature
1490         Signature sig;
1491         if (protocolVersion.useTLS12PlusSpec()) {
1492             sig = JsseJce.getSignature(
1493                         preferableSignatureAlgorithm.getAlgorithmName());
1494         } else {
1495             sig = getSignature(signingKey.getAlgorithm());
1496         }
1497         sig.initVerify(signingKey);
1498 
1499         updateSignature(sig, clntNonce, svrNonce);
1500 
1501         if (sig.verify(signatureBytes) == false ) {
1502             throw new SSLKeyException(
1503                 "Invalid signature on ECDH server key exchange message");
1504         }
1505     }
1506 
1507     /*
1508      * Get the ephemeral EC public key encapsulated in this message.
1509      */
1510     ECPublicKey getPublicKey() {
1511         return publicKey;
1512     }
1513 
1514     private static Signature getSignature(String keyAlgorithm)
1515             throws NoSuchAlgorithmException {
1516             switch (keyAlgorithm) {
1517                 case "EC":
1518                     return JsseJce.getSignature(JsseJce.SIGNATURE_ECDSA);
1519                 case "RSA":
1520                     return RSASignature.getInstance();
1521                 default:
1522                     throw new NoSuchAlgorithmException(
1523                         "neither an RSA or a EC key : " + keyAlgorithm);
1524             }
1525     }
1526 
1527     private void updateSignature(Signature sig, byte[] clntNonce,
1528             byte[] svrNonce) throws SignatureException {
1529         sig.update(clntNonce);
1530         sig.update(svrNonce);
1531 
1532         sig.update((byte)CURVE_NAMED_CURVE);
1533         sig.update((byte)(curveId >> 8));
1534         sig.update((byte)curveId);
1535         sig.update((byte)pointBytes.length);
1536         sig.update(pointBytes);
1537     }
1538 
1539     @Override
1540     int messageLength() {
1541         int sigLen = 0;
1542         if (signatureBytes != null) {
1543             sigLen = 2 + signatureBytes.length;
1544             if (protocolVersion.useTLS12PlusSpec()) {
1545                 sigLen += SignatureAndHashAlgorithm.sizeInRecord();
1546             }
1547         }
1548 
1549         return 4 + pointBytes.length + sigLen;
1550     }
1551 
1552     @Override
1553     void send(HandshakeOutStream s) throws IOException {
1554         s.putInt8(CURVE_NAMED_CURVE);
1555         s.putInt16(curveId);
1556         s.putBytes8(pointBytes);
1557 
1558         if (signatureBytes != null) {
1559             if (protocolVersion.useTLS12PlusSpec()) {
1560                 s.putInt8(preferableSignatureAlgorithm.getHashValue());
1561                 s.putInt8(preferableSignatureAlgorithm.getSignatureValue());
1562             }
1563 
1564             s.putBytes16(signatureBytes);
1565         }
1566     }
1567 
1568     @Override
1569     void print(PrintStream s) throws IOException {
1570         s.println("*** ECDH ServerKeyExchange");
1571 
1572         if (debug != null && Debug.isOn("verbose")) {
1573             if (signatureBytes == null) {
1574                 s.println("Anonymous");
1575             } else {
1576                 if (protocolVersion.useTLS12PlusSpec()) {
1577                     s.println("Signature Algorithm " +
1578                             preferableSignatureAlgorithm.getAlgorithmName());
1579                 }
1580             }
1581 
1582             s.println("Server key: " + publicKey);
1583         }
1584     }
1585 }
1586 
1587 static final class DistinguishedName {
1588 
1589     /*
1590      * DER encoded distinguished name.
1591      * TLS requires that its not longer than 65535 bytes.
1592      */
1593     byte[] name;
1594 
1595     DistinguishedName(HandshakeInStream input) throws IOException {
1596         name = input.getBytes16();
1597     }
1598 
1599     DistinguishedName(X500Principal dn) {
1600         name = dn.getEncoded();
1601     }
1602 
1603     X500Principal getX500Principal() throws IOException {
1604         try {
1605             return new X500Principal(name);
1606         } catch (IllegalArgumentException e) {
1607             throw (SSLProtocolException)new SSLProtocolException(
1608                 e.getMessage()).initCause(e);
1609         }
1610     }
1611 
1612     int length() {
1613         return 2 + name.length;
1614     }
1615 
1616     void send(HandshakeOutStream output) throws IOException {
1617         output.putBytes16(name);
1618     }
1619 
1620     void print(PrintStream output) throws IOException {
1621         X500Principal principal = new X500Principal(name);
1622         output.println("<" + principal.toString() + ">");
1623     }
1624 }
1625 
1626 /*
1627  * CertificateRequest ... SERVER --> CLIENT
1628  *
1629  * Authenticated servers may ask clients to authenticate themselves
1630  * in turn, using this message.
1631  *
1632  * Prior to TLS 1.2, the structure of the message is defined as:
1633  *     struct {
1634  *         ClientCertificateType certificate_types<1..2^8-1>;
1635  *         DistinguishedName certificate_authorities<0..2^16-1>;
1636  *     } CertificateRequest;
1637  *
1638  * In TLS 1.2, the structure is changed to:
1639  *     struct {
1640  *         ClientCertificateType certificate_types<1..2^8-1>;
1641  *         SignatureAndHashAlgorithm
1642  *           supported_signature_algorithms<2^16-1>;
1643  *         DistinguishedName certificate_authorities<0..2^16-1>;
1644  *     } CertificateRequest;
1645  *
1646  */
1647 static final
1648 class CertificateRequest extends HandshakeMessage
1649 {
1650     // enum ClientCertificateType
1651     static final int   cct_rsa_sign = 1;
1652     static final int   cct_dss_sign = 2;
1653     static final int   cct_rsa_fixed_dh = 3;
1654     static final int   cct_dss_fixed_dh = 4;
1655 
1656     // The existance of these two values is a bug in the SSL specification.
1657     // They are never used in the protocol.
1658     static final int   cct_rsa_ephemeral_dh = 5;
1659     static final int   cct_dss_ephemeral_dh = 6;
1660 
1661     // From RFC 4492 (ECC)
1662     static final int    cct_ecdsa_sign       = 64;
1663     static final int    cct_rsa_fixed_ecdh   = 65;
1664     static final int    cct_ecdsa_fixed_ecdh = 66;
1665 
1666     private static final byte[] TYPES_NO_ECC = { cct_rsa_sign, cct_dss_sign };
1667     private static final byte[] TYPES_ECC =
1668         { cct_rsa_sign, cct_dss_sign, cct_ecdsa_sign };
1669 
1670     byte[]                types;               // 1 to 255 types
1671     DistinguishedName[]   authorities;         // 3 to 2^16 - 1
1672         // ... "3" because that's the smallest DER-encoded X500 DN
1673 
1674     // protocol version being established using this CertificateRequest message
1675     ProtocolVersion protocolVersion;
1676 
1677     // supported_signature_algorithms for TLS 1.2 or later
1678     private Collection<SignatureAndHashAlgorithm> algorithms;
1679 
1680     // length of supported_signature_algorithms
1681     private int algorithmsLen;
1682 
1683     CertificateRequest(X509Certificate[] ca, KeyExchange keyExchange,
1684             Collection<SignatureAndHashAlgorithm> signAlgs,
1685             ProtocolVersion protocolVersion) throws IOException {
1686 
1687         this.protocolVersion = protocolVersion;
1688 
1689         // always use X500Principal
1690         authorities = new DistinguishedName[ca.length];
1691         for (int i = 0; i < ca.length; i++) {
1692             X500Principal x500Principal = ca[i].getSubjectX500Principal();
1693             authorities[i] = new DistinguishedName(x500Principal);
1694         }
1695         // we support RSA, DSS, and ECDSA client authentication and they
1696         // can be used with all ciphersuites. If this changes, the code
1697         // needs to be adapted to take keyExchange into account.
1698         // We only request ECDSA client auth if we have ECC crypto available.
1699         this.types = JsseJce.isEcAvailable() ? TYPES_ECC : TYPES_NO_ECC;
1700 
1701         // Use supported_signature_algorithms for TLS 1.2 or later.
1702         if (protocolVersion.useTLS12PlusSpec()) {
1703             if (signAlgs == null || signAlgs.isEmpty()) {
1704                 throw new SSLProtocolException(
1705                         "No supported signature algorithms");
1706             }
1707 
1708             algorithms = new ArrayList<SignatureAndHashAlgorithm>(signAlgs);
1709             algorithmsLen =
1710                 SignatureAndHashAlgorithm.sizeInRecord() * algorithms.size();
1711         } else {
1712             algorithms = new ArrayList<SignatureAndHashAlgorithm>();
1713             algorithmsLen = 0;
1714         }
1715     }
1716 
1717     CertificateRequest(HandshakeInStream input,
1718             ProtocolVersion protocolVersion) throws IOException {
1719 
1720         this.protocolVersion = protocolVersion;
1721 
1722         // Read the certificate_types.
1723         types = input.getBytes8();
1724 
1725         // Read the supported_signature_algorithms for TLS 1.2 or later.
1726         if (protocolVersion.useTLS12PlusSpec()) {
1727             algorithmsLen = input.getInt16();
1728             if (algorithmsLen < 2) {
1729                 throw new SSLProtocolException(
1730                     "Invalid supported_signature_algorithms field: " +
1731                     algorithmsLen);
1732             }
1733 
1734             algorithms = new ArrayList<SignatureAndHashAlgorithm>();
1735             int remains = algorithmsLen;
1736             int sequence = 0;
1737             while (remains > 1) {    // needs at least two bytes
1738                 int hash = input.getInt8();         // hash algorithm
1739                 int signature = input.getInt8();    // signature algorithm
1740 
1741                 SignatureAndHashAlgorithm algorithm =
1742                     SignatureAndHashAlgorithm.valueOf(hash, signature,
1743                                                                 ++sequence);
1744                 algorithms.add(algorithm);
1745                 remains -= 2;  // one byte for hash, one byte for signature
1746             }
1747 
1748             if (remains != 0) {
1749                 throw new SSLProtocolException(
1750                     "Invalid supported_signature_algorithms field. remains: " +
1751                     remains);
1752             }
1753         } else {
1754             algorithms = new ArrayList<SignatureAndHashAlgorithm>();
1755             algorithmsLen = 0;
1756         }
1757 
1758         // read the certificate_authorities
1759         int len = input.getInt16();
1760         ArrayList<DistinguishedName> v = new ArrayList<>();
1761         while (len >= 3) {
1762             DistinguishedName dn = new DistinguishedName(input);
1763             v.add(dn);
1764             len -= dn.length();
1765         }
1766 
1767         if (len != 0) {
1768             throw new SSLProtocolException(
1769                 "Bad CertificateRequest DN length: " + len);
1770         }
1771 
1772         authorities = v.toArray(new DistinguishedName[v.size()]);
1773     }
1774 
1775     X500Principal[] getAuthorities() throws IOException {
1776         X500Principal[] ret = new X500Principal[authorities.length];
1777         for (int i = 0; i < authorities.length; i++) {
1778             ret[i] = authorities[i].getX500Principal();
1779         }
1780         return ret;
1781     }
1782 
1783     Collection<SignatureAndHashAlgorithm> getSignAlgorithms() {
1784         return algorithms;
1785     }
1786 
1787     @Override
1788     int messageType() {
1789         return ht_certificate_request;
1790     }
1791 
1792     @Override
1793     int messageLength() {
1794         int len = 1 + types.length + 2;
1795 
1796         if (protocolVersion.useTLS12PlusSpec()) {
1797             len += algorithmsLen + 2;
1798         }
1799 
1800         for (int i = 0; i < authorities.length; i++) {
1801             len += authorities[i].length();
1802         }
1803 
1804         return len;
1805     }
1806 
1807     @Override
1808     void send(HandshakeOutStream output) throws IOException {
1809         // put certificate_types
1810         output.putBytes8(types);
1811 
1812         // put supported_signature_algorithms
1813         if (protocolVersion.useTLS12PlusSpec()) {
1814             output.putInt16(algorithmsLen);
1815             for (SignatureAndHashAlgorithm algorithm : algorithms) {
1816                 output.putInt8(algorithm.getHashValue());      // hash
1817                 output.putInt8(algorithm.getSignatureValue()); // signature
1818             }
1819         }
1820 
1821         // put certificate_authorities
1822         int len = 0;
1823         for (int i = 0; i < authorities.length; i++) {
1824             len += authorities[i].length();
1825         }
1826 
1827         output.putInt16(len);
1828         for (int i = 0; i < authorities.length; i++) {
1829             authorities[i].send(output);
1830         }
1831     }
1832 
1833     @Override
1834     void print(PrintStream s) throws IOException {
1835         s.println("*** CertificateRequest");
1836 
1837         if (debug != null && Debug.isOn("verbose")) {
1838             s.print("Cert Types: ");
1839             for (int i = 0; i < types.length; i++) {
1840                 switch (types[i]) {
1841                   case cct_rsa_sign:
1842                     s.print("RSA"); break;
1843                   case cct_dss_sign:
1844                     s.print("DSS"); break;
1845                   case cct_rsa_fixed_dh:
1846                     s.print("Fixed DH (RSA sig)"); break;
1847                   case cct_dss_fixed_dh:
1848                     s.print("Fixed DH (DSS sig)"); break;
1849                   case cct_rsa_ephemeral_dh:
1850                     s.print("Ephemeral DH (RSA sig)"); break;
1851                   case cct_dss_ephemeral_dh:
1852                     s.print("Ephemeral DH (DSS sig)"); break;
1853                   case cct_ecdsa_sign:
1854                     s.print("ECDSA"); break;
1855                   case cct_rsa_fixed_ecdh:
1856                     s.print("Fixed ECDH (RSA sig)"); break;
1857                   case cct_ecdsa_fixed_ecdh:
1858                     s.print("Fixed ECDH (ECDSA sig)"); break;
1859                   default:
1860                     s.print("Type-" + (types[i] & 0xff)); break;
1861                 }
1862                 if (i != types.length - 1) {
1863                     s.print(", ");
1864                 }
1865             }
1866             s.println();
1867 
1868             if (protocolVersion.useTLS12PlusSpec()) {
1869                 StringBuilder sb = new StringBuilder();
1870                 boolean opened = false;
1871                 for (SignatureAndHashAlgorithm signAlg : algorithms) {
1872                     if (opened) {
1873                         sb.append(", ").append(signAlg.getAlgorithmName());
1874                     } else {
1875                         sb.append(signAlg.getAlgorithmName());
1876                         opened = true;
1877                     }
1878                 }
1879                 s.println("Supported Signature Algorithms: " + sb);
1880             }
1881 
1882             s.println("Cert Authorities:");
1883             if (authorities.length == 0) {
1884                 s.println("<Empty>");
1885             } else {
1886                 for (int i = 0; i < authorities.length; i++) {
1887                     authorities[i].print(s);
1888                 }
1889             }
1890         }
1891     }
1892 }
1893 
1894 
1895 /*
1896  * ServerHelloDone ... SERVER --> CLIENT
1897  *
1898  * When server's done sending its messages in response to the client's
1899  * "hello" (e.g. its own hello, certificate, key exchange message, perhaps
1900  * client certificate request) it sends this message to flag that it's
1901  * done that part of the handshake.
1902  */
1903 static final
1904 class ServerHelloDone extends HandshakeMessage
1905 {
1906     @Override
1907     int messageType() { return ht_server_hello_done; }
1908 
1909     ServerHelloDone() { }
1910 
1911     ServerHelloDone(HandshakeInStream input)
1912     {
1913         // nothing to do
1914     }
1915 
1916     @Override
1917     int messageLength()
1918     {
1919         return 0;
1920     }
1921 
1922     @Override
1923     void send(HandshakeOutStream s) throws IOException
1924     {
1925         // nothing to send
1926     }
1927 
1928     @Override
1929     void print(PrintStream s) throws IOException
1930     {
1931         s.println("*** ServerHelloDone");
1932     }
1933 }
1934 
1935 
1936 /*
1937  * CertificateVerify ... CLIENT --> SERVER
1938  *
1939  * Sent after client sends signature-capable certificates (e.g. not
1940  * Diffie-Hellman) to verify.
1941  */
1942 static final class CertificateVerify extends HandshakeMessage {
1943 
1944     // the signature bytes
1945     private byte[] signature;
1946 
1947     // protocol version being established using this CertificateVerify message
1948     ProtocolVersion protocolVersion;
1949 
1950     // the preferable signature algorithm used by this CertificateVerify message
1951     private SignatureAndHashAlgorithm preferableSignatureAlgorithm = null;
1952 
1953     /*
1954      * Create an RSA or DSA signed certificate verify message.
1955      */
1956     CertificateVerify(ProtocolVersion protocolVersion,
1957             HandshakeHash handshakeHash, PrivateKey privateKey,
1958             SecretKey masterSecret, SecureRandom sr,
1959             SignatureAndHashAlgorithm signAlgorithm)
1960             throws GeneralSecurityException {
1961 
1962         this.protocolVersion = protocolVersion;
1963 
1964         String algorithm = privateKey.getAlgorithm();
1965         Signature sig = null;
1966         if (protocolVersion.useTLS12PlusSpec()) {
1967             this.preferableSignatureAlgorithm = signAlgorithm;
1968             sig = JsseJce.getSignature(signAlgorithm.getAlgorithmName());
1969         } else {
1970             sig = getSignature(protocolVersion, algorithm);
1971         }
1972         sig.initSign(privateKey, sr);
1973         updateSignature(sig, protocolVersion, handshakeHash, algorithm,
1974                         masterSecret);
1975         signature = sig.sign();
1976     }
1977 
1978     //
1979     // Unmarshal the signed data from the input stream.
1980     //
1981     CertificateVerify(HandshakeInStream input,
1982             Collection<SignatureAndHashAlgorithm> localSupportedSignAlgs,
1983             ProtocolVersion protocolVersion) throws IOException  {
1984 
1985         this.protocolVersion = protocolVersion;
1986 
1987         // read the signature and hash algorithm
1988         if (protocolVersion.useTLS12PlusSpec()) {
1989             int hashAlg = input.getInt8();         // hash algorithm
1990             int signAlg = input.getInt8();         // signature algorithm
1991 
1992             preferableSignatureAlgorithm =
1993                 SignatureAndHashAlgorithm.valueOf(hashAlg, signAlg, 0);
1994 
1995             // Is it a local supported signature algorithm?
1996             if (!localSupportedSignAlgs.contains(
1997                     preferableSignatureAlgorithm)) {
1998                 throw new SSLHandshakeException(
1999                     "Unsupported SignatureAndHashAlgorithm in " +
2000                     "CertificateVerify message: " + preferableSignatureAlgorithm);
2001             }
2002         }
2003 
2004         // read the signature
2005         signature = input.getBytes16();
2006     }
2007 
2008     /*
2009      * Get the preferable signature algorithm used by this message
2010      */
2011     SignatureAndHashAlgorithm getPreferableSignatureAlgorithm() {
2012         return preferableSignatureAlgorithm;
2013     }
2014 
2015     /*
2016      * Verify a certificate verify message. Return the result of verification,
2017      * if there is a problem throw a GeneralSecurityException.
2018      */
2019     boolean verify(ProtocolVersion protocolVersion,
2020             HandshakeHash handshakeHash, PublicKey publicKey,
2021             SecretKey masterSecret) throws GeneralSecurityException {
2022         String algorithm = publicKey.getAlgorithm();
2023         Signature sig = null;
2024         if (protocolVersion.useTLS12PlusSpec()) {
2025             sig = JsseJce.getSignature(
2026                         preferableSignatureAlgorithm.getAlgorithmName());
2027         } else {
2028             sig = getSignature(protocolVersion, algorithm);
2029         }
2030         sig.initVerify(publicKey);
2031         updateSignature(sig, protocolVersion, handshakeHash, algorithm,
2032                         masterSecret);
2033         return sig.verify(signature);
2034     }
2035 
2036     /*
2037      * Get the Signature object appropriate for verification using the
2038      * given signature algorithm and protocol version.
2039      */
2040     private static Signature getSignature(ProtocolVersion protocolVersion,
2041             String algorithm) throws GeneralSecurityException {
2042             switch (algorithm) {
2043                 case "RSA":
2044                     return RSASignature.getInternalInstance();
2045                 case "DSA":
2046                     return JsseJce.getSignature(JsseJce.SIGNATURE_RAWDSA);
2047                 case "EC":
2048                     return JsseJce.getSignature(JsseJce.SIGNATURE_RAWECDSA);
2049                 default:
2050                     throw new SignatureException("Unrecognized algorithm: "
2051                         + algorithm);
2052             }
2053     }
2054 
2055     /*
2056      * Update the Signature with the data appropriate for the given
2057      * signature algorithm and protocol version so that the object is
2058      * ready for signing or verifying.
2059      */
2060     private static void updateSignature(Signature sig,
2061             ProtocolVersion protocolVersion,
2062             HandshakeHash handshakeHash, String algorithm, SecretKey masterKey)
2063             throws SignatureException {
2064 
2065         if (algorithm.equals("RSA")) {
2066             if (!protocolVersion.useTLS12PlusSpec()) {  // TLS1.1-
2067                 MessageDigest md5Clone = handshakeHash.getMD5Clone();
2068                 MessageDigest shaClone = handshakeHash.getSHAClone();
2069 
2070                 if (!protocolVersion.useTLS10PlusSpec()) {  // SSLv3
2071                     updateDigest(md5Clone, MD5_pad1, MD5_pad2, masterKey);
2072                     updateDigest(shaClone, SHA_pad1, SHA_pad2, masterKey);
2073                 }
2074 
2075                 // The signature must be an instance of RSASignature, need
2076                 // to use these hashes directly.
2077                 RSASignature.setHashes(sig, md5Clone, shaClone);
2078             } else {  // TLS1.2+
2079                 sig.update(handshakeHash.getAllHandshakeMessages());
2080             }
2081         } else { // DSA, ECDSA
2082             if (!protocolVersion.useTLS12PlusSpec()) {  // TLS1.1-
2083                 MessageDigest shaClone = handshakeHash.getSHAClone();
2084 
2085                 if (!protocolVersion.useTLS10PlusSpec()) {  // SSLv3
2086                     updateDigest(shaClone, SHA_pad1, SHA_pad2, masterKey);
2087                 }
2088 
2089                 sig.update(shaClone.digest());
2090             } else {  // TLS1.2+
2091                 sig.update(handshakeHash.getAllHandshakeMessages());
2092             }
2093         }
2094     }
2095 
2096     /*
2097      * Update the MessageDigest for SSLv3 certificate verify or finished
2098      * message calculation. The digest must already have been updated with
2099      * all preceding handshake messages.
2100      * Used by the Finished class as well.
2101      */
2102     private static void updateDigest(MessageDigest md,
2103             byte[] pad1, byte[] pad2,
2104             SecretKey masterSecret) {
2105         // Digest the key bytes if available.
2106         // Otherwise (sensitive key), try digesting the key directly.
2107         // That is currently only implemented in SunPKCS11 using a private
2108         // reflection API, so we avoid that if possible.
2109         byte[] keyBytes = "RAW".equals(masterSecret.getFormat())
2110                         ? masterSecret.getEncoded() : null;
2111         if (keyBytes != null) {
2112             md.update(keyBytes);
2113         } else {
2114             digestKey(md, masterSecret);
2115         }
2116         md.update(pad1);
2117         byte[] temp = md.digest();
2118 
2119         if (keyBytes != null) {
2120             md.update(keyBytes);
2121         } else {
2122             digestKey(md, masterSecret);
2123         }
2124         md.update(pad2);
2125         md.update(temp);
2126     }
2127 
2128     private static void digestKey(MessageDigest md, SecretKey key) {
2129         try {
2130             if (md instanceof MessageDigestSpi2) {
2131                 ((MessageDigestSpi2)md).engineUpdate(key);
2132             } else {
2133                 throw new Exception(
2134                     "Digest does not support implUpdate(SecretKey)");
2135             }
2136         } catch (Exception e) {
2137             throw new RuntimeException(
2138                 "Could not obtain encoded key and "
2139                 + "MessageDigest cannot digest key", e);
2140         }
2141     }
2142 
2143     @Override
2144     int messageType() {
2145         return ht_certificate_verify;
2146     }
2147 
2148     @Override
2149     int messageLength() {
2150         int temp = 2;
2151 
2152         if (protocolVersion.useTLS12PlusSpec()) {
2153             temp += SignatureAndHashAlgorithm.sizeInRecord();
2154         }
2155 
2156         return temp + signature.length;
2157     }
2158 
2159     @Override
2160     void send(HandshakeOutStream s) throws IOException {
2161         if (protocolVersion.useTLS12PlusSpec()) {
2162             s.putInt8(preferableSignatureAlgorithm.getHashValue());
2163             s.putInt8(preferableSignatureAlgorithm.getSignatureValue());
2164         }
2165 
2166         s.putBytes16(signature);
2167     }
2168 
2169     @Override
2170     void print(PrintStream s) throws IOException {
2171         s.println("*** CertificateVerify");
2172 
2173         if (debug != null && Debug.isOn("verbose")) {
2174             if (protocolVersion.useTLS12PlusSpec()) {
2175                 s.println("Signature Algorithm " +
2176                         preferableSignatureAlgorithm.getAlgorithmName());
2177             }
2178         }
2179     }
2180 }
2181 
2182 
2183 /*
2184  * FINISHED ... sent by both CLIENT and SERVER
2185  *
2186  * This is the FINISHED message as defined in the SSL and TLS protocols.
2187  * Both protocols define this handshake message slightly differently.
2188  * This class supports both formats.
2189  *
2190  * When handshaking is finished, each side sends a "change_cipher_spec"
2191  * record, then immediately sends a "finished" handshake message prepared
2192  * according to the newly adopted cipher spec.
2193  *
2194  * NOTE that until this is sent, no application data may be passed, unless
2195  * some non-default cipher suite has already been set up on this connection
2196  * connection (e.g. a previous handshake arranged one).
2197  */
2198 static final class Finished extends HandshakeMessage {
2199 
2200     // constant for a Finished message sent by the client
2201     static final int CLIENT = 1;
2202 
2203     // constant for a Finished message sent by the server
2204     static final int SERVER = 2;
2205 
2206     // enum Sender:  "CLNT" and "SRVR"
2207     private static final byte[] SSL_CLIENT = { 0x43, 0x4C, 0x4E, 0x54 };
2208     private static final byte[] SSL_SERVER = { 0x53, 0x52, 0x56, 0x52 };
2209 
2210     /*
2211      * Contents of the finished message ("checksum"). For TLS, it
2212      * is 12 bytes long, for SSLv3 36 bytes.
2213      */
2214     private byte[] verifyData;
2215 
2216     /*
2217      * Current cipher suite we are negotiating.  TLS 1.2 has
2218      * ciphersuite-defined PRF algorithms.
2219      */
2220     private ProtocolVersion protocolVersion;
2221     private CipherSuite cipherSuite;
2222 
2223     /*
2224      * Create a finished message to send to the remote peer.
2225      */
2226     Finished(ProtocolVersion protocolVersion, HandshakeHash handshakeHash,
2227             int sender, SecretKey master, CipherSuite cipherSuite) {
2228         this.protocolVersion = protocolVersion;
2229         this.cipherSuite = cipherSuite;
2230         verifyData = getFinished(handshakeHash, sender, master);
2231     }
2232 
2233     /*
2234      * Constructor that reads FINISHED message from stream.
2235      */
2236     Finished(ProtocolVersion protocolVersion, HandshakeInStream input,
2237             CipherSuite cipherSuite) throws IOException {
2238         this.protocolVersion = protocolVersion;
2239         this.cipherSuite = cipherSuite;
2240         int msgLen = protocolVersion.useTLS10PlusSpec() ?  12 : 36;
2241         verifyData = new byte[msgLen];
2242         input.read(verifyData);
2243     }
2244 
2245     /*
2246      * Verify that the hashes here are what would have been produced
2247      * according to a given set of inputs.  This is used to ensure that
2248      * both client and server are fully in sync, and that the handshake
2249      * computations have been successful.
2250      */
2251     boolean verify(HandshakeHash handshakeHash, int sender, SecretKey master) {
2252         byte[] myFinished = getFinished(handshakeHash, sender, master);
2253         return MessageDigest.isEqual(myFinished, verifyData);
2254     }
2255 
2256     /*
2257      * Perform the actual finished message calculation.
2258      */
2259     private byte[] getFinished(HandshakeHash handshakeHash,
2260             int sender, SecretKey masterKey) {
2261         byte[] sslLabel;
2262         String tlsLabel;
2263         if (sender == CLIENT) {
2264             sslLabel = SSL_CLIENT;
2265             tlsLabel = "client finished";
2266         } else if (sender == SERVER) {
2267             sslLabel = SSL_SERVER;
2268             tlsLabel = "server finished";
2269         } else {
2270             throw new RuntimeException("Invalid sender: " + sender);
2271         }
2272 
2273         if (protocolVersion.useTLS10PlusSpec()) {
2274             // TLS 1.0+
2275             try {
2276                 byte[] seed;
2277                 String prfAlg;
2278                 PRF prf;
2279 
2280                 // Get the KeyGenerator alg and calculate the seed.
2281                 if (protocolVersion.useTLS12PlusSpec()) {
2282                     // TLS 1.2+ or DTLS 1.2+
2283                     seed = handshakeHash.getFinishedHash();
2284 
2285                     prfAlg = "SunTls12Prf";
2286                     prf = cipherSuite.prfAlg;
2287                 } else {
2288                     // TLS 1.0/1.1, DTLS 1.0
2289                     MessageDigest md5Clone = handshakeHash.getMD5Clone();
2290                     MessageDigest shaClone = handshakeHash.getSHAClone();
2291                     seed = new byte[36];
2292                     md5Clone.digest(seed, 0, 16);
2293                     shaClone.digest(seed, 16, 20);
2294 
2295                     prfAlg = "SunTlsPrf";
2296                     prf = P_NONE;
2297                 }
2298 
2299                 String prfHashAlg = prf.getPRFHashAlg();
2300                 int prfHashLength = prf.getPRFHashLength();
2301                 int prfBlockSize = prf.getPRFBlockSize();
2302 
2303                 /*
2304                  * RFC 5246/7.4.9 says that finished messages can
2305                  * be ciphersuite-specific in both length/PRF hash
2306                  * algorithm.  If we ever run across a different
2307                  * length, this call will need to be updated.
2308                  */
2309                 @SuppressWarnings("deprecation")
2310                 TlsPrfParameterSpec spec = new TlsPrfParameterSpec(
2311                     masterKey, tlsLabel, seed, 12,
2312                     prfHashAlg, prfHashLength, prfBlockSize);
2313 
2314                 KeyGenerator kg = JsseJce.getKeyGenerator(prfAlg);
2315                 kg.init(spec);
2316                 SecretKey prfKey = kg.generateKey();
2317                 if ("RAW".equals(prfKey.getFormat()) == false) {
2318                     throw new ProviderException(
2319                         "Invalid PRF output, format must be RAW. " +
2320                         "Format received: " + prfKey.getFormat());
2321                 }
2322                 byte[] finished = prfKey.getEncoded();
2323                 return finished;
2324             } catch (GeneralSecurityException e) {
2325                 throw new RuntimeException("PRF failed", e);
2326             }
2327         } else {
2328             // SSLv3
2329             MessageDigest md5Clone = handshakeHash.getMD5Clone();
2330             MessageDigest shaClone = handshakeHash.getSHAClone();
2331             updateDigest(md5Clone, sslLabel, MD5_pad1, MD5_pad2, masterKey);
2332             updateDigest(shaClone, sslLabel, SHA_pad1, SHA_pad2, masterKey);
2333             byte[] finished = new byte[36];
2334             try {
2335                 md5Clone.digest(finished, 0, 16);
2336                 shaClone.digest(finished, 16, 20);
2337             } catch (DigestException e) {
2338                 // cannot occur
2339                 throw new RuntimeException("Digest failed", e);
2340             }
2341             return finished;
2342         }
2343     }
2344 
2345     /*
2346      * Update the MessageDigest for SSLv3 finished message calculation.
2347      * The digest must already have been updated with all preceding handshake
2348      * messages. This operation is almost identical to the certificate verify
2349      * hash, reuse that code.
2350      */
2351     private static void updateDigest(MessageDigest md, byte[] sender,
2352             byte[] pad1, byte[] pad2, SecretKey masterSecret) {
2353         md.update(sender);
2354         CertificateVerify.updateDigest(md, pad1, pad2, masterSecret);
2355     }
2356 
2357     // get the verify_data of the finished message
2358     byte[] getVerifyData() {
2359         return verifyData;
2360     }
2361 
2362     @Override
2363     int messageType() { return ht_finished; }
2364 
2365     @Override
2366     int messageLength() {
2367         return verifyData.length;
2368     }
2369 
2370     @Override
2371     void send(HandshakeOutStream out) throws IOException {
2372         out.write(verifyData);
2373     }
2374 
2375     @Override
2376     void print(PrintStream s) throws IOException {
2377         s.println("*** Finished");
2378         if (debug != null && Debug.isOn("verbose")) {
2379             Debug.println(s, "verify_data", verifyData);
2380             s.println("***");
2381         }
2382     }
2383 }
2384 
2385 //
2386 // END of nested classes
2387 //
2388 
2389 }