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