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