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