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