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 
26 package sun.security.ssl;
27 
28 import java.io.*;
29 import java.math.BigInteger;
30 import java.security.*;
31 import java.security.interfaces.*;
32 import java.security.spec.*;
33 import java.security.cert.*;
34 import java.security.cert.Certificate;
35 import java.util.*;
36 import java.util.concurrent.ConcurrentHashMap;
37 
38 import java.lang.reflect.*;
39 
40 import javax.security.auth.x500.X500Principal;
41 
42 import javax.crypto.KeyGenerator;
43 import javax.crypto.SecretKey;
44 import javax.crypto.spec.DHPublicKeySpec;
45 
46 import javax.net.ssl.*;
47 
48 import sun.security.internal.spec.TlsPrfParameterSpec;
49 import sun.security.ssl.CipherSuite.*;
50 import static sun.security.ssl.CipherSuite.PRF.*;
51 import sun.security.util.KeyUtil;
52 
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  */
74 public abstract class HandshakeMessage {
75 
HandshakeMessage()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      */
toByteArray(BigInteger bi)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 
genPad(int b, int count)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      */
write(HandshakeOutStream s)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      */
messageType()150     abstract int  messageType();
messageLength()151     abstract int  messageLength();
send(HandshakeOutStream s)152     abstract void send(HandshakeOutStream s) throws IOException;
153 
154     /*
155      * Write a descriptive message on the output stream; for debugging.
156      */
print(PrintStream p)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  */
174 static final class HelloRequest extends HandshakeMessage {
messageType()175     int messageType() { return ht_hello_request; }
176 
HelloRequest()177     HelloRequest() { }
178 
HelloRequest(HandshakeInStream in)179     HelloRequest(HandshakeInStream in) throws IOException
180     {
181         // nothing in this message
182     }
183 
messageLength()184     int messageLength() { return 0; }
185 
send(HandshakeOutStream out)186     void send(HandshakeOutStream out) throws IOException
187     {
188         // nothing in this messaage
189     }
190 
print(PrintStream out)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  */
210 static 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 
ClientHello(SecureRandom generator, ProtocolVersion protocolVersion, SessionId sessionId, CipherSuiteList cipherSuites)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 
ClientHello(HandshakeInStream s, int messageLength)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 
getCipherSuites()249     CipherSuiteList getCipherSuites() {
250         return cipherSuites;
251     }
252 
253     // add renegotiation_info extension
addRenegotiationInfoExtension(byte[] clientVerifyData)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
addServerNameIndicationExtension(String hostname)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
addSignatureAlgorithmsExtension( Collection<SignatureAndHashAlgorithm> algorithms)274     void addSignatureAlgorithmsExtension(
275             Collection<SignatureAndHashAlgorithm> algorithms) {
276         HelloExtension signatureAlgorithm =
277                 new SignatureAlgorithmsExtension(algorithms);
278         extensions.add(signatureAlgorithm);
279     }
280 
281     @Override
messageType()282     int messageType() { return ht_client_hello; }
283 
284     @Override
messageLength()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
send(HandshakeOutStream s)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
print(PrintStream s)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  */
335 static final
336 class ServerHello extends HandshakeMessage
337 {
messageType()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 
ServerHello()347     ServerHello() {
348         // empty
349     }
350 
ServerHello(HandshakeInStream input, int messageLength)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 
messageLength()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 
send(HandshakeOutStream s)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 
print(PrintStream s)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  */
422 static final
423 class CertificateMsg extends HandshakeMessage
424 {
messageType()425     int messageType() { return ht_certificate; }
426 
427     private X509Certificate[] chain;
428 
429     private List<byte[]> encodedChain;
430 
431     private int messageLength;
432 
CertificateMsg(X509Certificate[] certs)433     CertificateMsg(X509Certificate[] certs) {
434         chain = certs;
435     }
436 
CertificateMsg(HandshakeInStream input)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 
messageLength()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 
send(HandshakeOutStream s)477     void send(HandshakeOutStream s) throws IOException {
478         s.putInt24(messageLength() - 3);
479         for (byte[] b : encodedChain) {
480             s.putBytes24(b);
481         }
482     }
483 
print(PrintStream s)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 
getCertificateChain()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  */
535 static abstract class ServerKeyExchange extends HandshakeMessage
536 {
messageType()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  */
549 static final
550 class 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      */
updateSignature(byte clntNonce[], byte svrNonce[])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      */
RSA_ServerKeyExchange(PublicKey ephemeralKey, PrivateKey privateKey, RandomCookie clntNonce, RandomCookie svrNonce, SecureRandom sr)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      */
RSA_ServerKeyExchange(HandshakeInStream input)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      */
getPublicKey()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      */
verify(PublicKey certifiedKey, RandomCookie clntNonce, RandomCookie svrNonce)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 
messageLength()644     int messageLength() {
645         return 6 + rsa_modulus.length + rsa_exponent.length
646                + signatureBytes.length;
647     }
648 
send(HandshakeOutStream s)649     void send(HandshakeOutStream s) throws IOException {
650         s.putBytes16(rsa_modulus);
651         s.putBytes16(rsa_exponent);
652         s.putBytes16(signatureBytes);
653     }
654 
print(PrintStream s)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  */
680 static final
681 class 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      */
DH_ServerKeyExchange(DHCrypt obj, ProtocolVersion protocolVersion)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      */
DH_ServerKeyExchange(DHCrypt obj, PrivateKey key, byte clntNonce[], byte svrNonce[], SecureRandom sr, SignatureAndHashAlgorithm signAlgorithm, ProtocolVersion protocolVersion)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      */
DH_ServerKeyExchange(HandshakeInStream input, ProtocolVersion protocolVersion)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      */
DH_ServerKeyExchange(HandshakeInStream input, PublicKey publicKey, byte clntNonce[], byte svrNonce[], int messageSize, Collection<SignatureAndHashAlgorithm> localSupportedSignAlgs, ProtocolVersion protocolVersion)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 */
getModulus()844     BigInteger getModulus() {
845         return new BigInteger(1, dh_p);
846     }
847 
848     /* Return the Diffie-Hellman base/generator */
getBase()849     BigInteger getBase() {
850         return new BigInteger(1, dh_g);
851     }
852 
853     /* Return the server's Diffie-Hellman public key */
getServerPublicKey()854     BigInteger getServerPublicKey() {
855         return new BigInteger(1, dh_Ys);
856     }
857 
858     /*
859      * Update sig with nonces and Diffie-Hellman public key.
860      */
updateSignature(Signature sig, byte clntNonce[], byte svrNonce[])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 
setValues(DHCrypt obj)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 
messageLength()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 
send(HandshakeOutStream s)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 
print(PrintStream s)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  */
959 static final
960 class 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 
ECDH_ServerKeyExchange(ECDHCrypt obj, PrivateKey privateKey, byte[] clntNonce, byte[] svrNonce, SecureRandom sr, SignatureAndHashAlgorithm signAlgorithm, ProtocolVersion protocolVersion)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      */
ECDH_ServerKeyExchange(HandshakeInStream input, PublicKey signingKey, byte[] clntNonce, byte[] svrNonce, Collection<SignatureAndHashAlgorithm> localSupportedSignAlgs, ProtocolVersion protocolVersion)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      */
getPublicKey()1106     ECPublicKey getPublicKey() {
1107         return publicKey;
1108     }
1109 
getSignature(String keyAlgorithm)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 
updateSignature(Signature sig, byte clntNonce[], byte svrNonce[])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 
messageLength()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 
send(HandshakeOutStream s)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 
print(PrintStream s)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 
1178 static 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 
DistinguishedName(HandshakeInStream input)1186     DistinguishedName(HandshakeInStream input) throws IOException {
1187         name = input.getBytes16();
1188     }
1189 
DistinguishedName(X500Principal dn)1190     DistinguishedName(X500Principal dn) {
1191         name = dn.getEncoded();
1192     }
1193 
getX500Principal()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 
length()1203     int length() {
1204         return 2 + name.length;
1205     }
1206 
send(HandshakeOutStream output)1207     void send(HandshakeOutStream output) throws IOException {
1208         output.putBytes16(name);
1209     }
1210 
print(PrintStream output)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  */
1238 static final
1239 class 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 
CertificateRequest(X509Certificate ca[], KeyExchange keyExchange, Collection<SignatureAndHashAlgorithm> signAlgs, ProtocolVersion protocolVersion)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 
CertificateRequest(HandshakeInStream input, ProtocolVersion protocolVersion)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 
getAuthorities()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 
getSignAlgorithms()1371     Collection<SignatureAndHashAlgorithm> getSignAlgorithms() {
1372         return algorithms;
1373     }
1374 
1375     @Override
messageType()1376     int messageType() {
1377         return ht_certificate_request;
1378     }
1379 
1380     @Override
messageLength()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
send(HandshakeOutStream output)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
print(PrintStream s)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  */
1491 static final
1492 class ServerHelloDone extends HandshakeMessage
1493 {
messageType()1494     int messageType() { return ht_server_hello_done; }
1495 
ServerHelloDone()1496     ServerHelloDone() { }
1497 
ServerHelloDone(HandshakeInStream input)1498     ServerHelloDone(HandshakeInStream input)
1499     {
1500         // nothing to do
1501     }
1502 
messageLength()1503     int messageLength()
1504     {
1505         return 0;
1506     }
1507 
send(HandshakeOutStream s)1508     void send(HandshakeOutStream s) throws IOException
1509     {
1510         // nothing to send
1511     }
1512 
print(PrintStream s)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  */
1526 static 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      */
CertificateVerify(ProtocolVersion protocolVersion, HandshakeHash handshakeHash, PrivateKey privateKey, SecretKey masterSecret, SecureRandom sr, SignatureAndHashAlgorithm signAlgorithm)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     //
CertificateVerify(HandshakeInStream input, Collection<SignatureAndHashAlgorithm> localSupportedSignAlgs, ProtocolVersion protocolVersion)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      */
getPreferableSignatureAlgorithm()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      */
verify(ProtocolVersion protocolVersion, HandshakeHash handshakeHash, PublicKey publicKey, SecretKey masterSecret)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      */
getSignature(ProtocolVersion protocolVersion, String algorithm)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      */
updateSignature(Signature sig, ProtocolVersion protocolVersion, HandshakeHash handshakeHash, String algorithm, SecretKey masterKey)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      */
updateDigest(MessageDigest md, byte[] pad1, byte[] pad2, SecretKey masterSecret)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 
makeAccessible(final AccessibleObject o)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 
digestKey(MessageDigest md, SecretKey key)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
messageType()1775     int messageType() {
1776         return ht_certificate_verify;
1777     }
1778 
1779     @Override
messageLength()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
send(HandshakeOutStream s)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
print(PrintStream s)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  */
1829 static 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      */
Finished(ProtocolVersion protocolVersion, HandshakeHash handshakeHash, int sender, SecretKey master, CipherSuite cipherSuite)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      */
Finished(ProtocolVersion protocolVersion, HandshakeInStream input, CipherSuite cipherSuite)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      */
verify(HandshakeHash handshakeHash, int sender, SecretKey master)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      */
getFinished(HandshakeHash handshakeHash, int sender, SecretKey masterKey)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      */
updateDigest(MessageDigest md, byte[] sender, byte[] pad1, byte[] pad2, SecretKey masterSecret)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
getVerifyData()1987     byte[] getVerifyData() {
1988         return verifyData;
1989     }
1990 
1991     @Override
messageType()1992     int messageType() { return ht_finished; }
1993 
1994     @Override
messageLength()1995     int messageLength() {
1996         return verifyData.length;
1997     }
1998 
1999     @Override
send(HandshakeOutStream out)2000     void send(HandshakeOutStream out) throws IOException {
2001         out.write(verifyData);
2002     }
2003 
2004     @Override
print(PrintStream s)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