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
26package sun.security.ssl;
27
28import java.io.*;
29import java.math.BigInteger;
30import java.security.*;
31import java.security.interfaces.*;
32import java.security.spec.*;
33import java.security.cert.*;
34import java.security.cert.Certificate;
35import java.util.*;
36import java.util.concurrent.ConcurrentHashMap;
37
38import java.lang.reflect.*;
39
40import javax.security.auth.x500.X500Principal;
41
42import javax.crypto.KeyGenerator;
43import javax.crypto.SecretKey;
44import javax.crypto.spec.DHPublicKeySpec;
45
46import javax.net.ssl.*;
47
48import sun.security.internal.spec.TlsPrfParameterSpec;
49import sun.security.ssl.CipherSuite.*;
50import static sun.security.ssl.CipherSuite.PRF.*;
51import sun.security.util.KeyUtil;
52import sun.security.util.MessageDigestSpi2;
53import 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 */
76public 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 */
207static 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 */
250static 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 */
310static 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 */
505static final
506class 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 */
595static final
596class 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 */
692static 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 */
949abstract 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 */
964static final
965class 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 */
1098static final
1099class 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 */
1385static final
1386class 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
1624static 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 */
1684static final
1685class 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 */
1940static final
1941class 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 */
1979static 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 */
2235static 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}
2427