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