< prev index next >

src/java.base/share/classes/sun/security/ssl/SSLEngineImpl.java

Print this page


   1 /*
   2  * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package sun.security.ssl;
  27 
  28 import java.io.*;
  29 import java.nio.*;
  30 import java.security.*;
  31 import java.util.*;




  32 import java.util.function.BiFunction;











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



1241 
1242         // check engine parameters
1243         checkEngineParas(netData, appData, offset, length, true);


1244 
1245         /*
1246          * We can be smarter about using smaller buffer sizes later.
1247          * For now, force it to be large enough to handle any valid record.
1248          */
1249         if (netData.remaining() < sess.getPacketBufferSize()) {
1250             return new SSLEngineResult(
1251                 Status.BUFFER_OVERFLOW, getHSStatus(null), 0, 0);
1252         }
1253 








1254         try {
1255             synchronized (wrapLock) {
1256                 return writeAppRecord(appData, offset, length, netData);
1257             }
1258         } catch (SSLProtocolException spe) {
1259             // may be an unexpected handshake message
1260             fatal(Alerts.alert_unexpected_message, spe.getMessage(), spe);
1261             return null;  // make compiler happy
1262         } catch (Exception e) {
1263             fatal(Alerts.alert_internal_error,
1264                 "problem wrapping app data", e);
1265             return null;  // make compiler happy
1266         }
1267     }
1268 
1269     /*
1270      * Makes additional checks for unwrap, but this time more
1271      * specific to this packet and the current state of the machine.
1272      */
1273     private SSLEngineResult writeAppRecord(ByteBuffer[] appData,
1274             int offset, int length, ByteBuffer netData) throws IOException {
1275 
1276         Status status = null;
1277         HandshakeStatus hsStatus = null;
1278 
1279         /*
1280          * See if the handshaker needs to report back some SSLException.
1281          */
1282         checkTaskThrown();
1283 
1284         /*
1285          * short circuit if we're closed/closing.
1286          */
1287         if (isOutboundDone()) {
1288             return new SSLEngineResult(Status.CLOSED, getHSStatus(null), 0, 0);

1289         }
1290 
1291         /*
1292          * If we're still in cs_HANDSHAKE, make sure it's been
1293          * started.
1294          */
1295         synchronized (this) {
1296             if ((connectionState == cs_HANDSHAKE) ||
1297                 (connectionState == cs_START)) {
1298 
1299                 kickstartHandshake();
1300 
1301                 /*
1302                  * If there's no HS data available to write, we can return
1303                  * without trying to wrap anything.
1304                  */
1305                 hsStatus = getHSStatus(null);
1306                 if (hsStatus == HandshakeStatus.NEED_UNWRAP) {
1307                     /*
1308                      * For DTLS, if the handshake state is
1309                      * HandshakeStatus.NEED_UNWRAP, a call to SSLEngine.wrap()
1310                      * means that the previous handshake packets (if delivered)
1311                      * get lost, and need retransmit the handshake messages.
1312                      */
1313                     if (!isDTLS || !enableRetransmissions ||
1314                             (handshaker == null) || outputRecord.firstMessage) {

1315 
1316                         return new SSLEngineResult(Status.OK, hsStatus, 0, 0);
1317                     }   // otherwise, need retransmission
1318                 }
1319             }
1320         }
1321 
1322         /*
1323          * Grab a copy of this if it doesn't already exist,
1324          * and we can use it several places before anything major
1325          * happens on this side.  Races aren't critical
1326          * here.
1327          */
1328         if (hsStatus == null) {
1329             hsStatus = getHSStatus(null);
1330         }
1331 
1332         /*
1333          * If we have a task outstanding, this *MUST* be done before
1334          * doing any more wrapping, because we could be in the middle
1335          * of receiving a handshake message, for example, a finished
1336          * message which would change the ciphers.
1337          */
1338         if (hsStatus == HandshakeStatus.NEED_TASK) {
1339             return new SSLEngineResult(Status.OK, hsStatus, 0, 0);
1340         }
1341 
1342         /*
1343          * This will obtain any waiting outbound data, or will
1344          * process the outbound appData.
1345          */
1346         int netPos = netData.position();
1347         int appRemains = 0;
1348         for (int i = offset; i < offset + length; i++) {
1349             if (appData[i] == null) {
1350                 throw new IllegalArgumentException(
1351                         "appData[" + i + "] == null");


1352             }
1353             appRemains += appData[i].remaining();



1354         }
1355 
1356         Ciphertext ciphertext = null;
1357         try {
1358             if (appRemains != 0) {
1359                 synchronized (writeLock) {
1360                     ciphertext = writeRecord(appData, offset, length, netData);






1361                 }
1362             } else {
1363                 synchronized (writeLock) {
1364                     ciphertext = writeRecord(null, 0, 0, netData);

1365                 }





1366             }
1367         } catch (SSLException e) {
1368             throw e;
1369         } catch (IOException e) {
1370             throw new SSLException("Write problems", e);
1371         }
1372 
1373         /*
1374          * writeRecord might have reported some status.
1375          * Now check for the remaining cases.
1376          *
1377          * status above should cover:  NEED_WRAP/FINISHED
1378          */
1379         status = (isOutboundDone() ? Status.CLOSED : Status.OK);
1380         hsStatus = getHSStatus(ciphertext.handshakeStatus);




1381 
1382         int deltaNet = netData.position() - netPos;
1383         int deltaApp = appRemains;
1384         for (int i = offset; i < offset + length; i++) {
1385             deltaApp -= appData[i].remaining();
1386         }
1387 
1388         return new SSLEngineResult(
1389                 status, hsStatus, deltaApp, deltaNet, ciphertext.recordSN);

1390     }
1391 
1392     /*
1393      * Central point to write/get all of the outgoing data.
1394      */
1395     private Ciphertext writeRecord(ByteBuffer[] appData,
1396             int offset, int length, ByteBuffer netData) throws IOException {


1397 
1398         Ciphertext ciphertext = null;
1399         try {
1400             // Acquire the buffered to-be-delivered records or retransmissions.
1401             //
1402             // May have buffered records, or need retransmission if handshaking.
1403             if (!outputRecord.isEmpty() ||
1404                     (enableRetransmissions && handshaker != null)) {
1405                 ciphertext = outputRecord.acquireCiphertext(netData);
1406             }
1407 
1408             if ((ciphertext == null) && (appData != null)) {
1409                 ciphertext = outputRecord.encode(
1410                         appData, offset, length, netData);
1411             }
1412         } catch (SSLHandshakeException she) {
1413             // may be record sequence number overflow
1414             fatal(Alerts.alert_handshake_failure, she);
1415 
1416             return Ciphertext.CIPHERTEXT_NULL;   // make the complier happy
1417         } catch (IOException e) {
1418             fatal(Alerts.alert_unexpected_message, e);
1419 
1420             return Ciphertext.CIPHERTEXT_NULL;   // make the complier happy
1421         }
1422 
1423         if (ciphertext == null) {
1424             return Ciphertext.CIPHERTEXT_NULL;
1425         }
1426 
1427         HandshakeStatus hsStatus = null;
1428         Ciphertext.RecordType recordType = ciphertext.recordType;
1429         if ((recordType.contentType == Record.ct_handshake) &&
1430             (recordType.handshakeType == HandshakeMessage.ht_finished) &&
1431             outputRecord.isEmpty()) {
1432 
1433             if (handshaker == null) {
1434                 hsStatus = HandshakeStatus.FINISHED;
1435             } else if (handshaker.isDone()) {
1436                 hsStatus = finishHandshake();
1437                 connectionState = cs_DATA;
1438 
1439                 // Retransmit the last flight twice.
1440                 //
1441                 // The application data transactions may begin immediately
1442                 // after the last flight.  If the last flight get lost, the
1443                 // application data may be discarded accordingly.  As could
1444                 // be an issue for some applications.  This impact can be
1445                 // mitigated by sending the last fligth twice.
1446                 if (isDTLS && enableRetransmissions) {
1447                     if (debug != null && Debug.isOn("verbose")) {
1448                         Debug.log(
1449                             "Retransmit the last flight messages.");
1450                     }
1451 
1452                     synchronized (this) {
1453                         outputRecord.launchRetransmission();
1454                     }
1455 

1456                     hsStatus = HandshakeStatus.NEED_WRAP;
1457                 }
1458             }
1459         }   // Otherwise, the followed call to getHSStatus() will help.
1460 
1461         /*
1462          * We only need to check the sequence number state for
1463          * non-handshaking record.
1464          *
1465          * Note that in order to maintain the handshake status
1466          * properly, we check the sequence number after the last
1467          * record writing process. As we request renegotiation
1468          * or close the connection for wrapped sequence number
1469          * when there is enough sequence number space left to
1470          * handle a few more records, so the sequence number
1471          * of the last record cannot be wrapped.
1472          */
1473         hsStatus = getHSStatus(hsStatus);
1474         if (connectionState < cs_ERROR && !isOutboundDone() &&
1475                 (hsStatus == HandshakeStatus.NOT_HANDSHAKING) &&
1476                 (outputRecord.seqNumIsHuge())) {
1477             /*
1478              * Ask for renegotiation when need to renew sequence number.
1479              *
1480              * Don't bother to kickstart the renegotiation when the local is
1481              * asking for it.
1482              */
1483             if (debug != null && Debug.isOn("ssl")) {
1484                 System.out.println(Thread.currentThread().getName() +
1485                         ", request renegotiation " +
1486                         "to avoid sequence number overflow");
1487             }
1488 
1489             beginHandshake();
1490 
1491             hsStatus = getHSStatus(null);
1492         }


1493         ciphertext.handshakeStatus = hsStatus;
1494 
1495         return ciphertext;
1496     }
1497 
1498     private HandshakeStatus finishHandshake() {
1499         handshaker = null;
1500         inputRecord.setHandshakeHash(null);
1501         outputRecord.setHandshakeHash(null);
1502         connectionState = cs_DATA;
1503 
1504        return HandshakeStatus.FINISHED;

1505    }

1506 
1507     //
1508     // Close code
1509     //
1510 
1511     /**
1512      * Signals that no more outbound application data will be sent
1513      * on this <code>SSLEngine</code>.






1514      */
1515     private void closeOutboundInternal() {
1516 
1517         if ((debug != null) && Debug.isOn("ssl")) {
1518             System.out.println(Thread.currentThread().getName() +
1519                                     ", closeOutboundInternal()");






1520         }
1521 
1522         /*
1523          * Already closed, ignore
1524          */
1525         if (outboundDone) {
1526             return;
1527         }
1528 
1529         switch (connectionState) {


1530 
1531         /*
1532          * If we haven't even started yet, don't bother reading inbound.
1533          */
1534         case cs_START:
1535             try {
1536                 outputRecord.close();
1537             } catch (IOException ioe) {
1538                // ignore
1539             }
1540             outboundDone = true;
1541 
1542             try {
1543                 inputRecord.close();
1544             } catch (IOException ioe) {
1545                // ignore
1546             }
1547             inboundDone = true;
1548             break;
1549 
1550         case cs_ERROR:
1551         case cs_CLOSED:
1552             break;


1553 
1554         /*
1555          * Otherwise we indicate clean termination.
1556          */
1557         // case cs_HANDSHAKE:
1558         // case cs_DATA:
1559         // case cs_RENEGOTIATE:
1560         default:
1561             warning(Alerts.alert_close_notify);
1562             try {
1563                 outputRecord.close();
1564             } catch (IOException ioe) {
1565                // ignore
1566             }
1567             outboundDone = true;
1568             break;
1569         }
1570 
1571         connectionState = cs_CLOSED;



1572     }
1573 
1574     @Override
1575     public synchronized void closeOutbound() {
1576         /*
1577          * Dump out a close_notify to the remote side
1578          */
1579         if ((debug != null) && Debug.isOn("ssl")) {
1580             System.out.println(Thread.currentThread().getName() +
1581                                     ", called closeOutbound()");
1582         }
1583 
1584         closeOutboundInternal();
1585     }
1586 
1587     /**
1588      * Returns the outbound application data closure state
1589      */
1590     @Override
1591     public boolean isOutboundDone() {
1592         return outboundDone && outputRecord.isEmpty();


1593     }
1594 
1595     /**
1596      * Signals that no more inbound network data will be sent
1597      * to this <code>SSLEngine</code>.
1598      */
1599     private void closeInboundInternal() {
1600 
1601         if ((debug != null) && Debug.isOn("ssl")) {
1602             System.out.println(Thread.currentThread().getName() +
1603                                     ", closeInboundInternal()");
1604         }
1605 
1606         /*
1607          * Already closed, ignore
1608          */
1609         if (inboundDone) {
1610             return;
1611         }
1612 
1613         closeOutboundInternal();

1614 
1615         try {
1616             inputRecord.close();





1617         } catch (IOException ioe) {
1618            // ignore










1619         }
1620         inboundDone = true;
1621 
1622         connectionState = cs_CLOSED;
1623     }
1624 




1625     /*
1626      * Close the inbound side of the connection.  We grab the
1627      * lock here, and do the real work in the internal verison.
1628      * We do check for truncation attacks.
1629      */
1630     @Override
1631     public synchronized void closeInbound() throws SSLException {
1632         /*
1633          * Currently closes the outbound side as well.  The IETF TLS
1634          * working group has expressed the opinion that 1/2 open
1635          * connections are not allowed by the spec.  May change
1636          * someday in the future.
1637          */
1638         if ((debug != null) && Debug.isOn("ssl")) {
1639             System.out.println(Thread.currentThread().getName() +
1640                                     ", called closeInbound()");
1641         }
1642 




1643         /*
1644          * No need to throw an Exception if we haven't even started yet.
1645          */
1646         if ((connectionState != cs_START) && !recvCN) {
1647             recvCN = true;  // Only receive the Exception once
1648             fatal(Alerts.alert_internal_error,
1649                 "Inbound closed before receiving peer's close_notify: " +
1650                 "possible truncation attack?");
1651         } else {
1652             /*
1653              * Currently, this is a no-op, but in case we change
1654              * the close inbound code later.
1655              */
1656             closeInboundInternal();


1657         }
1658     }
1659 
1660     /**
1661      * Returns the network inbound data closure state
1662      */
1663     @Override
1664     public synchronized boolean isInboundDone() {
1665         return inboundDone;
1666     }
1667 
1668 
1669     //
1670     // Misc stuff
1671     //
1672 
1673 
1674     /**
1675      * Returns the current <code>SSLSession</code> for this
1676      * <code>SSLEngine</code>
1677      * <P>
1678      * These can be long lived, and frequently correspond to an
1679      * entire login session for some user.
1680      */
1681     @Override
1682     public synchronized SSLSession getSession() {
1683         return sess;












1684     }
1685 
1686     @Override
1687     public synchronized SSLSession getHandshakeSession() {
1688         return handshakeSession;


1689     }
1690 
1691     synchronized void setHandshakeSession(SSLSessionImpl session) {
1692         // update the fragment size, which may be negotiated during handshaking
1693         inputRecord.changeFragmentSize(session.getNegotiatedMaxFragSize());
1694         outputRecord.changeFragmentSize(session.getNegotiatedMaxFragSize());
1695 
1696         handshakeSession = session;
1697     }
1698 
1699     /**
1700      * Returns a delegated <code>Runnable</code> task for
1701      * this <code>SSLEngine</code>.
1702      */
1703     @Override
1704     public synchronized Runnable getDelegatedTask() {
1705         if (handshaker != null) {
1706             return handshaker.getTask();
1707         }
1708         return null;
1709     }
1710 
1711 
1712     //
1713     // EXCEPTION AND ALERT HANDLING
1714     //
1715 
1716     /*
1717      * Send a warning alert.

1718      */
1719     void warning(byte description) {
1720         sendAlert(Alerts.alert_warning, description);







1721     }
1722 
1723     synchronized void fatal(byte description, String diagnostic)
1724             throws SSLException {
1725         fatal(description, diagnostic, null, false);
1726     }

1727 
1728     synchronized void fatal(byte description, Throwable cause)
1729             throws SSLException {
1730         fatal(description, null, cause, false);
1731     }
1732 
1733     synchronized void fatal(byte description, String diagnostic,
1734             Throwable cause) throws SSLException {
1735         fatal(description, diagnostic, cause, false);

1736     }
1737 
1738     /*
1739      * We've got a fatal error here, so start the shutdown process.
1740      *
1741      * Because of the way the code was written, we have some code
1742      * calling fatal directly when the "description" is known
1743      * and some throwing Exceptions which are then caught by higher
1744      * levels which then call here.  This code needs to determine
1745      * if one of the lower levels has already started the process.
1746      *
1747      * We won't worry about Errors, if we have one of those,
1748      * we're in worse trouble.  Note:  the networking code doesn't
1749      * deal with Errors either.
1750      */
1751     synchronized void fatal(byte description, String diagnostic,
1752             Throwable cause, boolean recvFatalAlert) throws SSLException {
1753 
1754         /*
1755          * If we have no further information, make a general-purpose
1756          * message for folks to see.  We generally have one or the other.
1757          */
1758         if (diagnostic == null) {
1759             diagnostic = "General SSLEngine problem";





1760         }
1761         if (cause == null) {
1762             cause = Alerts.getSSLException(description, cause, diagnostic);
1763         }
1764 
1765         /*
1766          * If we've already shutdown because of an error,
1767          * there is nothing we can do except rethrow the exception.
1768          *
1769          * Most exceptions seen here will be SSLExceptions.
1770          * We may find the occasional Exception which hasn't been
1771          * converted to a SSLException, so we'll do it here.
1772          */
1773         if (closeReason != null) {
1774             if ((debug != null) && Debug.isOn("ssl")) {
1775                 System.out.println(Thread.currentThread().getName() +
1776                     ", fatal: engine already closed.  Rethrowing " +
1777                     cause.toString());
1778             }
1779             if (cause instanceof RuntimeException) {
1780                 throw (RuntimeException)cause;
1781             } else if (cause instanceof SSLException) {
1782                 throw (SSLException)cause;
1783             } else if (cause instanceof Exception) {
1784                 throw new SSLException("fatal SSLEngine condition", cause);
1785             }
1786         }
1787 
1788         if ((debug != null) && Debug.isOn("ssl")) {
1789             System.out.println(Thread.currentThread().getName()
1790                         + ", fatal error: " + description +
1791                         ": " + diagnostic + "\n" + cause.toString());
1792         }
1793 
1794         /*
1795          * Ok, this engine's going down.
1796          */
1797         int oldState = connectionState;
1798         connectionState = cs_ERROR;
1799 
1800         try {
1801             inputRecord.close();

1802         } catch (IOException ioe) {
1803            // ignore



1804         }
1805         inboundDone = true;
1806 
1807         sess.invalidate();
1808         if (handshakeSession != null) {
1809             handshakeSession.invalidate();
1810         }
1811 
1812         /*
1813          * If we haven't even started handshaking yet, or we are the
1814          * recipient of a fatal alert, no need to generate a fatal close
1815          * alert.





1816          */
1817         if (oldState != cs_START && !recvFatalAlert) {
1818             sendAlert(Alerts.alert_fatal, description);
1819         }
1820 
1821         if (cause instanceof SSLException) { // only true if != null
1822             closeReason = (SSLException)cause;
1823         } else {
1824             /*
1825              * Including RuntimeExceptions, but we'll throw those
1826              * down below.  The closeReason isn't used again,
1827              * except for null checks.
1828              */
1829             closeReason =
1830                 Alerts.getSSLException(description, cause, diagnostic);
1831         }
1832 
1833         try {
1834             outputRecord.close();
1835         } catch (IOException ioe) {
1836            // ignore
1837         }
1838         outboundDone = true;
1839 
1840         connectionState = cs_CLOSED;
1841 
1842         if (cause instanceof RuntimeException) {
1843             throw (RuntimeException)cause;
1844         } else {
1845             throw closeReason;
1846         }
1847     }
1848 
1849     /*
1850      * Process an incoming alert ... caller must already have synchronized
1851      * access to "this".
1852      */
1853     private void recvAlert(ByteBuffer fragment) throws IOException {
1854         byte level = fragment.get();
1855         byte description = fragment.get();
1856 
1857         if (debug != null && (Debug.isOn("record") ||
1858                 Debug.isOn("handshake"))) {
1859             synchronized (System.out) {
1860                 System.out.print(Thread.currentThread().getName());
1861                 System.out.print(", RECV " + protocolVersion + " ALERT:  ");
1862                 if (level == Alerts.alert_fatal) {
1863                     System.out.print("fatal, ");
1864                 } else if (level == Alerts.alert_warning) {
1865                     System.out.print("warning, ");
1866                 } else {
1867                     System.out.print("<level " + (0x0ff & level) + ">, ");
1868                 }
1869                 System.out.println(Alerts.alertDescription(description));
1870             }
1871         }
1872 
1873         if (level == Alerts.alert_warning) {
1874             if (description == -1) {    // check for short message
1875                 fatal(Alerts.alert_illegal_parameter, "Short alert message");
1876             } else if (description == Alerts.alert_close_notify) {
1877                 if (connectionState == cs_HANDSHAKE) {
1878                     fatal(Alerts.alert_unexpected_message,
1879                                 "Received close_notify during handshake");






1880                 } else {
1881                     recvCN = true;
1882                     closeInboundInternal();  // reply to close
1883                 }
1884             } else {
1885 
1886                 //
1887                 // The other legal warnings relate to certificates,
1888                 // e.g. no_certificate, bad_certificate, etc; these
1889                 // are important to the handshaking code, which can
1890                 // also handle illegal protocol alerts if needed.
1891                 //
1892                 if (handshaker != null) {
1893                     handshaker.handshakeAlert(description);
1894                 }
1895             }
1896         } else { // fatal or unknown level
1897             String reason = "Received fatal alert: "
1898                 + Alerts.alertDescription(description);
1899 
1900             // The inbound and outbound queues will be closed as part of
1901             // the call to fatal.  The handhaker to needs to be set to null
1902             // so subsequent calls to getHandshakeStatus will return
1903             // NOT_HANDSHAKING.
1904             handshaker = null;
1905             Throwable cause = Alerts.getSSLException(description, reason);
1906             fatal(description, null, cause, true);
1907         }
1908     }
1909 
1910 
1911     /*
1912      * Emit alerts.  Caller must have synchronized with "this".
1913      */
1914     private void sendAlert(byte level, byte description) {
1915         // the connectionState cannot be cs_START
1916         if (connectionState >= cs_CLOSED) {
1917             return;
1918         }
1919 
1920         // For initial handshaking, don't send alert message to peer if
1921         // handshaker has not started.
1922         //
1923         // Shall we send an fatal alter to terminate the connection gracefully?
1924         if (connectionState <= cs_HANDSHAKE &&
1925                 (handshaker == null || !handshaker.started() ||
1926                         !handshaker.activated())) {
1927             return;
1928         }
1929 
1930         try {
1931             outputRecord.encodeAlert(level, description);
1932         } catch (IOException ioe) {
1933             // ignore
1934         }
1935     }
1936 
1937 
1938     //
1939     // VARIOUS OTHER METHODS (COMMON TO SSLSocket)
1940     //
1941 
1942 
1943     /**
1944      * Controls whether new connections may cause creation of new SSL
1945      * sessions.
1946      *
1947      * As long as handshaking has not started, we can change
1948      * whether we enable session creations.  Otherwise,
1949      * we will need to wait for the next handshake.
1950      */
1951     @Override
1952     public synchronized void setEnableSessionCreation(boolean flag) {
1953         enableSessionCreation = flag;
1954 
1955         if ((handshaker != null) && !handshaker.activated()) {
1956             handshaker.setEnableSessionCreation(enableSessionCreation);
1957         }
1958     }
1959 
1960     /**
1961      * Returns true if new connections may cause creation of new SSL
1962      * sessions.
1963      */
1964     @Override
1965     public synchronized boolean getEnableSessionCreation() {
1966         return enableSessionCreation;
1967     }
1968 
1969 
1970     /**
1971      * Sets the flag controlling whether a server mode engine
1972      * *REQUIRES* SSL client authentication.
1973      *
1974      * As long as handshaking has not started, we can change
1975      * whether client authentication is needed.  Otherwise,
1976      * we will need to wait for the next handshake.
1977      */
1978     @Override
1979     public synchronized void setNeedClientAuth(boolean flag) {
1980         doClientAuth = (flag ?
1981                 ClientAuthType.CLIENT_AUTH_REQUIRED :
1982                 ClientAuthType.CLIENT_AUTH_NONE);
1983 
1984         if ((handshaker != null) &&
1985                 (handshaker instanceof ServerHandshaker) &&
1986                 !handshaker.activated()) {
1987             ((ServerHandshaker) handshaker).setClientAuth(doClientAuth);
1988         }
1989     }
1990 
1991     @Override
1992     public synchronized boolean getNeedClientAuth() {
1993         return (doClientAuth == ClientAuthType.CLIENT_AUTH_REQUIRED);
1994     }
1995 
1996     /**
1997      * Sets the flag controlling whether a server mode engine
1998      * *REQUESTS* SSL client authentication.
1999      *
2000      * As long as handshaking has not started, we can change
2001      * whether client authentication is requested.  Otherwise,
2002      * we will need to wait for the next handshake.
2003      */
2004     @Override
2005     public synchronized void setWantClientAuth(boolean flag) {
2006         doClientAuth = (flag ?
2007                 ClientAuthType.CLIENT_AUTH_REQUESTED :
2008                 ClientAuthType.CLIENT_AUTH_NONE);
2009 
2010         if ((handshaker != null) &&
2011                 (handshaker instanceof ServerHandshaker) &&
2012                 !handshaker.activated()) {
2013             ((ServerHandshaker) handshaker).setClientAuth(doClientAuth);
2014         }
2015     }
2016 
2017     @Override
2018     public synchronized boolean getWantClientAuth() {
2019         return (doClientAuth == ClientAuthType.CLIENT_AUTH_REQUESTED);
2020     }
2021 
2022 
2023     /**
2024      * Sets the flag controlling whether the engine is in SSL
2025      * client or server mode.  Must be called before any SSL
2026      * traffic has started.
2027      */
2028     @Override
2029     @SuppressWarnings("fallthrough")
2030     public synchronized void setUseClientMode(boolean flag) {
2031         switch (connectionState) {
2032 
2033         case cs_START:
2034             /*
2035              * If we need to change the socket mode and the enabled
2036              * protocols and cipher suites haven't specifically been
2037              * set by the user, change them to the corresponding
2038              * default ones.
2039              */
2040             if (roleIsServer != (!flag)) {
2041                 if (sslContext.isDefaultProtocolList(enabledProtocols)) {
2042                     enabledProtocols =
2043                             sslContext.getDefaultProtocolList(!flag);
2044                 }
2045 
2046                 if (sslContext.isDefaultCipherSuiteList(enabledCipherSuites)) {
2047                     enabledCipherSuites =
2048                             sslContext.getDefaultCipherSuiteList(!flag);
2049                 }
2050             }
2051 
2052             roleIsServer = !flag;
2053             serverModeSet = true;
2054             break;
2055 
2056         case cs_HANDSHAKE:
2057             /*
2058              * If we have a handshaker, but haven't started
2059              * SSL traffic, we can throw away our current
2060              * handshaker, and start from scratch.  Don't
2061              * need to call doneConnect() again, we already
2062              * have the streams.
2063              */
2064             assert(handshaker != null);
2065             if (!handshaker.activated()) {
2066                 /*
2067                  * If we need to change the socket mode and the enabled
2068                  * protocols and cipher suites haven't specifically been
2069                  * set by the user, change them to the corresponding
2070                  * default ones.
2071                  */
2072                 if (roleIsServer != (!flag)) {
2073                     if (sslContext.isDefaultProtocolList(enabledProtocols)) {
2074                         enabledProtocols =
2075                                 sslContext.getDefaultProtocolList(!flag);
2076                     }
2077 
2078                     if (sslContext.isDefaultCipherSuiteList(
2079                                                     enabledCipherSuites)) {
2080                         enabledCipherSuites =
2081                             sslContext.getDefaultCipherSuiteList(!flag);
2082                     }





2083                 }
2084 
2085                 roleIsServer = !flag;
2086                 connectionState = cs_START;
2087                 initHandshaker();
2088                 break;
2089             }
2090 
2091             // If handshake has started, that's an error.  Fall through...



2092 
2093         default:
2094             if (debug != null && Debug.isOn("ssl")) {
2095                 System.out.println(Thread.currentThread().getName() +
2096                     ", setUseClientMode() invoked in state = " +
2097                     connectionState);
2098             }
2099 
2100             /*
2101              * We can let them continue if they catch this correctly,
2102              * we don't need to shut this down.
2103              */
2104             throw new IllegalArgumentException(
2105                 "Cannot change mode after SSL traffic has started");
2106         }




2107     }
2108 
2109     @Override
2110     public synchronized boolean getUseClientMode() {
2111         return !roleIsServer;
2112     }
2113 






2114 
2115     /**
2116      * Returns the names of the cipher suites which could be enabled for use
2117      * on an SSL connection.  Normally, only a subset of these will actually
2118      * be enabled by default, since this list may include cipher suites which
2119      * do not support the mutual authentication of servers and clients, or
2120      * which do not protect data confidentiality.  Servers may also need
2121      * certain kinds of certificates to use certain cipher suites.
2122      *
2123      * @return an array of cipher suite names
2124      */
2125     @Override
2126     public String[] getSupportedCipherSuites() {
2127         return sslContext.getSupportedCipherSuiteList().toStringArray();

2128     }
2129 
2130     /**
2131      * Controls which particular cipher suites are enabled for use on
2132      * this connection.  The cipher suites must have been listed by
2133      * getCipherSuites() as being supported.  Even if a suite has been
2134      * enabled, it might never be used if no peer supports it or the
2135      * requisite certificates (and private keys) are not available.
2136      *
2137      * @param suites Names of all the cipher suites to enable.
2138      */
2139     @Override
2140     public synchronized void setEnabledCipherSuites(String[] suites) {
2141         enabledCipherSuites = new CipherSuiteList(suites);
2142         if ((handshaker != null) && !handshaker.activated()) {
2143             handshaker.setEnabledCipherSuites(enabledCipherSuites);
2144         }





2145     }
2146 
2147     /**
2148      * Returns the names of the SSL cipher suites which are currently enabled
2149      * for use on this connection.  When an SSL engine is first created,
2150      * all enabled cipher suites <em>(a)</em> protect data confidentiality,
2151      * by traffic encryption, and <em>(b)</em> can mutually authenticate
2152      * both clients and servers.  Thus, in some environments, this value
2153      * might be empty.
2154      *
2155      * @return an array of cipher suite names
2156      */
2157     @Override
2158     public synchronized String[] getEnabledCipherSuites() {
2159         return enabledCipherSuites.toStringArray();
2160     }
2161 




2162 
2163     /**
2164      * Returns the protocols that are supported by this implementation.
2165      * A subset of the supported protocols may be enabled for this connection
2166      * @return an array of protocol names.
2167      */
2168     @Override
2169     public String[] getSupportedProtocols() {
2170         return sslContext.getSuportedProtocolList().toStringArray();
2171     }
2172 
2173     /**
2174      * Controls which protocols are enabled for use on
2175      * this connection.  The protocols must have been listed by
2176      * getSupportedProtocols() as being supported.
2177      *
2178      * @param protocols protocols to enable.
2179      * @exception IllegalArgumentException when one of the protocols
2180      *  named by the parameter is not supported.
2181      */
2182     @Override
2183     public synchronized void setEnabledProtocols(String[] protocols) {
2184         enabledProtocols = new ProtocolList(protocols);
2185         if ((handshaker != null) && !handshaker.activated()) {
2186             handshaker.setEnabledProtocols(enabledProtocols);


2187         }
2188     }
2189 
2190     @Override
2191     public synchronized String[] getEnabledProtocols() {
2192         return enabledProtocols.toStringArray();
2193     }
2194 
2195     /**
2196      * Returns the SSLParameters in effect for this SSLEngine.
2197      */
2198     @Override
2199     public synchronized SSLParameters getSSLParameters() {
2200         SSLParameters params = super.getSSLParameters();
2201 
2202         // the super implementation does not handle the following parameters
2203         params.setEndpointIdentificationAlgorithm(identificationProtocol);
2204         params.setAlgorithmConstraints(algorithmConstraints);
2205         params.setSNIMatchers(sniMatchers);
2206         params.setServerNames(serverNames);
2207         params.setUseCipherSuitesOrder(preferLocalCipherSuites);
2208         params.setEnableRetransmissions(enableRetransmissions);
2209         params.setMaximumPacketSize(maximumPacketSize);
2210         params.setApplicationProtocols(applicationProtocols);
2211 
2212         return params;



2213     }
2214 
2215     /**
2216      * Applies SSLParameters to this engine.
2217      */
2218     @Override
2219     public synchronized void setSSLParameters(SSLParameters params) {
2220         super.setSSLParameters(params);


2221 
2222         // the super implementation does not handle the following parameters
2223         identificationProtocol = params.getEndpointIdentificationAlgorithm();
2224         algorithmConstraints = params.getAlgorithmConstraints();
2225         preferLocalCipherSuites = params.getUseCipherSuitesOrder();
2226         enableRetransmissions = params.getEnableRetransmissions();
2227         maximumPacketSize = params.getMaximumPacketSize();
2228 
2229         if (maximumPacketSize != 0) {
2230             outputRecord.changePacketSize(maximumPacketSize);
2231         } else {
2232             // use the implicit maximum packet size.
2233             maximumPacketSize = outputRecord.getMaxPacketSize();



2234         }
2235 
2236         List<SNIServerName> sniNames = params.getServerNames();
2237         if (sniNames != null) {
2238             serverNames = sniNames;
2239         }




2240 
2241         Collection<SNIMatcher> matchers = params.getSNIMatchers();
2242         if (matchers != null) {
2243             sniMatchers = matchers;
2244         }
2245         applicationProtocols = params.getApplicationProtocols();
2246 
2247         if ((handshaker != null) && !handshaker.activated()) {
2248             handshaker.setIdentificationProtocol(identificationProtocol);
2249             handshaker.setAlgorithmConstraints(algorithmConstraints);
2250             handshaker.setMaximumPacketSize(maximumPacketSize);
2251             handshaker.setApplicationProtocols(applicationProtocols);
2252             if (roleIsServer) {
2253                 handshaker.setSNIMatchers(sniMatchers);
2254                 handshaker.setUseCipherSuitesOrder(preferLocalCipherSuites);








2255             } else {
2256                 handshaker.setSNIServerNames(serverNames);
2257             }
2258         }









2259     }
2260 
2261     @Override
2262     public synchronized String getApplicationProtocol() {
2263         return applicationProtocol;



2264     }
2265 
2266     @Override
2267     public synchronized String getHandshakeApplicationProtocol() {
2268         if ((handshaker != null) && handshaker.started()) {
2269             return handshaker.getHandshakeApplicationProtocol();

















2270         }
2271         return null;
2272     }
2273 
2274     @Override
2275     public synchronized void setHandshakeApplicationProtocolSelector(
2276         BiFunction<SSLEngine, List<String>, String> selector) {
2277         applicationProtocolSelector = selector;
2278         if ((handshaker != null) && !handshaker.activated()) {
2279             handshaker.setApplicationProtocolSelectorSSLEngine(selector);
2280         }
2281     }
2282 
2283     @Override
2284     public synchronized BiFunction<SSLEngine, List<String>, String>
2285         getHandshakeApplicationProtocolSelector() {
2286         return this.applicationProtocolSelector;

2287     }
2288 
2289     /**
2290      * Returns a printable representation of this end of the connection.
2291      */
2292     @Override
2293     public String toString() {
2294         StringBuilder retval = new StringBuilder(80);
2295 
2296         retval.append(Integer.toHexString(hashCode()));
2297         retval.append("[");
2298         retval.append("SSLEngine[hostname=");
2299         String host = getPeerHost();
2300         retval.append((host == null) ? "null" : host);
2301         retval.append(" port=");
2302         retval.append(Integer.toString(getPeerPort()));
2303         retval.append(" role=" + (roleIsServer ? "Server" : "Client"));
2304         retval.append("] ");
2305         retval.append(getSession().getCipherSuite());
2306         retval.append("]");
2307 
2308         return retval.toString();


2309     }
2310 }
   1 /*
   2  * Copyright (c) 2003, 2018, 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.IOException;
  29 import java.nio.ByteBuffer;
  30 import java.nio.ReadOnlyBufferException;
  31 import java.security.AccessController;
  32 import java.security.PrivilegedActionException;
  33 import java.security.PrivilegedExceptionAction;
  34 import java.util.List;
  35 import java.util.Map;
  36 import java.util.function.BiFunction;
  37 import javax.net.ssl.SSLEngine;
  38 import javax.net.ssl.SSLEngineResult;
  39 import javax.net.ssl.SSLEngineResult.HandshakeStatus;
  40 import javax.net.ssl.SSLEngineResult.Status;
  41 import javax.net.ssl.SSLException;
  42 import javax.net.ssl.SSLHandshakeException;
  43 import javax.net.ssl.SSLKeyException;
  44 import javax.net.ssl.SSLParameters;
  45 import javax.net.ssl.SSLPeerUnverifiedException;
  46 import javax.net.ssl.SSLProtocolException;
  47 import javax.net.ssl.SSLSession;
  48 
  49 /**
  50  * Implementation of an non-blocking SSLEngine.
  51  *
  52  * @author Brad Wetmore







































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































  53  */
  54 final class SSLEngineImpl extends SSLEngine implements SSLTransport {
  55     private final SSLContextImpl        sslContext;
  56     final TransportContext              conContext;
  57 
  58     /**
  59      * Constructor for an SSLEngine from SSLContext, without
  60      * host/port hints.




  61      *
  62      * This Engine will not be able to cache sessions, but must renegotiate
  63      * everything by hand.



  64      */
  65     SSLEngineImpl(SSLContextImpl sslContext) {
  66         this(sslContext, null, -1);







  67     }
  68 
  69     /**
  70      * Constructor for an SSLEngine from SSLContext.




  71      */
  72     SSLEngineImpl(SSLContextImpl sslContext,
  73             String host, int port) {
  74         super(host, port);
  75         this.sslContext = sslContext;
  76         HandshakeHash handshakeHash = new HandshakeHash();
  77         if (sslContext.isDTLS()) {
  78             this.conContext = new TransportContext(sslContext, this,
  79                     new DTLSInputRecord(handshakeHash),
  80                     new DTLSOutputRecord(handshakeHash));
  81         } else {
  82             this.conContext = new TransportContext(sslContext, this,
  83                     new SSLEngineInputRecord(handshakeHash),
  84                     new SSLEngineOutputRecord(handshakeHash));





























  85         }
  86 
  87         // Server name indication is a connection scope extension.
  88         if (host != null) {
  89             this.conContext.sslConfig.serverNames =
  90                     Utilities.addToSNIServerNameList(
  91                             conContext.sslConfig.serverNames, host);











  92         }
  93     }
  94 
  95     @Override
  96     public synchronized void beginHandshake() throws SSLException {
  97         if (conContext.isUnsureMode) {
  98             throw new IllegalStateException(
  99                     "Client/Server mode has not yet been set.");













 100         }
 101 











 102         try {
 103             conContext.kickstart();
 104         } catch (IOException ioe) {
 105             conContext.fatal(Alert.HANDSHAKE_FAILURE,
 106                 "Couldn't kickstart handshaking", ioe);
 107         } catch (Exception ex) {     // including RuntimeException
 108             conContext.fatal(Alert.INTERNAL_ERROR,
 109                 "Fail to begin handshake", ex);















































 110         }


 111     }
 112 










 113     @Override
 114     public synchronized SSLEngineResult wrap(ByteBuffer[] appData,
 115             int offset, int length, ByteBuffer netData) throws SSLException {
 116         return wrap(
 117                 appData, offset, length, new ByteBuffer[]{ netData }, 0, 1);
 118     }
 119 
 120     // @Override
 121     public synchronized SSLEngineResult wrap(
 122         ByteBuffer[] srcs, int srcsOffset, int srcsLength,
 123         ByteBuffer[] dsts, int dstsOffset, int dstsLength) throws SSLException {
 124 
 125         if (conContext.isUnsureMode) {
 126             throw new IllegalStateException(
 127                     "Client/Server mode has not yet been set.");




 128         }
 129 
 130         // See if the handshaker needs to report back some SSLException.
 131         if (conContext.outputRecord.isEmpty()) {
 132             checkTaskThrown();
 133         }   // Otherwise, deliver cached records before throwing task exception.
 134 
 135         // check parameters
 136         checkParams(srcs, srcsOffset, srcsLength, dsts, dstsOffset, dstsLength);
 137 
 138         try {
 139             return writeRecord(
 140                 srcs, srcsOffset, srcsLength, dsts, dstsOffset, dstsLength);

 141         } catch (SSLProtocolException spe) {
 142             // may be an unexpected handshake message
 143             conContext.fatal(Alert.UNEXPECTED_MESSAGE, spe);
 144         } catch (IOException ioe) {
 145             conContext.fatal(Alert.INTERNAL_ERROR,
 146                 "problem wrapping app data", ioe);
 147         } catch (Exception ex) {     // including RuntimeException
 148             conContext.fatal(Alert.INTERNAL_ERROR,
 149                 "Fail to wrap application data", ex);
 150         }
 151 
 152         return null;    // make compiler happy
 153     }







 154 
 155     private SSLEngineResult writeRecord(
 156         ByteBuffer[] srcs, int srcsOffset, int srcsLength,
 157         ByteBuffer[] dsts, int dstsOffset, int dstsLength) throws IOException {

 158 



 159         if (isOutboundDone()) {
 160             return new SSLEngineResult(
 161                     Status.CLOSED, getHandshakeStatus(), 0, 0);
 162         }
 163 
 164         HandshakeContext hc = conContext.handshakeContext;
 165         HandshakeStatus hsStatus = null;
 166         if (!conContext.isNegotiated) {
 167             conContext.kickstart();





 168 
 169             hsStatus = getHandshakeStatus();




 170             if (hsStatus == HandshakeStatus.NEED_UNWRAP) {
 171                 /*
 172                  * For DTLS, if the handshake state is
 173                  * HandshakeStatus.NEED_UNWRAP, a call to SSLEngine.wrap()
 174                  * means that the previous handshake packets (if delivered)
 175                  * get lost, and need retransmit the handshake messages.
 176                  */
 177                 if (!sslContext.isDTLS() || hc == null ||
 178                         !hc.sslConfig.enableRetransmissions ||
 179                         conContext.outputRecord.firstMessage) {
 180 
 181                     return new SSLEngineResult(Status.OK, hsStatus, 0, 0);
 182                 }   // otherwise, need retransmission
 183             }
 184         }

 185 






 186         if (hsStatus == null) {
 187             hsStatus = getHandshakeStatus();
 188         }
 189 
 190         /*
 191          * If we have a task outstanding, this *MUST* be done before
 192          * doing any more wrapping, because we could be in the middle
 193          * of receiving a handshake message, for example, a finished
 194          * message which would change the ciphers.
 195          */
 196         if (hsStatus == HandshakeStatus.NEED_TASK) {
 197             return new SSLEngineResult(Status.OK, hsStatus, 0, 0);
 198         }
 199 
 200         int dstsRemains = 0;
 201         for (int i = dstsOffset; i < dstsOffset + dstsLength; i++) {
 202             dstsRemains += dsts[i].remaining();
 203         }
 204 
 205         // Check destination buffer size.
 206         //
 207         // We can be smarter about using smaller buffer sizes later.  For
 208         // now, force it to be large enough to handle any valid record.
 209         if (dstsRemains < conContext.conSession.getPacketBufferSize()) {
 210             return new SSLEngineResult(
 211                 Status.BUFFER_OVERFLOW, getHandshakeStatus(), 0, 0);
 212         }
 213 
 214         int srcsRemains = 0;
 215         for (int i = srcsOffset; i < srcsOffset + srcsLength; i++) {
 216             srcsRemains += srcs[i].remaining();
 217         }
 218 
 219         Ciphertext ciphertext = null;
 220         try {
 221             // Acquire the buffered to-be-delivered records or retransmissions.
 222             //
 223             // May have buffered records, or need retransmission if handshaking.
 224             if (!conContext.outputRecord.isEmpty() || (hc != null &&
 225                     hc.sslConfig.enableRetransmissions &&
 226                     hc.sslContext.isDTLS() &&
 227                     hsStatus == HandshakeStatus.NEED_UNWRAP)) {
 228                 ciphertext = encode(null, 0, 0,
 229                         dsts, dstsOffset, dstsLength);
 230             }
 231 
 232             if (ciphertext == null && srcsRemains != 0) {
 233                 ciphertext = encode(srcs, srcsOffset, srcsLength,
 234                         dsts, dstsOffset, dstsLength);
 235             }
 236         } catch (IOException ioe) {
 237             if (ioe instanceof SSLException) {
 238                 throw ioe;
 239             } else {
 240                 throw new SSLException("Write problems", ioe);
 241             }




 242         }
 243 
 244         /*
 245          * Check for status.



 246          */
 247         Status status = (isOutboundDone() ? Status.CLOSED : Status.OK);
 248         if (ciphertext != null && ciphertext.handshakeStatus != null) {
 249             hsStatus = ciphertext.handshakeStatus;
 250         } else {
 251             hsStatus = getHandshakeStatus();
 252         }
 253 
 254         int deltaSrcs = srcsRemains;
 255         for (int i = srcsOffset; i < srcsOffset + srcsLength; i++) {
 256             deltaSrcs -= srcs[i].remaining();

 257         }
 258 
 259         int deltaDsts = dstsRemains;
 260         for (int i = dstsOffset; i < dstsOffset + dstsLength; i++) {
 261             deltaDsts -= dsts[i].remaining();
 262         }
 263 
 264         return new SSLEngineResult(status, hsStatus, deltaSrcs, deltaDsts,
 265                 ciphertext != null ? ciphertext.recordSN : -1L);
 266     }
 267 
 268     private Ciphertext encode(
 269         ByteBuffer[] srcs, int srcsOffset, int srcsLength,
 270         ByteBuffer[] dsts, int dstsOffset, int dstsLength) throws IOException {
 271 
 272         Ciphertext ciphertext = null;
 273         try {
 274             ciphertext = conContext.outputRecord.encode(
 275                 srcs, srcsOffset, srcsLength, dsts, dstsOffset, dstsLength);










 276         } catch (SSLHandshakeException she) {
 277             // may be record sequence number overflow
 278             conContext.fatal(Alert.HANDSHAKE_FAILURE, she);


 279         } catch (IOException e) {
 280             conContext.fatal(Alert.UNEXPECTED_MESSAGE, e);


 281         }
 282 
 283         if (ciphertext == null) {
 284             return Ciphertext.CIPHERTEXT_NULL;
 285         }
 286 
 287         // Is the handshake completed?
 288         boolean needRetransmission =
 289                 conContext.sslContext.isDTLS() &&
 290                 conContext.handshakeContext != null &&
 291                 conContext.handshakeContext.sslConfig.enableRetransmissions;
 292         HandshakeStatus hsStatus =
 293                 tryToFinishHandshake(ciphertext.contentType);
 294         if (needRetransmission &&
 295                 hsStatus == HandshakeStatus.FINISHED &&
 296                 conContext.sslContext.isDTLS() &&
 297                 ciphertext.handshakeType == SSLHandshake.FINISHED.id) {
 298             // Retransmit the last flight for DTLS.

 299             //
 300             // The application data transactions may begin immediately
 301             // after the last flight.  If the last flight get lost, the
 302             // application data may be discarded accordingly.  As could
 303             // be an issue for some applications.  This impact can be
 304             // mitigated by sending the last fligth twice.
 305             if (SSLLogger.isOn && SSLLogger.isOn("ssl,verbose")) {
 306                 SSLLogger.finest("retransmit the last flight messages");






 307             }
 308 
 309             conContext.outputRecord.launchRetransmission();
 310             hsStatus = HandshakeStatus.NEED_WRAP;
 311         }


 312 
 313         if (hsStatus == null) {
 314             hsStatus = conContext.getHandshakeStatus();
























 315         }
 316 
 317         // Is the sequence number is nearly overflow?
 318         if (conContext.outputRecord.seqNumIsHuge()) {
 319             hsStatus = tryKeyUpdate(hsStatus);
 320         }
 321 
 322         // update context status
 323         ciphertext.handshakeStatus = hsStatus;
 324 
 325         return ciphertext;
 326     }
 327 
 328     private HandshakeStatus tryToFinishHandshake(byte contentType) {
 329         HandshakeStatus hsStatus = null;
 330         if ((contentType == ContentType.HANDSHAKE.id) &&
 331                 conContext.outputRecord.isEmpty()) {
 332             if (conContext.handshakeContext == null) {
 333                 hsStatus = HandshakeStatus.FINISHED;
 334             } else if (conContext.handshakeContext.handshakeFinished) {
 335                 hsStatus = conContext.finishHandshake();
 336             }
 337         }   // Otherwise, the followed call to getHSStatus() will help.
 338 
 339         return hsStatus;
 340     }

 341 
 342     /**
 343      * Try renegotiation or key update for sequence number wrap.
 344      *
 345      * Note that in order to maintain the handshake status properly, we check
 346      * the sequence number after the last record reading/writing process.  As
 347      * we request renegotiation or close the connection for wrapped sequence
 348      * number when there is enough sequence number space left to handle a few
 349      * more records, so the sequence number of the last record cannot be
 350      * wrapped.
 351      */
 352     private HandshakeStatus tryKeyUpdate(
 353             HandshakeStatus currentHandshakeStatus) throws IOException {
 354         // Don't bother to kickstart the renegotiation or key update when the
 355         // local is asking for it.
 356         if ((conContext.handshakeContext == null) &&
 357                 !conContext.isClosed() && !conContext.isBroken) {
 358             if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
 359                 SSLLogger.finest("key update to wrap sequence number");
 360             }
 361             conContext.keyUpdate();
 362             return conContext.getHandshakeStatus();
 363         }
 364 
 365         return currentHandshakeStatus;




 366     }
 367 
 368     private static void checkParams(
 369             ByteBuffer[] srcs, int srcsOffset, int srcsLength,
 370             ByteBuffer[] dsts, int dstsOffset, int dstsLength) {
 371 
 372         if ((srcs == null) || (dsts == null)) {
 373             throw new IllegalArgumentException(
 374                     "source or destination buffer is null");





 375         }

 376 
 377         if ((srcsOffset < 0) || (srcsLength < 0) ||
 378                 (srcsOffset > srcs.length - srcsLength)) {
 379             throw new IndexOutOfBoundsException(
 380                     "index out of bound of the source buffers");
 381         }


 382 
 383         if ((dstsOffset < 0) || (dstsLength < 0) ||
 384                 (dstsOffset > dsts.length - dstsLength)) {
 385             throw new IndexOutOfBoundsException(
 386                     "index out of bound of the destination buffers");
 387         }
 388 
 389         for (int i = srcsOffset; i < srcsOffset + srcsLength; i++) {
 390             if (srcs[i] == null) {
 391                 throw new IllegalArgumentException(
 392                         "source buffer[" + i + "] == null");








 393             }


 394         }
 395 
 396         for (int i = dstsOffset; i < dstsOffset + dstsLength; i++) {
 397             if (dsts[i] == null) {
 398                 throw new IllegalArgumentException(
 399                         "destination buffer[" + i + "] == null");
 400             }
 401 


 402             /*
 403              * Make sure the destination bufffers are writable.
 404              */
 405             if (dsts[i].isReadOnly()) {
 406                 throw new ReadOnlyBufferException();
 407             }
 408         }


 409     }
 410 



 411     @Override
 412     public synchronized SSLEngineResult unwrap(ByteBuffer src,
 413             ByteBuffer[] dsts, int offset, int length) throws SSLException {
 414         return unwrap(
 415                 new ByteBuffer[]{src}, 0, 1, dsts, offset, length);
 416     }
 417 
 418     // @Override
 419     public synchronized SSLEngineResult unwrap(
 420         ByteBuffer[] srcs, int srcsOffset, int srcsLength,
 421         ByteBuffer[] dsts, int dstsOffset, int dstsLength) throws SSLException {

 422 
 423         if (conContext.isUnsureMode) {
 424             throw new IllegalStateException(
 425                     "Client/Server mode has not yet been set.");
 426         }
 427 
 428         // See if the handshaker needs to report back some SSLException.
 429         checkTaskThrown();




 430 
 431         // check parameters
 432         checkParams(srcs, srcsOffset, srcsLength, dsts, dstsOffset, dstsLength);
 433 
 434         try {
 435             return readRecord(
 436                 srcs, srcsOffset, srcsLength, dsts, dstsOffset, dstsLength);
 437         } catch (SSLProtocolException spe) {
 438             // may be an unexpected handshake message
 439             conContext.fatal(Alert.UNEXPECTED_MESSAGE,
 440                     spe.getMessage(), spe);
 441         } catch (IOException ioe) {
 442             /*
 443              * Don't reset position so it looks like we didn't
 444              * consume anything.  We did consume something, and it
 445              * got us into this situation, so report that much back.
 446              * Our days of consuming are now over anyway.
 447              */
 448             conContext.fatal(Alert.INTERNAL_ERROR,
 449                     "problem unwrapping net record", ioe);
 450         } catch (Exception ex) {     // including RuntimeException
 451             conContext.fatal(Alert.INTERNAL_ERROR,
 452                 "Fail to unwrap network record", ex);
 453         }

 454 
 455         return null;    // make compiler happy
 456     }
 457 
 458     private SSLEngineResult readRecord(
 459         ByteBuffer[] srcs, int srcsOffset, int srcsLength,
 460         ByteBuffer[] dsts, int dstsOffset, int dstsLength) throws IOException {
 461 
 462         /*
 463          * Check if we are closing/closed.










 464          */
 465         if (isInboundDone()) {
 466             return new SSLEngineResult(
 467                     Status.CLOSED, getHandshakeStatus(), 0, 0);
 468         }
 469 
 470         HandshakeStatus hsStatus = null;
 471         if (!conContext.isNegotiated) {
 472             conContext.kickstart();
 473 
 474             /*
 475              * If there's still outbound data to flush, we
 476              * can return without trying to unwrap anything.









 477              */
 478             hsStatus = getHandshakeStatus();
 479             if (hsStatus == HandshakeStatus.NEED_WRAP) {
 480                 return new SSLEngineResult(Status.OK, hsStatus, 0, 0);
 481             }
 482         }
 483 
 484         if (hsStatus == null) {
 485             hsStatus = getHandshakeStatus();




 486         }
 487 
 488         /*
 489          * If we have a task outstanding, this *MUST* be done before
 490          * doing any more unwrapping, because we could be in the middle
 491          * of receiving a handshake message, for example, a finished
 492          * message which would change the ciphers.







 493          */
 494         if (hsStatus == HandshakeStatus.NEED_TASK) {
 495             return new SSLEngineResult(Status.OK, hsStatus, 0, 0);
 496         }
 497 
 498         if (hsStatus == SSLEngineResult.HandshakeStatus.NEED_UNWRAP_AGAIN) {
 499             Plaintext plainText = null;
 500             try {
 501                 plainText = decode(null, 0, 0,
 502                         dsts, dstsOffset, dstsLength);
 503             } catch (IOException ioe) {
 504                 if (ioe instanceof SSLException) {
 505                     throw ioe;
 506                 } else {
 507                     throw new SSLException("readRecord", ioe);
 508                 }
 509             }
 510 
 511             Status status = (isInboundDone() ? Status.CLOSED : Status.OK);
 512             if (plainText.handshakeStatus != null) {
 513                 hsStatus = plainText.handshakeStatus;
 514             } else {
 515                 hsStatus = getHandshakeStatus();
 516             }
 517 
 518             return new SSLEngineResult(
 519                     status, hsStatus, 0, 0, plainText.recordSN);




 520         }
 521 
 522         int srcsRemains = 0;
 523         for (int i = srcsOffset; i < srcsOffset + srcsLength; i++) {
 524             srcsRemains += srcs[i].remaining();







 525         }
 526 
 527         if (srcsRemains == 0) {
 528             return new SSLEngineResult(Status.OK, getHandshakeStatus(), 0, 0);
 529         }

 530 
 531         /*
 532          * Check the packet to make sure enough is here.
 533          * This will also indirectly check for 0 len packets.
 534          */
 535         int packetLen = 0;
 536         try {
 537             packetLen = conContext.inputRecord.bytesInCompletePacket(
 538                     srcs, srcsOffset, srcsLength);
 539         } catch (SSLException ssle) {
 540             // Need to discard invalid records for DTLS protocols.
 541             if (sslContext.isDTLS()) {
 542                 if (SSLLogger.isOn && SSLLogger.isOn("ssl,verbose")) {
 543                     SSLLogger.finest("Discard invalid DTLS records", ssle);
 544                 }
 545 
 546                 // invalid, discard the entire data [section 4.1.2.7, RFC 6347]
 547                 // TODO
 548                 int deltaNet = 0;
 549                 // int deltaNet = netData.remaining();
 550                 // netData.position(netData.limit());
 551 
 552                 Status status = (isInboundDone() ? Status.CLOSED : Status.OK);
 553                 if (hsStatus == null) {
 554                     hsStatus = getHandshakeStatus();
 555                 }
 556 
 557                 return new SSLEngineResult(status, hsStatus, deltaNet, 0, -1L);
 558             } else {
 559                 throw ssle;
 560             }
 561         }
 562 
 563         // Is this packet bigger than SSL/TLS normally allows?
 564         if (packetLen > conContext.conSession.getPacketBufferSize()) {
 565             int largestRecordSize = sslContext.isDTLS() ?
 566                     DTLSRecord.maxRecordSize : SSLRecord.maxLargeRecordSize;
 567             if ((packetLen <= largestRecordSize) && !sslContext.isDTLS()) {
 568                 // Expand the expected maximum packet/application buffer
 569                 // sizes.
 570                 //
 571                 // Only apply to SSL/TLS protocols.






 572 
 573                 // Old behavior: shall we honor the System Property
 574                 // "jsse.SSLEngine.acceptLargeFragments" if it is "false"?
 575                 conContext.conSession.expandBufferSizes();
 576             }
 577 
 578             // check the packet again
 579             largestRecordSize = conContext.conSession.getPacketBufferSize();
 580             if (packetLen > largestRecordSize) {
 581                 throw new SSLProtocolException(
 582                         "Input record too big: max = " +
 583                         largestRecordSize + " len = " + packetLen);
 584             }


 585         }
 586 
 587         /*
 588          * Check for OVERFLOW.

 589          *
 590          * Delay enforcing the application buffer free space requirement
 591          * until after the initial handshaking.

 592          */
 593         int dstsRemains = 0;
 594         for (int i = dstsOffset; i < dstsOffset + dstsLength; i++) {
 595             dstsRemains += dsts[i].remaining();
 596         }
 597 
 598         if (conContext.isNegotiated) {
 599             int FragLen =
 600                     conContext.inputRecord.estimateFragmentSize(packetLen);
 601             if (FragLen > dstsRemains) {
 602                 return new SSLEngineResult(
 603                         Status.BUFFER_OVERFLOW, hsStatus, 0, 0);

 604             }
 605         }
 606 
 607         // check for UNDERFLOW.
 608         if ((packetLen == -1) || (srcsRemains < packetLen)) {
 609             return new SSLEngineResult(Status.BUFFER_UNDERFLOW, hsStatus, 0, 0);

 610         }
 611 
 612         /*
 613          * We're now ready to actually do the read.
 614          */
 615         Plaintext plainText = null;


 616         try {
 617             plainText = decode(srcs, srcsOffset, srcsLength,
 618                             dsts, dstsOffset, dstsLength);
 619         } catch (IOException ioe) {
 620             if (ioe instanceof SSLException) {
 621                 throw ioe;
 622             } else {
 623                 throw new SSLException("readRecord", ioe);
 624             }





 625         }
 626 
 627         /*
 628          * Check the various condition that we could be reporting.
 629          *
 630          * It's *possible* something might have happened between the
 631          * above and now, but it was better to minimally lock "this"
 632          * during the read process.  We'll return the current
 633          * status, which is more representative of the current state.
 634          *
 635          * status above should cover:  FINISHED, NEED_TASK
 636          */
 637         Status status = (isInboundDone() ? Status.CLOSED : Status.OK);
 638         if (plainText.handshakeStatus != null) {
 639             hsStatus = plainText.handshakeStatus;



 640         } else {
 641             hsStatus = getHandshakeStatus();






 642         }
 643 
 644         int deltaNet = srcsRemains;
 645         for (int i = srcsOffset; i < srcsOffset + srcsLength; i++) {
 646             deltaNet -= srcs[i].remaining();

 647         }

 648 
 649         int deltaApp = dstsRemains;
 650         for (int i = dstsOffset; i < dstsOffset + dstsLength; i++) {
 651             deltaApp -= dsts[i].remaining();




 652         }
 653 
 654         return new SSLEngineResult(
 655                 status, hsStatus, deltaNet, deltaApp, plainText.recordSN);




















 656     }
 657 
 658     private Plaintext decode(
 659         ByteBuffer[] srcs, int srcsOffset, int srcsLength,
 660         ByteBuffer[] dsts, int dstsOffset, int dstsLength) throws IOException {
 661 
 662         Plaintext pt = SSLTransport.decode(conContext,
 663                             srcs, srcsOffset, srcsLength,
 664                             dsts, dstsOffset, dstsLength);
 665 
 666         // Is the handshake completed?
 667         if (pt != Plaintext.PLAINTEXT_NULL) {
 668             HandshakeStatus hsStatus = tryToFinishHandshake(pt.contentType);
 669             if (hsStatus == null) {
 670                 pt.handshakeStatus = conContext.getHandshakeStatus();
 671             } else {
 672                 pt.handshakeStatus = hsStatus;

 673             }

 674 
 675             // Is the sequence number is nearly overflow?
 676             if (conContext.inputRecord.seqNumIsHuge()) {
 677                 pt.handshakeStatus =
 678                         tryKeyUpdate(pt.handshakeStatus);

















 679             }
 680         }
 681 
 682         return pt;







 683     }
 684 
 685     @Override
 686     public synchronized Runnable getDelegatedTask() {
 687         if (conContext.handshakeContext != null &&
 688                 !conContext.handshakeContext.taskDelegated &&
 689                 !conContext.handshakeContext.delegatedActions.isEmpty()) {
 690             conContext.handshakeContext.taskDelegated = true;
 691             return new DelegatedTask(this);

 692         }
 693 
 694         return null;




 695     }
 696 














 697     @Override
 698     public synchronized void closeInbound() throws SSLException {
 699         conContext.closeInbound();




 700     }
 701 




 702     @Override
 703     public synchronized boolean isInboundDone() {
 704         return conContext.isInboundDone();
 705     }
 706 









 707     @Override
 708     public synchronized void closeOutbound() {
 709         conContext.closeOutbound();








 710     }
 711 
 712     @Override
 713     public synchronized boolean isOutboundDone() {
 714         return conContext.isOutboundDone();
 715     }
 716 








 717     @Override
 718     public String[] getSupportedCipherSuites() {
 719         return CipherSuite.namesOf(sslContext.getSupportedCipherSuites());








 720     }
 721 
 722     @Override
 723     public synchronized String[] getEnabledCipherSuites() {
 724         return CipherSuite.namesOf(conContext.sslConfig.enabledCipherSuites);
 725     }
 726 






 727     @Override
 728     public synchronized void setEnabledCipherSuites(String[] suites) {
 729         if (suites == null) {
 730             throw new IllegalArgumentException("CipherSuites cannot be null");












 731         }
 732 
 733         conContext.sslConfig.enabledCipherSuites =
 734                 CipherSuite.validValuesOf(suites);


 735     }
 736 
 737     @Override
 738     public String[] getSupportedProtocols() {
 739         return ProtocolVersion.toStringArray(
 740                 sslContext.getSuportedProtocolVersions());




















 741     }
 742 
 743     @Override
 744     public synchronized String[] getEnabledProtocols() {
 745         return ProtocolVersion.toStringArray(
 746                 conContext.sslConfig.enabledProtocols);
 747     }
 748 
 749     @Override
 750     public synchronized void setEnabledProtocols(String[] protocols) {
 751         if (protocols == null) {
 752             throw new IllegalArgumentException("Protocols cannot be null");
 753         }
 754 
 755         conContext.sslConfig.enabledProtocols =
 756                 ProtocolVersion.namesOf(protocols);


 757     }
 758 
 759     @Override
 760     public synchronized SSLSession getSession() {
 761         return conContext.conSession;
 762     }
 763 
 764     @Override
 765     public synchronized SSLSession getHandshakeSession() {
 766         return conContext.handshakeContext == null ?
 767                 null : conContext.handshakeContext.handshakeSession;

 768     }
 769 
 770     @Override
 771     public synchronized SSLEngineResult.HandshakeStatus getHandshakeStatus() {
 772         return conContext.getHandshakeStatus();



 773     }
 774 
 775     @Override
 776     public synchronized void setUseClientMode(boolean mode) {
 777         conContext.setUseClientMode(mode);
 778     }
 779 
 780     @Override
 781     public synchronized boolean getUseClientMode() {
 782         return conContext.sslConfig.isClientMode;
 783     }
 784 
 785     @Override
 786     public synchronized void setNeedClientAuth(boolean need) {
 787         conContext.sslConfig.clientAuthType =
 788                 (need ? ClientAuthType.CLIENT_AUTH_REQUIRED :
 789                         ClientAuthType.CLIENT_AUTH_NONE);
 790     }
 791 










 792     @Override
 793     public synchronized boolean getNeedClientAuth() {
 794         return (conContext.sslConfig.clientAuthType ==
 795                         ClientAuthType.CLIENT_AUTH_REQUIRED);
 796     }
 797 









 798     @Override
 799     public synchronized void setWantClientAuth(boolean want) {
 800         conContext.sslConfig.clientAuthType =
 801                 (want ? ClientAuthType.CLIENT_AUTH_REQUESTED :
 802                         ClientAuthType.CLIENT_AUTH_NONE);
 803     }
 804 
 805     @Override
 806     public synchronized boolean getWantClientAuth() {
 807         return (conContext.sslConfig.clientAuthType ==
 808                         ClientAuthType.CLIENT_AUTH_REQUESTED);
 809     }
 810 










 811     @Override
 812     public synchronized void setEnableSessionCreation(boolean flag) {
 813         conContext.sslConfig.enableSessionCreation = flag;
 814     }
 815 
 816     @Override
 817     public synchronized boolean getEnableSessionCreation() {
 818         return conContext.sslConfig.enableSessionCreation;
 819     }
 820 





 821     @Override
 822     public synchronized SSLParameters getSSLParameters() {
 823         return conContext.sslConfig.getSSLParameters();
 824     }
 825 









 826     @Override
 827     public synchronized void setSSLParameters(SSLParameters params) {
 828         conContext.sslConfig.setSSLParameters(params);
 829 
 830         if (conContext.sslConfig.maximumPacketSize != 0) {
 831             conContext.outputRecord.changePacketSize(
 832                     conContext.sslConfig.maximumPacketSize);
 833         }
 834     }
 835 
 836     @Override
 837     public synchronized String getApplicationProtocol() {
 838         return conContext.applicationProtocol;
 839     }
 840 



 841     @Override
 842     public synchronized String getHandshakeApplicationProtocol() {
 843         return conContext.handshakeContext == null ?
 844                 null : conContext.handshakeContext.applicationProtocol;
 845     }








 846 
 847     @Override
 848     public synchronized void setHandshakeApplicationProtocolSelector(
 849             BiFunction<SSLEngine, List<String>, String> selector) {
 850         conContext.sslConfig.engineAPSelector = selector;
 851     }
 852 



 853     @Override
 854     public synchronized BiFunction<SSLEngine, List<String>, String>
 855             getHandshakeApplicationProtocolSelector() {
 856         return conContext.sslConfig.engineAPSelector;
 857     }
 858 
 859     @Override
 860     public boolean useDelegatedTask() {
 861         return true;
 862     }


 863 
 864     private synchronized void checkTaskThrown() throws SSLException {
 865         HandshakeContext hc = conContext.handshakeContext;
 866         if (hc != null && hc.delegatedThrown != null) {
 867             try {
 868                 throw getTaskThrown(hc.delegatedThrown);
 869             } finally {
 870                 hc.delegatedThrown = null;
 871             }
 872         }
 873 
 874         if (conContext.isBroken && conContext.closeReason != null) {
 875             throw getTaskThrown(conContext.closeReason);

 876         }
 877     }
 878 
 879     private static SSLException getTaskThrown(Exception taskThrown) {
 880         String msg = taskThrown.getMessage();
 881 
 882         if (msg == null) {
 883             msg = "Delegated task threw Exception or Error";

 884         }

 885 
 886         if (taskThrown instanceof RuntimeException) {
 887             throw new RuntimeException(msg, taskThrown);
 888         } else if (taskThrown instanceof SSLHandshakeException) {
 889             return (SSLHandshakeException)
 890                 new SSLHandshakeException(msg).initCause(taskThrown);
 891         } else if (taskThrown instanceof SSLKeyException) {
 892             return (SSLKeyException)
 893                 new SSLKeyException(msg).initCause(taskThrown);
 894         } else if (taskThrown instanceof SSLPeerUnverifiedException) {
 895             return (SSLPeerUnverifiedException)
 896                 new SSLPeerUnverifiedException(msg).initCause(taskThrown);
 897         } else if (taskThrown instanceof SSLProtocolException) {
 898             return (SSLProtocolException)
 899                 new SSLProtocolException(msg).initCause(taskThrown);
 900         } else if (taskThrown instanceof SSLException) {
 901             return (SSLException)taskThrown;
 902         } else {
 903             return new SSLException(msg, taskThrown);
 904         }
 905     }
 906 
 907     /**
 908      * Implement a simple task delegator.
 909      */
 910     private static class DelegatedTask implements Runnable {
 911         private final SSLEngineImpl engine;
 912 
 913         DelegatedTask(SSLEngineImpl engineInstance) {
 914             this.engine = engineInstance;
 915         }
 916 
 917         @Override
 918         public void run() {
 919             synchronized (engine) {
 920                 HandshakeContext hc = engine.conContext.handshakeContext;
 921                 if (hc == null || hc.delegatedActions.isEmpty()) {
 922                     return;
 923                 }
 924 
 925                 try {
 926                     AccessController.doPrivileged(
 927                             new DelegatedAction(hc), engine.conContext.acc);
 928                 } catch (PrivilegedActionException pae) {
 929                     // Get the handshake context again in case the
 930                     // handshaking has completed.
 931                     hc = engine.conContext.handshakeContext;
 932                     if (hc != null) {
 933                         hc.delegatedThrown = pae.getException();
 934                     } else if (engine.conContext.closeReason != null) {
 935                         engine.conContext.closeReason =
 936                                 getTaskThrown(pae.getException());
 937                     }
 938                 } catch (RuntimeException rte) {
 939                     // Get the handshake context again in case the
 940                     // handshaking has completed.
 941                     hc = engine.conContext.handshakeContext;
 942                     if (hc != null) {
 943                         hc.delegatedThrown = rte;
 944                     } else if (engine.conContext.closeReason != null) {
 945                         engine.conContext.closeReason = rte;
 946                     }

 947                 }
 948 
 949                 // Get the handshake context again in case the
 950                 // handshaking has completed.
 951                 hc = engine.conContext.handshakeContext;
 952                 if (hc != null) {
 953                     hc.taskDelegated = false;
 954                 }
 955             }
 956         }
 957 
 958         private static class DelegatedAction
 959                 implements PrivilegedExceptionAction<Void> {
 960             final HandshakeContext context;
 961             DelegatedAction(HandshakeContext context) {
 962                 this.context = context;
 963             }
 964 



 965             @Override
 966             public Void run() throws Exception {
 967                 while (!context.delegatedActions.isEmpty()) {
 968                     // Report back the task SSLException
 969                     if (context.delegatedThrown != null) {
 970                         Exception delegatedThrown = context.delegatedThrown;
 971                         context.delegatedThrown = null;
 972                         throw getTaskThrown(delegatedThrown);
 973                     }
 974 
 975                     Map.Entry<Byte, ByteBuffer> me =
 976                             context.delegatedActions.poll();
 977                     if (me != null) {
 978                         context.dispatch(me.getKey(), me.getValue());
 979                     }
 980                 }
 981                 return null;
 982             }
 983         }
 984     }
 985 }
< prev index next >