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