8167680 DTLS implementation bugs

   1 /*
   2  * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package sun.security.ssl;
  27 
  28 import java.io.*;
  29 import java.nio.*;
  30 import java.util.*;
  31 import java.security.*;
  32 
  33 import javax.crypto.BadPaddingException;
  34 
  35 import javax.net.ssl.*;
  36 import javax.net.ssl.SSLEngineResult.*;
  37 
  38 /**
  39  * Implementation of an non-blocking SSLEngine.
  40  *
  41  * *Currently*, the SSLEngine code exists in parallel with the current
  42  * SSLSocket.  As such, the current implementation is using legacy code
  43  * with many of the same abstractions.  However, it varies in many
  44  * areas, most dramatically in the IO handling.
  45  *
  46  * There are three main I/O threads that can be existing in parallel:
  47  * wrap(), unwrap(), and beginHandshake().  We are encouraging users to
  48  * not call multiple instances of wrap or unwrap, because the data could
  49  * appear to flow out of the SSLEngine in a non-sequential order.  We
  50  * take all steps we can to at least make sure the ordering remains
  51  * consistent, but once the calls returns, anything can happen.  For
  52  * example, thread1 and thread2 both call wrap, thread1 gets the first
  53  * packet, thread2 gets the second packet, but thread2 gets control back
  54  * before thread1, and sends the data.  The receiving side would see an
  55  * out-of-order error.
  56  *
  57  * @author Brad Wetmore
  58  */
  59 public final class SSLEngineImpl extends SSLEngine {
  60 
  61     //
  62     // Fields and global comments
  63     //
  64 
  65     /*
  66      * There's a state machine associated with each connection, which
  67      * among other roles serves to negotiate session changes.
  68      *
  69      * - START with constructor, until the TCP connection's around.
  70      * - HANDSHAKE picks session parameters before allowing traffic.
  71      *          There are many substates due to sequencing requirements
  72      *          for handshake messages.
  73      * - DATA may be transmitted.
  74      * - RENEGOTIATE state allows concurrent data and handshaking
  75      *          traffic ("same" substates as HANDSHAKE), and terminates
  76      *          in selection of new session (and connection) parameters
  77      * - ERROR state immediately precedes abortive disconnect.
  78      * - CLOSED when one side closes down, used to start the shutdown
  79      *          process.  SSL connection objects are not reused.
  80      *
  81      * State affects what SSL record types may legally be sent:
  82      *
  83      * - Handshake ... only in HANDSHAKE and RENEGOTIATE states
  84      * - App Data ... only in DATA and RENEGOTIATE states
  85      * - Alert ... in HANDSHAKE, DATA, RENEGOTIATE
  86      *
  87      * Re what may be received:  same as what may be sent, except that
  88      * HandshakeRequest handshaking messages can come from servers even
  89      * in the application data state, to request entry to RENEGOTIATE.
  90      *
  91      * The state machine within HANDSHAKE and RENEGOTIATE states controls
  92      * the pending session, not the connection state, until the change
  93      * cipher spec and "Finished" handshake messages are processed and
  94      * make the "new" session become the current one.
  95      *
  96      * NOTE: details of the SMs always need to be nailed down better.
  97      * The text above illustrates the core ideas.
  98      *
  99      *                +---->-------+------>--------->-------+
 100      *                |            |                        |
 101      *     <-----<    ^            ^  <-----<               |
 102      *START>----->HANDSHAKE>----->DATA>----->RENEGOTIATE    |
 103      *                v            v               v        |
 104      *                |            |               |        |
 105      *                +------------+---------------+        |
 106      *                |                                     |
 107      *                v                                     |
 108      *               ERROR>------>----->CLOSED<--------<----+
 109      *
 110      * ALSO, note that the purpose of handshaking (renegotiation is
 111      * included) is to assign a different, and perhaps new, session to
 112      * the connection.  The SSLv3 spec is a bit confusing on that new
 113      * protocol feature.
 114      */
 115     private int                 connectionState;
 116 
 117     private static final int    cs_START = 0;
 118     private static final int    cs_HANDSHAKE = 1;
 119     private static final int    cs_DATA = 2;
 120     private static final int    cs_RENEGOTIATE = 3;
 121     private static final int    cs_ERROR = 4;
 122     private static final int    cs_CLOSED = 6;
 123 
 124     /*
 125      * Once we're in state cs_CLOSED, we can continue to
 126      * wrap/unwrap until we finish sending/receiving the messages
 127      * for close_notify.
 128      */
 129     private boolean             inboundDone = false;
 130     private boolean             outboundDone = false;
 131 
 132     /*
 133      * The authentication context holds all information used to establish
 134      * who this end of the connection is (certificate chains, private keys,
 135      * etc) and who is trusted (e.g. as CAs or websites).
 136      */
 137     private SSLContextImpl      sslContext;
 138 
 139     /*
 140      * This connection is one of (potentially) many associated with
 141      * any given session.  The output of the handshake protocol is a
 142      * new session ... although all the protocol description talks
 143      * about changing the cipher spec (and it does change), in fact
 144      * that's incidental since it's done by changing everything that
 145      * is associated with a session at the same time.  (TLS/IETF may
 146      * change that to add client authentication w/o new key exchg.)
 147      */
 148     private Handshaker                  handshaker;
 149     private SSLSessionImpl              sess;
 150     private volatile SSLSessionImpl     handshakeSession;
 151 
 152     /*
 153      * Flag indicating if the next record we receive MUST be a Finished
 154      * message. Temporarily set during the handshake to ensure that
 155      * a change cipher spec message is followed by a finished message.
 156      */
 157     private boolean             expectingFinished;
 158 
 159 
 160     /*
 161      * If someone tries to closeInbound() (say at End-Of-Stream)
 162      * our engine having received a close_notify, we need to
 163      * notify the app that we may have a truncation attack underway.
 164      */
 165     private boolean             recvCN;
 166 
 167     /*
 168      * For improved diagnostics, we detail connection closure
 169      * If the engine is closed (connectionState >= cs_ERROR),
 170      * closeReason != null indicates if the engine was closed
 171      * because of an error or because or normal shutdown.
 172      */
 173     private SSLException        closeReason;
 174 
 175     /*
 176      * Per-connection private state that doesn't change when the
 177      * session is changed.
 178      */
 179     private ClientAuthType          doClientAuth =
 180                                             ClientAuthType.CLIENT_AUTH_NONE;
 181     private boolean                 enableSessionCreation = true;
 182     InputRecord                     inputRecord;
 183     OutputRecord                    outputRecord;
 184     private AccessControlContext    acc;
 185 
 186     // The cipher suites enabled for use on this connection.
 187     private CipherSuiteList             enabledCipherSuites;
 188 
 189     // the endpoint identification protocol
 190     private String                      identificationProtocol = null;
 191 
 192     // The cryptographic algorithm constraints
 193     private AlgorithmConstraints        algorithmConstraints = null;
 194 
 195     // The server name indication and matchers
 196     List<SNIServerName>         serverNames =
 197                                     Collections.<SNIServerName>emptyList();
 198     Collection<SNIMatcher>      sniMatchers =
 199                                     Collections.<SNIMatcher>emptyList();
 200 
 201     // Configured application protocol values
 202     String[] applicationProtocols = new String[0];
 203 
 204     // Negotiated application protocol value.
 205     //
 206     // The value under negotiation will be obtained from handshaker.
 207     String applicationProtocol = null;
 208 
 209     // Have we been told whether we're client or server?
 210     private boolean                     serverModeSet = false;
 211     private boolean                     roleIsServer;
 212 
 213     /*
 214      * The protocol versions enabled for use on this connection.
 215      *
 216      * Note: we support a pseudo protocol called SSLv2Hello which when
 217      * set will result in an SSL v2 Hello being sent with SSL (version 3.0)
 218      * or TLS (version 3.1, 3.2, etc.) version info.
 219      */
 220     private ProtocolList        enabledProtocols;
 221 
 222     /*
 223      * The SSL version associated with this connection.
 224      */
 225     private ProtocolVersion     protocolVersion;
 226 
 227     /*
 228      * security parameters for secure renegotiation.
 229      */
 230     private boolean             secureRenegotiation;
 231     private byte[]              clientVerifyData;
 232     private byte[]              serverVerifyData;
 233 
 234     /*
 235      * READ ME * READ ME * READ ME * READ ME * READ ME * READ ME *
 236      * IMPORTANT STUFF TO UNDERSTANDING THE SYNCHRONIZATION ISSUES.
 237      * READ ME * READ ME * READ ME * READ ME * READ ME * READ ME *
 238      *
 239      * There are several locks here.
 240      *
 241      * The primary lock is the per-instance lock used by
 242      * synchronized(this) and the synchronized methods.  It controls all
 243      * access to things such as the connection state and variables which
 244      * affect handshaking.  If we are inside a synchronized method, we
 245      * can access the state directly, otherwise, we must use the
 246      * synchronized equivalents.
 247      *
 248      * Note that we must never acquire the <code>this</code> lock after
 249      * <code>writeLock</code> or run the risk of deadlock.
 250      *
 251      * Grab some coffee, and be careful with any code changes.
 252      */
 253     private Object              wrapLock;
 254     private Object              unwrapLock;
 255     Object                      writeLock;
 256 
 257     /*
 258      * Whether local cipher suites preference in server side should be
 259      * honored during handshaking?
 260      */
 261     private boolean preferLocalCipherSuites = false;
 262 
 263     /*
 264      * whether DTLS handshake retransmissions should be enabled?
 265      */
 266     private boolean enableRetransmissions = false;
 267 
 268     /*
 269      * The maximum expected network packet size for SSL/TLS/DTLS records.
 270      */
 271     private int maximumPacketSize = 0;
 272 
 273     /*
 274      * Is this an instance for Datagram Transport Layer Security (DTLS)?
 275      */
 276     private final boolean isDTLS;
 277 
 278     /*
 279      * Class and subclass dynamic debugging support
 280      */
 281     private static final Debug debug = Debug.getInstance("ssl");
 282 
 283     //
 284     // Initialization/Constructors
 285     //
 286 
 287     /**
 288      * Constructor for an SSLEngine from SSLContext, without
 289      * host/port hints.  This Engine will not be able to cache
 290      * sessions, but must renegotiate everything by hand.
 291      */
 292     SSLEngineImpl(SSLContextImpl ctx, boolean isDTLS) {
 293         super();
 294         this.isDTLS = isDTLS;
 295         init(ctx, isDTLS);
 296     }
 297 
 298     /**
 299      * Constructor for an SSLEngine from SSLContext.
 300      */
 301     SSLEngineImpl(SSLContextImpl ctx, String host, int port, boolean isDTLS) {
 302         super(host, port);
 303         this.isDTLS = isDTLS;
 304         init(ctx, isDTLS);
 305     }
 306 
 307     /**
 308      * Initializes the Engine
 309      */
 310     private void init(SSLContextImpl ctx, boolean isDTLS) {
 311         if (debug != null && Debug.isOn("ssl")) {
 312             System.out.println("Using SSLEngineImpl.");
 313         }
 314 
 315         sslContext = ctx;
 316         sess = SSLSessionImpl.nullSession;
 317         handshakeSession = null;
 318         protocolVersion = isDTLS ?
 319                 ProtocolVersion.DEFAULT_DTLS : ProtocolVersion.DEFAULT_TLS;
 320 
 321         /*
 322          * State is cs_START until we initialize the handshaker.
 323          *
 324          * Apps using SSLEngine are probably going to be server.
 325          * Somewhat arbitrary choice.
 326          */
 327         roleIsServer = true;
 328         connectionState = cs_START;
 329 
 330         // default server name indication
 331         serverNames =
 332             Utilities.addToSNIServerNameList(serverNames, getPeerHost());
 333 
 334         // default security parameters for secure renegotiation
 335         secureRenegotiation = false;
 336         clientVerifyData = new byte[0];
 337         serverVerifyData = new byte[0];
 338 
 339         enabledCipherSuites =
 340                 sslContext.getDefaultCipherSuiteList(roleIsServer);
 341         enabledProtocols =
 342                 sslContext.getDefaultProtocolList(roleIsServer);
 343 
 344         wrapLock = new Object();
 345         unwrapLock = new Object();
 346         writeLock = new Object();
 347 
 348         /*
 349          * Save the Access Control Context.  This will be used later
 350          * for a couple of things, including providing a context to
 351          * run tasks in, and for determining which credentials
 352          * to use for Subject based (JAAS) decisions
 353          */
 354         acc = AccessController.getContext();
 355 
 356         /*
 357          * All outbound application data goes through this OutputRecord,
 358          * other data goes through their respective records created
 359          * elsewhere.  All inbound data goes through this one
 360          * input record.
 361          */
 362         if (isDTLS) {
 363             enableRetransmissions = true;
 364 
 365             // SSLEngine needs no record local buffer
 366             outputRecord = new DTLSOutputRecord();
 367             inputRecord = new DTLSInputRecord();
 368 
 369         } else {
 370             outputRecord = new SSLEngineOutputRecord();
 371             inputRecord = new SSLEngineInputRecord();
 372         }
 373 
 374         maximumPacketSize = outputRecord.getMaxPacketSize();
 375     }
 376 
 377     /**
 378      * Initialize the handshaker object. This means:
 379      *
 380      *  . if a handshake is already in progress (state is cs_HANDSHAKE
 381      *    or cs_RENEGOTIATE), do nothing and return
 382      *
 383      *  . if the engine is already closed, throw an Exception (internal error)
 384      *
 385      *  . otherwise (cs_START or cs_DATA), create the appropriate handshaker
 386      *    object and advance the connection state (to cs_HANDSHAKE or
 387      *    cs_RENEGOTIATE, respectively).
 388      *
 389      * This method is called right after a new engine is created, when
 390      * starting renegotiation, or when changing client/server mode of the
 391      * engine.
 392      */
 393     private void initHandshaker() {
 394         switch (connectionState) {
 395 
 396         //
 397         // Starting a new handshake.
 398         //
 399         case cs_START:
 400         case cs_DATA:
 401             break;
 402 
 403         //
 404         // We're already in the middle of a handshake.
 405         //
 406         case cs_HANDSHAKE:
 407         case cs_RENEGOTIATE:
 408             return;
 409 
 410         //
 411         // Anyone allowed to call this routine is required to
 412         // do so ONLY if the connection state is reasonable...
 413         //
 414         default:
 415             throw new IllegalStateException("Internal error");
 416         }
 417 
 418         // state is either cs_START or cs_DATA
 419         if (connectionState == cs_START) {
 420             connectionState = cs_HANDSHAKE;
 421         } else { // cs_DATA
 422             connectionState = cs_RENEGOTIATE;
 423         }
 424 
 425         if (roleIsServer) {
 426             handshaker = new ServerHandshaker(this, sslContext,
 427                     enabledProtocols, doClientAuth,
 428                     protocolVersion, connectionState == cs_HANDSHAKE,
 429                     secureRenegotiation, clientVerifyData, serverVerifyData,
 430                     isDTLS);
 431             handshaker.setSNIMatchers(sniMatchers);
 432             handshaker.setUseCipherSuitesOrder(preferLocalCipherSuites);
 433         } else {
 434             handshaker = new ClientHandshaker(this, sslContext,
 435                     enabledProtocols,
 436                     protocolVersion, connectionState == cs_HANDSHAKE,
 437                     secureRenegotiation, clientVerifyData, serverVerifyData,
 438                     isDTLS);
 439             handshaker.setSNIServerNames(serverNames);
 440         }
 441         handshaker.setMaximumPacketSize(maximumPacketSize);
 442         handshaker.setEnabledCipherSuites(enabledCipherSuites);
 443         handshaker.setEnableSessionCreation(enableSessionCreation);
 444         handshaker.setApplicationProtocols(applicationProtocols);
 445 
 446         outputRecord.initHandshaker();
 447     }
 448 
 449     /*
 450      * Report the current status of the Handshaker
 451      */
 452     private HandshakeStatus getHSStatus(HandshakeStatus hss) {
 453 
 454         if (hss != null) {
 455             return hss;
 456         }
 457 
 458         synchronized (this) {
 459             if (!outputRecord.isEmpty()) {
 460                 // If no handshaking, special case to wrap alters.
 461                 return HandshakeStatus.NEED_WRAP;
 462             } else if (handshaker != null) {
 463                 if (handshaker.taskOutstanding()) {
 464                     return HandshakeStatus.NEED_TASK;
 465                 } else if (isDTLS && !inputRecord.isEmpty()) {
 466                     return HandshakeStatus.NEED_UNWRAP_AGAIN;
 467                 } else {
 468                     return HandshakeStatus.NEED_UNWRAP;
 469                 }
 470             } else if (connectionState == cs_CLOSED) {
 471                 /*
 472                  * Special case where we're closing, but
 473                  * still need the close_notify before we
 474                  * can officially be closed.
 475                  *
 476                  * Note isOutboundDone is taken care of by
 477                  * hasOutboundData() above.
 478                  */
 479                 if (!isInboundDone()) {
 480                     return HandshakeStatus.NEED_UNWRAP;
 481                 } // else not handshaking
 482             }
 483 
 484             return HandshakeStatus.NOT_HANDSHAKING;
 485         }
 486     }
 487 
 488     private synchronized void checkTaskThrown() throws SSLException {
 489         if (handshaker != null) {
 490             handshaker.checkThrown();
 491         }
 492     }
 493 
 494     //
 495     // Handshaking and connection state code
 496     //
 497 
 498     /*
 499      * Provides "this" synchronization for connection state.
 500      * Otherwise, you can access it directly.
 501      */
 502     private synchronized int getConnectionState() {
 503         return connectionState;
 504     }
 505 
 506     private synchronized void setConnectionState(int state) {
 507         connectionState = state;
 508     }
 509 
 510     /*
 511      * Get the Access Control Context.
 512      *
 513      * Used for a known context to
 514      * run tasks in, and for determining which credentials
 515      * to use for Subject-based (JAAS) decisions.
 516      */
 517     AccessControlContext getAcc() {
 518         return acc;
 519     }
 520 
 521     /*
 522      * Is a handshake currently underway?
 523      */
 524     @Override
 525     public SSLEngineResult.HandshakeStatus getHandshakeStatus() {
 526         return getHSStatus(null);
 527     }
 528 
 529     /*
 530      * used by Handshaker to change the active write cipher, follows
 531      * the output of the CCS message.
 532      *
 533      * Also synchronized on "this" from readRecord/delegatedTask.
 534      */
 535     void changeWriteCiphers() throws IOException {
 536 
 537         Authenticator writeAuthenticator;
 538         CipherBox writeCipher;
 539         try {
 540             writeCipher = handshaker.newWriteCipher();
 541             writeAuthenticator = handshaker.newWriteAuthenticator();
 542         } catch (GeneralSecurityException e) {
 543             // "can't happen"
 544             throw new SSLException("Algorithm missing:  ", e);
 545         }
 546 
 547         outputRecord.changeWriteCiphers(writeAuthenticator, writeCipher);
 548     }
 549 
 550     /*
 551      * Updates the SSL version associated with this connection.
 552      * Called from Handshaker once it has determined the negotiated version.
 553      */
 554     synchronized void setVersion(ProtocolVersion protocolVersion) {
 555         this.protocolVersion = protocolVersion;
 556         outputRecord.setVersion(protocolVersion);
 557     }
 558 
 559 
 560     /**
 561      * Kickstart the handshake if it is not already in progress.
 562      * This means:
 563      *
 564      *  . if handshaking is already underway, do nothing and return
 565      *
 566      *  . if the engine is not connected or already closed, throw an
 567      *    Exception.
 568      *
 569      *  . otherwise, call initHandshake() to initialize the handshaker
 570      *    object and progress the state. Then, send the initial
 571      *    handshaking message if appropriate (always on clients and
 572      *    on servers when renegotiating).
 573      */
 574     private synchronized void kickstartHandshake() throws IOException {
 575         switch (connectionState) {
 576 
 577         case cs_START:
 578             if (!serverModeSet) {
 579                 throw new IllegalStateException(
 580                     "Client/Server mode not yet set.");
 581             }
 582             initHandshaker();
 583             break;
 584 
 585         case cs_HANDSHAKE:
 586             // handshaker already setup, proceed
 587             break;
 588 
 589         case cs_DATA:
 590             if (!secureRenegotiation && !Handshaker.allowUnsafeRenegotiation) {
 591                 throw new SSLHandshakeException(
 592                         "Insecure renegotiation is not allowed");
 593             }
 594 
 595             if (!secureRenegotiation) {
 596                 if (debug != null && Debug.isOn("handshake")) {
 597                     System.out.println(
 598                         "Warning: Using insecure renegotiation");
 599                 }
 600             }
 601 
 602             // initialize the handshaker, move to cs_RENEGOTIATE
 603             initHandshaker();
 604             break;
 605 
 606         case cs_RENEGOTIATE:
 607             // handshaking already in progress, return
 608             return;
 609 
 610         default:
 611             // cs_ERROR/cs_CLOSED
 612             throw new SSLException("SSLEngine is closing/closed");
 613         }
 614 
 615         //
 616         // Kickstart handshake state machine if we need to ...
 617         //
 618         if (!handshaker.activated()) {
 619              // prior to handshaking, activate the handshake
 620             if (connectionState == cs_RENEGOTIATE) {
 621                 // don't use SSLv2Hello when renegotiating
 622                 handshaker.activate(protocolVersion);
 623             } else {
 624                 handshaker.activate(null);
 625             }
 626 
 627             if (handshaker instanceof ClientHandshaker) {
 628                 // send client hello
 629                 handshaker.kickstart();
 630             } else {    // instanceof ServerHandshaker
 631                 if (connectionState == cs_HANDSHAKE) {
 632                     // initial handshake, no kickstart message to send
 633                 } else {
 634                     // we want to renegotiate, send hello request
 635                     handshaker.kickstart();
 636                 }
 637             }
 638         }
 639     }
 640 
 641     /*
 642      * Start a SSLEngine handshake
 643      */
 644     @Override
 645     public void beginHandshake() throws SSLException {
 646         try {
 647             kickstartHandshake();
 648         } catch (Exception e) {
 649             fatal(Alerts.alert_handshake_failure,
 650                 "Couldn't kickstart handshaking", e);
 651         }
 652     }
 653 
 654 
 655     //
 656     // Read/unwrap side
 657     //
 658 
 659 
 660     /**
 661      * Unwraps a buffer.  Does a variety of checks before grabbing
 662      * the unwrapLock, which blocks multiple unwraps from occurring.
 663      */
 664     @Override
 665     public SSLEngineResult unwrap(ByteBuffer netData, ByteBuffer[] appData,
 666             int offset, int length) throws SSLException {
 667 
 668         // check engine parameters
 669         checkEngineParas(netData, appData, offset, length, false);
 670 
 671         try {
 672             synchronized (unwrapLock) {
 673                 return readNetRecord(netData, appData, offset, length);
 674             }
 675         } catch (SSLProtocolException spe) {
 676             // may be an unexpected handshake message
 677             fatal(Alerts.alert_unexpected_message, spe.getMessage(), spe);
 678             return null;  // make compiler happy
 679         } catch (Exception e) {
 680             /*
 681              * Don't reset position so it looks like we didn't
 682              * consume anything.  We did consume something, and it
 683              * got us into this situation, so report that much back.
 684              * Our days of consuming are now over anyway.
 685              */
 686             fatal(Alerts.alert_internal_error,
 687                 "problem unwrapping net record", e);
 688             return null;  // make compiler happy
 689         }
 690     }
 691 
 692     private static void checkEngineParas(ByteBuffer netData,
 693             ByteBuffer[] appData, int offset, int len, boolean isForWrap) {
 694 
 695         if ((netData == null) || (appData == null)) {
 696             throw new IllegalArgumentException("src/dst is null");
 697         }
 698 
 699         if ((offset < 0) || (len < 0) || (offset > appData.length - len)) {
 700             throw new IndexOutOfBoundsException();
 701         }
 702 
 703         /*
 704          * If wrapping, make sure the destination bufffer is writable.
 705          */
 706         if (isForWrap && netData.isReadOnly()) {
 707             throw new ReadOnlyBufferException();
 708         }
 709 
 710         for (int i = offset; i < offset + len; i++) {
 711             if (appData[i] == null) {
 712                 throw new IllegalArgumentException(
 713                         "appData[" + i + "] == null");
 714             }
 715 
 716             /*
 717              * If unwrapping, make sure the destination bufffers are writable.
 718              */
 719             if (!isForWrap && appData[i].isReadOnly()) {
 720                 throw new ReadOnlyBufferException();
 721             }
 722         }
 723     }
 724 
 725     /*
 726      * Makes additional checks for unwrap, but this time more
 727      * specific to this packet and the current state of the machine.
 728      */
 729     private SSLEngineResult readNetRecord(ByteBuffer netData,
 730             ByteBuffer[] appData, int offset, int length) throws IOException {
 731 
 732         Status status = null;
 733         HandshakeStatus hsStatus = null;
 734 
 735         /*
 736          * See if the handshaker needs to report back some SSLException.
 737          */
 738         checkTaskThrown();
 739 
 740         /*
 741          * Check if we are closing/closed.
 742          */
 743         if (isInboundDone()) {
 744             return new SSLEngineResult(Status.CLOSED, getHSStatus(null), 0, 0);
 745         }
 746 
 747         /*
 748          * If we're still in cs_HANDSHAKE, make sure it's been
 749          * started.
 750          */
 751         synchronized (this) {
 752             if ((connectionState == cs_HANDSHAKE) ||
 753                     (connectionState == cs_START)) {
 754                 kickstartHandshake();
 755 
 756                 /*
 757                  * If there's still outbound data to flush, we
 758                  * can return without trying to unwrap anything.
 759                  */
 760                 hsStatus = getHSStatus(null);
 761 
 762                 if (hsStatus == HandshakeStatus.NEED_WRAP) {
 763                     return new SSLEngineResult(Status.OK, hsStatus, 0, 0);
 764                 }
 765             }
 766         }
 767 
 768         /*
 769          * Grab a copy of this if it doesn't already exist,
 770          * and we can use it several places before anything major
 771          * happens on this side.  Races aren't critical
 772          * here.
 773          */
 774         if (hsStatus == null) {
 775             hsStatus = getHSStatus(null);
 776         }
 777 
 778         /*
 779          * If we have a task outstanding, this *MUST* be done before
 780          * doing any more unwrapping, because we could be in the middle
 781          * of receiving a handshake message, for example, a finished
 782          * message which would change the ciphers.
 783          */
 784         if (hsStatus == HandshakeStatus.NEED_TASK) {
 785             return new SSLEngineResult(Status.OK, hsStatus, 0, 0);
 786         }
 787 
 788         if (hsStatus == SSLEngineResult.HandshakeStatus.NEED_UNWRAP_AGAIN) {
 789             Plaintext plainText = null;
 790             try {
 791                 plainText = readRecord(null, null, 0, 0);
 792             } catch (SSLException e) {
 793                 throw e;
 794             } catch (IOException e) {
 795                 throw new SSLException("readRecord", e);
 796             }
 797 
 798             status = (isInboundDone() ? Status.CLOSED : Status.OK);
 799             hsStatus = getHSStatus(plainText.handshakeStatus);
 800 
 801             return new SSLEngineResult(
 802                     status, hsStatus, 0, 0, plainText.recordSN);
 803         }
 804 
 805         /*
 806          * Check the packet to make sure enough is here.
 807          * This will also indirectly check for 0 len packets.
 808          */
 809         int packetLen = 0;
 810         try {
 811             packetLen = inputRecord.bytesInCompletePacket(netData);
 812         } catch (SSLException ssle) {
 813             // Need to discard invalid records for DTLS protocols.
 814             if (isDTLS) {
 815                 if (debug != null && Debug.isOn("ssl")) {
 816                     System.out.println(
 817                         Thread.currentThread().getName() +
 818                         " discard invalid record: " + ssle);
 819                 }
 820 
 821                 // invalid, discard the entire data [section 4.1.2.7, RFC 6347]
 822                 int deltaNet = netData.remaining();
 823                 netData.position(netData.limit());
 824 
 825                 status = (isInboundDone() ? Status.CLOSED : Status.OK);
 826                 hsStatus = getHSStatus(hsStatus);
 827 
 828                 return new SSLEngineResult(status, hsStatus, deltaNet, 0, -1L);
 829             } else {
 830                 throw ssle;
 831             }
 832         }
 833 
 834         // Is this packet bigger than SSL/TLS normally allows?
 835         if (packetLen > sess.getPacketBufferSize()) {
 836             int largestRecordSize = isDTLS ?
 837                     DTLSRecord.maxRecordSize : SSLRecord.maxLargeRecordSize;
 838             if ((packetLen <= largestRecordSize) && !isDTLS) {
 839                 // Expand the expected maximum packet/application buffer
 840                 // sizes.
 841                 //
 842                 // Only apply to SSL/TLS protocols.
 843 
 844                 // Old behavior: shall we honor the System Property
 845                 // "jsse.SSLEngine.acceptLargeFragments" if it is "false"?
 846                 sess.expandBufferSizes();
 847             }
 848 
 849             // check the packet again
 850             largestRecordSize = sess.getPacketBufferSize();
 851             if (packetLen > largestRecordSize) {
 852                 throw new SSLProtocolException(
 853                         "Input record too big: max = " +
 854                         largestRecordSize + " len = " + packetLen);
 855             }
 856         }
 857 
 858         int netPos = netData.position();
 859         int appRemains = 0;
 860         for (int i = offset; i < offset + length; i++) {
 861             if (appData[i] == null) {
 862                 throw new IllegalArgumentException(
 863                         "appData[" + i + "] == null");
 864             }
 865             appRemains += appData[i].remaining();
 866         }
 867 
 868         /*
 869          * Check for OVERFLOW.
 870          *
 871          * Delay enforcing the application buffer free space requirement
 872          * until after the initial handshaking.
 873          */
 874         // synchronize connectionState?
 875         if ((connectionState == cs_DATA) ||
 876                 (connectionState == cs_RENEGOTIATE)) {
 877 
 878             int FragLen = inputRecord.estimateFragmentSize(packetLen);
 879             if (FragLen > appRemains) {
 880                 return new SSLEngineResult(
 881                         Status.BUFFER_OVERFLOW, hsStatus, 0, 0);
 882             }
 883         }
 884 
 885         // check for UNDERFLOW.
 886         if ((packetLen == -1) || (netData.remaining() < packetLen)) {
 887             return new SSLEngineResult(Status.BUFFER_UNDERFLOW, hsStatus, 0, 0);
 888         }
 889 
 890         /*
 891          * We're now ready to actually do the read.
 892          */
 893         Plaintext plainText = null;
 894         try {
 895             plainText = readRecord(netData, appData, offset, length);
 896         } catch (SSLException e) {
 897             throw e;
 898         } catch (IOException e) {
 899             throw new SSLException("readRecord", e);
 900         }
 901 
 902         /*
 903          * Check the various condition that we could be reporting.
 904          *
 905          * It's *possible* something might have happened between the
 906          * above and now, but it was better to minimally lock "this"
 907          * during the read process.  We'll return the current
 908          * status, which is more representative of the current state.
 909          *
 910          * status above should cover:  FINISHED, NEED_TASK
 911          */
 912         status = (isInboundDone() ? Status.CLOSED : Status.OK);
 913         hsStatus = getHSStatus(plainText.handshakeStatus);
 914 
 915         int deltaNet = netData.position() - netPos;
 916         int deltaApp = appRemains;
 917         for (int i = offset; i < offset + length; i++) {
 918             deltaApp -= appData[i].remaining();
 919         }
 920 
 921         return new SSLEngineResult(
 922                 status, hsStatus, deltaNet, deltaApp, plainText.recordSN);
 923     }
 924 
 925     // the caller have synchronized readLock
 926     void expectingFinishFlight() {
 927         inputRecord.expectingFinishFlight();
 928     }
 929 
 930     /*
 931      * Actually do the read record processing.
 932      *
 933      * Returns a Status if it can make specific determinations
 934      * of the engine state.  In particular, we need to signal
 935      * that a handshake just completed.
 936      *
 937      * It would be nice to be symmetrical with the write side and move
 938      * the majority of this to SSLInputRecord, but there's too much
 939      * SSLEngine state to do that cleanly.  It must still live here.
 940      */
 941     private Plaintext readRecord(ByteBuffer netData,
 942             ByteBuffer[] appData, int offset, int length) throws IOException {
 943 
 944         /*
 945          * The various operations will return new sliced BB's,
 946          * this will avoid having to worry about positions and
 947          * limits in the netBB.
 948          */
 949         Plaintext plainText = null;
 950 
 951         if (getConnectionState() == cs_ERROR) {
 952             return Plaintext.PLAINTEXT_NULL;
 953         }
 954 
 955         /*
 956          * Read a record ... maybe emitting an alert if we get a
 957          * comprehensible but unsupported "hello" message during
 958          * format checking (e.g. V2).
 959          */
 960         try {
 961             if (isDTLS) {
 962                 // Don't process the incoming record until all of the
 963                 // buffered records get handled.
 964                 plainText = inputRecord.acquirePlaintext();
 965             }
 966 
 967             if ((!isDTLS || plainText == null) && netData != null) {
 968                 plainText = inputRecord.decode(netData);
 969             }
 970         } catch (UnsupportedOperationException unsoe) {         // SSLv2Hello
 971             // Hack code to deliver SSLv2 error message for SSL/TLS connections.
 972             if (!isDTLS) {
 973                 outputRecord.encodeV2NoCipher();
 974             }
 975 
 976             fatal(Alerts.alert_unexpected_message, unsoe);
 977         } catch (BadPaddingException e) {
 978             /*
 979              * The basic SSLv3 record protection involves (optional)
 980              * encryption for privacy, and an integrity check ensuring
 981              * data origin authentication.  We do them both here, and
 982              * throw a fatal alert if the integrity check fails.
 983              */
 984             byte alertType = (connectionState != cs_DATA) ?
 985                     Alerts.alert_handshake_failure :
 986                     Alerts.alert_bad_record_mac;
 987             fatal(alertType, e.getMessage(), e);
 988         } catch (SSLHandshakeException she) {
 989             // may be record sequence number overflow
 990             fatal(Alerts.alert_handshake_failure, she);
 991         } catch (IOException ioe) {
 992             fatal(Alerts.alert_unexpected_message, ioe);
 993         }
 994 
 995         // plainText should never be null for TLS protocols
 996         HandshakeStatus hsStatus = null;
 997         if (!isDTLS || plainText != null) {















 998             hsStatus = processInputRecord(plainText, appData, offset, length);
 999         }
1000 
1001         if (hsStatus == null) {
1002             hsStatus = getHSStatus(null);
1003         }
1004 
1005         if (plainText == null) {
1006             plainText = new Plaintext();
1007         }
1008         plainText.handshakeStatus = hsStatus;
1009 
1010         return plainText;
1011     }
1012 
1013     /*
1014      * Process the record.
1015      */
1016     private synchronized HandshakeStatus processInputRecord(
1017             Plaintext plainText,
1018             ByteBuffer[] appData, int offset, int length) throws IOException {
1019 
1020         HandshakeStatus hsStatus = null;
1021         switch (plainText.contentType) {
1022             case Record.ct_handshake:
1023                 /*
1024                  * Handshake messages always go to a pending session
1025                  * handshaker ... if there isn't one, create one.  This
1026                  * must work asynchronously, for renegotiation.
1027                  *
1028                  * NOTE that handshaking will either resume a session
1029                  * which was in the cache (and which might have other
1030                  * connections in it already), or else will start a new
1031                  * session (new keys exchanged) with just this connection
1032                  * in it.
1033                  */
1034                 initHandshaker();
1035                 if (!handshaker.activated()) {
1036                     // prior to handshaking, activate the handshake
1037                     if (connectionState == cs_RENEGOTIATE) {
1038                         // don't use SSLv2Hello when renegotiating
1039                         handshaker.activate(protocolVersion);
1040                     } else {
1041                         handshaker.activate(null);
1042                     }
1043                 }
1044 
1045                 /*
1046                  * process the handshake record ... may contain just
1047                  * a partial handshake message or multiple messages.
1048                  *
1049                  * The handshaker state machine will ensure that it's
1050                  * a finished message.
1051                  */
1052                 handshaker.processRecord(plainText.fragment, expectingFinished);
1053                 expectingFinished = false;
1054 
1055                 if (handshaker.invalidated) {
1056                     finishHandshake();
1057 
1058                     // if state is cs_RENEGOTIATE, revert it to cs_DATA
1059                     if (connectionState == cs_RENEGOTIATE) {
1060                         connectionState = cs_DATA;
1061                     }
1062                 } else if (handshaker.isDone()) {
1063                     // reset the parameters for secure renegotiation.
1064                     secureRenegotiation =
1065                                 handshaker.isSecureRenegotiation();
1066                     clientVerifyData = handshaker.getClientVerifyData();
1067                     serverVerifyData = handshaker.getServerVerifyData();
1068                     // set connection ALPN value
1069                     applicationProtocol =
1070                         handshaker.getHandshakeApplicationProtocol();
1071 
1072                     sess = handshaker.getSession();
1073                     handshakeSession = null;
1074                     if (outputRecord.isEmpty()) {
1075                         hsStatus = finishHandshake();
1076                         connectionState = cs_DATA;
1077                     }
1078 
1079                     // No handshakeListeners here.  That's a
1080                     // SSLSocket thing.
1081                 } else if (handshaker.taskOutstanding()) {
1082                     hsStatus = HandshakeStatus.NEED_TASK;
1083                 }
1084                 break;
1085 
1086             case Record.ct_application_data:
1087                 // Pass this right back up to the application.
1088                 if ((connectionState != cs_DATA)
1089                         && (connectionState != cs_RENEGOTIATE)
1090                         && (connectionState != cs_CLOSED)) {
1091                     throw new SSLProtocolException(
1092                             "Data received in non-data state: " +
1093                             connectionState);
1094                 }
1095 
1096                 if (expectingFinished) {
1097                     throw new SSLProtocolException
1098                             ("Expecting finished message, received data");
1099                 }
1100 
1101                 if (!inboundDone) {
1102                     ByteBuffer fragment = plainText.fragment;
1103                     int remains = fragment.remaining();
1104 
1105                     // Should have enough room in appData.
1106                     for (int i = offset;
1107                             ((i < (offset + length)) && (remains > 0)); i++) {
1108                         int amount = Math.min(appData[i].remaining(), remains);
1109                         fragment.limit(fragment.position() + amount);
1110                         appData[i].put(fragment);
1111                         remains -= amount;
1112                     }
1113                 }
1114 
1115                 break;
1116 
1117             case Record.ct_alert:
1118                 recvAlert(plainText.fragment);
1119                 break;
1120 
1121             case Record.ct_change_cipher_spec:
1122                 if ((connectionState != cs_HANDSHAKE
1123                         && connectionState != cs_RENEGOTIATE)) {
1124                     // For the CCS message arriving in the wrong state
1125                     fatal(Alerts.alert_unexpected_message,
1126                             "illegal change cipher spec msg, conn state = "
1127                             + connectionState);
1128                 } else if (plainText.fragment.remaining() != 1
1129                         || plainText.fragment.get() != 1) {
1130                     // For structural/content issues with the CCS
1131                     fatal(Alerts.alert_unexpected_message,
1132                             "Malformed change cipher spec msg");
1133                 }
1134 
1135                 //
1136                 // The first message after a change_cipher_spec
1137                 // record MUST be a "Finished" handshake record,
1138                 // else it's a protocol violation.  We force this
1139                 // to be checked by a minor tweak to the state
1140                 // machine.
1141                 //
1142                 handshaker.receiveChangeCipherSpec();
1143 
1144                 CipherBox readCipher;
1145                 Authenticator readAuthenticator;
1146                 try {
1147                     readCipher = handshaker.newReadCipher();
1148                     readAuthenticator = handshaker.newReadAuthenticator();
1149                 } catch (GeneralSecurityException e) {
1150                     // can't happen
1151                     throw new SSLException("Algorithm missing:  ", e);
1152                 }
1153                 inputRecord.changeReadCiphers(readAuthenticator, readCipher);
1154 
1155                 // next message MUST be a finished message
1156                 expectingFinished = true;
1157                 break;
1158 
1159             default:
1160                 //
1161                 // TLS requires that unrecognized records be ignored.
1162                 //
1163                 if (debug != null && Debug.isOn("ssl")) {
1164                     System.out.println(Thread.currentThread().getName() +
1165                             ", Received record type: " + plainText.contentType);
1166                 }
1167                 break;
1168         } // switch
1169 
1170         /*
1171          * We only need to check the sequence number state for
1172          * non-handshaking record.
1173          *
1174          * Note that in order to maintain the handshake status
1175          * properly, we check the sequence number after the last
1176          * record reading process. As we request renegotiation
1177          * or close the connection for wrapped sequence number
1178          * when there is enough sequence number space left to
1179          * handle a few more records, so the sequence number
1180          * of the last record cannot be wrapped.
1181          */
1182         hsStatus = getHSStatus(hsStatus);
1183         if (connectionState < cs_ERROR && !isInboundDone() &&
1184                 (hsStatus == HandshakeStatus.NOT_HANDSHAKING) &&
1185                 (inputRecord.seqNumIsHuge())) {
1186             /*
1187              * Ask for renegotiation when need to renew sequence number.
1188              *
1189              * Don't bother to kickstart the renegotiation when the local is
1190              * asking for it.
1191              */
1192             if (debug != null && Debug.isOn("ssl")) {
1193                 System.out.println(Thread.currentThread().getName() +
1194                         ", request renegotiation " +
1195                         "to avoid sequence number overflow");
1196             }
1197 
1198             beginHandshake();
1199 
1200             hsStatus = getHSStatus(null);
1201         }
1202 
1203         return hsStatus;
1204     }
1205 
1206 
1207     //
1208     // write/wrap side
1209     //
1210 
1211 
1212     /**
1213      * Wraps a buffer.  Does a variety of checks before grabbing
1214      * the wrapLock, which blocks multiple wraps from occurring.
1215      */
1216     @Override
1217     public SSLEngineResult wrap(ByteBuffer[] appData,
1218             int offset, int length, ByteBuffer netData) throws SSLException {
1219 
1220         // check engine parameters
1221         checkEngineParas(netData, appData, offset, length, true);
1222 
1223         /*
1224          * We can be smarter about using smaller buffer sizes later.
1225          * For now, force it to be large enough to handle any valid record.
1226          */
1227         if (netData.remaining() < sess.getPacketBufferSize()) {
1228             return new SSLEngineResult(
1229                 Status.BUFFER_OVERFLOW, getHSStatus(null), 0, 0);
1230         }
1231 
1232         try {
1233             synchronized (wrapLock) {
1234                 return writeAppRecord(appData, offset, length, netData);
1235             }
1236         } catch (SSLProtocolException spe) {
1237             // may be an unexpected handshake message
1238             fatal(Alerts.alert_unexpected_message, spe.getMessage(), spe);
1239             return null;  // make compiler happy
1240         } catch (Exception e) {
1241             fatal(Alerts.alert_internal_error,
1242                 "problem wrapping app data", e);
1243             return null;  // make compiler happy
1244         }
1245     }
1246 
1247     /*
1248      * Makes additional checks for unwrap, but this time more
1249      * specific to this packet and the current state of the machine.
1250      */
1251     private SSLEngineResult writeAppRecord(ByteBuffer[] appData,
1252             int offset, int length, ByteBuffer netData) throws IOException {
1253 
1254         Status status = null;
1255         HandshakeStatus hsStatus = null;
1256 
1257         /*
1258          * See if the handshaker needs to report back some SSLException.
1259          */
1260         checkTaskThrown();
1261 
1262         /*
1263          * short circuit if we're closed/closing.
1264          */
1265         if (isOutboundDone()) {
1266             return new SSLEngineResult(Status.CLOSED, getHSStatus(null), 0, 0);
1267         }
1268 
1269         /*
1270          * If we're still in cs_HANDSHAKE, make sure it's been
1271          * started.
1272          */
1273         synchronized (this) {
1274             if ((connectionState == cs_HANDSHAKE) ||
1275                 (connectionState == cs_START)) {
1276 
1277                 kickstartHandshake();
1278 
1279                 /*
1280                  * If there's no HS data available to write, we can return
1281                  * without trying to wrap anything.
1282                  */
1283                 hsStatus = getHSStatus(null);
1284                 if (hsStatus == HandshakeStatus.NEED_UNWRAP) {
1285                     /*
1286                      * For DTLS, if the handshake state is
1287                      * HandshakeStatus.NEED_UNWRAP, a call to SSLEngine.wrap()
1288                      * means that the previous handshake packets (if delivered)
1289                      * get lost, and need retransmit the handshake messages.
1290                      */
1291                     if (!isDTLS || !enableRetransmissions ||
1292                             (handshaker == null) || outputRecord.firstMessage) {
1293 
1294                         return new SSLEngineResult(Status.OK, hsStatus, 0, 0);
1295                     }   // otherwise, need retransmission
1296                 }
1297             }
1298         }
1299 
1300         /*
1301          * Grab a copy of this if it doesn't already exist,
1302          * and we can use it several places before anything major
1303          * happens on this side.  Races aren't critical
1304          * here.
1305          */
1306         if (hsStatus == null) {
1307             hsStatus = getHSStatus(null);
1308         }
1309 
1310         /*
1311          * If we have a task outstanding, this *MUST* be done before
1312          * doing any more wrapping, because we could be in the middle
1313          * of receiving a handshake message, for example, a finished
1314          * message which would change the ciphers.
1315          */
1316         if (hsStatus == HandshakeStatus.NEED_TASK) {
1317             return new SSLEngineResult(Status.OK, hsStatus, 0, 0);
1318         }
1319 
1320         /*
1321          * This will obtain any waiting outbound data, or will
1322          * process the outbound appData.
1323          */
1324         int netPos = netData.position();
1325         int appRemains = 0;
1326         for (int i = offset; i < offset + length; i++) {
1327             if (appData[i] == null) {
1328                 throw new IllegalArgumentException(
1329                         "appData[" + i + "] == null");
1330             }
1331             appRemains += appData[i].remaining();
1332         }
1333 
1334         Ciphertext ciphertext = null;
1335         try {
1336             if (appRemains != 0) {
1337                 synchronized (writeLock) {
1338                     ciphertext = writeRecord(appData, offset, length, netData);
1339                 }
1340             } else {
1341                 synchronized (writeLock) {
1342                     ciphertext = writeRecord(null, 0, 0, netData);
1343                 }
1344             }
1345         } catch (SSLException e) {
1346             throw e;
1347         } catch (IOException e) {
1348             throw new SSLException("Write problems", e);
1349         }
1350 
1351         /*
1352          * writeRecord might have reported some status.
1353          * Now check for the remaining cases.
1354          *
1355          * status above should cover:  NEED_WRAP/FINISHED
1356          */
1357         status = (isOutboundDone() ? Status.CLOSED : Status.OK);
1358         hsStatus = getHSStatus(ciphertext.handshakeStatus);
1359 
1360         int deltaNet = netData.position() - netPos;
1361         int deltaApp = appRemains;
1362         for (int i = offset; i < offset + length; i++) {
1363             deltaApp -= appData[i].remaining();
1364         }
1365 
1366         return new SSLEngineResult(
1367                 status, hsStatus, deltaApp, deltaNet, ciphertext.recordSN);
1368     }
1369 
1370     /*
1371      * Central point to write/get all of the outgoing data.
1372      */
1373     private Ciphertext writeRecord(ByteBuffer[] appData,
1374             int offset, int length, ByteBuffer netData) throws IOException {
1375 
1376         Ciphertext ciphertext = null;
1377         try {
1378             // Acquire the buffered to-be-delivered records or retransmissions.
1379             //
1380             // May have buffered records, or need retransmission if handshaking.
1381             if (!outputRecord.isEmpty() || (handshaker != null)) {

1382                 ciphertext = outputRecord.acquireCiphertext(netData);
1383             }
1384 
1385             if ((ciphertext == null) && (appData != null)) {
1386                 ciphertext = outputRecord.encode(
1387                         appData, offset, length, netData);
1388             }
1389         } catch (SSLHandshakeException she) {
1390             // may be record sequence number overflow
1391             fatal(Alerts.alert_handshake_failure, she);
1392 
1393             return Ciphertext.CIPHERTEXT_NULL;   // make the complier happy
1394         } catch (IOException e) {
1395             fatal(Alerts.alert_unexpected_message, e);
1396 
1397             return Ciphertext.CIPHERTEXT_NULL;   // make the complier happy
1398         }
1399 
1400         if (ciphertext == null) {
1401             return Ciphertext.CIPHERTEXT_NULL;
1402         }
1403 
1404         HandshakeStatus hsStatus = null;
1405         Ciphertext.RecordType recordType = ciphertext.recordType;
1406         if ((handshaker != null) &&
1407                 (recordType.contentType == Record.ct_handshake) &&
1408                 (recordType.handshakeType == HandshakeMessage.ht_finished) &&
1409                 handshaker.isDone() && outputRecord.isEmpty()) {
1410 



1411             hsStatus = finishHandshake();
1412             connectionState = cs_DATA;





















1413         }   // Otherwise, the followed call to getHSStatus() will help.
1414 
1415         /*
1416          * We only need to check the sequence number state for
1417          * non-handshaking record.
1418          *
1419          * Note that in order to maintain the handshake status
1420          * properly, we check the sequence number after the last
1421          * record writing process. As we request renegotiation
1422          * or close the connection for wrapped sequence number
1423          * when there is enough sequence number space left to
1424          * handle a few more records, so the sequence number
1425          * of the last record cannot be wrapped.
1426          */
1427         hsStatus = getHSStatus(hsStatus);
1428         if (connectionState < cs_ERROR && !isOutboundDone() &&
1429                 (hsStatus == HandshakeStatus.NOT_HANDSHAKING) &&
1430                 (outputRecord.seqNumIsHuge())) {
1431             /*
1432              * Ask for renegotiation when need to renew sequence number.
1433              *
1434              * Don't bother to kickstart the renegotiation when the local is
1435              * asking for it.
1436              */
1437             if (debug != null && Debug.isOn("ssl")) {
1438                 System.out.println(Thread.currentThread().getName() +
1439                         ", request renegotiation " +
1440                         "to avoid sequence number overflow");
1441             }
1442 
1443             beginHandshake();
1444 
1445             hsStatus = getHSStatus(null);
1446         }
1447         ciphertext.handshakeStatus = hsStatus;
1448 
1449         return ciphertext;
1450     }
1451 
1452     private HandshakeStatus finishHandshake() {
1453         handshaker = null;
1454         inputRecord.setHandshakeHash(null);
1455         outputRecord.setHandshakeHash(null);
1456         connectionState = cs_DATA;
1457 
1458        return HandshakeStatus.FINISHED;
1459    }
1460 
1461     //
1462     // Close code
1463     //
1464 
1465     /**
1466      * Signals that no more outbound application data will be sent
1467      * on this <code>SSLEngine</code>.
1468      */
1469     private void closeOutboundInternal() {
1470 
1471         if ((debug != null) && Debug.isOn("ssl")) {
1472             System.out.println(Thread.currentThread().getName() +
1473                                     ", closeOutboundInternal()");
1474         }
1475 
1476         /*
1477          * Already closed, ignore
1478          */
1479         if (outboundDone) {
1480             return;
1481         }
1482 
1483         switch (connectionState) {
1484 
1485         /*
1486          * If we haven't even started yet, don't bother reading inbound.
1487          */
1488         case cs_START:
1489             try {
1490                 outputRecord.close();
1491             } catch (IOException ioe) {
1492                // ignore
1493             }
1494             outboundDone = true;
1495 
1496             try {
1497                 inputRecord.close();
1498             } catch (IOException ioe) {
1499                // ignore
1500             }
1501             inboundDone = true;
1502             break;
1503 
1504         case cs_ERROR:
1505         case cs_CLOSED:
1506             break;
1507 
1508         /*
1509          * Otherwise we indicate clean termination.
1510          */
1511         // case cs_HANDSHAKE:
1512         // case cs_DATA:
1513         // case cs_RENEGOTIATE:
1514         default:
1515             warning(Alerts.alert_close_notify);
1516             try {
1517                 outputRecord.close();
1518             } catch (IOException ioe) {
1519                // ignore
1520             }
1521             outboundDone = true;
1522             break;
1523         }
1524 
1525         connectionState = cs_CLOSED;
1526     }
1527 
1528     @Override
1529     public synchronized void closeOutbound() {
1530         /*
1531          * Dump out a close_notify to the remote side
1532          */
1533         if ((debug != null) && Debug.isOn("ssl")) {
1534             System.out.println(Thread.currentThread().getName() +
1535                                     ", called closeOutbound()");
1536         }
1537 
1538         closeOutboundInternal();
1539     }
1540 
1541     /**
1542      * Returns the outbound application data closure state
1543      */
1544     @Override
1545     public boolean isOutboundDone() {
1546         return outboundDone && outputRecord.isEmpty();
1547     }
1548 
1549     /**
1550      * Signals that no more inbound network data will be sent
1551      * to this <code>SSLEngine</code>.
1552      */
1553     private void closeInboundInternal() {
1554 
1555         if ((debug != null) && Debug.isOn("ssl")) {
1556             System.out.println(Thread.currentThread().getName() +
1557                                     ", closeInboundInternal()");
1558         }
1559 
1560         /*
1561          * Already closed, ignore
1562          */
1563         if (inboundDone) {
1564             return;
1565         }
1566 
1567         closeOutboundInternal();
1568 
1569         try {
1570             inputRecord.close();
1571         } catch (IOException ioe) {
1572            // ignore
1573         }
1574         inboundDone = true;
1575 
1576         connectionState = cs_CLOSED;
1577     }
1578 
1579     /*
1580      * Close the inbound side of the connection.  We grab the
1581      * lock here, and do the real work in the internal verison.
1582      * We do check for truncation attacks.
1583      */
1584     @Override
1585     public synchronized void closeInbound() throws SSLException {
1586         /*
1587          * Currently closes the outbound side as well.  The IETF TLS
1588          * working group has expressed the opinion that 1/2 open
1589          * connections are not allowed by the spec.  May change
1590          * someday in the future.
1591          */
1592         if ((debug != null) && Debug.isOn("ssl")) {
1593             System.out.println(Thread.currentThread().getName() +
1594                                     ", called closeInbound()");
1595         }
1596 
1597         /*
1598          * No need to throw an Exception if we haven't even started yet.
1599          */
1600         if ((connectionState != cs_START) && !recvCN) {
1601             recvCN = true;  // Only receive the Exception once
1602             fatal(Alerts.alert_internal_error,
1603                 "Inbound closed before receiving peer's close_notify: " +
1604                 "possible truncation attack?");
1605         } else {
1606             /*
1607              * Currently, this is a no-op, but in case we change
1608              * the close inbound code later.
1609              */
1610             closeInboundInternal();
1611         }
1612     }
1613 
1614     /**
1615      * Returns the network inbound data closure state
1616      */
1617     @Override
1618     public synchronized boolean isInboundDone() {
1619         return inboundDone;
1620     }
1621 
1622 
1623     //
1624     // Misc stuff
1625     //
1626 
1627 
1628     /**
1629      * Returns the current <code>SSLSession</code> for this
1630      * <code>SSLEngine</code>
1631      * <P>
1632      * These can be long lived, and frequently correspond to an
1633      * entire login session for some user.
1634      */
1635     @Override
1636     public synchronized SSLSession getSession() {
1637         return sess;
1638     }
1639 
1640     @Override
1641     public synchronized SSLSession getHandshakeSession() {
1642         return handshakeSession;
1643     }
1644 
1645     synchronized void setHandshakeSession(SSLSessionImpl session) {
1646         // update the fragment size, which may be negotiated during handshaking
1647         inputRecord.changeFragmentSize(session.getNegotiatedMaxFragSize());
1648         outputRecord.changeFragmentSize(session.getNegotiatedMaxFragSize());
1649 
1650         handshakeSession = session;
1651     }
1652 
1653     /**
1654      * Returns a delegated <code>Runnable</code> task for
1655      * this <code>SSLEngine</code>.
1656      */
1657     @Override
1658     public synchronized Runnable getDelegatedTask() {
1659         if (handshaker != null) {
1660             return handshaker.getTask();
1661         }
1662         return null;
1663     }
1664 
1665 
1666     //
1667     // EXCEPTION AND ALERT HANDLING
1668     //
1669 
1670     /*
1671      * Send a warning alert.
1672      */
1673     void warning(byte description) {
1674         sendAlert(Alerts.alert_warning, description);
1675     }
1676 
1677     synchronized void fatal(byte description, String diagnostic)
1678             throws SSLException {
1679         fatal(description, diagnostic, null);
1680     }
1681 
1682     synchronized void fatal(byte description, Throwable cause)
1683             throws SSLException {
1684         fatal(description, null, cause);
1685     }
1686 
1687     /*
1688      * We've got a fatal error here, so start the shutdown process.
1689      *
1690      * Because of the way the code was written, we have some code
1691      * calling fatal directly when the "description" is known
1692      * and some throwing Exceptions which are then caught by higher
1693      * levels which then call here.  This code needs to determine
1694      * if one of the lower levels has already started the process.
1695      *
1696      * We won't worry about Error's, if we have one of those,
1697      * we're in worse trouble.  Note:  the networking code doesn't
1698      * deal with Errors either.
1699      */
1700     synchronized void fatal(byte description, String diagnostic,
1701             Throwable cause) throws SSLException {
1702 
1703         /*
1704          * If we have no further information, make a general-purpose
1705          * message for folks to see.  We generally have one or the other.
1706          */
1707         if (diagnostic == null) {
1708             diagnostic = "General SSLEngine problem";
1709         }
1710         if (cause == null) {
1711             cause = Alerts.getSSLException(description, cause, diagnostic);
1712         }
1713 
1714         /*
1715          * If we've already shutdown because of an error,
1716          * there is nothing we can do except rethrow the exception.
1717          *
1718          * Most exceptions seen here will be SSLExceptions.
1719          * We may find the occasional Exception which hasn't been
1720          * converted to a SSLException, so we'll do it here.
1721          */
1722         if (closeReason != null) {
1723             if ((debug != null) && Debug.isOn("ssl")) {
1724                 System.out.println(Thread.currentThread().getName() +
1725                     ", fatal: engine already closed.  Rethrowing " +
1726                     cause.toString());
1727             }
1728             if (cause instanceof RuntimeException) {
1729                 throw (RuntimeException)cause;
1730             } else if (cause instanceof SSLException) {
1731                 throw (SSLException)cause;
1732             } else if (cause instanceof Exception) {
1733                 throw new SSLException("fatal SSLEngine condition", cause);
1734             }
1735         }
1736 
1737         if ((debug != null) && Debug.isOn("ssl")) {
1738             System.out.println(Thread.currentThread().getName()
1739                         + ", fatal error: " + description +
1740                         ": " + diagnostic + "\n" + cause.toString());
1741         }
1742 
1743         /*
1744          * Ok, this engine's going down.
1745          */
1746         int oldState = connectionState;
1747         connectionState = cs_ERROR;
1748 
1749         try {
1750             inputRecord.close();
1751         } catch (IOException ioe) {
1752            // ignore
1753         }
1754         inboundDone = true;
1755 
1756         sess.invalidate();
1757         if (handshakeSession != null) {
1758             handshakeSession.invalidate();
1759         }
1760 
1761         /*
1762          * If we haven't even started handshaking yet, no need
1763          * to generate the fatal close alert.
1764          */
1765         if (oldState != cs_START) {
1766             sendAlert(Alerts.alert_fatal, description);
1767         }
1768 
1769         if (cause instanceof SSLException) { // only true if != null
1770             closeReason = (SSLException)cause;
1771         } else {
1772             /*
1773              * Including RuntimeExceptions, but we'll throw those
1774              * down below.  The closeReason isn't used again,
1775              * except for null checks.
1776              */
1777             closeReason =
1778                 Alerts.getSSLException(description, cause, diagnostic);
1779         }
1780 
1781         try {
1782             outputRecord.close();
1783         } catch (IOException ioe) {
1784            // ignore
1785         }
1786         outboundDone = true;
1787 
1788         connectionState = cs_CLOSED;
1789 
1790         if (cause instanceof RuntimeException) {
1791             throw (RuntimeException)cause;
1792         } else {
1793             throw closeReason;
1794         }
1795     }
1796 
1797     /*
1798      * Process an incoming alert ... caller must already have synchronized
1799      * access to "this".
1800      */
1801     private void recvAlert(ByteBuffer fragment) throws IOException {
1802         byte level = fragment.get();
1803         byte description = fragment.get();
1804 
1805         if (description == -1) { // check for short message
1806             fatal(Alerts.alert_illegal_parameter, "Short alert message");
1807         }
1808 
1809         if (debug != null && (Debug.isOn("record") ||
1810                 Debug.isOn("handshake"))) {
1811             synchronized (System.out) {
1812                 System.out.print(Thread.currentThread().getName());
1813                 System.out.print(", RECV " + protocolVersion + " ALERT:  ");
1814                 if (level == Alerts.alert_fatal) {
1815                     System.out.print("fatal, ");
1816                 } else if (level == Alerts.alert_warning) {
1817                     System.out.print("warning, ");
1818                 } else {
1819                     System.out.print("<level " + (0x0ff & level) + ">, ");
1820                 }
1821                 System.out.println(Alerts.alertDescription(description));
1822             }
1823         }
1824 
1825         if (level == Alerts.alert_warning) {
1826             if (description == Alerts.alert_close_notify) {
1827                 if (connectionState == cs_HANDSHAKE) {
1828                     fatal(Alerts.alert_unexpected_message,
1829                                 "Received close_notify during handshake");
1830                 } else {
1831                     recvCN = true;
1832                     closeInboundInternal();  // reply to close
1833                 }
1834             } else {
1835 
1836                 //
1837                 // The other legal warnings relate to certificates,
1838                 // e.g. no_certificate, bad_certificate, etc; these
1839                 // are important to the handshaking code, which can
1840                 // also handle illegal protocol alerts if needed.
1841                 //
1842                 if (handshaker != null) {
1843                     handshaker.handshakeAlert(description);
1844                 }
1845             }
1846         } else { // fatal or unknown level
1847             String reason = "Received fatal alert: "
1848                 + Alerts.alertDescription(description);
1849             if (closeReason == null) {
1850                 closeReason = Alerts.getSSLException(description, reason);
1851             }
1852             fatal(Alerts.alert_unexpected_message, reason);
1853         }
1854     }
1855 
1856 
1857     /*
1858      * Emit alerts.  Caller must have synchronized with "this".
1859      */
1860     private void sendAlert(byte level, byte description) {
1861         // the connectionState cannot be cs_START
1862         if (connectionState >= cs_CLOSED) {
1863             return;
1864         }
1865 
1866         // For initial handshaking, don't send alert message to peer if
1867         // handshaker has not started.
1868         //
1869         // Shall we send an fatal alter to terminate the connection gracefully?
1870         if (connectionState <= cs_HANDSHAKE &&
1871                 (handshaker == null || !handshaker.started() ||
1872                         !handshaker.activated())) {
1873             return;
1874         }
1875 
1876         try {
1877             outputRecord.encodeAlert(level, description);
1878         } catch (IOException ioe) {
1879             // ignore
1880         }
1881     }
1882 
1883 
1884     //
1885     // VARIOUS OTHER METHODS (COMMON TO SSLSocket)
1886     //
1887 
1888 
1889     /**
1890      * Controls whether new connections may cause creation of new SSL
1891      * sessions.
1892      *
1893      * As long as handshaking has not started, we can change
1894      * whether we enable session creations.  Otherwise,
1895      * we will need to wait for the next handshake.
1896      */
1897     @Override
1898     public synchronized void setEnableSessionCreation(boolean flag) {
1899         enableSessionCreation = flag;
1900 
1901         if ((handshaker != null) && !handshaker.activated()) {
1902             handshaker.setEnableSessionCreation(enableSessionCreation);
1903         }
1904     }
1905 
1906     /**
1907      * Returns true if new connections may cause creation of new SSL
1908      * sessions.
1909      */
1910     @Override
1911     public synchronized boolean getEnableSessionCreation() {
1912         return enableSessionCreation;
1913     }
1914 
1915 
1916     /**
1917      * Sets the flag controlling whether a server mode engine
1918      * *REQUIRES* SSL client authentication.
1919      *
1920      * As long as handshaking has not started, we can change
1921      * whether client authentication is needed.  Otherwise,
1922      * we will need to wait for the next handshake.
1923      */
1924     @Override
1925     public synchronized void setNeedClientAuth(boolean flag) {
1926         doClientAuth = (flag ?
1927                 ClientAuthType.CLIENT_AUTH_REQUIRED :
1928                 ClientAuthType.CLIENT_AUTH_NONE);
1929 
1930         if ((handshaker != null) &&
1931                 (handshaker instanceof ServerHandshaker) &&
1932                 !handshaker.activated()) {
1933             ((ServerHandshaker) handshaker).setClientAuth(doClientAuth);
1934         }
1935     }
1936 
1937     @Override
1938     public synchronized boolean getNeedClientAuth() {
1939         return (doClientAuth == ClientAuthType.CLIENT_AUTH_REQUIRED);
1940     }
1941 
1942     /**
1943      * Sets the flag controlling whether a server mode engine
1944      * *REQUESTS* SSL client authentication.
1945      *
1946      * As long as handshaking has not started, we can change
1947      * whether client authentication is requested.  Otherwise,
1948      * we will need to wait for the next handshake.
1949      */
1950     @Override
1951     public synchronized void setWantClientAuth(boolean flag) {
1952         doClientAuth = (flag ?
1953                 ClientAuthType.CLIENT_AUTH_REQUESTED :
1954                 ClientAuthType.CLIENT_AUTH_NONE);
1955 
1956         if ((handshaker != null) &&
1957                 (handshaker instanceof ServerHandshaker) &&
1958                 !handshaker.activated()) {
1959             ((ServerHandshaker) handshaker).setClientAuth(doClientAuth);
1960         }
1961     }
1962 
1963     @Override
1964     public synchronized boolean getWantClientAuth() {
1965         return (doClientAuth == ClientAuthType.CLIENT_AUTH_REQUESTED);
1966     }
1967 
1968 
1969     /**
1970      * Sets the flag controlling whether the engine is in SSL
1971      * client or server mode.  Must be called before any SSL
1972      * traffic has started.
1973      */
1974     @Override
1975     @SuppressWarnings("fallthrough")
1976     public synchronized void setUseClientMode(boolean flag) {
1977         switch (connectionState) {
1978 
1979         case cs_START:
1980             /*
1981              * If we need to change the socket mode and the enabled
1982              * protocols and cipher suites haven't specifically been
1983              * set by the user, change them to the corresponding
1984              * default ones.
1985              */
1986             if (roleIsServer != (!flag)) {
1987                 if (sslContext.isDefaultProtocolList(enabledProtocols)) {
1988                     enabledProtocols =
1989                             sslContext.getDefaultProtocolList(!flag);
1990                 }
1991 
1992                 if (sslContext.isDefaultCipherSuiteList(enabledCipherSuites)) {
1993                     enabledCipherSuites =
1994                             sslContext.getDefaultCipherSuiteList(!flag);
1995                 }
1996             }
1997 
1998             roleIsServer = !flag;
1999             serverModeSet = true;
2000             break;
2001 
2002         case cs_HANDSHAKE:
2003             /*
2004              * If we have a handshaker, but haven't started
2005              * SSL traffic, we can throw away our current
2006              * handshaker, and start from scratch.  Don't
2007              * need to call doneConnect() again, we already
2008              * have the streams.
2009              */
2010             assert(handshaker != null);
2011             if (!handshaker.activated()) {
2012                 /*
2013                  * If we need to change the socket mode and the enabled
2014                  * protocols and cipher suites haven't specifically been
2015                  * set by the user, change them to the corresponding
2016                  * default ones.
2017                  */
2018                 if (roleIsServer != (!flag)) {
2019                     if (sslContext.isDefaultProtocolList(enabledProtocols)) {
2020                         enabledProtocols =
2021                                 sslContext.getDefaultProtocolList(!flag);
2022                     }
2023 
2024                     if (sslContext.isDefaultCipherSuiteList(
2025                                                     enabledCipherSuites)) {
2026                         enabledCipherSuites =
2027                             sslContext.getDefaultCipherSuiteList(!flag);
2028                     }
2029                 }
2030 
2031                 roleIsServer = !flag;
2032                 connectionState = cs_START;
2033                 initHandshaker();
2034                 break;
2035             }
2036 
2037             // If handshake has started, that's an error.  Fall through...
2038 
2039         default:
2040             if (debug != null && Debug.isOn("ssl")) {
2041                 System.out.println(Thread.currentThread().getName() +
2042                     ", setUseClientMode() invoked in state = " +
2043                     connectionState);
2044             }
2045 
2046             /*
2047              * We can let them continue if they catch this correctly,
2048              * we don't need to shut this down.
2049              */
2050             throw new IllegalArgumentException(
2051                 "Cannot change mode after SSL traffic has started");
2052         }
2053     }
2054 
2055     @Override
2056     public synchronized boolean getUseClientMode() {
2057         return !roleIsServer;
2058     }
2059 
2060 
2061     /**
2062      * Returns the names of the cipher suites which could be enabled for use
2063      * on an SSL connection.  Normally, only a subset of these will actually
2064      * be enabled by default, since this list may include cipher suites which
2065      * do not support the mutual authentication of servers and clients, or
2066      * which do not protect data confidentiality.  Servers may also need
2067      * certain kinds of certificates to use certain cipher suites.
2068      *
2069      * @return an array of cipher suite names
2070      */
2071     @Override
2072     public String[] getSupportedCipherSuites() {
2073         return sslContext.getSupportedCipherSuiteList().toStringArray();
2074     }
2075 
2076     /**
2077      * Controls which particular cipher suites are enabled for use on
2078      * this connection.  The cipher suites must have been listed by
2079      * getCipherSuites() as being supported.  Even if a suite has been
2080      * enabled, it might never be used if no peer supports it or the
2081      * requisite certificates (and private keys) are not available.
2082      *
2083      * @param suites Names of all the cipher suites to enable.
2084      */
2085     @Override
2086     public synchronized void setEnabledCipherSuites(String[] suites) {
2087         enabledCipherSuites = new CipherSuiteList(suites);
2088         if ((handshaker != null) && !handshaker.activated()) {
2089             handshaker.setEnabledCipherSuites(enabledCipherSuites);
2090         }
2091     }
2092 
2093     /**
2094      * Returns the names of the SSL cipher suites which are currently enabled
2095      * for use on this connection.  When an SSL engine is first created,
2096      * all enabled cipher suites <em>(a)</em> protect data confidentiality,
2097      * by traffic encryption, and <em>(b)</em> can mutually authenticate
2098      * both clients and servers.  Thus, in some environments, this value
2099      * might be empty.
2100      *
2101      * @return an array of cipher suite names
2102      */
2103     @Override
2104     public synchronized String[] getEnabledCipherSuites() {
2105         return enabledCipherSuites.toStringArray();
2106     }
2107 
2108 
2109     /**
2110      * Returns the protocols that are supported by this implementation.
2111      * A subset of the supported protocols may be enabled for this connection
2112      * @return an array of protocol names.
2113      */
2114     @Override
2115     public String[] getSupportedProtocols() {
2116         return sslContext.getSuportedProtocolList().toStringArray();
2117     }
2118 
2119     /**
2120      * Controls which protocols are enabled for use on
2121      * this connection.  The protocols must have been listed by
2122      * getSupportedProtocols() as being supported.
2123      *
2124      * @param protocols protocols to enable.
2125      * @exception IllegalArgumentException when one of the protocols
2126      *  named by the parameter is not supported.
2127      */
2128     @Override
2129     public synchronized void setEnabledProtocols(String[] protocols) {
2130         enabledProtocols = new ProtocolList(protocols);
2131         if ((handshaker != null) && !handshaker.activated()) {
2132             handshaker.setEnabledProtocols(enabledProtocols);
2133         }
2134     }
2135 
2136     @Override
2137     public synchronized String[] getEnabledProtocols() {
2138         return enabledProtocols.toStringArray();
2139     }
2140 
2141     /**
2142      * Returns the SSLParameters in effect for this SSLEngine.
2143      */
2144     @Override
2145     public synchronized SSLParameters getSSLParameters() {
2146         SSLParameters params = super.getSSLParameters();
2147 
2148         // the super implementation does not handle the following parameters
2149         params.setEndpointIdentificationAlgorithm(identificationProtocol);
2150         params.setAlgorithmConstraints(algorithmConstraints);
2151         params.setSNIMatchers(sniMatchers);
2152         params.setServerNames(serverNames);
2153         params.setUseCipherSuitesOrder(preferLocalCipherSuites);
2154         params.setEnableRetransmissions(enableRetransmissions);
2155         params.setMaximumPacketSize(maximumPacketSize);
2156         params.setApplicationProtocols(applicationProtocols);
2157 
2158         return params;
2159     }
2160 
2161     /**
2162      * Applies SSLParameters to this engine.
2163      */
2164     @Override
2165     public synchronized void setSSLParameters(SSLParameters params) {
2166         super.setSSLParameters(params);
2167 
2168         // the super implementation does not handle the following parameters
2169         identificationProtocol = params.getEndpointIdentificationAlgorithm();
2170         algorithmConstraints = params.getAlgorithmConstraints();
2171         preferLocalCipherSuites = params.getUseCipherSuitesOrder();
2172         enableRetransmissions = params.getEnableRetransmissions();
2173         maximumPacketSize = params.getMaximumPacketSize();
2174 
2175         if (maximumPacketSize != 0) {
2176             outputRecord.changePacketSize(maximumPacketSize);
2177         } else {
2178             // use the implicit maximum packet size.
2179             maximumPacketSize = outputRecord.getMaxPacketSize();
2180         }
2181 
2182         List<SNIServerName> sniNames = params.getServerNames();
2183         if (sniNames != null) {
2184             serverNames = sniNames;
2185         }
2186 
2187         Collection<SNIMatcher> matchers = params.getSNIMatchers();
2188         if (matchers != null) {
2189             sniMatchers = matchers;
2190         }
2191         applicationProtocols = params.getApplicationProtocols();
2192 
2193         if ((handshaker != null) && !handshaker.started()) {
2194             handshaker.setIdentificationProtocol(identificationProtocol);
2195             handshaker.setAlgorithmConstraints(algorithmConstraints);
2196             handshaker.setMaximumPacketSize(maximumPacketSize);
2197             handshaker.setApplicationProtocols(applicationProtocols);
2198             if (roleIsServer) {
2199                 handshaker.setSNIMatchers(sniMatchers);
2200                 handshaker.setUseCipherSuitesOrder(preferLocalCipherSuites);
2201             } else {
2202                 handshaker.setSNIServerNames(serverNames);
2203             }
2204         }
2205     }
2206 
2207     @Override
2208     public synchronized String getApplicationProtocol() {
2209         return applicationProtocol;
2210     }
2211 
2212     @Override
2213     public synchronized String getHandshakeApplicationProtocol() {
2214         if ((handshaker != null) && handshaker.started()) {
2215             return handshaker.getHandshakeApplicationProtocol();
2216         }
2217         return null;
2218     }
2219 
2220     /**
2221      * Returns a printable representation of this end of the connection.
2222      */
2223     @Override
2224     public String toString() {
2225         StringBuilder retval = new StringBuilder(80);
2226 
2227         retval.append(Integer.toHexString(hashCode()));
2228         retval.append("[");
2229         retval.append("SSLEngine[hostname=");
2230         String host = getPeerHost();
2231         retval.append((host == null) ? "null" : host);
2232         retval.append(" port=");
2233         retval.append(Integer.toString(getPeerPort()));
2234         retval.append(" role=" + (roleIsServer ? "Server" : "Client"));
2235         retval.append("] ");
2236         retval.append(getSession().getCipherSuite());
2237         retval.append("]");
2238 
2239         return retval.toString();
2240     }
2241 }
--- EOF ---