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