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