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