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