History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/sun/security/ssl/Handshaker.java (1 of 18352 files). Show all

Unified · Split

java/pkg/sun/security/ssl/Handshaker.java+1386−0
@@ -0,0 +1,1386 @@
1/*
2 * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26
27package sun.security.ssl;
28
29import java.io.*;
30import java.util.*;
31import java.security.*;
32import java.security.NoSuchAlgorithmException;
33import java.security.AccessController;
34import java.security.AlgorithmConstraints;
35import java.security.AccessControlContext;
36import java.security.PrivilegedExceptionAction;
37import java.security.PrivilegedActionException;
38
39import javax.crypto.*;
40import javax.crypto.spec.*;
41
42import javax.net.ssl.*;
43import sun.misc.HexDumpEncoder;
44
45import sun.security.internal.spec.*;
46import sun.security.internal.interfaces.TlsMasterSecret;
47
48import sun.security.ssl.HandshakeMessage.*;
49import sun.security.ssl.CipherSuite.*;
50
51import static sun.security.ssl.CipherSuite.PRF.*;
52
53/**
54 * Handshaker ... processes handshake records from an SSL V3.0
55 * data stream, handling all the details of the handshake protocol.
56 *
57 * Note that the real protocol work is done in two subclasses, the base
58 * class just provides the control flow and key generation framework.
59 *
60 * @author David Brownell
61 */
62abstract class Handshaker {
63
64 // protocol version being established using this Handshaker
65 ProtocolVersion protocolVersion;
66
67 // the currently active protocol version during a renegotiation
68 ProtocolVersion activeProtocolVersion;
69
70 // security parameters for secure renegotiation.
71 boolean secureRenegotiation;
72 byte[] clientVerifyData;
73 byte[] serverVerifyData;
74
75 // Is it an initial negotiation or a renegotiation?
76 boolean isInitialHandshake;
77
78 // List of enabled protocols
79 private ProtocolList enabledProtocols;
80
81 // List of enabled CipherSuites
82 private CipherSuiteList enabledCipherSuites;
83
84 // The endpoint identification protocol
85 String identificationProtocol;
86
87 // The cryptographic algorithm constraints
88 private AlgorithmConstraints algorithmConstraints = null;
89
90 // Local supported signature and algorithms
91 Collection<SignatureAndHashAlgorithm> localSupportedSignAlgs;
92
93 // Peer supported signature and algorithms
94 Collection<SignatureAndHashAlgorithm> peerSupportedSignAlgs;
95
96 /*
97
98 /*
99 * List of active protocols
100 *
101 * Active protocols is a subset of enabled protocols, and will
102 * contain only those protocols that have vaild cipher suites
103 * enabled.
104 */
105 private ProtocolList activeProtocols;
106
107 /*
108 * List of active cipher suites
109 *
110 * Active cipher suites is a subset of enabled cipher suites, and will
111 * contain only those cipher suites available for the active protocols.
112 */
113 private CipherSuiteList activeCipherSuites;
114
115 private boolean isClient;
116 private boolean needCertVerify;
117
118 SSLSocketImpl conn = null;
119 SSLEngineImpl engine = null;
120
121 HandshakeHash handshakeHash;
122 HandshakeInStream input;
123 HandshakeOutStream output;
124 int state;
125 SSLContextImpl sslContext;
126 RandomCookie clnt_random, svr_random;
127 SSLSessionImpl session;
128
129 // current CipherSuite. Never null, initially SSL_NULL_WITH_NULL_NULL
130 CipherSuite cipherSuite;
131
132 // current key exchange. Never null, initially K_NULL
133 KeyExchange keyExchange;
134
135 /* True if this session is being resumed (fast handshake) */
136 boolean resumingSession;
137
138 /* True if it's OK to start a new SSL session */
139 boolean enableNewSession;
140
141 // Temporary storage for the individual keys. Set by
142 // calculateConnectionKeys() and cleared once the ciphers are
143 // activated.
144 private SecretKey clntWriteKey, svrWriteKey;
145 private IvParameterSpec clntWriteIV, svrWriteIV;
146 private SecretKey clntMacSecret, svrMacSecret;
147
148 /*
149 * Delegated task subsystem data structures.
150 *
151 * If thrown is set, we need to propagate this back immediately
152 * on entry into processMessage().
153 *
154 * Data is protected by the SSLEngine.this lock.
155 */
156 private volatile boolean taskDelegated = false;
157 private volatile DelegatedTask delegatedTask = null;
158 private volatile Exception thrown = null;
159
160 // Could probably use a java.util.concurrent.atomic.AtomicReference
161 // here instead of using this lock. Consider changing.
162 private Object thrownLock = new Object();
163
164 /* Class and subclass dynamic debugging support */
165 static final Debug debug = Debug.getInstance("ssl");
166
167 // By default, disable the unsafe legacy session renegotiation
168 static final boolean allowUnsafeRenegotiation = Debug.getBooleanProperty(
169 "sun.security.ssl.allowUnsafeRenegotiation", false);
170
171 // For maximum interoperability and backward compatibility, RFC 5746
172 // allows server (or client) to accept ClientHello (or ServerHello)
173 // message without the secure renegotiation_info extension or SCSV.
174 //
175 // For maximum security, RFC 5746 also allows server (or client) to
176 // reject such message with a fatal "handshake_failure" alert.
177 //
178 // By default, allow such legacy hello messages.
179 static final boolean allowLegacyHelloMessages = Debug.getBooleanProperty(
180 "sun.security.ssl.allowLegacyHelloMessages", true);
181
182 // need to dispose the object when it is invalidated
183 boolean invalidated;
184
185 Handshaker(SSLSocketImpl c, SSLContextImpl context,
186 ProtocolList enabledProtocols, boolean needCertVerify,
187 boolean isClient, ProtocolVersion activeProtocolVersion,
188 boolean isInitialHandshake, boolean secureRenegotiation,
189 byte[] clientVerifyData, byte[] serverVerifyData) {
190 this.conn = c;
191 init(context, enabledProtocols, needCertVerify, isClient,
192 activeProtocolVersion, isInitialHandshake, secureRenegotiation,
193 clientVerifyData, serverVerifyData);
194 }
195
196 Handshaker(SSLEngineImpl engine, SSLContextImpl context,
197 ProtocolList enabledProtocols, boolean needCertVerify,
198 boolean isClient, ProtocolVersion activeProtocolVersion,
199 boolean isInitialHandshake, boolean secureRenegotiation,
200 byte[] clientVerifyData, byte[] serverVerifyData) {
201 this.engine = engine;
202 init(context, enabledProtocols, needCertVerify, isClient,
203 activeProtocolVersion, isInitialHandshake, secureRenegotiation,
204 clientVerifyData, serverVerifyData);
205 }
206
207 private void init(SSLContextImpl context, ProtocolList enabledProtocols,
208 boolean needCertVerify, boolean isClient,
209 ProtocolVersion activeProtocolVersion,
210 boolean isInitialHandshake, boolean secureRenegotiation,
211 byte[] clientVerifyData, byte[] serverVerifyData) {
212
213 if (debug != null && Debug.isOn("handshake")) {
214 System.out.println(
215 "Allow unsafe renegotiation: " + allowUnsafeRenegotiation +
216 "\nAllow legacy hello messages: " + allowLegacyHelloMessages +
217 "\nIs initial handshake: " + isInitialHandshake +
218 "\nIs secure renegotiation: " + secureRenegotiation);
219 }
220
221 this.sslContext = context;
222 this.isClient = isClient;
223 this.needCertVerify = needCertVerify;
224 this.activeProtocolVersion = activeProtocolVersion;
225 this.isInitialHandshake = isInitialHandshake;
226 this.secureRenegotiation = secureRenegotiation;
227 this.clientVerifyData = clientVerifyData;
228 this.serverVerifyData = serverVerifyData;
229 enableNewSession = true;
230 invalidated = false;
231
232 setCipherSuite(CipherSuite.C_NULL);
233 setEnabledProtocols(enabledProtocols);
234
235 if (conn != null) {
236 algorithmConstraints = new SSLAlgorithmConstraints(conn, true);
237 } else { // engine != null
238 algorithmConstraints = new SSLAlgorithmConstraints(engine, true);
239 }
240
241
242 //
243 // In addition to the connection state machine, controlling
244 // how the connection deals with the different sorts of records
245 // that get sent (notably handshake transitions!), there's
246 // also a handshaking state machine that controls message
247 // sequencing.
248 //
249 // It's a convenient artifact of the protocol that this can,
250 // with only a couple of minor exceptions, be driven by the
251 // type constant for the last message seen: except for the
252 // client's cert verify, those constants are in a convenient
253 // order to drastically simplify state machine checking.
254 //
255 state = -2; // initialized but not activated
256 }
257
258 /*
259 * Reroutes calls to the SSLSocket or SSLEngine (*SE).
260 *
261 * We could have also done it by extra classes
262 * and letting them override, but this seemed much
263 * less involved.
264 */
265 void fatalSE(byte b, String diagnostic) throws IOException {
266 fatalSE(b, diagnostic, null);
267 }
268
269 void fatalSE(byte b, Throwable cause) throws IOException {
270 fatalSE(b, null, cause);
271 }
272
273 void fatalSE(byte b, String diagnostic, Throwable cause)
274 throws IOException {
275 if (conn != null) {
276 conn.fatal(b, diagnostic, cause);
277 } else {
278 engine.fatal(b, diagnostic, cause);
279 }
280 }
281
282 void warningSE(byte b) {
283 if (conn != null) {
284 conn.warning(b);
285 } else {
286 engine.warning(b);
287 }
288 }
289
290 String getRawHostnameSE() {
291 if (conn != null) {
292 return conn.getRawHostname();
293 } else {
294 return engine.getPeerHost();
295 }
296 }
297
298 String getHostSE() {
299 if (conn != null) {
300 return conn.getHost();
301 } else {
302 return engine.getPeerHost();
303 }
304 }
305
306 String getHostAddressSE() {
307 if (conn != null) {
308 return conn.getInetAddress().getHostAddress();
309 } else {
310 /*
311 * This is for caching only, doesn't matter that's is really
312 * a hostname. The main thing is that it doesn't do
313 * a reverse DNS lookup, potentially slowing things down.
314 */
315 return engine.getPeerHost();
316 }
317 }
318
319 boolean isLoopbackSE() {
320 if (conn != null) {
321 return conn.getInetAddress().isLoopbackAddress();
322 } else {
323 return false;
324 }
325 }
326
327 int getPortSE() {
328 if (conn != null) {
329 return conn.getPort();
330 } else {
331 return engine.getPeerPort();
332 }
333 }
334
335 int getLocalPortSE() {
336 if (conn != null) {
337 return conn.getLocalPort();
338 } else {
339 return -1;
340 }
341 }
342
343 AccessControlContext getAccSE() {
344 if (conn != null) {
345 return conn.getAcc();
346 } else {
347 return engine.getAcc();
348 }
349 }
350
351 private void setVersionSE(ProtocolVersion protocolVersion) {
352 if (conn != null) {
353 conn.setVersion(protocolVersion);
354 } else {
355 engine.setVersion(protocolVersion);
356 }
357 }
358
359 /**
360 * Set the active protocol version and propagate it to the SSLSocket
361 * and our handshake streams. Called from ClientHandshaker
362 * and ServerHandshaker with the negotiated protocol version.
363 */
364 void setVersion(ProtocolVersion protocolVersion) {
365 this.protocolVersion = protocolVersion;
366 setVersionSE(protocolVersion);
367
368 output.r.setVersion(protocolVersion);
369 }
370
371 /**
372 * Set the enabled protocols. Called from the constructor or
373 * SSLSocketImpl/SSLEngineImpl.setEnabledProtocols() (if the
374 * handshake is not yet in progress).
375 */
376 void setEnabledProtocols(ProtocolList enabledProtocols) {
377 activeCipherSuites = null;
378 activeProtocols = null;
379
380 this.enabledProtocols = enabledProtocols;
381 }
382
383 /**
384 * Set the enabled cipher suites. Called from
385 * SSLSocketImpl/SSLEngineImpl.setEnabledCipherSuites() (if the
386 * handshake is not yet in progress).
387 */
388 void setEnabledCipherSuites(CipherSuiteList enabledCipherSuites) {
389 activeCipherSuites = null;
390 activeProtocols = null;
391 this.enabledCipherSuites = enabledCipherSuites;
392 }
393
394 /**
395 * Set the algorithm constraints. Called from the constructor or
396 * SSLSocketImpl/SSLEngineImpl.setAlgorithmConstraints() (if the
397 * handshake is not yet in progress).
398 */
399 void setAlgorithmConstraints(AlgorithmConstraints algorithmConstraints) {
400 activeCipherSuites = null;
401 activeProtocols = null;
402
403 this.algorithmConstraints =
404 new SSLAlgorithmConstraints(algorithmConstraints);
405 this.localSupportedSignAlgs = null;
406 }
407
408 Collection<SignatureAndHashAlgorithm> getLocalSupportedSignAlgs() {
409 if (localSupportedSignAlgs == null) {
410 localSupportedSignAlgs =
411 SignatureAndHashAlgorithm.getSupportedAlgorithms(
412 algorithmConstraints);
413 }
414
415 return localSupportedSignAlgs;
416 }
417
418 void setPeerSupportedSignAlgs(
419 Collection<SignatureAndHashAlgorithm> algorithms) {
420 peerSupportedSignAlgs =
421 new ArrayList<SignatureAndHashAlgorithm>(algorithms);
422 }
423
424 Collection<SignatureAndHashAlgorithm> getPeerSupportedSignAlgs() {
425 return peerSupportedSignAlgs;
426 }
427
428
429 /**
430 * Set the identification protocol. Called from the constructor or
431 * SSLSocketImpl/SSLEngineImpl.setIdentificationProtocol() (if the
432 * handshake is not yet in progress).
433 */
434 void setIdentificationProtocol(String protocol) {
435 this.identificationProtocol = protocol;
436 }
437
438 /**
439 * Prior to handshaking, activate the handshake and initialize the version,
440 * input stream and output stream.
441 */
442 void activate(ProtocolVersion helloVersion) throws IOException {
443 if (activeProtocols == null) {
444 activeProtocols = getActiveProtocols();
445 }
446
447 if (activeProtocols.collection().isEmpty() ||
448 activeProtocols.max.v == ProtocolVersion.NONE.v) {
449 throw new SSLHandshakeException("No appropriate protocol");
450 }
451
452 if (activeCipherSuites == null) {
453 activeCipherSuites = getActiveCipherSuites();
454 }
455
456 if (activeCipherSuites.collection().isEmpty()) {
457 throw new SSLHandshakeException("No appropriate cipher suite");
458 }
459
460 // temporary protocol version until the actual protocol version
461 // is negotiated in the Hello exchange. This affects the record
462 // version we sent with the ClientHello.
463 if (!isInitialHandshake) {
464 protocolVersion = activeProtocolVersion;
465 } else {
466 protocolVersion = activeProtocols.max;
467 }
468
469 if (helloVersion == null || helloVersion.v == ProtocolVersion.NONE.v) {
470 helloVersion = activeProtocols.helloVersion;
471 }
472
473 // We accumulate digests of the handshake messages so that
474 // we can read/write CertificateVerify and Finished messages,
475 // getting assurance against some particular active attacks.
476 Set<String> localSupportedHashAlgorithms =
477 SignatureAndHashAlgorithm.getHashAlgorithmNames(
478 getLocalSupportedSignAlgs());
479 handshakeHash = new HandshakeHash(!isClient, needCertVerify,
480 localSupportedHashAlgorithms);
481
482 // Generate handshake input/output stream.
483 input = new HandshakeInStream(handshakeHash);
484 if (conn != null) {
485 output = new HandshakeOutStream(protocolVersion, helloVersion,
486 handshakeHash, conn);
487 conn.getAppInputStream().r.setHandshakeHash(handshakeHash);
488 conn.getAppInputStream().r.setHelloVersion(helloVersion);
489 conn.getAppOutputStream().r.setHelloVersion(helloVersion);
490 } else {
491 output = new HandshakeOutStream(protocolVersion, helloVersion,
492 handshakeHash, engine);
493 engine.inputRecord.setHandshakeHash(handshakeHash);
494 engine.inputRecord.setHelloVersion(helloVersion);
495 engine.outputRecord.setHelloVersion(helloVersion);
496 }
497
498 // move state to activated
499 state = -1;
500 }
501
502 /**
503 * Set cipherSuite and keyExchange to the given CipherSuite.
504 * Does not perform any verification that this is a valid selection,
505 * this must be done before calling this method.
506 */
507 void setCipherSuite(CipherSuite s) {
508 this.cipherSuite = s;
509 this.keyExchange = s.keyExchange;
510 }
511
512 /**
513 * Check if the given ciphersuite is enabled and available.
514 * Does not check if the required server certificates are available.
515 */
516 boolean isNegotiable(CipherSuite s) {
517 if (activeCipherSuites == null) {
518 activeCipherSuites = getActiveCipherSuites();
519 }
520
521 return activeCipherSuites.contains(s) && s.isNegotiable();
522 }
523
524 /**
525 * Check if the given protocol version is enabled and available.
526 */
527 boolean isNegotiable(ProtocolVersion protocolVersion) {
528 if (activeProtocols == null) {
529 activeProtocols = getActiveProtocols();
530 }
531
532 return activeProtocols.contains(protocolVersion);
533 }
534
535 /**
536 * Select a protocol version from the list. Called from
537 * ServerHandshaker to negotiate protocol version.
538 *
539 * Return the lower of the protocol version suggested in the
540 * clien hello and the highest supported by the server.
541 */
542 ProtocolVersion selectProtocolVersion(ProtocolVersion protocolVersion) {
543 if (activeProtocols == null) {
544 activeProtocols = getActiveProtocols();
545 }
546
547 return activeProtocols.selectProtocolVersion(protocolVersion);
548 }
549
550 /**
551 * Get the active cipher suites.
552 *
553 * In TLS 1.1, many weak or vulnerable cipher suites were obsoleted,
554 * such as TLS_RSA_EXPORT_WITH_RC4_40_MD5. The implementation MUST NOT
555 * negotiate these cipher suites in TLS 1.1 or later mode.
556 *
557 * Therefore, when the active protocols only include TLS 1.1 or later,
558 * the client cannot request to negotiate those obsoleted cipher
559 * suites. That is, the obsoleted suites should not be included in the
560 * client hello. So we need to create a subset of the enabled cipher
561 * suites, the active cipher suites, which does not contain obsoleted
562 * cipher suites of the minimum active protocol.
563 *
564 * Return empty list instead of null if no active cipher suites.
565 */
566 CipherSuiteList getActiveCipherSuites() {
567 if (activeCipherSuites == null) {
568 if (activeProtocols == null) {
569 activeProtocols = getActiveProtocols();
570 }
571
572 ArrayList<CipherSuite> suites = new ArrayList<>();
573 if (!(activeProtocols.collection().isEmpty()) &&
574 activeProtocols.min.v != ProtocolVersion.NONE.v) {
575 for (CipherSuite suite : enabledCipherSuites.collection()) {
576 if (suite.obsoleted > activeProtocols.min.v &&
577 suite.supported <= activeProtocols.max.v) {
578 if (algorithmConstraints.permits(
579 EnumSet.of(CryptoPrimitive.KEY_AGREEMENT),
580 suite.name, null)) {
581 suites.add(suite);
582 }
583 } else if (debug != null && Debug.isOn("verbose")) {
584 if (suite.obsoleted <= activeProtocols.min.v) {
585 System.out.println(
586 "Ignoring obsoleted cipher suite: " + suite);
587 } else {
588 System.out.println(
589 "Ignoring unsupported cipher suite: " + suite);
590 }
591 }
592 }
593 }
594 activeCipherSuites = new CipherSuiteList(suites);
595 }
596
597 return activeCipherSuites;
598 }
599
600 /*
601 * Get the active protocol versions.
602 *
603 * In TLS 1.1, many weak or vulnerable cipher suites were obsoleted,
604 * such as TLS_RSA_EXPORT_WITH_RC4_40_MD5. The implementation MUST NOT
605 * negotiate these cipher suites in TLS 1.1 or later mode.
606 *
607 * For example, if "TLS_RSA_EXPORT_WITH_RC4_40_MD5" is the
608 * only enabled cipher suite, the client cannot request TLS 1.1 or
609 * later, even though TLS 1.1 or later is enabled. We need to create a
610 * subset of the enabled protocols, called the active protocols, which
611 * contains protocols appropriate to the list of enabled Ciphersuites.
612 *
613 * Return empty list instead of null if no active protocol versions.
614 */
615 ProtocolList getActiveProtocols() {
616 if (activeProtocols == null) {
617 ArrayList<ProtocolVersion> protocols = new ArrayList<>(4);
618 for (ProtocolVersion protocol : enabledProtocols.collection()) {
619 boolean found = false;
620 for (CipherSuite suite : enabledCipherSuites.collection()) {
621 if (suite.isAvailable() && suite.obsoleted > protocol.v &&
622 suite.supported <= protocol.v) {
623 if (algorithmConstraints.permits(
624 EnumSet.of(CryptoPrimitive.KEY_AGREEMENT),
625 suite.name, null)) {
626 protocols.add(protocol);
627 found = true;
628 break;
629 } else if (debug != null && Debug.isOn("verbose")) {
630 System.out.println(
631 "Ignoring disabled cipher suite: " + suite +
632 " for " + protocol);
633 }
634 } else if (debug != null && Debug.isOn("verbose")) {
635 System.out.println(
636 "Ignoring unsupported cipher suite: " + suite +
637 " for " + protocol);
638 }
639 }
640 if (!found && (debug != null) && Debug.isOn("handshake")) {
641 System.out.println(
642 "No available cipher suite for " + protocol);
643 }
644 }
645 activeProtocols = new ProtocolList(protocols);
646 }
647
648 return activeProtocols;
649 }
650
651 /**
652 * As long as handshaking has not activated, we can
653 * change whether session creations are allowed.
654 *
655 * Callers should do their own checking if handshaking
656 * has activated.
657 */
658 void setEnableSessionCreation(boolean newSessions) {
659 enableNewSession = newSessions;
660 }
661
662 /**
663 * Create a new read cipher and return it to caller.
664 */
665 CipherBox newReadCipher() throws NoSuchAlgorithmException {
666 BulkCipher cipher = cipherSuite.cipher;
667 CipherBox box;
668 if (isClient) {
669 box = cipher.newCipher(protocolVersion, svrWriteKey, svrWriteIV,
670 sslContext.getSecureRandom(), false);
671 svrWriteKey = null;
672 svrWriteIV = null;
673 } else {
674 box = cipher.newCipher(protocolVersion, clntWriteKey, clntWriteIV,
675 sslContext.getSecureRandom(), false);
676 clntWriteKey = null;
677 clntWriteIV = null;
678 }
679 return box;
680 }
681
682 /**
683 * Create a new write cipher and return it to caller.
684 */
685 CipherBox newWriteCipher() throws NoSuchAlgorithmException {
686 BulkCipher cipher = cipherSuite.cipher;
687 CipherBox box;
688 if (isClient) {
689 box = cipher.newCipher(protocolVersion, clntWriteKey, clntWriteIV,
690 sslContext.getSecureRandom(), true);
691 clntWriteKey = null;
692 clntWriteIV = null;
693 } else {
694 box = cipher.newCipher(protocolVersion, svrWriteKey, svrWriteIV,
695 sslContext.getSecureRandom(), true);
696 svrWriteKey = null;
697 svrWriteIV = null;
698 }
699 return box;
700 }
701
702 /**
703 * Create a new read MAC and return it to caller.
704 */
705 MAC newReadMAC() throws NoSuchAlgorithmException, InvalidKeyException {
706 MacAlg macAlg = cipherSuite.macAlg;
707 MAC mac;
708 if (isClient) {
709 mac = macAlg.newMac(protocolVersion, svrMacSecret);
710 svrMacSecret = null;
711 } else {
712 mac = macAlg.newMac(protocolVersion, clntMacSecret);
713 clntMacSecret = null;
714 }
715 return mac;
716 }
717
718 /**
719 * Create a new write MAC and return it to caller.
720 */
721 MAC newWriteMAC() throws NoSuchAlgorithmException, InvalidKeyException {
722 MacAlg macAlg = cipherSuite.macAlg;
723 MAC mac;
724 if (isClient) {
725 mac = macAlg.newMac(protocolVersion, clntMacSecret);
726 clntMacSecret = null;
727 } else {
728 mac = macAlg.newMac(protocolVersion, svrMacSecret);
729 svrMacSecret = null;
730 }
731 return mac;
732 }
733
734 /*
735 * Returns true iff the handshake sequence is done, so that
736 * this freshly created session can become the current one.
737 */
738 boolean isDone() {
739 return state == HandshakeMessage.ht_finished;
740 }
741
742
743 /*
744 * Returns the session which was created through this
745 * handshake sequence ... should be called after isDone()
746 * returns true.
747 */
748 SSLSessionImpl getSession() {
749 return session;
750 }
751
752 /*
753 * Set the handshake session
754 */
755 void setHandshakeSessionSE(SSLSessionImpl handshakeSession) {
756 if (conn != null) {
757 conn.setHandshakeSession(handshakeSession);
758 } else {
759 engine.setHandshakeSession(handshakeSession);
760 }
761 }
762
763 /*
764 * Returns true if renegotiation is in use for this connection.
765 */
766 boolean isSecureRenegotiation() {
767 return secureRenegotiation;
768 }
769
770 /*
771 * Returns the verify_data from the Finished message sent by the client.
772 */
773 byte[] getClientVerifyData() {
774 return clientVerifyData;
775 }
776
777 /*
778 * Returns the verify_data from the Finished message sent by the server.
779 */
780 byte[] getServerVerifyData() {
781 return serverVerifyData;
782 }
783
784 /*
785 * This routine is fed SSL handshake records when they become available,
786 * and processes messages found therein.
787 */
788 void process_record(InputRecord r, boolean expectingFinished)
789 throws IOException {
790
791 checkThrown();
792
793 /*
794 * Store the incoming handshake data, then see if we can
795 * now process any completed handshake messages
796 */
797 input.incomingRecord(r);
798
799 /*
800 * We don't need to create a separate delegatable task
801 * for finished messages.
802 */
803 if ((conn != null) || expectingFinished) {
804 processLoop();
805 } else {
806 delegateTask(new PrivilegedExceptionAction<Void>() {
807 public Void run() throws Exception {
808 processLoop();
809 return null;
810 }
811 });
812 }
813 }
814
815 /*
816 * On input, we hash messages one at a time since servers may need
817 * to access an intermediate hash to validate a CertificateVerify
818 * message.
819 *
820 * Note that many handshake messages can come in one record (and often
821 * do, to reduce network resource utilization), and one message can also
822 * require multiple records (e.g. very large Certificate messages).
823 */
824 void processLoop() throws IOException {
825
826 // need to read off 4 bytes at least to get the handshake
827 // message type and length.
828 while (input.available() >= 4) {
829 byte messageType;
830 int messageLen;
831
832 /*
833 * See if we can read the handshake message header, and
834 * then the entire handshake message. If not, wait till
835 * we can read and process an entire message.
836 */
837 input.mark(4);
838
839 messageType = (byte)input.getInt8();
840 messageLen = input.getInt24();
841
842 if (input.available() < messageLen) {
843 input.reset();
844 return;
845 }
846
847 /*
848 * Process the messsage. We require
849 * that processMessage() consumes the entire message. In
850 * lieu of explicit error checks (how?!) we assume that the
851 * data will look like garbage on encoding/processing errors,
852 * and that other protocol code will detect such errors.
853 *
854 * Note that digesting is normally deferred till after the
855 * message has been processed, though to process at least the
856 * client's Finished message (i.e. send the server's) we need
857 * to acccelerate that digesting.
858 *
859 * Also, note that hello request messages are never hashed;
860 * that includes the hello request header, too.
861 */
862 if (messageType == HandshakeMessage.ht_hello_request) {
863 input.reset();
864 processMessage(messageType, messageLen);
865 input.ignore(4 + messageLen);
866 } else {
867 input.mark(messageLen);
868 processMessage(messageType, messageLen);
869 input.digestNow();
870 }
871 }
872 }
873
874
875 /**
876 * Returns true iff the handshaker has been activated.
877 *
878 * In activated state, the handshaker may not send any messages out.
879 */
880 boolean activated() {
881 return state >= -1;
882 }
883
884 /**
885 * Returns true iff the handshaker has sent any messages.
886 */
887 boolean started() {
888 return state >= 0; // 0: HandshakeMessage.ht_hello_request
889 // 1: HandshakeMessage.ht_client_hello
890 }
891
892
893 /*
894 * Used to kickstart the negotiation ... either writing a
895 * ClientHello or a HelloRequest as appropriate, whichever
896 * the subclass returns. NOP if handshaking's already started.
897 */
898 void kickstart() throws IOException {
899 if (state >= 0) {
900 return;
901 }
902
903 HandshakeMessage m = getKickstartMessage();
904
905 if (debug != null && Debug.isOn("handshake")) {
906 m.print(System.out);
907 }
908 m.write(output);
909 output.flush();
910
911 state = m.messageType();
912 }
913
914 /**
915 * Both client and server modes can start handshaking; but the
916 * message they send to do so is different.
917 */
918 abstract HandshakeMessage getKickstartMessage() throws SSLException;
919
920 /*
921 * Client and Server side protocols are each driven though this
922 * call, which processes a single message and drives the appropriate
923 * side of the protocol state machine (depending on the subclass).
924 */
925 abstract void processMessage(byte messageType, int messageLen)
926 throws IOException;
927
928 /*
929 * Most alerts in the protocol relate to handshaking problems.
930 * Alerts are detected as the connection reads data.
931 */
932 abstract void handshakeAlert(byte description) throws SSLProtocolException;
933
934 /*
935 * Sends a change cipher spec message and updates the write side
936 * cipher state so that future messages use the just-negotiated spec.
937 */
938 void sendChangeCipherSpec(Finished mesg, boolean lastMessage)
939 throws IOException {
940
941 output.flush(); // i.e. handshake data
942
943 /*
944 * The write cipher state is protected by the connection write lock
945 * so we must grab it while making the change. We also
946 * make sure no writes occur between sending the ChangeCipherSpec
947 * message, installing the new cipher state, and sending the
948 * Finished message.
949 *
950 * We already hold SSLEngine/SSLSocket "this" by virtue
951 * of this being called from the readRecord code.
952 */
953 OutputRecord r;
954 if (conn != null) {
955 r = new OutputRecord(Record.ct_change_cipher_spec);
956 } else {
957 r = new EngineOutputRecord(Record.ct_change_cipher_spec, engine);
958 }
959
960 r.setVersion(protocolVersion);
961 r.write(1); // single byte of data
962
963 if (conn != null) {
964 conn.writeLock.lock();
965 try {
966 conn.writeRecord(r);
967 conn.changeWriteCiphers();
968 if (debug != null && Debug.isOn("handshake")) {
969 mesg.print(System.out);
970 }
971 mesg.write(output);
972 output.flush();
973 } finally {
974 conn.writeLock.unlock();
975 }
976 } else {
977 synchronized (engine.writeLock) {
978 engine.writeRecord((EngineOutputRecord)r);
979 engine.changeWriteCiphers();
980 if (debug != null && Debug.isOn("handshake")) {
981 mesg.print(System.out);
982 }
983 mesg.write(output);
984
985 if (lastMessage) {
986 output.setFinishedMsg();
987 }
988 output.flush();
989 }
990 }
991 }
992
993 /*
994 * Single access point to key calculation logic. Given the
995 * pre-master secret and the nonces from client and server,
996 * produce all the keying material to be used.
997 */
998 void calculateKeys(SecretKey preMasterSecret, ProtocolVersion version) {
999 SecretKey master = calculateMasterSecret(preMasterSecret, version);
1000 session.setMasterSecret(master);
1001 calculateConnectionKeys(master);
1002 }
1003
1004
1005 /*
1006 * Calculate the master secret from its various components. This is
1007 * used for key exchange by all cipher suites.
1008 *
1009 * The master secret is the catenation of three MD5 hashes, each
1010 * consisting of the pre-master secret and a SHA1 hash. Those three
1011 * SHA1 hashes are of (different) constant strings, the pre-master
1012 * secret, and the nonces provided by the client and the server.
1013 */
1014 private SecretKey calculateMasterSecret(SecretKey preMasterSecret,
1015 ProtocolVersion requestedVersion) {
1016
1017 if (debug != null && Debug.isOn("keygen")) {
1018 HexDumpEncoder dump = new HexDumpEncoder();
1019
1020 System.out.println("SESSION KEYGEN:");
1021
1022 System.out.println("PreMaster Secret:");
1023 printHex(dump, preMasterSecret.getEncoded());
1024
1025 // Nonces are dumped with connection keygen, no
1026 // benefit to doing it twice
1027 }
1028
1029 // What algs/params do we need to use?
1030 String masterAlg;
1031 PRF prf;
1032
1033 if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
1034 masterAlg = "SunTls12MasterSecret";
1035 prf = cipherSuite.prfAlg;
1036 } else {
1037 masterAlg = "SunTlsMasterSecret";
1038 prf = P_NONE;
1039 }
1040
1041 String prfHashAlg = prf.getPRFHashAlg();
1042 int prfHashLength = prf.getPRFHashLength();
1043 int prfBlockSize = prf.getPRFBlockSize();
1044
1045 TlsMasterSecretParameterSpec spec = new TlsMasterSecretParameterSpec(
1046 preMasterSecret, protocolVersion.major, protocolVersion.minor,
1047 clnt_random.random_bytes, svr_random.random_bytes,
1048 prfHashAlg, prfHashLength, prfBlockSize);
1049
1050 SecretKey masterSecret;
1051 try {
1052 KeyGenerator kg = JsseJce.getKeyGenerator(masterAlg);
1053 kg.init(spec);
1054 masterSecret = kg.generateKey();
1055 } catch (GeneralSecurityException e) {
1056 // For RSA premaster secrets, do not signal a protocol error
1057 // due to the Bleichenbacher attack. See comments further down.
1058 if (!preMasterSecret.getAlgorithm().equals(
1059 "TlsRsaPremasterSecret")) {
1060 throw new ProviderException(e);
1061 }
1062
1063 if (debug != null && Debug.isOn("handshake")) {
1064 System.out.println("RSA master secret generation error:");
1065 e.printStackTrace(System.out);
1066 System.out.println("Generating new random premaster secret");
1067 }
1068
1069 if (requestedVersion != null) {
1070 preMasterSecret =
1071 RSAClientKeyExchange.generateDummySecret(requestedVersion);
1072 } else {
1073 preMasterSecret =
1074 RSAClientKeyExchange.generateDummySecret(protocolVersion);
1075 }
1076
1077 // recursive call with new premaster secret
1078 return calculateMasterSecret(preMasterSecret, null);
1079 }
1080
1081 // if no version check requested (client side handshake), or version
1082 // information is not available (not an RSA premaster secret),
1083 // return master secret immediately.
1084 if ((requestedVersion == null) ||
1085 !(masterSecret instanceof TlsMasterSecret)) {
1086 return masterSecret;
1087 }
1088
1089 // we have checked the ClientKeyExchange message when reading TLS
1090 // record, the following check is necessary to ensure that
1091 // JCE provider does not ignore the checking, or the previous
1092 // checking process bypassed the premaster secret version checking.
1093 TlsMasterSecret tlsKey = (TlsMasterSecret)masterSecret;
1094 int major = tlsKey.getMajorVersion();
1095 int minor = tlsKey.getMinorVersion();
1096 if ((major < 0) || (minor < 0)) {
1097 return masterSecret;
1098 }
1099
1100 // check if the premaster secret version is ok
1101 // the specification says that it must be the maximum version supported
1102 // by the client from its ClientHello message. However, many
1103 // implementations send the negotiated version, so accept both
1104 // for SSL v3.0 and TLS v1.0.
1105 // NOTE that we may be comparing two unsupported version numbers, which
1106 // is why we cannot use object reference equality in this special case.
1107 ProtocolVersion premasterVersion =
1108 ProtocolVersion.valueOf(major, minor);
1109 boolean versionMismatch = (premasterVersion.v != requestedVersion.v);
1110
1111 /*
1112 * we never checked the client_version in server side
1113 * for TLS v1.0 and SSL v3.0. For compatibility, we
1114 * maintain this behavior.
1115 */
1116 if (versionMismatch && requestedVersion.v <= ProtocolVersion.TLS10.v) {
1117 versionMismatch = (premasterVersion.v != protocolVersion.v);
1118 }
1119
1120 if (versionMismatch == false) {
1121 // check passed, return key
1122 return masterSecret;
1123 }
1124
1125 // Due to the Bleichenbacher attack, do not signal a protocol error.
1126 // Generate a random premaster secret and continue with the handshake,
1127 // which will fail when verifying the finished messages.
1128 // For more information, see comments in PreMasterSecret.
1129 if (debug != null && Debug.isOn("handshake")) {
1130 System.out.println("RSA PreMasterSecret version error: expected"
1131 + protocolVersion + " or " + requestedVersion + ", decrypted: "
1132 + premasterVersion);
1133 System.out.println("Generating new random premaster secret");
1134 }
1135 preMasterSecret =
1136 RSAClientKeyExchange.generateDummySecret(requestedVersion);
1137
1138 // recursive call with new premaster secret
1139 return calculateMasterSecret(preMasterSecret, null);
1140 }
1141
1142 /*
1143 * Calculate the keys needed for this connection, once the session's
1144 * master secret has been calculated. Uses the master key and nonces;
1145 * the amount of keying material generated is a function of the cipher
1146 * suite that's been negotiated.
1147 *
1148 * This gets called both on the "full handshake" (where we exchanged
1149 * a premaster secret and started a new session) as well as on the
1150 * "fast handshake" (where we just resumed a pre-existing session).
1151 */
1152 void calculateConnectionKeys(SecretKey masterKey) {
1153 /*
1154 * For both the read and write sides of the protocol, we use the
1155 * master to generate MAC secrets and cipher keying material. Block
1156 * ciphers need initialization vectors, which we also generate.
1157 *
1158 * First we figure out how much keying material is needed.
1159 */
1160 int hashSize = cipherSuite.macAlg.size;
1161 boolean is_exportable = cipherSuite.exportable;
1162 BulkCipher cipher = cipherSuite.cipher;
1163 int expandedKeySize = is_exportable ? cipher.expandedKeySize : 0;
1164
1165 // Which algs/params do we need to use?
1166 String keyMaterialAlg;
1167 PRF prf;
1168
1169 if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
1170 keyMaterialAlg = "SunTls12KeyMaterial";
1171 prf = cipherSuite.prfAlg;
1172 } else {
1173 keyMaterialAlg = "SunTlsKeyMaterial";
1174 prf = P_NONE;
1175 }
1176
1177 String prfHashAlg = prf.getPRFHashAlg();
1178 int prfHashLength = prf.getPRFHashLength();
1179 int prfBlockSize = prf.getPRFBlockSize();
1180
1181 TlsKeyMaterialParameterSpec spec = new TlsKeyMaterialParameterSpec(
1182 masterKey, protocolVersion.major, protocolVersion.minor,
1183 clnt_random.random_bytes, svr_random.random_bytes,
1184 cipher.algorithm, cipher.keySize, expandedKeySize,
1185 cipher.ivSize, hashSize,
1186 prfHashAlg, prfHashLength, prfBlockSize);
1187
1188 try {
1189 KeyGenerator kg = JsseJce.getKeyGenerator(keyMaterialAlg);
1190 kg.init(spec);
1191 TlsKeyMaterialSpec keySpec = (TlsKeyMaterialSpec)kg.generateKey();
1192
1193 clntWriteKey = keySpec.getClientCipherKey();
1194 svrWriteKey = keySpec.getServerCipherKey();
1195
1196 // Return null if IVs are not supposed to be generated.
1197 // e.g. TLS 1.1+.
1198 clntWriteIV = keySpec.getClientIv();
1199 svrWriteIV = keySpec.getServerIv();
1200
1201 clntMacSecret = keySpec.getClientMacKey();
1202 svrMacSecret = keySpec.getServerMacKey();
1203 } catch (GeneralSecurityException e) {
1204 throw new ProviderException(e);
1205 }
1206
1207 //
1208 // Dump the connection keys as they're generated.
1209 //
1210 if (debug != null && Debug.isOn("keygen")) {
1211 synchronized (System.out) {
1212 HexDumpEncoder dump = new HexDumpEncoder();
1213
1214 System.out.println("CONNECTION KEYGEN:");
1215
1216 // Inputs:
1217 System.out.println("Client Nonce:");
1218 printHex(dump, clnt_random.random_bytes);
1219 System.out.println("Server Nonce:");
1220 printHex(dump, svr_random.random_bytes);
1221 System.out.println("Master Secret:");
1222 printHex(dump, masterKey.getEncoded());
1223
1224 // Outputs:
1225 System.out.println("Client MAC write Secret:");
1226 printHex(dump, clntMacSecret.getEncoded());
1227 System.out.println("Server MAC write Secret:");
1228 printHex(dump, svrMacSecret.getEncoded());
1229
1230 if (clntWriteKey != null) {
1231 System.out.println("Client write key:");
1232 printHex(dump, clntWriteKey.getEncoded());
1233 System.out.println("Server write key:");
1234 printHex(dump, svrWriteKey.getEncoded());
1235 } else {
1236 System.out.println("... no encryption keys used");
1237 }
1238
1239 if (clntWriteIV != null) {
1240 System.out.println("Client write IV:");
1241 printHex(dump, clntWriteIV.getIV());
1242 System.out.println("Server write IV:");
1243 printHex(dump, svrWriteIV.getIV());
1244 } else {
1245 if (protocolVersion.v >= ProtocolVersion.TLS11.v) {
1246 System.out.println(
1247 "... no IV derived for this protocol");
1248 } else {
1249 System.out.println("... no IV used for this cipher");
1250 }
1251 }
1252 System.out.flush();
1253 }
1254 }
1255 }
1256
1257 private static void printHex(HexDumpEncoder dump, byte[] bytes) {
1258 if (bytes == null) {
1259 System.out.println("(key bytes not available)");
1260 } else {
1261 try {
1262 dump.encodeBuffer(bytes, System.out);
1263 } catch (IOException e) {
1264 // just for debugging, ignore this
1265 }
1266 }
1267 }
1268
1269 /**
1270 * Throw an SSLException with the specified message and cause.
1271 * Shorthand until a new SSLException constructor is added.
1272 * This method never returns.
1273 */
1274 static void throwSSLException(String msg, Throwable cause)
1275 throws SSLException {
1276 SSLException e = new SSLException(msg);
1277 e.initCause(cause);
1278 throw e;
1279 }
1280
1281
1282 /*
1283 * Implement a simple task delegator.
1284 *
1285 * We are currently implementing this as a single delegator, may
1286 * try for parallel tasks later. Client Authentication could
1287 * benefit from this, where ClientKeyExchange/CertificateVerify
1288 * could be carried out in parallel.
1289 */
1290 class DelegatedTask<E> implements Runnable {
1291
1292 private PrivilegedExceptionAction<E> pea;
1293
1294 DelegatedTask(PrivilegedExceptionAction<E> pea) {
1295 this.pea = pea;
1296 }
1297
1298 public void run() {
1299 synchronized (engine) {
1300 try {
1301 AccessController.doPrivileged(pea, engine.getAcc());
1302 } catch (PrivilegedActionException pae) {
1303 thrown = pae.getException();
1304 } catch (RuntimeException rte) {
1305 thrown = rte;
1306 }
1307 delegatedTask = null;
1308 taskDelegated = false;
1309 }
1310 }
1311 }
1312
1313 private <T> void delegateTask(PrivilegedExceptionAction<T> pea) {
1314 delegatedTask = new DelegatedTask<T>(pea);
1315 taskDelegated = false;
1316 thrown = null;
1317 }
1318
1319 DelegatedTask getTask() {
1320 if (!taskDelegated) {
1321 taskDelegated = true;
1322 return delegatedTask;
1323 } else {
1324 return null;
1325 }
1326 }
1327
1328 /*
1329 * See if there are any tasks which need to be delegated
1330 *
1331 * Locked by SSLEngine.this.
1332 */
1333 boolean taskOutstanding() {
1334 return (delegatedTask != null);
1335 }
1336
1337 /*
1338 * The previous caller failed for some reason, report back the
1339 * Exception. We won't worry about Error's.
1340 *
1341 * Locked by SSLEngine.this.
1342 */
1343 void checkThrown() throws SSLException {
1344 synchronized (thrownLock) {
1345 if (thrown != null) {
1346
1347 String msg = thrown.getMessage();
1348
1349 if (msg == null) {
1350 msg = "Delegated task threw Exception/Error";
1351 }
1352
1353 /*
1354 * See what the underlying type of exception is. We should
1355 * throw the same thing. Chain thrown to the new exception.
1356 */
1357 Exception e = thrown;
1358 thrown = null;
1359
1360 if (e instanceof RuntimeException) {
1361 throw (RuntimeException)
1362 new RuntimeException(msg).initCause(e);
1363 } else if (e instanceof SSLHandshakeException) {
1364 throw (SSLHandshakeException)
1365 new SSLHandshakeException(msg).initCause(e);
1366 } else if (e instanceof SSLKeyException) {
1367 throw (SSLKeyException)
1368 new SSLKeyException(msg).initCause(e);
1369 } else if (e instanceof SSLPeerUnverifiedException) {
1370 throw (SSLPeerUnverifiedException)
1371 new SSLPeerUnverifiedException(msg).initCause(e);
1372 } else if (e instanceof SSLProtocolException) {
1373 throw (SSLProtocolException)
1374 new SSLProtocolException(msg).initCause(e);
1375 } else {
1376 /*
1377 * If it's SSLException or any other Exception,
1378 * we'll wrap it in an SSLException.
1379 */
1380 throw (SSLException)
1381 new SSLException(msg).initCause(e);
1382 }
1383 }
1384 }
1385 }
1386}