• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 
26 
27 package sun.security.ssl;
28 
29 import java.io.*;
30 import java.util.*;
31 import java.security.*;
32 import java.security.NoSuchAlgorithmException;
33 import java.security.AccessController;
34 import java.security.AlgorithmConstraints;
35 import java.security.AccessControlContext;
36 import java.security.PrivilegedExceptionAction;
37 import java.security.PrivilegedActionException;
38 
39 import javax.crypto.*;
40 import javax.crypto.spec.*;
41 
42 import javax.net.ssl.*;
43 import sun.misc.HexDumpEncoder;
44 
45 import sun.security.internal.spec.*;
46 import sun.security.internal.interfaces.TlsMasterSecret;
47 
48 import sun.security.ssl.HandshakeMessage.*;
49 import sun.security.ssl.CipherSuite.*;
50 
51 import 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  */
62 abstract 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 
Handshaker(SSLSocketImpl c, SSLContextImpl context, ProtocolList enabledProtocols, boolean needCertVerify, boolean isClient, ProtocolVersion activeProtocolVersion, boolean isInitialHandshake, boolean secureRenegotiation, byte[] clientVerifyData, byte[] serverVerifyData)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 
Handshaker(SSLEngineImpl engine, SSLContextImpl context, ProtocolList enabledProtocols, boolean needCertVerify, boolean isClient, ProtocolVersion activeProtocolVersion, boolean isInitialHandshake, boolean secureRenegotiation, byte[] clientVerifyData, byte[] serverVerifyData)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 
init(SSLContextImpl context, ProtocolList enabledProtocols, boolean needCertVerify, boolean isClient, ProtocolVersion activeProtocolVersion, boolean isInitialHandshake, boolean secureRenegotiation, byte[] clientVerifyData, byte[] serverVerifyData)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      */
fatalSE(byte b, String diagnostic)265     void fatalSE(byte b, String diagnostic) throws IOException {
266         fatalSE(b, diagnostic, null);
267     }
268 
fatalSE(byte b, Throwable cause)269     void fatalSE(byte b, Throwable cause) throws IOException {
270         fatalSE(b, null, cause);
271     }
272 
fatalSE(byte b, String diagnostic, Throwable cause)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 
warningSE(byte b)282     void warningSE(byte b) {
283         if (conn != null) {
284             conn.warning(b);
285         } else {
286             engine.warning(b);
287         }
288     }
289 
getRawHostnameSE()290     String getRawHostnameSE() {
291         if (conn != null) {
292             return conn.getRawHostname();
293         } else {
294             return engine.getPeerHost();
295         }
296     }
297 
getHostSE()298     String getHostSE() {
299         if (conn != null) {
300             return conn.getHost();
301         } else {
302             return engine.getPeerHost();
303         }
304     }
305 
getHostAddressSE()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 
isLoopbackSE()319     boolean isLoopbackSE() {
320         if (conn != null) {
321             return conn.getInetAddress().isLoopbackAddress();
322         } else {
323             return false;
324         }
325     }
326 
getPortSE()327     int getPortSE() {
328         if (conn != null) {
329             return conn.getPort();
330         } else {
331             return engine.getPeerPort();
332         }
333     }
334 
getLocalPortSE()335     int getLocalPortSE() {
336         if (conn != null) {
337             return conn.getLocalPort();
338         } else {
339             return -1;
340         }
341     }
342 
getAccSE()343     AccessControlContext getAccSE() {
344         if (conn != null) {
345             return conn.getAcc();
346         } else {
347             return engine.getAcc();
348         }
349     }
350 
setVersionSE(ProtocolVersion protocolVersion)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      */
setVersion(ProtocolVersion protocolVersion)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      */
setEnabledProtocols(ProtocolList enabledProtocols)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      */
setEnabledCipherSuites(CipherSuiteList enabledCipherSuites)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      */
setAlgorithmConstraints(AlgorithmConstraints algorithmConstraints)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 
getLocalSupportedSignAlgs()408     Collection<SignatureAndHashAlgorithm> getLocalSupportedSignAlgs() {
409         if (localSupportedSignAlgs == null) {
410             localSupportedSignAlgs =
411                 SignatureAndHashAlgorithm.getSupportedAlgorithms(
412                                                     algorithmConstraints);
413         }
414 
415         return localSupportedSignAlgs;
416     }
417 
setPeerSupportedSignAlgs( Collection<SignatureAndHashAlgorithm> algorithms)418     void setPeerSupportedSignAlgs(
419             Collection<SignatureAndHashAlgorithm> algorithms) {
420         peerSupportedSignAlgs =
421             new ArrayList<SignatureAndHashAlgorithm>(algorithms);
422     }
423 
getPeerSupportedSignAlgs()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      */
setIdentificationProtocol(String protocol)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      */
activate(ProtocolVersion helloVersion)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      */
setCipherSuite(CipherSuite s)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      */
isNegotiable(CipherSuite s)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      */
isNegotiable(ProtocolVersion protocolVersion)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      */
selectProtocolVersion(ProtocolVersion protocolVersion)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      */
getActiveCipherSuites()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      */
getActiveProtocols()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      */
setEnableSessionCreation(boolean newSessions)658     void setEnableSessionCreation(boolean newSessions) {
659         enableNewSession = newSessions;
660     }
661 
662     /**
663      * Create a new read cipher and return it to caller.
664      */
newReadCipher()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      */
newWriteCipher()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      */
newReadMAC()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      */
newWriteMAC()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      */
isDone()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      */
getSession()748     SSLSessionImpl getSession() {
749         return session;
750     }
751 
752     /*
753      * Set the handshake session
754      */
setHandshakeSessionSE(SSLSessionImpl handshakeSession)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      */
isSecureRenegotiation()766     boolean isSecureRenegotiation() {
767         return secureRenegotiation;
768     }
769 
770     /*
771      * Returns the verify_data from the Finished message sent by the client.
772      */
getClientVerifyData()773     byte[] getClientVerifyData() {
774         return clientVerifyData;
775     }
776 
777     /*
778      * Returns the verify_data from the Finished message sent by the server.
779      */
getServerVerifyData()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      */
process_record(InputRecord r, boolean expectingFinished)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      */
processLoop()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      */
activated()880     boolean activated() {
881         return state >= -1;
882     }
883 
884     /**
885      * Returns true iff the handshaker has sent any messages.
886      */
started()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      */
kickstart()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      */
getKickstartMessage()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      */
processMessage(byte messageType, int messageLen)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      */
handshakeAlert(byte description)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      */
sendChangeCipherSpec(Finished mesg, boolean lastMessage)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      */
calculateKeys(SecretKey preMasterSecret, ProtocolVersion version)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      */
calculateMasterSecret(SecretKey preMasterSecret, ProtocolVersion requestedVersion)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             }
1067 
1068             if (requestedVersion != null) {
1069                 preMasterSecret =
1070                     RSAClientKeyExchange.generateDummySecret(requestedVersion);
1071             } else {
1072                 preMasterSecret =
1073                     RSAClientKeyExchange.generateDummySecret(protocolVersion);
1074             }
1075 
1076             // recursive call with new premaster secret
1077             return calculateMasterSecret(preMasterSecret, null);
1078         }
1079 
1080         // if no version check requested (client side handshake), or version
1081         // information is not available (not an RSA premaster secret),
1082         // return master secret immediately.
1083         if ((requestedVersion == null) ||
1084                 !(masterSecret instanceof TlsMasterSecret)) {
1085             return masterSecret;
1086         }
1087 
1088         // we have checked the ClientKeyExchange message when reading TLS
1089         // record, the following check is necessary to ensure that
1090         // JCE provider does not ignore the checking, or the previous
1091         // checking process bypassed the premaster secret version checking.
1092         TlsMasterSecret tlsKey = (TlsMasterSecret)masterSecret;
1093         int major = tlsKey.getMajorVersion();
1094         int minor = tlsKey.getMinorVersion();
1095         if ((major < 0) || (minor < 0)) {
1096             return masterSecret;
1097         }
1098 
1099         // check if the premaster secret version is ok
1100         // the specification says that it must be the maximum version supported
1101         // by the client from its ClientHello message. However, many
1102         // implementations send the negotiated version, so accept both
1103         // for SSL v3.0 and TLS v1.0.
1104         // NOTE that we may be comparing two unsupported version numbers, which
1105         // is why we cannot use object reference equality in this special case.
1106         ProtocolVersion premasterVersion =
1107                                     ProtocolVersion.valueOf(major, minor);
1108         boolean versionMismatch = (premasterVersion.v != requestedVersion.v);
1109 
1110         /*
1111          * we never checked the client_version in server side
1112          * for TLS v1.0 and SSL v3.0. For compatibility, we
1113          * maintain this behavior.
1114          */
1115         if (versionMismatch && requestedVersion.v <= ProtocolVersion.TLS10.v) {
1116             versionMismatch = (premasterVersion.v != protocolVersion.v);
1117         }
1118 
1119         if (versionMismatch == false) {
1120             // check passed, return key
1121             return masterSecret;
1122         }
1123 
1124         // Due to the Bleichenbacher attack, do not signal a protocol error.
1125         // Generate a random premaster secret and continue with the handshake,
1126         // which will fail when verifying the finished messages.
1127         // For more information, see comments in PreMasterSecret.
1128         if (debug != null && Debug.isOn("handshake")) {
1129             System.out.println("RSA PreMasterSecret version error: expected"
1130                 + protocolVersion + " or " + requestedVersion + ", decrypted: "
1131                 + premasterVersion);
1132         }
1133         preMasterSecret =
1134             RSAClientKeyExchange.generateDummySecret(requestedVersion);
1135 
1136         // recursive call with new premaster secret
1137         return calculateMasterSecret(preMasterSecret, null);
1138     }
1139 
1140     /*
1141      * Calculate the keys needed for this connection, once the session's
1142      * master secret has been calculated.  Uses the master key and nonces;
1143      * the amount of keying material generated is a function of the cipher
1144      * suite that's been negotiated.
1145      *
1146      * This gets called both on the "full handshake" (where we exchanged
1147      * a premaster secret and started a new session) as well as on the
1148      * "fast handshake" (where we just resumed a pre-existing session).
1149      */
calculateConnectionKeys(SecretKey masterKey)1150     void calculateConnectionKeys(SecretKey masterKey) {
1151         /*
1152          * For both the read and write sides of the protocol, we use the
1153          * master to generate MAC secrets and cipher keying material.  Block
1154          * ciphers need initialization vectors, which we also generate.
1155          *
1156          * First we figure out how much keying material is needed.
1157          */
1158         int hashSize = cipherSuite.macAlg.size;
1159         boolean is_exportable = cipherSuite.exportable;
1160         BulkCipher cipher = cipherSuite.cipher;
1161         int expandedKeySize = is_exportable ? cipher.expandedKeySize : 0;
1162 
1163         // Which algs/params do we need to use?
1164         String keyMaterialAlg;
1165         PRF prf;
1166 
1167         if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
1168             keyMaterialAlg = "SunTls12KeyMaterial";
1169             prf = cipherSuite.prfAlg;
1170         } else {
1171             keyMaterialAlg = "SunTlsKeyMaterial";
1172             prf = P_NONE;
1173         }
1174 
1175         String prfHashAlg = prf.getPRFHashAlg();
1176         int prfHashLength = prf.getPRFHashLength();
1177         int prfBlockSize = prf.getPRFBlockSize();
1178 
1179         TlsKeyMaterialParameterSpec spec = new TlsKeyMaterialParameterSpec(
1180             masterKey, protocolVersion.major, protocolVersion.minor,
1181             clnt_random.random_bytes, svr_random.random_bytes,
1182             cipher.algorithm, cipher.keySize, expandedKeySize,
1183             cipher.ivSize, hashSize,
1184             prfHashAlg, prfHashLength, prfBlockSize);
1185 
1186         try {
1187             KeyGenerator kg = JsseJce.getKeyGenerator(keyMaterialAlg);
1188             kg.init(spec);
1189             TlsKeyMaterialSpec keySpec = (TlsKeyMaterialSpec)kg.generateKey();
1190 
1191             clntWriteKey = keySpec.getClientCipherKey();
1192             svrWriteKey = keySpec.getServerCipherKey();
1193 
1194             // Return null if IVs are not supposed to be generated.
1195             // e.g. TLS 1.1+.
1196             clntWriteIV = keySpec.getClientIv();
1197             svrWriteIV = keySpec.getServerIv();
1198 
1199             clntMacSecret = keySpec.getClientMacKey();
1200             svrMacSecret = keySpec.getServerMacKey();
1201         } catch (GeneralSecurityException e) {
1202             throw new ProviderException(e);
1203         }
1204 
1205         //
1206         // Dump the connection keys as they're generated.
1207         //
1208         if (debug != null && Debug.isOn("keygen")) {
1209             synchronized (System.out) {
1210                 HexDumpEncoder  dump = new HexDumpEncoder();
1211 
1212                 System.out.println("CONNECTION KEYGEN:");
1213 
1214                 // Inputs:
1215                 System.out.println("Client Nonce:");
1216                 printHex(dump, clnt_random.random_bytes);
1217                 System.out.println("Server Nonce:");
1218                 printHex(dump, svr_random.random_bytes);
1219                 System.out.println("Master Secret:");
1220                 printHex(dump, masterKey.getEncoded());
1221 
1222                 // Outputs:
1223                 System.out.println("Client MAC write Secret:");
1224                 printHex(dump, clntMacSecret.getEncoded());
1225                 System.out.println("Server MAC write Secret:");
1226                 printHex(dump, svrMacSecret.getEncoded());
1227 
1228                 if (clntWriteKey != null) {
1229                     System.out.println("Client write key:");
1230                     printHex(dump, clntWriteKey.getEncoded());
1231                     System.out.println("Server write key:");
1232                     printHex(dump, svrWriteKey.getEncoded());
1233                 } else {
1234                     System.out.println("... no encryption keys used");
1235                 }
1236 
1237                 if (clntWriteIV != null) {
1238                     System.out.println("Client write IV:");
1239                     printHex(dump, clntWriteIV.getIV());
1240                     System.out.println("Server write IV:");
1241                     printHex(dump, svrWriteIV.getIV());
1242                 } else {
1243                     if (protocolVersion.v >= ProtocolVersion.TLS11.v) {
1244                         System.out.println(
1245                                 "... no IV derived for this protocol");
1246                     } else {
1247                         System.out.println("... no IV used for this cipher");
1248                     }
1249                 }
1250                 System.out.flush();
1251             }
1252         }
1253     }
1254 
printHex(HexDumpEncoder dump, byte[] bytes)1255     private static void printHex(HexDumpEncoder dump, byte[] bytes) {
1256         if (bytes == null) {
1257             System.out.println("(key bytes not available)");
1258         } else {
1259             try {
1260                 dump.encodeBuffer(bytes, System.out);
1261             } catch (IOException e) {
1262                 // just for debugging, ignore this
1263             }
1264         }
1265     }
1266 
1267     /**
1268      * Throw an SSLException with the specified message and cause.
1269      * Shorthand until a new SSLException constructor is added.
1270      * This method never returns.
1271      */
throwSSLException(String msg, Throwable cause)1272     static void throwSSLException(String msg, Throwable cause)
1273             throws SSLException {
1274         SSLException e = new SSLException(msg);
1275         e.initCause(cause);
1276         throw e;
1277     }
1278 
1279 
1280     /*
1281      * Implement a simple task delegator.
1282      *
1283      * We are currently implementing this as a single delegator, may
1284      * try for parallel tasks later.  Client Authentication could
1285      * benefit from this, where ClientKeyExchange/CertificateVerify
1286      * could be carried out in parallel.
1287      */
1288     class DelegatedTask<E> implements Runnable {
1289 
1290         private PrivilegedExceptionAction<E> pea;
1291 
DelegatedTask(PrivilegedExceptionAction<E> pea)1292         DelegatedTask(PrivilegedExceptionAction<E> pea) {
1293             this.pea = pea;
1294         }
1295 
run()1296         public void run() {
1297             synchronized (engine) {
1298                 try {
1299                     AccessController.doPrivileged(pea, engine.getAcc());
1300                 } catch (PrivilegedActionException pae) {
1301                     thrown = pae.getException();
1302                 } catch (RuntimeException rte) {
1303                     thrown = rte;
1304                 }
1305                 delegatedTask = null;
1306                 taskDelegated = false;
1307             }
1308         }
1309     }
1310 
delegateTask(PrivilegedExceptionAction<T> pea)1311     private <T> void delegateTask(PrivilegedExceptionAction<T> pea) {
1312         delegatedTask = new DelegatedTask<T>(pea);
1313         taskDelegated = false;
1314         thrown = null;
1315     }
1316 
getTask()1317     DelegatedTask getTask() {
1318         if (!taskDelegated) {
1319             taskDelegated = true;
1320             return delegatedTask;
1321         } else {
1322             return null;
1323         }
1324     }
1325 
1326     /*
1327      * See if there are any tasks which need to be delegated
1328      *
1329      * Locked by SSLEngine.this.
1330      */
taskOutstanding()1331     boolean taskOutstanding() {
1332         return (delegatedTask != null);
1333     }
1334 
1335     /*
1336      * The previous caller failed for some reason, report back the
1337      * Exception.  We won't worry about Error's.
1338      *
1339      * Locked by SSLEngine.this.
1340      */
checkThrown()1341     void checkThrown() throws SSLException {
1342         synchronized (thrownLock) {
1343             if (thrown != null) {
1344 
1345                 String msg = thrown.getMessage();
1346 
1347                 if (msg == null) {
1348                     msg = "Delegated task threw Exception/Error";
1349                 }
1350 
1351                 /*
1352                  * See what the underlying type of exception is.  We should
1353                  * throw the same thing.  Chain thrown to the new exception.
1354                  */
1355                 Exception e = thrown;
1356                 thrown = null;
1357 
1358                 if (e instanceof RuntimeException) {
1359                     throw (RuntimeException)
1360                         new RuntimeException(msg).initCause(e);
1361                 } else if (e instanceof SSLHandshakeException) {
1362                     throw (SSLHandshakeException)
1363                         new SSLHandshakeException(msg).initCause(e);
1364                 } else if (e instanceof SSLKeyException) {
1365                     throw (SSLKeyException)
1366                         new SSLKeyException(msg).initCause(e);
1367                 } else if (e instanceof SSLPeerUnverifiedException) {
1368                     throw (SSLPeerUnverifiedException)
1369                         new SSLPeerUnverifiedException(msg).initCause(e);
1370                 } else if (e instanceof SSLProtocolException) {
1371                     throw (SSLProtocolException)
1372                         new SSLProtocolException(msg).initCause(e);
1373                 } else {
1374                     /*
1375                      * If it's SSLException or any other Exception,
1376                      * we'll wrap it in an SSLException.
1377                      */
1378                     throw (SSLException)
1379                         new SSLException(msg).initCause(e);
1380                 }
1381             }
1382         }
1383     }
1384 }
1385