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