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 
  26 package sun.security.ssl;
  27 
  28 import java.io.*;
  29 import java.nio.*;
  30 import java.security.*;
  31 import java.util.*;
  32 import java.util.function.BiFunction;
  33 
  34 import javax.crypto.BadPaddingException;
  35 
  36 import javax.net.ssl.*;
  37 import 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  */
  60 public 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 }