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