1/*
2 * Copyright (c) 2003, 2016, 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
26package sun.security.ssl;
27
28import java.io.*;
29import java.nio.*;
30import java.security.*;
31import java.util.*;
32import java.util.function.BiFunction;
33
34import javax.crypto.BadPaddingException;
35
36import javax.net.ssl.*;
37import javax.net.ssl.SSLEngineResult.*;
38
39/**
40 * Implementation of an non-blocking SSLEngine.
41 *
42 * *Currently*, the SSLEngine code exists in parallel with the current
43 * SSLSocket.  As such, the current implementation is using legacy code
44 * with many of the same abstractions.  However, it varies in many
45 * areas, most dramatically in the IO handling.
46 *
47 * There are three main I/O threads that can be existing in parallel:
48 * wrap(), unwrap(), and beginHandshake().  We are encouraging users to
49 * not call multiple instances of wrap or unwrap, because the data could
50 * appear to flow out of the SSLEngine in a non-sequential order.  We
51 * take all steps we can to at least make sure the ordering remains
52 * consistent, but once the calls returns, anything can happen.  For
53 * example, thread1 and thread2 both call wrap, thread1 gets the first
54 * packet, thread2 gets the second packet, but thread2 gets control back
55 * before thread1, and sends the data.  The receiving side would see an
56 * out-of-order error.
57 *
58 * @author Brad Wetmore
59 */
60public final class SSLEngineImpl extends SSLEngine {
61
62    //
63    // Fields and global comments
64    //
65
66    /*
67     * There's a state machine associated with each connection, which
68     * among other roles serves to negotiate session changes.
69     *
70     * - START with constructor, until the TCP connection's around.
71     * - HANDSHAKE picks session parameters before allowing traffic.
72     *          There are many substates due to sequencing requirements
73     *          for handshake messages.
74     * - DATA may be transmitted.
75     * - RENEGOTIATE state allows concurrent data and handshaking
76     *          traffic ("same" substates as HANDSHAKE), and terminates
77     *          in selection of new session (and connection) parameters
78     * - ERROR state immediately precedes abortive disconnect.
79     * - CLOSED when one side closes down, used to start the shutdown
80     *          process.  SSL connection objects are not reused.
81     *
82     * State affects what SSL record types may legally be sent:
83     *
84     * - Handshake ... only in HANDSHAKE and RENEGOTIATE states
85     * - App Data ... only in DATA and RENEGOTIATE states
86     * - Alert ... in HANDSHAKE, DATA, RENEGOTIATE
87     *
88     * Re what may be received:  same as what may be sent, except that
89     * HandshakeRequest handshaking messages can come from servers even
90     * in the application data state, to request entry to RENEGOTIATE.
91     *
92     * The state machine within HANDSHAKE and RENEGOTIATE states controls
93     * the pending session, not the connection state, until the change
94     * cipher spec and "Finished" handshake messages are processed and
95     * make the "new" session become the current one.
96     *
97     * NOTE: details of the SMs always need to be nailed down better.
98     * The text above illustrates the core ideas.
99     *
100     *                +---->-------+------>--------->-------+
101     *                |            |                        |
102     *     <-----<    ^            ^  <-----<               |
103     *START>----->HANDSHAKE>----->DATA>----->RENEGOTIATE    |
104     *                v            v               v        |
105     *                |            |               |        |
106     *                +------------+---------------+        |
107     *                |                                     |
108     *                v                                     |
109     *               ERROR>------>----->CLOSED<--------<----+
110     *
111     * ALSO, note that the purpose of handshaking (renegotiation is
112     * included) is to assign a different, and perhaps new, session to
113     * the connection.  The SSLv3 spec is a bit confusing on that new
114     * protocol feature.
115     */
116    private int                 connectionState;
117
118    private static final int    cs_START = 0;
119    private static final int    cs_HANDSHAKE = 1;
120    private static final int    cs_DATA = 2;
121    private static final int    cs_RENEGOTIATE = 3;
122    private static final int    cs_ERROR = 4;
123    private static final int    cs_CLOSED = 6;
124
125    /*
126     * Once we're in state cs_CLOSED, we can continue to
127     * wrap/unwrap until we finish sending/receiving the messages
128     * for close_notify.
129     */
130    private boolean             inboundDone = false;
131    private boolean             outboundDone = false;
132
133    /*
134     * The authentication context holds all information used to establish
135     * who this end of the connection is (certificate chains, private keys,
136     * etc) and who is trusted (e.g. as CAs or websites).
137     */
138    private SSLContextImpl      sslContext;
139
140    /*
141     * This connection is one of (potentially) many associated with
142     * any given session.  The output of the handshake protocol is a
143     * new session ... although all the protocol description talks
144     * about changing the cipher spec (and it does change), in fact
145     * that's incidental since it's done by changing everything that
146     * is associated with a session at the same time.  (TLS/IETF may
147     * change that to add client authentication w/o new key exchg.)
148     */
149    private Handshaker                  handshaker;
150    private SSLSessionImpl              sess;
151    private volatile SSLSessionImpl     handshakeSession;
152
153    /*
154     * Flag indicating if the next record we receive MUST be a Finished
155     * message. Temporarily set during the handshake to ensure that
156     * a change cipher spec message is followed by a finished message.
157     */
158    private boolean             expectingFinished;
159
160
161    /*
162     * If someone tries to closeInbound() (say at End-Of-Stream)
163     * our engine having received a close_notify, we need to
164     * notify the app that we may have a truncation attack underway.
165     */
166    private boolean             recvCN;
167
168    /*
169     * For improved diagnostics, we detail connection closure
170     * If the engine is closed (connectionState >= cs_ERROR),
171     * closeReason != null indicates if the engine was closed
172     * because of an error or because or normal shutdown.
173     */
174    private SSLException        closeReason;
175
176    /*
177     * Per-connection private state that doesn't change when the
178     * session is changed.
179     */
180    private ClientAuthType          doClientAuth =
181                                            ClientAuthType.CLIENT_AUTH_NONE;
182    private boolean                 enableSessionCreation = true;
183    InputRecord                     inputRecord;
184    OutputRecord                    outputRecord;
185    private AccessControlContext    acc;
186
187    // The cipher suites enabled for use on this connection.
188    private CipherSuiteList             enabledCipherSuites;
189
190    // the endpoint identification protocol
191    private String                      identificationProtocol = null;
192
193    // The cryptographic algorithm constraints
194    private AlgorithmConstraints        algorithmConstraints = null;
195
196    // The server name indication and matchers
197    List<SNIServerName>         serverNames =
198                                    Collections.<SNIServerName>emptyList();
199    Collection<SNIMatcher>      sniMatchers =
200                                    Collections.<SNIMatcher>emptyList();
201
202    // Configured application protocol values
203    String[] applicationProtocols = new String[0];
204
205    // Negotiated application protocol value.
206    //
207    // The value under negotiation will be obtained from handshaker.
208    String applicationProtocol = null;
209
210    // Callback function that selects the application protocol value during
211    // the SSL/TLS handshake.
212    BiFunction<SSLEngine, List<String>, String> applicationProtocolSelector;
213
214    // Have we been told whether we're client or server?
215    private boolean                     serverModeSet = false;
216    private boolean                     roleIsServer;
217
218    /*
219     * The protocol versions enabled for use on this connection.
220     *
221     * Note: we support a pseudo protocol called SSLv2Hello which when
222     * set will result in an SSL v2 Hello being sent with SSL (version 3.0)
223     * or TLS (version 3.1, 3.2, etc.) version info.
224     */
225    private ProtocolList        enabledProtocols;
226
227    /*
228     * The SSL version associated with this connection.
229     */
230    private ProtocolVersion     protocolVersion;
231
232    /*
233     * security parameters for secure renegotiation.
234     */
235    private boolean             secureRenegotiation;
236    private byte[]              clientVerifyData;
237    private byte[]              serverVerifyData;
238
239    /*
240     * READ ME * READ ME * READ ME * READ ME * READ ME * READ ME *
241     * IMPORTANT STUFF TO UNDERSTANDING THE SYNCHRONIZATION ISSUES.
242     * READ ME * READ ME * READ ME * READ ME * READ ME * READ ME *
243     *
244     * There are several locks here.
245     *
246     * The primary lock is the per-instance lock used by
247     * synchronized(this) and the synchronized methods.  It controls all
248     * access to things such as the connection state and variables which
249     * affect handshaking.  If we are inside a synchronized method, we
250     * can access the state directly, otherwise, we must use the
251     * synchronized equivalents.
252     *
253     * Note that we must never acquire the <code>this</code> lock after
254     * <code>writeLock</code> or run the risk of deadlock.
255     *
256     * Grab some coffee, and be careful with any code changes.
257     */
258    private Object              wrapLock;
259    private Object              unwrapLock;
260    Object                      writeLock;
261
262    /*
263     * Whether local cipher suites preference in server side should be
264     * honored during handshaking?
265     */
266    private boolean preferLocalCipherSuites = false;
267
268    /*
269     * whether DTLS handshake retransmissions should be enabled?
270     */
271    private boolean enableRetransmissions = false;
272
273    /*
274     * The maximum expected network packet size for SSL/TLS/DTLS records.
275     */
276    private int maximumPacketSize = 0;
277
278    /*
279     * Is this an instance for Datagram Transport Layer Security (DTLS)?
280     */
281    private final boolean isDTLS;
282
283    /*
284     * Class and subclass dynamic debugging support
285     */
286    private static final Debug debug = Debug.getInstance("ssl");
287
288    //
289    // Initialization/Constructors
290    //
291
292    /**
293     * Constructor for an SSLEngine from SSLContext, without
294     * host/port hints.  This Engine will not be able to cache
295     * sessions, but must renegotiate everything by hand.
296     */
297    SSLEngineImpl(SSLContextImpl ctx, boolean isDTLS) {
298        super();
299        this.isDTLS = isDTLS;
300        init(ctx, isDTLS);
301    }
302
303    /**
304     * Constructor for an SSLEngine from SSLContext.
305     */
306    SSLEngineImpl(SSLContextImpl ctx, String host, int port, boolean isDTLS) {
307        super(host, port);
308        this.isDTLS = isDTLS;
309        init(ctx, isDTLS);
310    }
311
312    /**
313     * Initializes the Engine
314     */
315    private void init(SSLContextImpl ctx, boolean isDTLS) {
316        if (debug != null && Debug.isOn("ssl")) {
317            System.out.println("Using SSLEngineImpl.");
318        }
319
320        sslContext = ctx;
321        sess = SSLSessionImpl.nullSession;
322        handshakeSession = null;
323        protocolVersion = isDTLS ?
324                ProtocolVersion.DEFAULT_DTLS : ProtocolVersion.DEFAULT_TLS;
325
326        /*
327         * State is cs_START until we initialize the handshaker.
328         *
329         * Apps using SSLEngine are probably going to be server.
330         * Somewhat arbitrary choice.
331         */
332        roleIsServer = true;
333        connectionState = cs_START;
334
335        // default server name indication
336        serverNames =
337            Utilities.addToSNIServerNameList(serverNames, getPeerHost());
338
339        // default security parameters for secure renegotiation
340        secureRenegotiation = false;
341        clientVerifyData = new byte[0];
342        serverVerifyData = new byte[0];
343
344        enabledCipherSuites =
345                sslContext.getDefaultCipherSuiteList(roleIsServer);
346        enabledProtocols =
347                sslContext.getDefaultProtocolList(roleIsServer);
348
349        wrapLock = new Object();
350        unwrapLock = new Object();
351        writeLock = new Object();
352
353        /*
354         * Save the Access Control Context.  This will be used later
355         * for a couple of things, including providing a context to
356         * run tasks in, and for determining which credentials
357         * to use for Subject based (JAAS) decisions
358         */
359        acc = AccessController.getContext();
360
361        /*
362         * All outbound application data goes through this OutputRecord,
363         * other data goes through their respective records created
364         * elsewhere.  All inbound data goes through this one
365         * input record.
366         */
367        if (isDTLS) {
368            enableRetransmissions = true;
369
370            // SSLEngine needs no record local buffer
371            outputRecord = new DTLSOutputRecord();
372            inputRecord = new DTLSInputRecord();
373
374        } else {
375            outputRecord = new SSLEngineOutputRecord();
376            inputRecord = new SSLEngineInputRecord();
377        }
378
379        maximumPacketSize = outputRecord.getMaxPacketSize();
380    }
381
382    /**
383     * Initialize the handshaker object. This means:
384     *
385     *  . if a handshake is already in progress (state is cs_HANDSHAKE
386     *    or cs_RENEGOTIATE), do nothing and return
387     *
388     *  . if the engine is already closed, throw an Exception (internal error)
389     *
390     *  . otherwise (cs_START or cs_DATA), create the appropriate handshaker
391     *    object and advance the connection state (to cs_HANDSHAKE or
392     *    cs_RENEGOTIATE, respectively).
393     *
394     * This method is called right after a new engine is created, when
395     * starting renegotiation, or when changing client/server mode of the
396     * engine.
397     */
398    private void initHandshaker() {
399        switch (connectionState) {
400
401        //
402        // Starting a new handshake.
403        //
404        case cs_START:
405        case cs_DATA:
406            break;
407
408        //
409        // We're already in the middle of a handshake.
410        //
411        case cs_HANDSHAKE:
412        case cs_RENEGOTIATE:
413            return;
414
415        //
416        // Anyone allowed to call this routine is required to
417        // do so ONLY if the connection state is reasonable...
418        //
419        default:
420            throw new IllegalStateException("Internal error");
421        }
422
423        // state is either cs_START or cs_DATA
424        if (connectionState == cs_START) {
425            connectionState = cs_HANDSHAKE;
426        } else { // cs_DATA
427            connectionState = cs_RENEGOTIATE;
428        }
429
430        if (roleIsServer) {
431            handshaker = new ServerHandshaker(this, sslContext,
432                    enabledProtocols, doClientAuth,
433                    protocolVersion, connectionState == cs_HANDSHAKE,
434                    secureRenegotiation, clientVerifyData, serverVerifyData,
435                    isDTLS);
436            handshaker.setSNIMatchers(sniMatchers);
437            handshaker.setUseCipherSuitesOrder(preferLocalCipherSuites);
438        } else {
439            handshaker = new ClientHandshaker(this, sslContext,
440                    enabledProtocols,
441                    protocolVersion, connectionState == cs_HANDSHAKE,
442                    secureRenegotiation, clientVerifyData, serverVerifyData,
443                    isDTLS);
444            handshaker.setSNIServerNames(serverNames);
445        }
446        handshaker.setMaximumPacketSize(maximumPacketSize);
447        handshaker.setEnabledCipherSuites(enabledCipherSuites);
448        handshaker.setEnableSessionCreation(enableSessionCreation);
449        handshaker.setApplicationProtocols(applicationProtocols);
450        handshaker.setApplicationProtocolSelectorSSLEngine(
451            applicationProtocolSelector);
452
453        outputRecord.initHandshaker();
454    }
455
456    /*
457     * Report the current status of the Handshaker
458     */
459    private HandshakeStatus getHSStatus(HandshakeStatus hss) {
460
461        if (hss != null) {
462            return hss;
463        }
464
465        synchronized (this) {
466            if (!outputRecord.isEmpty()) {
467                // If no handshaking, special case to wrap alters.
468                return HandshakeStatus.NEED_WRAP;
469            } else if (handshaker != null) {
470                if (handshaker.taskOutstanding()) {
471                    return HandshakeStatus.NEED_TASK;
472                } else if (isDTLS && !inputRecord.isEmpty()) {
473                    return HandshakeStatus.NEED_UNWRAP_AGAIN;
474                } else {
475                    return HandshakeStatus.NEED_UNWRAP;
476                }
477            } else if (connectionState == cs_CLOSED) {
478                /*
479                 * Special case where we're closing, but
480                 * still need the close_notify before we
481                 * can officially be closed.
482                 *
483                 * Note isOutboundDone is taken care of by
484                 * hasOutboundData() above.
485                 */
486                if (!isInboundDone()) {
487                    return HandshakeStatus.NEED_UNWRAP;
488                } // else not handshaking
489            }
490
491            return HandshakeStatus.NOT_HANDSHAKING;
492        }
493    }
494
495    private synchronized void checkTaskThrown() throws SSLException {
496        if (handshaker != null) {
497            handshaker.checkThrown();
498        }
499    }
500
501    //
502    // Handshaking and connection state code
503    //
504
505    /*
506     * Provides "this" synchronization for connection state.
507     * Otherwise, you can access it directly.
508     */
509    private synchronized int getConnectionState() {
510        return connectionState;
511    }
512
513    private synchronized void setConnectionState(int state) {
514        connectionState = state;
515    }
516
517    /*
518     * Get the Access Control Context.
519     *
520     * Used for a known context to
521     * run tasks in, and for determining which credentials
522     * to use for Subject-based (JAAS) decisions.
523     */
524    AccessControlContext getAcc() {
525        return acc;
526    }
527
528    /*
529     * Is a handshake currently underway?
530     */
531    @Override
532    public SSLEngineResult.HandshakeStatus getHandshakeStatus() {
533        return getHSStatus(null);
534    }
535
536    /*
537     * used by Handshaker to change the active write cipher, follows
538     * the output of the CCS message.
539     *
540     * Also synchronized on "this" from readRecord/delegatedTask.
541     */
542    void changeWriteCiphers() throws IOException {
543
544        Authenticator writeAuthenticator;
545        CipherBox writeCipher;
546        try {
547            writeCipher = handshaker.newWriteCipher();
548            writeAuthenticator = handshaker.newWriteAuthenticator();
549        } catch (GeneralSecurityException e) {
550            // "can't happen"
551            throw new SSLException("Algorithm missing:  ", e);
552        }
553
554        outputRecord.changeWriteCiphers(writeAuthenticator, writeCipher);
555    }
556
557    /*
558     * Updates the SSL version associated with this connection.
559     * Called from Handshaker once it has determined the negotiated version.
560     */
561    synchronized void setVersion(ProtocolVersion protocolVersion) {
562        this.protocolVersion = protocolVersion;
563        outputRecord.setVersion(protocolVersion);
564    }
565
566
567    /**
568     * Kickstart the handshake if it is not already in progress.
569     * This means:
570     *
571     *  . if handshaking is already underway, do nothing and return
572     *
573     *  . if the engine is not connected or already closed, throw an
574     *    Exception.
575     *
576     *  . otherwise, call initHandshake() to initialize the handshaker
577     *    object and progress the state. Then, send the initial
578     *    handshaking message if appropriate (always on clients and
579     *    on servers when renegotiating).
580     */
581    private synchronized void kickstartHandshake() throws IOException {
582        switch (connectionState) {
583
584        case cs_START:
585            if (!serverModeSet) {
586                throw new IllegalStateException(
587                    "Client/Server mode not yet set.");
588            }
589            initHandshaker();
590            break;
591
592        case cs_HANDSHAKE:
593            // handshaker already setup, proceed
594            break;
595
596        case cs_DATA:
597            if (!secureRenegotiation && !Handshaker.allowUnsafeRenegotiation) {
598                throw new SSLHandshakeException(
599                        "Insecure renegotiation is not allowed");
600            }
601
602            if (!secureRenegotiation) {
603                if (debug != null && Debug.isOn("handshake")) {
604                    System.out.println(
605                        "Warning: Using insecure renegotiation");
606                }
607            }
608
609            // initialize the handshaker, move to cs_RENEGOTIATE
610            initHandshaker();
611            break;
612
613        case cs_RENEGOTIATE:
614            // handshaking already in progress, return
615            return;
616
617        default:
618            // cs_ERROR/cs_CLOSED
619            throw new SSLException("SSLEngine is closing/closed");
620        }
621
622        //
623        // Kickstart handshake state machine if we need to ...
624        //
625        if (!handshaker.activated()) {
626             // prior to handshaking, activate the handshake
627            if (connectionState == cs_RENEGOTIATE) {
628                // don't use SSLv2Hello when renegotiating
629                handshaker.activate(protocolVersion);
630            } else {
631                handshaker.activate(null);
632            }
633
634            if (handshaker instanceof ClientHandshaker) {
635                // send client hello
636                handshaker.kickstart();
637            } else {    // instanceof ServerHandshaker
638                if (connectionState == cs_HANDSHAKE) {
639                    // initial handshake, no kickstart message to send
640                } else {
641                    // we want to renegotiate, send hello request
642                    handshaker.kickstart();
643                }
644            }
645        }
646    }
647
648    /*
649     * Start a SSLEngine handshake
650     */
651    @Override
652    public void beginHandshake() throws SSLException {
653        try {
654            kickstartHandshake();
655        } catch (Exception e) {
656            fatal(Alerts.alert_handshake_failure,
657                "Couldn't kickstart handshaking", e);
658        }
659    }
660
661
662    //
663    // Read/unwrap side
664    //
665
666
667    /**
668     * Unwraps a buffer.  Does a variety of checks before grabbing
669     * the unwrapLock, which blocks multiple unwraps from occurring.
670     */
671    @Override
672    public SSLEngineResult unwrap(ByteBuffer netData, ByteBuffer[] appData,
673            int offset, int length) throws SSLException {
674
675        // check engine parameters
676        checkEngineParas(netData, appData, offset, length, false);
677
678        try {
679            synchronized (unwrapLock) {
680                return readNetRecord(netData, appData, offset, length);
681            }
682        } catch (SSLProtocolException spe) {
683            // may be an unexpected handshake message
684            fatal(Alerts.alert_unexpected_message, spe.getMessage(), spe);
685            return null;  // make compiler happy
686        } catch (Exception e) {
687            /*
688             * Don't reset position so it looks like we didn't
689             * consume anything.  We did consume something, and it
690             * got us into this situation, so report that much back.
691             * Our days of consuming are now over anyway.
692             */
693            fatal(Alerts.alert_internal_error,
694                "problem unwrapping net record", e);
695            return null;  // make compiler happy
696        }
697    }
698
699    private static void checkEngineParas(ByteBuffer netData,
700            ByteBuffer[] appData, int offset, int len, boolean isForWrap) {
701
702        if ((netData == null) || (appData == null)) {
703            throw new IllegalArgumentException("src/dst is null");
704        }
705
706        if ((offset < 0) || (len < 0) || (offset > appData.length - len)) {
707            throw new IndexOutOfBoundsException();
708        }
709
710        /*
711         * If wrapping, make sure the destination bufffer is writable.
712         */
713        if (isForWrap && netData.isReadOnly()) {
714            throw new ReadOnlyBufferException();
715        }
716
717        for (int i = offset; i < offset + len; i++) {
718            if (appData[i] == null) {
719                throw new IllegalArgumentException(
720                        "appData[" + i + "] == null");
721            }
722
723            /*
724             * If unwrapping, make sure the destination bufffers are writable.
725             */
726            if (!isForWrap && appData[i].isReadOnly()) {
727                throw new ReadOnlyBufferException();
728            }
729        }
730    }
731
732    /*
733     * Makes additional checks for unwrap, but this time more
734     * specific to this packet and the current state of the machine.
735     */
736    private SSLEngineResult readNetRecord(ByteBuffer netData,
737            ByteBuffer[] appData, int offset, int length) throws IOException {
738
739        Status status = null;
740        HandshakeStatus hsStatus = null;
741
742        /*
743         * See if the handshaker needs to report back some SSLException.
744         */
745        checkTaskThrown();
746
747        /*
748         * Check if we are closing/closed.
749         */
750        if (isInboundDone()) {
751            return new SSLEngineResult(Status.CLOSED, getHSStatus(null), 0, 0);
752        }
753
754        /*
755         * If we're still in cs_HANDSHAKE, make sure it's been
756         * started.
757         */
758        synchronized (this) {
759            if ((connectionState == cs_HANDSHAKE) ||
760                    (connectionState == cs_START)) {
761                kickstartHandshake();
762
763                /*
764                 * If there's still outbound data to flush, we
765                 * can return without trying to unwrap anything.
766                 */
767                hsStatus = getHSStatus(null);
768
769                if (hsStatus == HandshakeStatus.NEED_WRAP) {
770                    return new SSLEngineResult(Status.OK, hsStatus, 0, 0);
771                }
772            }
773        }
774
775        /*
776         * Grab a copy of this if it doesn't already exist,
777         * and we can use it several places before anything major
778         * happens on this side.  Races aren't critical
779         * here.
780         */
781        if (hsStatus == null) {
782            hsStatus = getHSStatus(null);
783        }
784
785        /*
786         * If we have a task outstanding, this *MUST* be done before
787         * doing any more unwrapping, because we could be in the middle
788         * of receiving a handshake message, for example, a finished
789         * message which would change the ciphers.
790         */
791        if (hsStatus == HandshakeStatus.NEED_TASK) {
792            return new SSLEngineResult(Status.OK, hsStatus, 0, 0);
793        }
794
795        if (hsStatus == SSLEngineResult.HandshakeStatus.NEED_UNWRAP_AGAIN) {
796            Plaintext plainText = null;
797            try {
798                plainText = readRecord(null, null, 0, 0);
799            } catch (SSLException e) {
800                throw e;
801            } catch (IOException e) {
802                throw new SSLException("readRecord", e);
803            }
804
805            status = (isInboundDone() ? Status.CLOSED : Status.OK);
806            hsStatus = getHSStatus(plainText.handshakeStatus);
807
808            return new SSLEngineResult(
809                    status, hsStatus, 0, 0, plainText.recordSN);
810        }
811
812        /*
813         * Check the packet to make sure enough is here.
814         * This will also indirectly check for 0 len packets.
815         */
816        int packetLen = 0;
817        try {
818            packetLen = inputRecord.bytesInCompletePacket(netData);
819        } catch (SSLException ssle) {
820            // Need to discard invalid records for DTLS protocols.
821            if (isDTLS) {
822                if (debug != null && Debug.isOn("ssl")) {
823                    System.out.println(
824                        Thread.currentThread().getName() +
825                        " discard invalid record: " + ssle);
826                }
827
828                // invalid, discard the entire data [section 4.1.2.7, RFC 6347]
829                int deltaNet = netData.remaining();
830                netData.position(netData.limit());
831
832                status = (isInboundDone() ? Status.CLOSED : Status.OK);
833                hsStatus = getHSStatus(hsStatus);
834
835                return new SSLEngineResult(status, hsStatus, deltaNet, 0, -1L);
836            } else {
837                throw ssle;
838            }
839        }
840
841        // Is this packet bigger than SSL/TLS normally allows?
842        if (packetLen > sess.getPacketBufferSize()) {
843            int largestRecordSize = isDTLS ?
844                    DTLSRecord.maxRecordSize : SSLRecord.maxLargeRecordSize;
845            if ((packetLen <= largestRecordSize) && !isDTLS) {
846                // Expand the expected maximum packet/application buffer
847                // sizes.
848                //
849                // Only apply to SSL/TLS protocols.
850
851                // Old behavior: shall we honor the System Property
852                // "jsse.SSLEngine.acceptLargeFragments" if it is "false"?
853                sess.expandBufferSizes();
854            }
855
856            // check the packet again
857            largestRecordSize = sess.getPacketBufferSize();
858            if (packetLen > largestRecordSize) {
859                throw new SSLProtocolException(
860                        "Input record too big: max = " +
861                        largestRecordSize + " len = " + packetLen);
862            }
863        }
864
865        int netPos = netData.position();
866        int appRemains = 0;
867        for (int i = offset; i < offset + length; i++) {
868            if (appData[i] == null) {
869                throw new IllegalArgumentException(
870                        "appData[" + i + "] == null");
871            }
872            appRemains += appData[i].remaining();
873        }
874
875        /*
876         * Check for OVERFLOW.
877         *
878         * Delay enforcing the application buffer free space requirement
879         * until after the initial handshaking.
880         */
881        // synchronize connectionState?
882        if ((connectionState == cs_DATA) ||
883                (connectionState == cs_RENEGOTIATE)) {
884
885            int FragLen = inputRecord.estimateFragmentSize(packetLen);
886            if (FragLen > appRemains) {
887                return new SSLEngineResult(
888                        Status.BUFFER_OVERFLOW, hsStatus, 0, 0);
889            }
890        }
891
892        // check for UNDERFLOW.
893        if ((packetLen == -1) || (netData.remaining() < packetLen)) {
894            return new SSLEngineResult(Status.BUFFER_UNDERFLOW, hsStatus, 0, 0);
895        }
896
897        /*
898         * We're now ready to actually do the read.
899         */
900        Plaintext plainText = null;
901        try {
902            plainText = readRecord(netData, appData, offset, length);
903        } catch (SSLException e) {
904            throw e;
905        } catch (IOException e) {
906            throw new SSLException("readRecord", e);
907        }
908
909        /*
910         * Check the various condition that we could be reporting.
911         *
912         * It's *possible* something might have happened between the
913         * above and now, but it was better to minimally lock "this"
914         * during the read process.  We'll return the current
915         * status, which is more representative of the current state.
916         *
917         * status above should cover:  FINISHED, NEED_TASK
918         */
919        status = (isInboundDone() ? Status.CLOSED : Status.OK);
920        hsStatus = getHSStatus(plainText.handshakeStatus);
921
922        int deltaNet = netData.position() - netPos;
923        int deltaApp = appRemains;
924        for (int i = offset; i < offset + length; i++) {
925            deltaApp -= appData[i].remaining();
926        }
927
928        return new SSLEngineResult(
929                status, hsStatus, deltaNet, deltaApp, plainText.recordSN);
930    }
931
932    // the caller have synchronized readLock
933    void expectingFinishFlight() {
934        inputRecord.expectingFinishFlight();
935    }
936
937    /*
938     * Actually do the read record processing.
939     *
940     * Returns a Status if it can make specific determinations
941     * of the engine state.  In particular, we need to signal
942     * that a handshake just completed.
943     *
944     * It would be nice to be symmetrical with the write side and move
945     * the majority of this to SSLInputRecord, but there's too much
946     * SSLEngine state to do that cleanly.  It must still live here.
947     */
948    private Plaintext readRecord(ByteBuffer netData,
949            ByteBuffer[] appData, int offset, int length) throws IOException {
950
951        /*
952         * The various operations will return new sliced BB's,
953         * this will avoid having to worry about positions and
954         * limits in the netBB.
955         */
956        Plaintext plainText = null;
957
958        if (getConnectionState() == cs_ERROR) {
959            return Plaintext.PLAINTEXT_NULL;
960        }
961
962        /*
963         * Read a record ... maybe emitting an alert if we get a
964         * comprehensible but unsupported "hello" message during
965         * format checking (e.g. V2).
966         */
967        try {
968            if (isDTLS) {
969                // Don't process the incoming record until all of the
970                // buffered records get handled.
971                plainText = inputRecord.acquirePlaintext();
972            }
973
974            if ((!isDTLS || plainText == null) && netData != null) {
975                plainText = inputRecord.decode(netData);
976            }
977        } catch (UnsupportedOperationException unsoe) {         // SSLv2Hello
978            // Hack code to deliver SSLv2 error message for SSL/TLS connections.
979            if (!isDTLS) {
980                outputRecord.encodeV2NoCipher();
981            }
982
983            fatal(Alerts.alert_unexpected_message, unsoe);
984        } catch (BadPaddingException e) {
985            /*
986             * The basic SSLv3 record protection involves (optional)
987             * encryption for privacy, and an integrity check ensuring
988             * data origin authentication.  We do them both here, and
989             * throw a fatal alert if the integrity check fails.
990             */
991            byte alertType = (connectionState != cs_DATA) ?
992                    Alerts.alert_handshake_failure :
993                    Alerts.alert_bad_record_mac;
994            fatal(alertType, e.getMessage(), e);
995        } catch (SSLHandshakeException she) {
996            // may be record sequence number overflow
997            fatal(Alerts.alert_handshake_failure, she);
998        } catch (IOException ioe) {
999            fatal(Alerts.alert_unexpected_message, ioe);
1000        }
1001
1002        // plainText should never be null for TLS protocols
1003        HandshakeStatus hsStatus = null;
1004        if (plainText == Plaintext.PLAINTEXT_NULL) {
1005            // Only happens for DTLS protocols.
1006            //
1007            // Received a retransmitted flight, and need to retransmit the
1008            // previous delivered handshake flight messages.
1009            if (enableRetransmissions) {
1010                if (debug != null && Debug.isOn("verbose")) {
1011                    Debug.log(
1012                        "Retransmit the previous handshake flight messages.");
1013                }
1014
1015                synchronized (this) {
1016                    outputRecord.launchRetransmission();
1017                }
1018            }   // Otherwise, discard the retransmitted flight.
1019        } else if (!isDTLS || plainText != null) {
1020            hsStatus = processInputRecord(plainText, appData, offset, length);
1021        }
1022
1023        if (hsStatus == null) {
1024            hsStatus = getHSStatus(null);
1025        }
1026
1027        if (plainText == null) {
1028            plainText = Plaintext.PLAINTEXT_NULL;
1029        }
1030        plainText.handshakeStatus = hsStatus;
1031
1032        return plainText;
1033    }
1034
1035    /*
1036     * Process the record.
1037     */
1038    private synchronized HandshakeStatus processInputRecord(
1039            Plaintext plainText,
1040            ByteBuffer[] appData, int offset, int length) throws IOException {
1041
1042        HandshakeStatus hsStatus = null;
1043        switch (plainText.contentType) {
1044            case Record.ct_handshake:
1045                /*
1046                 * Handshake messages always go to a pending session
1047                 * handshaker ... if there isn't one, create one.  This
1048                 * must work asynchronously, for renegotiation.
1049                 *
1050                 * NOTE that handshaking will either resume a session
1051                 * which was in the cache (and which might have other
1052                 * connections in it already), or else will start a new
1053                 * session (new keys exchanged) with just this connection
1054                 * in it.
1055                 */
1056                initHandshaker();
1057                if (!handshaker.activated()) {
1058                    // prior to handshaking, activate the handshake
1059                    if (connectionState == cs_RENEGOTIATE) {
1060                        // don't use SSLv2Hello when renegotiating
1061                        handshaker.activate(protocolVersion);
1062                    } else {
1063                        handshaker.activate(null);
1064                    }
1065                }
1066
1067                /*
1068                 * process the handshake record ... may contain just
1069                 * a partial handshake message or multiple messages.
1070                 *
1071                 * The handshaker state machine will ensure that it's
1072                 * a finished message.
1073                 */
1074                handshaker.processRecord(plainText.fragment, expectingFinished);
1075                expectingFinished = false;
1076
1077                if (handshaker.invalidated) {
1078                    finishHandshake();
1079
1080                    // if state is cs_RENEGOTIATE, revert it to cs_DATA
1081                    if (connectionState == cs_RENEGOTIATE) {
1082                        connectionState = cs_DATA;
1083                    }
1084                } else if (handshaker.isDone()) {
1085                    // reset the parameters for secure renegotiation.
1086                    secureRenegotiation =
1087                                handshaker.isSecureRenegotiation();
1088                    clientVerifyData = handshaker.getClientVerifyData();
1089                    serverVerifyData = handshaker.getServerVerifyData();
1090                    // set connection ALPN value
1091                    applicationProtocol =
1092                        handshaker.getHandshakeApplicationProtocol();
1093
1094                    sess = handshaker.getSession();
1095                    handshakeSession = null;
1096                    if (outputRecord.isEmpty()) {
1097                        hsStatus = finishHandshake();
1098                        connectionState = cs_DATA;
1099                    }
1100
1101                    // No handshakeListeners here.  That's a
1102                    // SSLSocket thing.
1103                } else if (handshaker.taskOutstanding()) {
1104                    hsStatus = HandshakeStatus.NEED_TASK;
1105                }
1106                break;
1107
1108            case Record.ct_application_data:
1109                // Pass this right back up to the application.
1110                if ((connectionState != cs_DATA)
1111                        && (connectionState != cs_RENEGOTIATE)
1112                        && (connectionState != cs_CLOSED)) {
1113                    throw new SSLProtocolException(
1114                            "Data received in non-data state: " +
1115                            connectionState);
1116                }
1117
1118                if (expectingFinished) {
1119                    throw new SSLProtocolException
1120                            ("Expecting finished message, received data");
1121                }
1122
1123                if (!inboundDone) {
1124                    ByteBuffer fragment = plainText.fragment;
1125                    int remains = fragment.remaining();
1126
1127                    // Should have enough room in appData.
1128                    for (int i = offset;
1129                            ((i < (offset + length)) && (remains > 0)); i++) {
1130                        int amount = Math.min(appData[i].remaining(), remains);
1131                        fragment.limit(fragment.position() + amount);
1132                        appData[i].put(fragment);
1133                        remains -= amount;
1134                    }
1135                }
1136
1137                break;
1138
1139            case Record.ct_alert:
1140                recvAlert(plainText.fragment);
1141                break;
1142
1143            case Record.ct_change_cipher_spec:
1144                if ((connectionState != cs_HANDSHAKE
1145                        && connectionState != cs_RENEGOTIATE)) {
1146                    // For the CCS message arriving in the wrong state
1147                    fatal(Alerts.alert_unexpected_message,
1148                            "illegal change cipher spec msg, conn state = "
1149                            + connectionState);
1150                } else if (plainText.fragment.remaining() != 1
1151                        || plainText.fragment.get() != 1) {
1152                    // For structural/content issues with the CCS
1153                    fatal(Alerts.alert_unexpected_message,
1154                            "Malformed change cipher spec msg");
1155                }
1156
1157                //
1158                // The first message after a change_cipher_spec
1159                // record MUST be a "Finished" handshake record,
1160                // else it's a protocol violation.  We force this
1161                // to be checked by a minor tweak to the state
1162                // machine.
1163                //
1164                handshaker.receiveChangeCipherSpec();
1165
1166                CipherBox readCipher;
1167                Authenticator readAuthenticator;
1168                try {
1169                    readCipher = handshaker.newReadCipher();
1170                    readAuthenticator = handshaker.newReadAuthenticator();
1171                } catch (GeneralSecurityException e) {
1172                    // can't happen
1173                    throw new SSLException("Algorithm missing:  ", e);
1174                }
1175                inputRecord.changeReadCiphers(readAuthenticator, readCipher);
1176
1177                // next message MUST be a finished message
1178                expectingFinished = true;
1179                break;
1180
1181            default:
1182                //
1183                // TLS requires that unrecognized records be ignored.
1184                //
1185                if (debug != null && Debug.isOn("ssl")) {
1186                    System.out.println(Thread.currentThread().getName() +
1187                            ", Received record type: " + plainText.contentType);
1188                }
1189                break;
1190        } // switch
1191
1192        /*
1193         * We only need to check the sequence number state for
1194         * non-handshaking record.
1195         *
1196         * Note that in order to maintain the handshake status
1197         * properly, we check the sequence number after the last
1198         * record reading process. As we request renegotiation
1199         * or close the connection for wrapped sequence number
1200         * when there is enough sequence number space left to
1201         * handle a few more records, so the sequence number
1202         * of the last record cannot be wrapped.
1203         */
1204        hsStatus = getHSStatus(hsStatus);
1205        if (connectionState < cs_ERROR && !isInboundDone() &&
1206                (hsStatus == HandshakeStatus.NOT_HANDSHAKING) &&
1207                (inputRecord.seqNumIsHuge())) {
1208            /*
1209             * Ask for renegotiation when need to renew sequence number.
1210             *
1211             * Don't bother to kickstart the renegotiation when the local is
1212             * asking for it.
1213             */
1214            if (debug != null && Debug.isOn("ssl")) {
1215                System.out.println(Thread.currentThread().getName() +
1216                        ", request renegotiation " +
1217                        "to avoid sequence number overflow");
1218            }
1219
1220            beginHandshake();
1221
1222            hsStatus = getHSStatus(null);
1223        }
1224
1225        return hsStatus;
1226    }
1227
1228
1229    //
1230    // write/wrap side
1231    //
1232
1233
1234    /**
1235     * Wraps a buffer.  Does a variety of checks before grabbing
1236     * the wrapLock, which blocks multiple wraps from occurring.
1237     */
1238    @Override
1239    public SSLEngineResult wrap(ByteBuffer[] appData,
1240            int offset, int length, ByteBuffer netData) throws SSLException {
1241
1242        // check engine parameters
1243        checkEngineParas(netData, appData, offset, length, true);
1244
1245        /*
1246         * We can be smarter about using smaller buffer sizes later.
1247         * For now, force it to be large enough to handle any valid record.
1248         */
1249        if (netData.remaining() < sess.getPacketBufferSize()) {
1250            return new SSLEngineResult(
1251                Status.BUFFER_OVERFLOW, getHSStatus(null), 0, 0);
1252        }
1253
1254        try {
1255            synchronized (wrapLock) {
1256                return writeAppRecord(appData, offset, length, netData);
1257            }
1258        } catch (SSLProtocolException spe) {
1259            // may be an unexpected handshake message
1260            fatal(Alerts.alert_unexpected_message, spe.getMessage(), spe);
1261            return null;  // make compiler happy
1262        } catch (Exception e) {
1263            fatal(Alerts.alert_internal_error,
1264                "problem wrapping app data", e);
1265            return null;  // make compiler happy
1266        }
1267    }
1268
1269    /*
1270     * Makes additional checks for unwrap, but this time more
1271     * specific to this packet and the current state of the machine.
1272     */
1273    private SSLEngineResult writeAppRecord(ByteBuffer[] appData,
1274            int offset, int length, ByteBuffer netData) throws IOException {
1275
1276        Status status = null;
1277        HandshakeStatus hsStatus = null;
1278
1279        /*
1280         * See if the handshaker needs to report back some SSLException.
1281         */
1282        checkTaskThrown();
1283
1284        /*
1285         * short circuit if we're closed/closing.
1286         */
1287        if (isOutboundDone()) {
1288            return new SSLEngineResult(Status.CLOSED, getHSStatus(null), 0, 0);
1289        }
1290
1291        /*
1292         * If we're still in cs_HANDSHAKE, make sure it's been
1293         * started.
1294         */
1295        synchronized (this) {
1296            if ((connectionState == cs_HANDSHAKE) ||
1297                (connectionState == cs_START)) {
1298
1299                kickstartHandshake();
1300
1301                /*
1302                 * If there's no HS data available to write, we can return
1303                 * without trying to wrap anything.
1304                 */
1305                hsStatus = getHSStatus(null);
1306                if (hsStatus == HandshakeStatus.NEED_UNWRAP) {
1307                    /*
1308                     * For DTLS, if the handshake state is
1309                     * HandshakeStatus.NEED_UNWRAP, a call to SSLEngine.wrap()
1310                     * means that the previous handshake packets (if delivered)
1311                     * get lost, and need retransmit the handshake messages.
1312                     */
1313                    if (!isDTLS || !enableRetransmissions ||
1314                            (handshaker == null) || outputRecord.firstMessage) {
1315
1316                        return new SSLEngineResult(Status.OK, hsStatus, 0, 0);
1317                    }   // otherwise, need retransmission
1318                }
1319            }
1320        }
1321
1322        /*
1323         * Grab a copy of this if it doesn't already exist,
1324         * and we can use it several places before anything major
1325         * happens on this side.  Races aren't critical
1326         * here.
1327         */
1328        if (hsStatus == null) {
1329            hsStatus = getHSStatus(null);
1330        }
1331
1332        /*
1333         * If we have a task outstanding, this *MUST* be done before
1334         * doing any more wrapping, because we could be in the middle
1335         * of receiving a handshake message, for example, a finished
1336         * message which would change the ciphers.
1337         */
1338        if (hsStatus == HandshakeStatus.NEED_TASK) {
1339            return new SSLEngineResult(Status.OK, hsStatus, 0, 0);
1340        }
1341
1342        /*
1343         * This will obtain any waiting outbound data, or will
1344         * process the outbound appData.
1345         */
1346        int netPos = netData.position();
1347        int appRemains = 0;
1348        for (int i = offset; i < offset + length; i++) {
1349            if (appData[i] == null) {
1350                throw new IllegalArgumentException(
1351                        "appData[" + i + "] == null");
1352            }
1353            appRemains += appData[i].remaining();
1354        }
1355
1356        Ciphertext ciphertext = null;
1357        try {
1358            if (appRemains != 0) {
1359                synchronized (writeLock) {
1360                    ciphertext = writeRecord(appData, offset, length, netData);
1361                }
1362            } else {
1363                synchronized (writeLock) {
1364                    ciphertext = writeRecord(null, 0, 0, netData);
1365                }
1366            }
1367        } catch (SSLException e) {
1368            throw e;
1369        } catch (IOException e) {
1370            throw new SSLException("Write problems", e);
1371        }
1372
1373        /*
1374         * writeRecord might have reported some status.
1375         * Now check for the remaining cases.
1376         *
1377         * status above should cover:  NEED_WRAP/FINISHED
1378         */
1379        status = (isOutboundDone() ? Status.CLOSED : Status.OK);
1380        hsStatus = getHSStatus(ciphertext.handshakeStatus);
1381
1382        int deltaNet = netData.position() - netPos;
1383        int deltaApp = appRemains;
1384        for (int i = offset; i < offset + length; i++) {
1385            deltaApp -= appData[i].remaining();
1386        }
1387
1388        return new SSLEngineResult(
1389                status, hsStatus, deltaApp, deltaNet, ciphertext.recordSN);
1390    }
1391
1392    /*
1393     * Central point to write/get all of the outgoing data.
1394     */
1395    private Ciphertext writeRecord(ByteBuffer[] appData,
1396            int offset, int length, ByteBuffer netData) throws IOException {
1397
1398        Ciphertext ciphertext = null;
1399        try {
1400            // Acquire the buffered to-be-delivered records or retransmissions.
1401            //
1402            // May have buffered records, or need retransmission if handshaking.
1403            if (!outputRecord.isEmpty() ||
1404                    (enableRetransmissions && handshaker != null)) {
1405                ciphertext = outputRecord.acquireCiphertext(netData);
1406            }
1407
1408            if ((ciphertext == null) && (appData != null)) {
1409                ciphertext = outputRecord.encode(
1410                        appData, offset, length, netData);
1411            }
1412        } catch (SSLHandshakeException she) {
1413            // may be record sequence number overflow
1414            fatal(Alerts.alert_handshake_failure, she);
1415
1416            return Ciphertext.CIPHERTEXT_NULL;   // make the complier happy
1417        } catch (IOException e) {
1418            fatal(Alerts.alert_unexpected_message, e);
1419
1420            return Ciphertext.CIPHERTEXT_NULL;   // make the complier happy
1421        }
1422
1423        if (ciphertext == null) {
1424            return Ciphertext.CIPHERTEXT_NULL;
1425        }
1426
1427        HandshakeStatus hsStatus = null;
1428        Ciphertext.RecordType recordType = ciphertext.recordType;
1429        if ((recordType.contentType == Record.ct_handshake) &&
1430            (recordType.handshakeType == HandshakeMessage.ht_finished) &&
1431            outputRecord.isEmpty()) {
1432
1433            if (handshaker == null) {
1434                hsStatus = HandshakeStatus.FINISHED;
1435            } else if (handshaker.isDone()) {
1436                hsStatus = finishHandshake();
1437                connectionState = cs_DATA;
1438
1439                // Retransmit the last flight twice.
1440                //
1441                // The application data transactions may begin immediately
1442                // after the last flight.  If the last flight get lost, the
1443                // application data may be discarded accordingly.  As could
1444                // be an issue for some applications.  This impact can be
1445                // mitigated by sending the last fligth twice.
1446                if (isDTLS && enableRetransmissions) {
1447                    if (debug != null && Debug.isOn("verbose")) {
1448                        Debug.log(
1449                            "Retransmit the last flight messages.");
1450                    }
1451
1452                    synchronized (this) {
1453                        outputRecord.launchRetransmission();
1454                    }
1455
1456                    hsStatus = HandshakeStatus.NEED_WRAP;
1457                }
1458            }
1459        }   // Otherwise, the followed call to getHSStatus() will help.
1460
1461        /*
1462         * We only need to check the sequence number state for
1463         * non-handshaking record.
1464         *
1465         * Note that in order to maintain the handshake status
1466         * properly, we check the sequence number after the last
1467         * record writing process. As we request renegotiation
1468         * or close the connection for wrapped sequence number
1469         * when there is enough sequence number space left to
1470         * handle a few more records, so the sequence number
1471         * of the last record cannot be wrapped.
1472         */
1473        hsStatus = getHSStatus(hsStatus);
1474        if (connectionState < cs_ERROR && !isOutboundDone() &&
1475                (hsStatus == HandshakeStatus.NOT_HANDSHAKING) &&
1476                (outputRecord.seqNumIsHuge())) {
1477            /*
1478             * Ask for renegotiation when need to renew sequence number.
1479             *
1480             * Don't bother to kickstart the renegotiation when the local is
1481             * asking for it.
1482             */
1483            if (debug != null && Debug.isOn("ssl")) {
1484                System.out.println(Thread.currentThread().getName() +
1485                        ", request renegotiation " +
1486                        "to avoid sequence number overflow");
1487            }
1488
1489            beginHandshake();
1490
1491            hsStatus = getHSStatus(null);
1492        }
1493        ciphertext.handshakeStatus = hsStatus;
1494
1495        return ciphertext;
1496    }
1497
1498    private HandshakeStatus finishHandshake() {
1499        handshaker = null;
1500        inputRecord.setHandshakeHash(null);
1501        outputRecord.setHandshakeHash(null);
1502        connectionState = cs_DATA;
1503
1504       return HandshakeStatus.FINISHED;
1505   }
1506
1507    //
1508    // Close code
1509    //
1510
1511    /**
1512     * Signals that no more outbound application data will be sent
1513     * on this <code>SSLEngine</code>.
1514     */
1515    private void closeOutboundInternal() {
1516
1517        if ((debug != null) && Debug.isOn("ssl")) {
1518            System.out.println(Thread.currentThread().getName() +
1519                                    ", closeOutboundInternal()");
1520        }
1521
1522        /*
1523         * Already closed, ignore
1524         */
1525        if (outboundDone) {
1526            return;
1527        }
1528
1529        switch (connectionState) {
1530
1531        /*
1532         * If we haven't even started yet, don't bother reading inbound.
1533         */
1534        case cs_START:
1535            try {
1536                outputRecord.close();
1537            } catch (IOException ioe) {
1538               // ignore
1539            }
1540            outboundDone = true;
1541
1542            try {
1543                inputRecord.close();
1544            } catch (IOException ioe) {
1545               // ignore
1546            }
1547            inboundDone = true;
1548            break;
1549
1550        case cs_ERROR:
1551        case cs_CLOSED:
1552            break;
1553
1554        /*
1555         * Otherwise we indicate clean termination.
1556         */
1557        // case cs_HANDSHAKE:
1558        // case cs_DATA:
1559        // case cs_RENEGOTIATE:
1560        default:
1561            warning(Alerts.alert_close_notify);
1562            try {
1563                outputRecord.close();
1564            } catch (IOException ioe) {
1565               // ignore
1566            }
1567            outboundDone = true;
1568            break;
1569        }
1570
1571        connectionState = cs_CLOSED;
1572    }
1573
1574    @Override
1575    public synchronized void closeOutbound() {
1576        /*
1577         * Dump out a close_notify to the remote side
1578         */
1579        if ((debug != null) && Debug.isOn("ssl")) {
1580            System.out.println(Thread.currentThread().getName() +
1581                                    ", called closeOutbound()");
1582        }
1583
1584        closeOutboundInternal();
1585    }
1586
1587    /**
1588     * Returns the outbound application data closure state
1589     */
1590    @Override
1591    public boolean isOutboundDone() {
1592        return outboundDone && outputRecord.isEmpty();
1593    }
1594
1595    /**
1596     * Signals that no more inbound network data will be sent
1597     * to this <code>SSLEngine</code>.
1598     */
1599    private void closeInboundInternal() {
1600
1601        if ((debug != null) && Debug.isOn("ssl")) {
1602            System.out.println(Thread.currentThread().getName() +
1603                                    ", closeInboundInternal()");
1604        }
1605
1606        /*
1607         * Already closed, ignore
1608         */
1609        if (inboundDone) {
1610            return;
1611        }
1612
1613        closeOutboundInternal();
1614
1615        try {
1616            inputRecord.close();
1617        } catch (IOException ioe) {
1618           // ignore
1619        }
1620        inboundDone = true;
1621
1622        connectionState = cs_CLOSED;
1623    }
1624
1625    /*
1626     * Close the inbound side of the connection.  We grab the
1627     * lock here, and do the real work in the internal verison.
1628     * We do check for truncation attacks.
1629     */
1630    @Override
1631    public synchronized void closeInbound() throws SSLException {
1632        /*
1633         * Currently closes the outbound side as well.  The IETF TLS
1634         * working group has expressed the opinion that 1/2 open
1635         * connections are not allowed by the spec.  May change
1636         * someday in the future.
1637         */
1638        if ((debug != null) && Debug.isOn("ssl")) {
1639            System.out.println(Thread.currentThread().getName() +
1640                                    ", called closeInbound()");
1641        }
1642
1643        /*
1644         * No need to throw an Exception if we haven't even started yet.
1645         */
1646        if ((connectionState != cs_START) && !recvCN) {
1647            recvCN = true;  // Only receive the Exception once
1648            fatal(Alerts.alert_internal_error,
1649                "Inbound closed before receiving peer's close_notify: " +
1650                "possible truncation attack?");
1651        } else {
1652            /*
1653             * Currently, this is a no-op, but in case we change
1654             * the close inbound code later.
1655             */
1656            closeInboundInternal();
1657        }
1658    }
1659
1660    /**
1661     * Returns the network inbound data closure state
1662     */
1663    @Override
1664    public synchronized boolean isInboundDone() {
1665        return inboundDone;
1666    }
1667
1668
1669    //
1670    // Misc stuff
1671    //
1672
1673
1674    /**
1675     * Returns the current <code>SSLSession</code> for this
1676     * <code>SSLEngine</code>
1677     * <P>
1678     * These can be long lived, and frequently correspond to an
1679     * entire login session for some user.
1680     */
1681    @Override
1682    public synchronized SSLSession getSession() {
1683        return sess;
1684    }
1685
1686    @Override
1687    public synchronized SSLSession getHandshakeSession() {
1688        return handshakeSession;
1689    }
1690
1691    synchronized void setHandshakeSession(SSLSessionImpl session) {
1692        // update the fragment size, which may be negotiated during handshaking
1693        inputRecord.changeFragmentSize(session.getNegotiatedMaxFragSize());
1694        outputRecord.changeFragmentSize(session.getNegotiatedMaxFragSize());
1695
1696        handshakeSession = session;
1697    }
1698
1699    /**
1700     * Returns a delegated <code>Runnable</code> task for
1701     * this <code>SSLEngine</code>.
1702     */
1703    @Override
1704    public synchronized Runnable getDelegatedTask() {
1705        if (handshaker != null) {
1706            return handshaker.getTask();
1707        }
1708        return null;
1709    }
1710
1711
1712    //
1713    // EXCEPTION AND ALERT HANDLING
1714    //
1715
1716    /*
1717     * Send a warning alert.
1718     */
1719    void warning(byte description) {
1720        sendAlert(Alerts.alert_warning, description);
1721    }
1722
1723    synchronized void fatal(byte description, String diagnostic)
1724            throws SSLException {
1725        fatal(description, diagnostic, null, false);
1726    }
1727
1728    synchronized void fatal(byte description, Throwable cause)
1729            throws SSLException {
1730        fatal(description, null, cause, false);
1731    }
1732
1733    synchronized void fatal(byte description, String diagnostic,
1734            Throwable cause) throws SSLException {
1735        fatal(description, diagnostic, cause, false);
1736    }
1737
1738    /*
1739     * We've got a fatal error here, so start the shutdown process.
1740     *
1741     * Because of the way the code was written, we have some code
1742     * calling fatal directly when the "description" is known
1743     * and some throwing Exceptions which are then caught by higher
1744     * levels which then call here.  This code needs to determine
1745     * if one of the lower levels has already started the process.
1746     *
1747     * We won't worry about Errors, if we have one of those,
1748     * we're in worse trouble.  Note:  the networking code doesn't
1749     * deal with Errors either.
1750     */
1751    synchronized void fatal(byte description, String diagnostic,
1752            Throwable cause, boolean recvFatalAlert) throws SSLException {
1753
1754        /*
1755         * If we have no further information, make a general-purpose
1756         * message for folks to see.  We generally have one or the other.
1757         */
1758        if (diagnostic == null) {
1759            diagnostic = "General SSLEngine problem";
1760        }
1761        if (cause == null) {
1762            cause = Alerts.getSSLException(description, cause, diagnostic);
1763        }
1764
1765        /*
1766         * If we've already shutdown because of an error,
1767         * there is nothing we can do except rethrow the exception.
1768         *
1769         * Most exceptions seen here will be SSLExceptions.
1770         * We may find the occasional Exception which hasn't been
1771         * converted to a SSLException, so we'll do it here.
1772         */
1773        if (closeReason != null) {
1774            if ((debug != null) && Debug.isOn("ssl")) {
1775                System.out.println(Thread.currentThread().getName() +
1776                    ", fatal: engine already closed.  Rethrowing " +
1777                    cause.toString());
1778            }
1779            if (cause instanceof RuntimeException) {
1780                throw (RuntimeException)cause;
1781            } else if (cause instanceof SSLException) {
1782                throw (SSLException)cause;
1783            } else if (cause instanceof Exception) {
1784                throw new SSLException("fatal SSLEngine condition", cause);
1785            }
1786        }
1787
1788        if ((debug != null) && Debug.isOn("ssl")) {
1789            System.out.println(Thread.currentThread().getName()
1790                        + ", fatal error: " + description +
1791                        ": " + diagnostic + "\n" + cause.toString());
1792        }
1793
1794        /*
1795         * Ok, this engine's going down.
1796         */
1797        int oldState = connectionState;
1798        connectionState = cs_ERROR;
1799
1800        try {
1801            inputRecord.close();
1802        } catch (IOException ioe) {
1803           // ignore
1804        }
1805        inboundDone = true;
1806
1807        sess.invalidate();
1808        if (handshakeSession != null) {
1809            handshakeSession.invalidate();
1810        }
1811
1812        /*
1813         * If we haven't even started handshaking yet, or we are the
1814         * recipient of a fatal alert, no need to generate a fatal close
1815         * alert.
1816         */
1817        if (oldState != cs_START && !recvFatalAlert) {
1818            sendAlert(Alerts.alert_fatal, description);
1819        }
1820
1821        if (cause instanceof SSLException) { // only true if != null
1822            closeReason = (SSLException)cause;
1823        } else {
1824            /*
1825             * Including RuntimeExceptions, but we'll throw those
1826             * down below.  The closeReason isn't used again,
1827             * except for null checks.
1828             */
1829            closeReason =
1830                Alerts.getSSLException(description, cause, diagnostic);
1831        }
1832
1833        try {
1834            outputRecord.close();
1835        } catch (IOException ioe) {
1836           // ignore
1837        }
1838        outboundDone = true;
1839
1840        connectionState = cs_CLOSED;
1841
1842        if (cause instanceof RuntimeException) {
1843            throw (RuntimeException)cause;
1844        } else {
1845            throw closeReason;
1846        }
1847    }
1848
1849    /*
1850     * Process an incoming alert ... caller must already have synchronized
1851     * access to "this".
1852     */
1853    private void recvAlert(ByteBuffer fragment) throws IOException {
1854        byte level = fragment.get();
1855        byte description = fragment.get();
1856
1857        if (debug != null && (Debug.isOn("record") ||
1858                Debug.isOn("handshake"))) {
1859            synchronized (System.out) {
1860                System.out.print(Thread.currentThread().getName());
1861                System.out.print(", RECV " + protocolVersion + " ALERT:  ");
1862                if (level == Alerts.alert_fatal) {
1863                    System.out.print("fatal, ");
1864                } else if (level == Alerts.alert_warning) {
1865                    System.out.print("warning, ");
1866                } else {
1867                    System.out.print("<level " + (0x0ff & level) + ">, ");
1868                }
1869                System.out.println(Alerts.alertDescription(description));
1870            }
1871        }
1872
1873        if (level == Alerts.alert_warning) {
1874            if (description == -1) {    // check for short message
1875                fatal(Alerts.alert_illegal_parameter, "Short alert message");
1876            } else if (description == Alerts.alert_close_notify) {
1877                if (connectionState == cs_HANDSHAKE) {
1878                    fatal(Alerts.alert_unexpected_message,
1879                                "Received close_notify during handshake");
1880                } else {
1881                    recvCN = true;
1882                    closeInboundInternal();  // reply to close
1883                }
1884            } else {
1885
1886                //
1887                // The other legal warnings relate to certificates,
1888                // e.g. no_certificate, bad_certificate, etc; these
1889                // are important to the handshaking code, which can
1890                // also handle illegal protocol alerts if needed.
1891                //
1892                if (handshaker != null) {
1893                    handshaker.handshakeAlert(description);
1894                }
1895            }
1896        } else { // fatal or unknown level
1897            String reason = "Received fatal alert: "
1898                + Alerts.alertDescription(description);
1899
1900            // The inbound and outbound queues will be closed as part of
1901            // the call to fatal.  The handhaker to needs to be set to null
1902            // so subsequent calls to getHandshakeStatus will return
1903            // NOT_HANDSHAKING.
1904            handshaker = null;
1905            Throwable cause = Alerts.getSSLException(description, reason);
1906            fatal(description, null, cause, true);
1907        }
1908    }
1909
1910
1911    /*
1912     * Emit alerts.  Caller must have synchronized with "this".
1913     */
1914    private void sendAlert(byte level, byte description) {
1915        // the connectionState cannot be cs_START
1916        if (connectionState >= cs_CLOSED) {
1917            return;
1918        }
1919
1920        // For initial handshaking, don't send alert message to peer if
1921        // handshaker has not started.
1922        //
1923        // Shall we send an fatal alter to terminate the connection gracefully?
1924        if (connectionState <= cs_HANDSHAKE &&
1925                (handshaker == null || !handshaker.started() ||
1926                        !handshaker.activated())) {
1927            return;
1928        }
1929
1930        try {
1931            outputRecord.encodeAlert(level, description);
1932        } catch (IOException ioe) {
1933            // ignore
1934        }
1935    }
1936
1937
1938    //
1939    // VARIOUS OTHER METHODS (COMMON TO SSLSocket)
1940    //
1941
1942
1943    /**
1944     * Controls whether new connections may cause creation of new SSL
1945     * sessions.
1946     *
1947     * As long as handshaking has not started, we can change
1948     * whether we enable session creations.  Otherwise,
1949     * we will need to wait for the next handshake.
1950     */
1951    @Override
1952    public synchronized void setEnableSessionCreation(boolean flag) {
1953        enableSessionCreation = flag;
1954
1955        if ((handshaker != null) && !handshaker.activated()) {
1956            handshaker.setEnableSessionCreation(enableSessionCreation);
1957        }
1958    }
1959
1960    /**
1961     * Returns true if new connections may cause creation of new SSL
1962     * sessions.
1963     */
1964    @Override
1965    public synchronized boolean getEnableSessionCreation() {
1966        return enableSessionCreation;
1967    }
1968
1969
1970    /**
1971     * Sets the flag controlling whether a server mode engine
1972     * *REQUIRES* SSL client authentication.
1973     *
1974     * As long as handshaking has not started, we can change
1975     * whether client authentication is needed.  Otherwise,
1976     * we will need to wait for the next handshake.
1977     */
1978    @Override
1979    public synchronized void setNeedClientAuth(boolean flag) {
1980        doClientAuth = (flag ?
1981                ClientAuthType.CLIENT_AUTH_REQUIRED :
1982                ClientAuthType.CLIENT_AUTH_NONE);
1983
1984        if ((handshaker != null) &&
1985                (handshaker instanceof ServerHandshaker) &&
1986                !handshaker.activated()) {
1987            ((ServerHandshaker) handshaker).setClientAuth(doClientAuth);
1988        }
1989    }
1990
1991    @Override
1992    public synchronized boolean getNeedClientAuth() {
1993        return (doClientAuth == ClientAuthType.CLIENT_AUTH_REQUIRED);
1994    }
1995
1996    /**
1997     * Sets the flag controlling whether a server mode engine
1998     * *REQUESTS* SSL client authentication.
1999     *
2000     * As long as handshaking has not started, we can change
2001     * whether client authentication is requested.  Otherwise,
2002     * we will need to wait for the next handshake.
2003     */
2004    @Override
2005    public synchronized void setWantClientAuth(boolean flag) {
2006        doClientAuth = (flag ?
2007                ClientAuthType.CLIENT_AUTH_REQUESTED :
2008                ClientAuthType.CLIENT_AUTH_NONE);
2009
2010        if ((handshaker != null) &&
2011                (handshaker instanceof ServerHandshaker) &&
2012                !handshaker.activated()) {
2013            ((ServerHandshaker) handshaker).setClientAuth(doClientAuth);
2014        }
2015    }
2016
2017    @Override
2018    public synchronized boolean getWantClientAuth() {
2019        return (doClientAuth == ClientAuthType.CLIENT_AUTH_REQUESTED);
2020    }
2021
2022
2023    /**
2024     * Sets the flag controlling whether the engine is in SSL
2025     * client or server mode.  Must be called before any SSL
2026     * traffic has started.
2027     */
2028    @Override
2029    @SuppressWarnings("fallthrough")
2030    public synchronized void setUseClientMode(boolean flag) {
2031        switch (connectionState) {
2032
2033        case cs_START:
2034            /*
2035             * If we need to change the socket mode and the enabled
2036             * protocols and cipher suites haven't specifically been
2037             * set by the user, change them to the corresponding
2038             * default ones.
2039             */
2040            if (roleIsServer != (!flag)) {
2041                if (sslContext.isDefaultProtocolList(enabledProtocols)) {
2042                    enabledProtocols =
2043                            sslContext.getDefaultProtocolList(!flag);
2044                }
2045
2046                if (sslContext.isDefaultCipherSuiteList(enabledCipherSuites)) {
2047                    enabledCipherSuites =
2048                            sslContext.getDefaultCipherSuiteList(!flag);
2049                }
2050            }
2051
2052            roleIsServer = !flag;
2053            serverModeSet = true;
2054            break;
2055
2056        case cs_HANDSHAKE:
2057            /*
2058             * If we have a handshaker, but haven't started
2059             * SSL traffic, we can throw away our current
2060             * handshaker, and start from scratch.  Don't
2061             * need to call doneConnect() again, we already
2062             * have the streams.
2063             */
2064            assert(handshaker != null);
2065            if (!handshaker.activated()) {
2066                /*
2067                 * If we need to change the socket mode and the enabled
2068                 * protocols and cipher suites haven't specifically been
2069                 * set by the user, change them to the corresponding
2070                 * default ones.
2071                 */
2072                if (roleIsServer != (!flag)) {
2073                    if (sslContext.isDefaultProtocolList(enabledProtocols)) {
2074                        enabledProtocols =
2075                                sslContext.getDefaultProtocolList(!flag);
2076                    }
2077
2078                    if (sslContext.isDefaultCipherSuiteList(
2079                                                    enabledCipherSuites)) {
2080                        enabledCipherSuites =
2081                            sslContext.getDefaultCipherSuiteList(!flag);
2082                    }
2083                }
2084
2085                roleIsServer = !flag;
2086                connectionState = cs_START;
2087                initHandshaker();
2088                break;
2089            }
2090
2091            // If handshake has started, that's an error.  Fall through...
2092
2093        default:
2094            if (debug != null && Debug.isOn("ssl")) {
2095                System.out.println(Thread.currentThread().getName() +
2096                    ", setUseClientMode() invoked in state = " +
2097                    connectionState);
2098            }
2099
2100            /*
2101             * We can let them continue if they catch this correctly,
2102             * we don't need to shut this down.
2103             */
2104            throw new IllegalArgumentException(
2105                "Cannot change mode after SSL traffic has started");
2106        }
2107    }
2108
2109    @Override
2110    public synchronized boolean getUseClientMode() {
2111        return !roleIsServer;
2112    }
2113
2114
2115    /**
2116     * Returns the names of the cipher suites which could be enabled for use
2117     * on an SSL connection.  Normally, only a subset of these will actually
2118     * be enabled by default, since this list may include cipher suites which
2119     * do not support the mutual authentication of servers and clients, or
2120     * which do not protect data confidentiality.  Servers may also need
2121     * certain kinds of certificates to use certain cipher suites.
2122     *
2123     * @return an array of cipher suite names
2124     */
2125    @Override
2126    public String[] getSupportedCipherSuites() {
2127        return sslContext.getSupportedCipherSuiteList().toStringArray();
2128    }
2129
2130    /**
2131     * Controls which particular cipher suites are enabled for use on
2132     * this connection.  The cipher suites must have been listed by
2133     * getCipherSuites() as being supported.  Even if a suite has been
2134     * enabled, it might never be used if no peer supports it or the
2135     * requisite certificates (and private keys) are not available.
2136     *
2137     * @param suites Names of all the cipher suites to enable.
2138     */
2139    @Override
2140    public synchronized void setEnabledCipherSuites(String[] suites) {
2141        enabledCipherSuites = new CipherSuiteList(suites);
2142        if ((handshaker != null) && !handshaker.activated()) {
2143            handshaker.setEnabledCipherSuites(enabledCipherSuites);
2144        }
2145    }
2146
2147    /**
2148     * Returns the names of the SSL cipher suites which are currently enabled
2149     * for use on this connection.  When an SSL engine is first created,
2150     * all enabled cipher suites <em>(a)</em> protect data confidentiality,
2151     * by traffic encryption, and <em>(b)</em> can mutually authenticate
2152     * both clients and servers.  Thus, in some environments, this value
2153     * might be empty.
2154     *
2155     * @return an array of cipher suite names
2156     */
2157    @Override
2158    public synchronized String[] getEnabledCipherSuites() {
2159        return enabledCipherSuites.toStringArray();
2160    }
2161
2162
2163    /**
2164     * Returns the protocols that are supported by this implementation.
2165     * A subset of the supported protocols may be enabled for this connection
2166     * @return an array of protocol names.
2167     */
2168    @Override
2169    public String[] getSupportedProtocols() {
2170        return sslContext.getSuportedProtocolList().toStringArray();
2171    }
2172
2173    /**
2174     * Controls which protocols are enabled for use on
2175     * this connection.  The protocols must have been listed by
2176     * getSupportedProtocols() as being supported.
2177     *
2178     * @param protocols protocols to enable.
2179     * @exception IllegalArgumentException when one of the protocols
2180     *  named by the parameter is not supported.
2181     */
2182    @Override
2183    public synchronized void setEnabledProtocols(String[] protocols) {
2184        enabledProtocols = new ProtocolList(protocols);
2185        if ((handshaker != null) && !handshaker.activated()) {
2186            handshaker.setEnabledProtocols(enabledProtocols);
2187        }
2188    }
2189
2190    @Override
2191    public synchronized String[] getEnabledProtocols() {
2192        return enabledProtocols.toStringArray();
2193    }
2194
2195    /**
2196     * Returns the SSLParameters in effect for this SSLEngine.
2197     */
2198    @Override
2199    public synchronized SSLParameters getSSLParameters() {
2200        SSLParameters params = super.getSSLParameters();
2201
2202        // the super implementation does not handle the following parameters
2203        params.setEndpointIdentificationAlgorithm(identificationProtocol);
2204        params.setAlgorithmConstraints(algorithmConstraints);
2205        params.setSNIMatchers(sniMatchers);
2206        params.setServerNames(serverNames);
2207        params.setUseCipherSuitesOrder(preferLocalCipherSuites);
2208        params.setEnableRetransmissions(enableRetransmissions);
2209        params.setMaximumPacketSize(maximumPacketSize);
2210        params.setApplicationProtocols(applicationProtocols);
2211
2212        return params;
2213    }
2214
2215    /**
2216     * Applies SSLParameters to this engine.
2217     */
2218    @Override
2219    public synchronized void setSSLParameters(SSLParameters params) {
2220        super.setSSLParameters(params);
2221
2222        // the super implementation does not handle the following parameters
2223        identificationProtocol = params.getEndpointIdentificationAlgorithm();
2224        algorithmConstraints = params.getAlgorithmConstraints();
2225        preferLocalCipherSuites = params.getUseCipherSuitesOrder();
2226        enableRetransmissions = params.getEnableRetransmissions();
2227        maximumPacketSize = params.getMaximumPacketSize();
2228
2229        if (maximumPacketSize != 0) {
2230            outputRecord.changePacketSize(maximumPacketSize);
2231        } else {
2232            // use the implicit maximum packet size.
2233            maximumPacketSize = outputRecord.getMaxPacketSize();
2234        }
2235
2236        List<SNIServerName> sniNames = params.getServerNames();
2237        if (sniNames != null) {
2238            serverNames = sniNames;
2239        }
2240
2241        Collection<SNIMatcher> matchers = params.getSNIMatchers();
2242        if (matchers != null) {
2243            sniMatchers = matchers;
2244        }
2245        applicationProtocols = params.getApplicationProtocols();
2246
2247        if ((handshaker != null) && !handshaker.activated()) {
2248            handshaker.setIdentificationProtocol(identificationProtocol);
2249            handshaker.setAlgorithmConstraints(algorithmConstraints);
2250            handshaker.setMaximumPacketSize(maximumPacketSize);
2251            handshaker.setApplicationProtocols(applicationProtocols);
2252            if (roleIsServer) {
2253                handshaker.setSNIMatchers(sniMatchers);
2254                handshaker.setUseCipherSuitesOrder(preferLocalCipherSuites);
2255            } else {
2256                handshaker.setSNIServerNames(serverNames);
2257            }
2258        }
2259    }
2260
2261    @Override
2262    public synchronized String getApplicationProtocol() {
2263        return applicationProtocol;
2264    }
2265
2266    @Override
2267    public synchronized String getHandshakeApplicationProtocol() {
2268        if ((handshaker != null) && handshaker.started()) {
2269            return handshaker.getHandshakeApplicationProtocol();
2270        }
2271        return null;
2272    }
2273
2274    @Override
2275    public synchronized void setHandshakeApplicationProtocolSelector(
2276        BiFunction<SSLEngine, List<String>, String> selector) {
2277        applicationProtocolSelector = selector;
2278        if ((handshaker != null) && !handshaker.activated()) {
2279            handshaker.setApplicationProtocolSelectorSSLEngine(selector);
2280        }
2281    }
2282
2283    @Override
2284    public synchronized BiFunction<SSLEngine, List<String>, String>
2285        getHandshakeApplicationProtocolSelector() {
2286        return this.applicationProtocolSelector;
2287    }
2288
2289    /**
2290     * Returns a printable representation of this end of the connection.
2291     */
2292    @Override
2293    public String toString() {
2294        StringBuilder retval = new StringBuilder(80);
2295
2296        retval.append(Integer.toHexString(hashCode()));
2297        retval.append("[");
2298        retval.append("SSLEngine[hostname=");
2299        String host = getPeerHost();
2300        retval.append((host == null) ? "null" : host);
2301        retval.append(" port=");
2302        retval.append(Integer.toString(getPeerPort()));
2303        retval.append(" role=" + (roleIsServer ? "Server" : "Client"));
2304        retval.append("] ");
2305        retval.append(getSession().getCipherSuite());
2306        retval.append("]");
2307
2308        return retval.toString();
2309    }
2310}
2311