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