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