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

Print this page




  37 
  38 /**
  39  * Implementation of an non-blocking SSLEngine.
  40  *
  41  * *Currently*, the SSLEngine code exists in parallel with the current
  42  * SSLSocket.  As such, the current implementation is using legacy code
  43  * with many of the same abstractions.  However, it varies in many
  44  * areas, most dramatically in the IO handling.
  45  *
  46  * There are three main I/O threads that can be existing in parallel:
  47  * wrap(), unwrap(), and beginHandshake().  We are encouraging users to
  48  * not call multiple instances of wrap or unwrap, because the data could
  49  * appear to flow out of the SSLEngine in a non-sequential order.  We
  50  * take all steps we can to at least make sure the ordering remains
  51  * consistent, but once the calls returns, anything can happen.  For
  52  * example, thread1 and thread2 both call wrap, thread1 gets the first
  53  * packet, thread2 gets the second packet, but thread2 gets control back
  54  * before thread1, and sends the data.  The receiving side would see an
  55  * out-of-order error.
  56  *
  57  * Handshaking is still done the same way as SSLSocket using the normal
  58  * InputStream/OutputStream abstactions.  We create
  59  * ClientHandshakers/ServerHandshakers, which produce/consume the
  60  * handshaking data.  The transfer of the data is largely handled by the
  61  * HandshakeInStream/HandshakeOutStreams.  Lastly, the
  62  * InputRecord/OutputRecords still have the same functionality, except
  63  * that they are overridden with EngineInputRecord/EngineOutputRecord,
  64  * which provide SSLEngine-specific functionality.
  65  *
  66  * Some of the major differences are:
  67  *
  68  * EngineInputRecord/EngineOutputRecord/EngineWriter:
  69  *
  70  *      In order to avoid writing whole new control flows for
  71  *      handshaking, and to reuse most of the same code, we kept most
  72  *      of the actual handshake code the same.  As usual, reading
  73  *      handshake data may trigger output of more handshake data, so
  74  *      what we do is write this data to internal buffers, and wait for
  75  *      wrap() to be called to give that data a ride.
  76  *
  77  *      All data is routed through
  78  *      EngineInputRecord/EngineOutputRecord.  However, all handshake
  79  *      data (ct_alert/ct_change_cipher_spec/ct_handshake) are passed
  80  *      through to the underlying InputRecord/OutputRecord, and
  81  *      the data uses the internal buffers.
  82  *
  83  *      Application data is handled slightly different, we copy the data
  84  *      directly from the src to the dst buffers, and do all operations
  85  *      on those buffers, saving the overhead of multiple copies.
  86  *
  87  *      In the case of an inbound record, unwrap passes the inbound
  88  *      ByteBuffer to the InputRecord.  If the data is handshake data,
  89  *      the data is read into the InputRecord's internal buffer.  If
  90  *      the data is application data, the data is decoded directly into
  91  *      the dst buffer.
  92  *
  93  *      In the case of an outbound record, when the write to the
  94  *      "real" OutputStream's would normally take place, instead we
  95  *      call back up to the EngineOutputRecord's version of
  96  *      writeBuffer, at which time we capture the resulting output in a
  97  *      ByteBuffer, and send that back to the EngineWriter for internal
  98  *      storage.
  99  *
 100  *      EngineWriter is responsible for "handling" all outbound
 101  *      data, be it handshake or app data, and for returning the data
 102  *      to wrap() in the proper order.
 103  *
 104  * ClientHandshaker/ServerHandshaker/Handshaker:
 105  *      Methods which relied on SSLSocket now have work on either
 106  *      SSLSockets or SSLEngines.
 107  *
 108  * @author Brad Wetmore
 109  */
 110 final public class SSLEngineImpl extends SSLEngine {
 111 
 112     //
 113     // Fields and global comments
 114     //
 115 
 116     /*
 117      * There's a state machine associated with each connection, which
 118      * among other roles serves to negotiate session changes.
 119      *
 120      * - START with constructor, until the TCP connection's around.
 121      * - HANDSHAKE picks session parameters before allowing traffic.
 122      *          There are many substates due to sequencing requirements
 123      *          for handshake messages.
 124      * - DATA may be transmitted.
 125      * - RENEGOTIATE state allows concurrent data and handshaking
 126      *          traffic ("same" substates as HANDSHAKE), and terminates
 127      *          in selection of new session (and connection) parameters


 158      *                v                                     |
 159      *               ERROR>------>----->CLOSED<--------<----+
 160      *
 161      * ALSO, note that the purpose of handshaking (renegotiation is
 162      * included) is to assign a different, and perhaps new, session to
 163      * the connection.  The SSLv3 spec is a bit confusing on that new
 164      * protocol feature.
 165      */
 166     private int                 connectionState;
 167 
 168     private static final int    cs_START = 0;
 169     private static final int    cs_HANDSHAKE = 1;
 170     private static final int    cs_DATA = 2;
 171     private static final int    cs_RENEGOTIATE = 3;
 172     private static final int    cs_ERROR = 4;
 173     private static final int    cs_CLOSED = 6;
 174 
 175     /*
 176      * Once we're in state cs_CLOSED, we can continue to
 177      * wrap/unwrap until we finish sending/receiving the messages
 178      * for close_notify.  EngineWriter handles outboundDone.
 179      */
 180     private boolean             inboundDone = false;

 181 
 182     EngineWriter                writer;
 183 
 184     /*
 185      * The authentication context holds all information used to establish
 186      * who this end of the connection is (certificate chains, private keys,
 187      * etc) and who is trusted (e.g. as CAs or websites).
 188      */
 189     private SSLContextImpl      sslContext;
 190 
 191     /*
 192      * This connection is one of (potentially) many associated with
 193      * any given session.  The output of the handshake protocol is a
 194      * new session ... although all the protocol description talks
 195      * about changing the cipher spec (and it does change), in fact
 196      * that's incidental since it's done by changing everything that
 197      * is associated with a session at the same time.  (TLS/IETF may
 198      * change that to add client authentication w/o new key exchg.)
 199      */
 200     private Handshaker                  handshaker;
 201     private SSLSessionImpl              sess;
 202     private volatile SSLSessionImpl     handshakeSession;
 203 
 204 
 205     /*
 206      * Client authentication be off, requested, or required.
 207      *
 208      * This will be used by both this class and SSLSocket's variants.
 209      */
 210     static final byte           clauth_none = 0;
 211     static final byte           clauth_requested = 1;
 212     static final byte           clauth_required = 2;
 213 
 214     /*
 215      * Flag indicating that the engine has received a ChangeCipherSpec message.
 216      */
 217     private boolean             receivedCCS;
 218 
 219     /*
 220      * Flag indicating if the next record we receive MUST be a Finished
 221      * message. Temporarily set during the handshake to ensure that
 222      * a change cipher spec message is followed by a finished message.
 223      */
 224     private boolean             expectingFinished;
 225 
 226 
 227     /*
 228      * If someone tries to closeInbound() (say at End-Of-Stream)
 229      * our engine having received a close_notify, we need to
 230      * notify the app that we may have a truncation attack underway.
 231      */
 232     private boolean             recvCN;
 233 
 234     /*
 235      * For improved diagnostics, we detail connection closure
 236      * If the engine is closed (connectionState >= cs_ERROR),
 237      * closeReason != null indicates if the engine was closed
 238      * because of an error or because or normal shutdown.
 239      */
 240     private SSLException        closeReason;
 241 
 242     /*
 243      * Per-connection private state that doesn't change when the
 244      * session is changed.
 245      */
 246     private byte                        doClientAuth;

 247     private boolean                     enableSessionCreation = true;
 248     EngineInputRecord                   inputRecord;
 249     EngineOutputRecord                  outputRecord;
 250     private AccessControlContext        acc;
 251 
 252     // The cipher suites enabled for use on this connection.
 253     private CipherSuiteList             enabledCipherSuites;
 254 
 255     // the endpoint identification protocol
 256     private String                      identificationProtocol = null;
 257 
 258     // The cryptographic algorithm constraints
 259     private AlgorithmConstraints        algorithmConstraints = null;
 260 
 261     // The server name indication and matchers
 262     List<SNIServerName>         serverNames =
 263                                     Collections.<SNIServerName>emptyList();
 264     Collection<SNIMatcher>      sniMatchers =
 265                                     Collections.<SNIMatcher>emptyList();
 266 
 267     // Have we been told whether we're client or server?
 268     private boolean                     serverModeSet = false;
 269     private boolean                     roleIsServer;
 270 
 271     /*
 272      * The protocol versions enabled for use on this connection.
 273      *
 274      * Note: we support a pseudo protocol called SSLv2Hello which when
 275      * set will result in an SSL v2 Hello being sent with SSL (version 3.0)
 276      * or TLS (version 3.1, 3.2, etc.) version info.
 277      */
 278     private ProtocolList        enabledProtocols;
 279 
 280     /*
 281      * The SSL version associated with this connection.
 282      */
 283     private ProtocolVersion     protocolVersion = ProtocolVersion.DEFAULT;
 284 
 285     /*
 286      * Crypto state that's reinitialized when the session changes.
 287      */
 288     private Authenticator       readAuthenticator, writeAuthenticator;
 289     private CipherBox           readCipher, writeCipher;
 290     // NOTE: compression state would be saved here
 291 
 292     /*
 293      * security parameters for secure renegotiation.
 294      */
 295     private boolean             secureRenegotiation;
 296     private byte[]              clientVerifyData;
 297     private byte[]              serverVerifyData;
 298 
 299     /*
 300      * READ ME * READ ME * READ ME * READ ME * READ ME * READ ME *
 301      * IMPORTANT STUFF TO UNDERSTANDING THE SYNCHRONIZATION ISSUES.
 302      * READ ME * READ ME * READ ME * READ ME * READ ME * READ ME *
 303      *
 304      * There are several locks here.
 305      *
 306      * The primary lock is the per-instance lock used by
 307      * synchronized(this) and the synchronized methods.  It controls all
 308      * access to things such as the connection state and variables which
 309      * affect handshaking.  If we are inside a synchronized method, we
 310      * can access the state directly, otherwise, we must use the
 311      * synchronized equivalents.
 312      *
 313      * Note that we must never acquire the <code>this</code> lock after
 314      * <code>writeLock</code> or run the risk of deadlock.
 315      *
 316      * Grab some coffee, and be careful with any code changes.
 317      */
 318     private Object              wrapLock;
 319     private Object              unwrapLock;
 320     Object                      writeLock;
 321 
 322     /*
 323      * Is it the first application record to write?
 324      */
 325     private boolean isFirstAppOutputRecord = true;
 326 
 327     /*
 328      * Whether local cipher suites preference in server side should be
 329      * honored during handshaking?
 330      */
 331     private boolean preferLocalCipherSuites = false;
 332 
 333     /*















 334      * Class and subclass dynamic debugging support
 335      */
 336     private static final Debug debug = Debug.getInstance("ssl");
 337 
 338     //
 339     // Initialization/Constructors
 340     //
 341 
 342     /**
 343      * Constructor for an SSLEngine from SSLContext, without
 344      * host/port hints.  This Engine will not be able to cache
 345      * sessions, but must renegotiate everything by hand.
 346      */
 347     SSLEngineImpl(SSLContextImpl ctx) {
 348         super();
 349         init(ctx);

 350     }
 351 
 352     /**
 353      * Constructor for an SSLEngine from SSLContext.
 354      */
 355     SSLEngineImpl(SSLContextImpl ctx, String host, int port) {
 356         super(host, port);
 357         init(ctx);

 358     }
 359 
 360     /**
 361      * Initializes the Engine
 362      */
 363     private void init(SSLContextImpl ctx) {
 364         if (debug != null && Debug.isOn("ssl")) {
 365             System.out.println("Using SSLEngineImpl.");
 366         }
 367 
 368         sslContext = ctx;
 369         sess = SSLSessionImpl.nullSession;
 370         handshakeSession = null;


 371 
 372         /*
 373          * State is cs_START until we initialize the handshaker.
 374          *
 375          * Apps using SSLEngine are probably going to be server.
 376          * Somewhat arbitrary choice.
 377          */
 378         roleIsServer = true;
 379         connectionState = cs_START;
 380         receivedCCS = false;
 381 
 382         // default server name indication
 383         serverNames =
 384             Utilities.addToSNIServerNameList(serverNames, getPeerHost());
 385 
 386         /*
 387          * default read and write side cipher and MAC support
 388          *
 389          * Note:  compression support would go here too
 390          */
 391         readCipher = CipherBox.NULL;
 392         readAuthenticator = MAC.NULL;
 393         writeCipher = CipherBox.NULL;
 394         writeAuthenticator = MAC.NULL;
 395 
 396         // default security parameters for secure renegotiation
 397         secureRenegotiation = false;
 398         clientVerifyData = new byte[0];
 399         serverVerifyData = new byte[0];
 400 
 401         enabledCipherSuites =
 402                 sslContext.getDefaultCipherSuiteList(roleIsServer);
 403         enabledProtocols =
 404                 sslContext.getDefaultProtocolList(roleIsServer);
 405 
 406         wrapLock = new Object();
 407         unwrapLock = new Object();
 408         writeLock = new Object();
 409 
 410         /*
 411          * Save the Access Control Context.  This will be used later
 412          * for a couple of things, including providing a context to
 413          * run tasks in, and for determining which credentials
 414          * to use for Subject based (JAAS) decisions
 415          */
 416         acc = AccessController.getContext();
 417 
 418         /*
 419          * All outbound application data goes through this OutputRecord,
 420          * other data goes through their respective records created
 421          * elsewhere.  All inbound data goes through this one
 422          * input record.
 423          */
 424         outputRecord =
 425             new EngineOutputRecord(Record.ct_application_data, this);
 426         inputRecord = new EngineInputRecord(this);
 427         inputRecord.enableFormatChecks();
 428 
 429         writer = new EngineWriter();






 430     }
 431 



 432     /**
 433      * Initialize the handshaker object. This means:
 434      *
 435      *  . if a handshake is already in progress (state is cs_HANDSHAKE
 436      *    or cs_RENEGOTIATE), do nothing and return
 437      *
 438      *  . if the engine is already closed, throw an Exception (internal error)
 439      *
 440      *  . otherwise (cs_START or cs_DATA), create the appropriate handshaker
 441      *    object and advance the connection state (to cs_HANDSHAKE or
 442      *    cs_RENEGOTIATE, respectively).
 443      *
 444      * This method is called right after a new engine is created, when
 445      * starting renegotiation, or when changing client/server mode of the
 446      * engine.
 447      */
 448     private void initHandshaker() {
 449         switch (connectionState) {
 450 
 451         //


 463             return;
 464 
 465         //
 466         // Anyone allowed to call this routine is required to
 467         // do so ONLY if the connection state is reasonable...
 468         //
 469         default:
 470             throw new IllegalStateException("Internal error");
 471         }
 472 
 473         // state is either cs_START or cs_DATA
 474         if (connectionState == cs_START) {
 475             connectionState = cs_HANDSHAKE;
 476         } else { // cs_DATA
 477             connectionState = cs_RENEGOTIATE;
 478         }
 479         if (roleIsServer) {
 480             handshaker = new ServerHandshaker(this, sslContext,
 481                     enabledProtocols, doClientAuth,
 482                     protocolVersion, connectionState == cs_HANDSHAKE,
 483                     secureRenegotiation, clientVerifyData, serverVerifyData);

 484             handshaker.setSNIMatchers(sniMatchers);
 485             handshaker.setUseCipherSuitesOrder(preferLocalCipherSuites);
 486         } else {
 487             handshaker = new ClientHandshaker(this, sslContext,
 488                     enabledProtocols,
 489                     protocolVersion, connectionState == cs_HANDSHAKE,
 490                     secureRenegotiation, clientVerifyData, serverVerifyData);

 491             handshaker.setSNIServerNames(serverNames);
 492         }

 493         handshaker.setEnabledCipherSuites(enabledCipherSuites);
 494         handshaker.setEnableSessionCreation(enableSessionCreation);


 495     }
 496 
 497     /*
 498      * Report the current status of the Handshaker
 499      */
 500     private HandshakeStatus getHSStatus(HandshakeStatus hss) {
 501 
 502         if (hss != null) {
 503             return hss;
 504         }
 505 
 506         synchronized (this) {
 507             if (writer.hasOutboundData()) {

 508                 return HandshakeStatus.NEED_WRAP;
 509             } else if (handshaker != null) {
 510                 if (handshaker.taskOutstanding()) {
 511                     return HandshakeStatus.NEED_TASK;


 512                 } else {
 513                     return HandshakeStatus.NEED_UNWRAP;
 514                 }
 515             } else if (connectionState == cs_CLOSED) {
 516                 /*
 517                  * Special case where we're closing, but
 518                  * still need the close_notify before we
 519                  * can officially be closed.
 520                  *
 521                  * Note isOutboundDone is taken care of by
 522                  * hasOutboundData() above.
 523                  */
 524                 if (!isInboundDone()) {
 525                     return HandshakeStatus.NEED_UNWRAP;
 526                 } // else not handshaking
 527             }
 528 
 529             return HandshakeStatus.NOT_HANDSHAKING;
 530         }
 531     }


 555     /*
 556      * Get the Access Control Context.
 557      *
 558      * Used for a known context to
 559      * run tasks in, and for determining which credentials
 560      * to use for Subject-based (JAAS) decisions.
 561      */
 562     AccessControlContext getAcc() {
 563         return acc;
 564     }
 565 
 566     /*
 567      * Is a handshake currently underway?
 568      */
 569     @Override
 570     public SSLEngineResult.HandshakeStatus getHandshakeStatus() {
 571         return getHSStatus(null);
 572     }
 573 
 574     /*
 575      * When a connection finishes handshaking by enabling use of a newly
 576      * negotiated session, each end learns about it in two halves (read,
 577      * and write).  When both read and write ciphers have changed, and the
 578      * last handshake message has been read, the connection has joined
 579      * (rejoined) the new session.
 580      *
 581      * NOTE:  The SSLv3 spec is rather unclear on the concepts here.
 582      * Sessions don't change once they're established (including cipher
 583      * suite and master secret) but connections can join them (and leave
 584      * them).  They're created by handshaking, though sometime handshaking
 585      * causes connections to join up with pre-established sessions.
 586      *
 587      * Synchronized on "this" from readRecord.
 588      */
 589     private void changeReadCiphers() throws SSLException {
 590         if (connectionState != cs_HANDSHAKE
 591                 && connectionState != cs_RENEGOTIATE) {
 592             throw new SSLProtocolException(
 593                 "State error, change cipher specs");
 594         }
 595 
 596         // ... create decompressor
 597 
 598         CipherBox oldCipher = readCipher;
 599 
 600         try {
 601             readCipher = handshaker.newReadCipher();
 602             readAuthenticator = handshaker.newReadAuthenticator();
 603         } catch (GeneralSecurityException e) {
 604             // "can't happen"
 605             throw new SSLException("Algorithm missing:  ", e);
 606         }
 607 
 608         /*
 609          * Dispose of any intermediate state in the underlying cipher.
 610          * For PKCS11 ciphers, this will release any attached sessions,
 611          * and thus make finalization faster.
 612          *
 613          * Since MAC's doFinal() is called for every SSL/TLS packet, it's
 614          * not necessary to do the same with MAC's.
 615          */
 616         oldCipher.dispose();
 617     }
 618 
 619     /*
 620      * used by Handshaker to change the active write cipher, follows
 621      * the output of the CCS message.
 622      *
 623      * Also synchronized on "this" from readRecord/delegatedTask.
 624      */
 625     void changeWriteCiphers() throws SSLException {
 626         if (connectionState != cs_HANDSHAKE
 627                 && connectionState != cs_RENEGOTIATE) {
 628             throw new SSLProtocolException(
 629                 "State error, change cipher specs");
 630         }
 631 
 632         // ... create compressor
 633 
 634         CipherBox oldCipher = writeCipher;
 635 
 636         try {
 637             writeCipher = handshaker.newWriteCipher();
 638             writeAuthenticator = handshaker.newWriteAuthenticator();
 639         } catch (GeneralSecurityException e) {
 640             // "can't happen"
 641             throw new SSLException("Algorithm missing:  ", e);
 642         }
 643 
 644         // See comment above.
 645         oldCipher.dispose();
 646 
 647         // reset the flag of the first application record
 648         isFirstAppOutputRecord = true;
 649     }
 650 
 651     /*
 652      * Updates the SSL version associated with this connection.
 653      * Called from Handshaker once it has determined the negotiated version.
 654      */
 655     synchronized void setVersion(ProtocolVersion protocolVersion) {
 656         this.protocolVersion = protocolVersion;
 657         outputRecord.setVersion(protocolVersion);
 658     }
 659 
 660 
 661     /**
 662      * Kickstart the handshake if it is not already in progress.
 663      * This means:
 664      *
 665      *  . if handshaking is already underway, do nothing and return
 666      *
 667      *  . if the engine is not connected or already closed, throw an
 668      *    Exception.


 699                         "Warning: Using insecure renegotiation");
 700                 }
 701             }
 702 
 703             // initialize the handshaker, move to cs_RENEGOTIATE
 704             initHandshaker();
 705             break;
 706 
 707         case cs_RENEGOTIATE:
 708             // handshaking already in progress, return
 709             return;
 710 
 711         default:
 712             // cs_ERROR/cs_CLOSED
 713             throw new SSLException("SSLEngine is closing/closed");
 714         }
 715 
 716         //
 717         // Kickstart handshake state machine if we need to ...
 718         //
 719         // Note that handshaker.kickstart() writes the message
 720         // to its HandshakeOutStream, which calls back into
 721         // SSLSocketImpl.writeRecord() to send it.
 722         //
 723         if (!handshaker.activated()) {
 724              // prior to handshaking, activate the handshake
 725             if (connectionState == cs_RENEGOTIATE) {
 726                 // don't use SSLv2Hello when renegotiating
 727                 handshaker.activate(protocolVersion);
 728             } else {
 729                 handshaker.activate(null);
 730             }
 731 
 732             if (handshaker instanceof ClientHandshaker) {
 733                 // send client hello
 734                 handshaker.kickstart();
 735             } else {    // instanceof ServerHandshaker
 736                 if (connectionState == cs_HANDSHAKE) {
 737                     // initial handshake, no kickstart message to send
 738                 } else {
 739                     // we want to renegotiate, send hello request
 740                     handshaker.kickstart();
 741 
 742                     // hello request is not included in the handshake
 743                     // hashes, reset them
 744                     handshaker.handshakeHash.reset();
 745                 }
 746             }
 747         }
 748     }
 749 
 750     /*
 751      * Start a SSLEngine handshake
 752      */
 753     @Override
 754     public void beginHandshake() throws SSLException {
 755         try {
 756             kickstartHandshake();
 757         } catch (Exception e) {
 758             fatal(Alerts.alert_handshake_failure,
 759                 "Couldn't kickstart handshaking", e);
 760         }
 761     }
 762 
 763 
 764     //
 765     // Read/unwrap side
 766     //
 767 
 768 
 769     /**
 770      * Unwraps a buffer.  Does a variety of checks before grabbing
 771      * the unwrapLock, which blocks multiple unwraps from occurring.
 772      */
 773     @Override
 774     public SSLEngineResult unwrap(ByteBuffer netData, ByteBuffer [] appData,
 775             int offset, int length) throws SSLException {
 776 
 777         EngineArgs ea = new EngineArgs(netData, appData, offset, length);

 778 
 779         try {
 780             synchronized (unwrapLock) {
 781                 return readNetRecord(ea);
 782             }




 783         } catch (Exception e) {
 784             /*
 785              * Don't reset position so it looks like we didn't
 786              * consume anything.  We did consume something, and it
 787              * got us into this situation, so report that much back.
 788              * Our days of consuming are now over anyway.
 789              */
 790             fatal(Alerts.alert_internal_error,
 791                 "problem unwrapping net record", e);
 792             return null;  // make compiler happy
 793         } finally {













 794             /*
 795              * Just in case something failed to reset limits properly.
 796              */
 797             ea.resetLim();

 798         }





 799     }
 800 
 801     /*









 802      * Makes additional checks for unwrap, but this time more
 803      * specific to this packet and the current state of the machine.
 804      */
 805     private SSLEngineResult readNetRecord(EngineArgs ea) throws IOException {

 806 
 807         Status status = null;
 808         HandshakeStatus hsStatus = null;
 809 
 810         /*
 811          * See if the handshaker needs to report back some SSLException.
 812          */
 813         checkTaskThrown();
 814 
 815         /*
 816          * Check if we are closing/closed.
 817          */
 818         if (isInboundDone()) {
 819             return new SSLEngineResult(Status.CLOSED, getHSStatus(null), 0, 0);
 820         }
 821 
 822         /*
 823          * If we're still in cs_HANDSHAKE, make sure it's been
 824          * started.
 825          */


 840             }
 841         }
 842 
 843         /*
 844          * Grab a copy of this if it doesn't already exist,
 845          * and we can use it several places before anything major
 846          * happens on this side.  Races aren't critical
 847          * here.
 848          */
 849         if (hsStatus == null) {
 850             hsStatus = getHSStatus(null);
 851         }
 852 
 853         /*
 854          * If we have a task outstanding, this *MUST* be done before
 855          * doing any more unwrapping, because we could be in the middle
 856          * of receiving a handshake message, for example, a finished
 857          * message which would change the ciphers.
 858          */
 859         if (hsStatus == HandshakeStatus.NEED_TASK) {
















 860             return new SSLEngineResult(
 861                 Status.OK, hsStatus, 0, 0);
 862         }
 863 
 864         /*
 865          * Check the packet to make sure enough is here.
 866          * This will also indirectly check for 0 len packets.
 867          */
 868         int packetLen = inputRecord.bytesInCompletePacket(ea.netData);










 869 













 870         // Is this packet bigger than SSL/TLS normally allows?
 871         if (packetLen > sess.getPacketBufferSize()) {
 872             if (packetLen > Record.maxLargeRecordSize) {
 873                 throw new SSLProtocolException(
 874                     "Input SSL/TLS record too big: max = " +
 875                     Record.maxLargeRecordSize +
 876                     " len = " + packetLen);
 877             } else {
 878                 // Expand the expected maximum packet/application buffer
 879                 // sizes.





 880                 sess.expandBufferSizes();
 881             }







 882         }

 883 










 884         /*
 885          * Check for OVERFLOW.
 886          *
 887          * To be considered: We could delay enforcing the application buffer
 888          * free space requirement until after the initial handshaking.
 889          */
 890         if ((packetLen - Record.headerSize) > ea.getAppRemaining()) {
 891             return new SSLEngineResult(Status.BUFFER_OVERFLOW, hsStatus, 0, 0);






 892         }

 893 
 894         // check for UNDERFLOW.
 895         if ((packetLen == -1) || (ea.netData.remaining() < packetLen)) {
 896             return new SSLEngineResult(
 897                 Status.BUFFER_UNDERFLOW, hsStatus, 0, 0);
 898         }
 899 
 900         /*
 901          * We're now ready to actually do the read.
 902          * The only result code we really need to be exactly
 903          * right is the HS finished, for signaling to
 904          * HandshakeCompletedListeners.
 905          */

 906         try {
 907             hsStatus = readRecord(ea);
 908         } catch (SSLException e) {
 909             throw e;
 910         } catch (IOException e) {
 911             throw new SSLException("readRecord", e);
 912         }
 913 
 914         /*
 915          * Check the various condition that we could be reporting.
 916          *
 917          * It's *possible* something might have happened between the
 918          * above and now, but it was better to minimally lock "this"
 919          * during the read process.  We'll return the current
 920          * status, which is more representative of the current state.
 921          *
 922          * status above should cover:  FINISHED, NEED_TASK
 923          */
 924         status = (isInboundDone() ? Status.CLOSED : Status.OK);
 925         hsStatus = getHSStatus(hsStatus);
 926 
 927         return new SSLEngineResult(status, hsStatus,
 928             ea.deltaNet(), ea.deltaApp());


 929     }
 930 









 931     /*
 932      * Actually do the read record processing.
 933      *
 934      * Returns a Status if it can make specific determinations
 935      * of the engine state.  In particular, we need to signal
 936      * that a handshake just completed.
 937      *
 938      * It would be nice to be symmetrical with the write side and move
 939      * the majority of this to EngineInputRecord, but there's too much
 940      * SSLEngine state to do that cleanly.  It must still live here.
 941      */
 942     private HandshakeStatus readRecord(EngineArgs ea) throws IOException {

 943 
 944         HandshakeStatus hsStatus = null;
 945 
 946         /*
 947          * The various operations will return new sliced BB's,
 948          * this will avoid having to worry about positions and
 949          * limits in the netBB.
 950          */
 951         ByteBuffer readBB = null;
 952         ByteBuffer decryptedBB = null;
 953 
 954         if (getConnectionState() != cs_ERROR) {


 955 
 956             /*
 957              * Read a record ... maybe emitting an alert if we get a
 958              * comprehensible but unsupported "hello" message during
 959              * format checking (e.g. V2).
 960              */
 961             try {
 962                 readBB = inputRecord.read(ea.netData);
 963             } catch (IOException e) {
 964                 fatal(Alerts.alert_unexpected_message, e);

 965             }
 966 











 967             /*
 968              * The basic SSLv3 record protection involves (optional)
 969              * encryption for privacy, and an integrity check ensuring
 970              * data origin authentication.  We do them both here, and
 971              * throw a fatal alert if the integrity check fails.
 972              */
 973             try {
 974                 decryptedBB = inputRecord.decrypt(
 975                                     readAuthenticator, readCipher, readBB);
 976             } catch (BadPaddingException e) {
 977                 byte alertType = (inputRecord.contentType() ==
 978                     Record.ct_handshake) ?
 979                         Alerts.alert_handshake_failure :
 980                         Alerts.alert_bad_record_mac;
 981                 fatal(alertType, e.getMessage(), e);





 982             }
 983 
 984             // if (!inputRecord.decompress(c))
 985             //     fatal(Alerts.alert_decompression_failure,
 986             //     "decompression failure");


 987 



 988 








 989             /*
 990              * Process the record.
 991              */



 992 
 993             synchronized (this) {
 994                 switch (inputRecord.contentType()) {
 995                 case Record.ct_handshake:
 996                     /*
 997                      * Handshake messages always go to a pending session
 998                      * handshaker ... if there isn't one, create one.  This
 999                      * must work asynchronously, for renegotiation.
1000                      *
1001                      * NOTE that handshaking will either resume a session
1002                      * which was in the cache (and which might have other
1003                      * connections in it already), or else will start a new
1004                      * session (new keys exchanged) with just this connection
1005                      * in it.
1006                      */
1007                     initHandshaker();
1008                     if (!handshaker.activated()) {
1009                         // prior to handshaking, activate the handshake
1010                         if (connectionState == cs_RENEGOTIATE) {
1011                             // don't use SSLv2Hello when renegotiating
1012                             handshaker.activate(protocolVersion);
1013                         } else {
1014                             handshaker.activate(null);
1015                         }
1016                     }
1017 
1018                     /*
1019                      * process the handshake record ... may contain just
1020                      * a partial handshake message or multiple messages.
1021                      *
1022                      * The handshaker state machine will ensure that it's
1023                      * a finished message.
1024                      */
1025                     handshaker.process_record(inputRecord, expectingFinished);
1026                     expectingFinished = false;
1027 
1028                     if (handshaker.invalidated) {
1029                         handshaker = null;
1030                         receivedCCS = false;
1031                         // if state is cs_RENEGOTIATE, revert it to cs_DATA
1032                         if (connectionState == cs_RENEGOTIATE) {
1033                             connectionState = cs_DATA;
1034                         }
1035                     } else if (handshaker.isDone()) {
1036                         // reset the parameters for secure renegotiation.
1037                         secureRenegotiation =
1038                                         handshaker.isSecureRenegotiation();
1039                         clientVerifyData = handshaker.getClientVerifyData();
1040                         serverVerifyData = handshaker.getServerVerifyData();
1041 
1042                         sess = handshaker.getSession();
1043                         handshakeSession = null;
1044                         if (!writer.hasOutboundData()) {
1045                             hsStatus = HandshakeStatus.FINISHED;
1046                         }
1047                         handshaker = null;
1048                         connectionState = cs_DATA;
1049                         receivedCCS = false;
1050 
1051                         // No handshakeListeners here.  That's a
1052                         // SSLSocket thing.
1053                     } else if (handshaker.taskOutstanding()) {
1054                         hsStatus = HandshakeStatus.NEED_TASK;
1055                     }
1056                     break;
1057 
1058                 case Record.ct_application_data:
1059                     // Pass this right back up to the application.
1060                     if ((connectionState != cs_DATA)
1061                             && (connectionState != cs_RENEGOTIATE)
1062                             && (connectionState != cs_CLOSED)) {
1063                         throw new SSLProtocolException(
1064                             "Data received in non-data state: " +
1065                             connectionState);
1066                     }
1067 
1068                     if (expectingFinished) {
1069                         throw new SSLProtocolException
1070                                 ("Expecting finished message, received data");
1071                     }
1072 
1073                     /*
1074                      * Don't return data once the inbound side is
1075                      * closed.
1076                      */
1077                     if (!inboundDone) {
1078                         ea.scatter(decryptedBB.slice());









1079                     }


1080                     break;
1081 
1082                 case Record.ct_alert:
1083                     recvAlert();
1084                     break;
1085 
1086                 case Record.ct_change_cipher_spec:
1087                     if ((connectionState != cs_HANDSHAKE
1088                                 && connectionState != cs_RENEGOTIATE)
1089                             || !handshaker.sessionKeysCalculated()
1090                             || receivedCCS) {
1091                         // For the CCS message arriving in the wrong state
1092                         fatal(Alerts.alert_unexpected_message,
1093                                 "illegal change cipher spec msg, conn state = "
1094                                 + connectionState + ", handshake state = "
1095                                 + handshaker.state);
1096                     } else if (inputRecord.available() != 1
1097                             || inputRecord.read() != 1) {
1098                         // For structural/content issues with the CCS
1099                         fatal(Alerts.alert_unexpected_message,
1100                                 "Malformed change cipher spec msg");
1101                     }
1102 
1103                     // Once we've received CCS, update the flag.
1104                     // If the remote endpoint sends it again in this handshake
1105                     // we won't process it.
1106                     receivedCCS = true;
1107 
1108                     //
1109                     // The first message after a change_cipher_spec
1110                     // record MUST be a "Finished" handshake record,
1111                     // else it's a protocol violation.  We force this
1112                     // to be checked by a minor tweak to the state
1113                     // machine.
1114                     //
1115                     changeReadCiphers();












1116                     // next message MUST be a finished message
1117                     expectingFinished = true;
1118                     break;
1119 
1120                 default:
1121                     //
1122                     // TLS requires that unrecognized records be ignored.
1123                     //
1124                     if (debug != null && Debug.isOn("ssl")) {
1125                         System.out.println(Thread.currentThread().getName() +
1126                             ", Received record type: "
1127                             + inputRecord.contentType());
1128                     }
1129                     break;
1130                 } // switch
1131 
1132                 /*
1133                  * We only need to check the sequence number state for
1134                  * non-handshaking record.
1135                  *
1136                  * Note that in order to maintain the handshake status
1137                  * properly, we check the sequence number after the last
1138                  * record reading process. As we request renegotiation
1139                  * or close the connection for wrapped sequence number
1140                  * when there is enough sequence number space left to
1141                  * handle a few more records, so the sequence number
1142                  * of the last record cannot be wrapped.
1143                  */
1144                 hsStatus = getHSStatus(hsStatus);
1145                 if (connectionState < cs_ERROR && !isInboundDone() &&
1146                         (hsStatus == HandshakeStatus.NOT_HANDSHAKING)) {
1147                     if (checkSequenceNumber(readAuthenticator,
1148                             inputRecord.contentType())) {













1149                         hsStatus = getHSStatus(null);
1150                     }
1151                 }
1152             } // synchronized (this)
1153         }
1154 
1155         return hsStatus;
1156     }
1157 
1158 
1159     //
1160     // write/wrap side
1161     //
1162 
1163 
1164     /**
1165      * Wraps a buffer.  Does a variety of checks before grabbing
1166      * the wrapLock, which blocks multiple wraps from occurring.
1167      */
1168     @Override
1169     public SSLEngineResult wrap(ByteBuffer [] appData,
1170             int offset, int length, ByteBuffer netData) throws SSLException {
1171 
1172         EngineArgs ea = new EngineArgs(appData, offset, length, netData);

1173 
1174         /*
1175          * We can be smarter about using smaller buffer sizes later.
1176          * For now, force it to be large enough to handle any
1177          * valid SSL/TLS record.
1178          */
1179         if (netData.remaining() < EngineOutputRecord.maxRecordSize) {
1180             return new SSLEngineResult(
1181                 Status.BUFFER_OVERFLOW, getHSStatus(null), 0, 0);
1182         }
1183 
1184         try {
1185             synchronized (wrapLock) {
1186                 return writeAppRecord(ea);
1187             }




1188         } catch (Exception e) {
1189             ea.resetPos();
1190 
1191             fatal(Alerts.alert_internal_error,
1192                 "problem wrapping app data", e);
1193             return null;  // make compiler happy
1194         } finally {
1195             /*
1196              * Just in case something didn't reset limits properly.
1197              */
1198             ea.resetLim();
1199         }
1200     }
1201 
1202     /*
1203      * Makes additional checks for unwrap, but this time more
1204      * specific to this packet and the current state of the machine.
1205      */
1206     private SSLEngineResult writeAppRecord(EngineArgs ea) throws IOException {

1207 
1208         Status status = null;
1209         HandshakeStatus hsStatus = null;
1210 
1211         /*
1212          * See if the handshaker needs to report back some SSLException.
1213          */
1214         checkTaskThrown();
1215 
1216         /*
1217          * short circuit if we're closed/closing.
1218          */
1219         if (writer.isOutboundDone()) {
1220             return new SSLEngineResult(Status.CLOSED, getHSStatus(null), 0, 0);
1221         }
1222 
1223         /*
1224          * If we're still in cs_HANDSHAKE, make sure it's been
1225          * started.
1226          */
1227         synchronized (this) {
1228             if ((connectionState == cs_HANDSHAKE) ||
1229                     (connectionState == cs_START)) {

1230                 kickstartHandshake();
1231 
1232                 /*
1233                  * If there's no HS data available to write, we can return
1234                  * without trying to wrap anything.
1235                  */
1236                 hsStatus = getHSStatus(null);
1237 
1238                 if (hsStatus == HandshakeStatus.NEED_UNWRAP) {









1239                     return new SSLEngineResult(Status.OK, hsStatus, 0, 0);

1240                 }
1241             }
1242         }
1243 
1244         /*
1245          * Grab a copy of this if it doesn't already exist,
1246          * and we can use it several places before anything major
1247          * happens on this side.  Races aren't critical
1248          * here.
1249          */
1250         if (hsStatus == null) {
1251             hsStatus = getHSStatus(null);
1252         }
1253 
1254         /*
1255          * If we have a task outstanding, this *MUST* be done before
1256          * doing any more wrapping, because we could be in the middle
1257          * of receiving a handshake message, for example, a finished
1258          * message which would change the ciphers.
1259          */
1260         if (hsStatus == HandshakeStatus.NEED_TASK) {
1261             return new SSLEngineResult(
1262                 Status.OK, hsStatus, 0, 0);
1263         }
1264 
1265         /*
1266          * This will obtain any waiting outbound data, or will
1267          * process the outbound appData.
1268          */











1269         try {

1270             synchronized (writeLock) {
1271                 hsStatus = writeRecord(outputRecord, ea);
1272             }





1273         } catch (SSLException e) {
1274             throw e;
1275         } catch (IOException e) {
1276             throw new SSLException("Write problems", e);
1277         }
1278 
1279         /*
1280          * writeRecord might have reported some status.
1281          * Now check for the remaining cases.
1282          *
1283          * status above should cover:  NEED_WRAP/FINISHED
1284          */
1285         status = (isOutboundDone() ? Status.CLOSED : Status.OK);
1286         hsStatus = getHSStatus(hsStatus);
1287 
1288         return new SSLEngineResult(status, hsStatus,
1289             ea.deltaApp(), ea.deltaNet());


1290     }
1291 




1292     /*
1293      * Central point to write/get all of the outgoing data.
1294      */
1295     private HandshakeStatus writeRecord(EngineOutputRecord eor,
1296             EngineArgs ea) throws IOException {
1297 
1298         // eventually compress as well.
1299         HandshakeStatus hsStatus =
1300                 writer.writeRecord(eor, ea, writeAuthenticator, writeCipher);
1301 
1302         /*
1303          * We only need to check the sequence number state for
1304          * non-handshaking record.
1305          *
1306          * Note that in order to maintain the handshake status
1307          * properly, we check the sequence number after the last
1308          * record writing process. As we request renegotiation
1309          * or close the connection for wrapped sequence number
1310          * when there is enough sequence number space left to
1311          * handle a few more records, so the sequence number
1312          * of the last record cannot be wrapped.
1313          */
1314         hsStatus = getHSStatus(hsStatus);
1315         if (connectionState < cs_ERROR && !isOutboundDone() &&
1316                 (hsStatus == HandshakeStatus.NOT_HANDSHAKING)) {
1317             if (checkSequenceNumber(writeAuthenticator, eor.contentType())) {
1318                 hsStatus = getHSStatus(null);
1319             }
1320         }
1321 
1322         /*
1323          * turn off the flag of the first application record if we really
1324          * consumed at least byte.
1325          */
1326         if (isFirstAppOutputRecord && ea.deltaApp() > 0) {
1327             isFirstAppOutputRecord = false;
1328         }



1329 
1330         return hsStatus;




1331     }
1332 
1333     /*
1334      * Need to split the payload except the following cases:
1335      *
1336      * 1. protocol version is TLS 1.1 or later;
1337      * 2. bulk cipher does not use CBC mode, including null bulk cipher suites.
1338      * 3. the payload is the first application record of a freshly
1339      *    negotiated TLS session.
1340      * 4. the CBC protection is disabled;
1341      *
1342      * More details, please refer to
1343      * EngineOutputRecord.write(EngineArgs, MAC, CipherBox).
1344      */
1345     boolean needToSplitPayload(CipherBox cipher, ProtocolVersion protocol) {
1346         return (protocol.v <= ProtocolVersion.TLS10.v) &&
1347                 cipher.isCBCMode() && !isFirstAppOutputRecord &&
1348                 Record.enableCBCProtection;
1349     }
1350 
1351     /*
1352      * Non-application OutputRecords go through here.
1353      */
1354     void writeRecord(EngineOutputRecord eor) throws IOException {
1355         // eventually compress as well.
1356         writer.writeRecord(eor, writeAuthenticator, writeCipher);
1357 




1358         /*
1359          * Check the sequence number state

1360          *
1361          * Note that in order to maintain the connection I/O
1362          * properly, we check the sequence number after the last
1363          * record writing process. As we request renegotiation
1364          * or close the connection for wrapped sequence number
1365          * when there is enough sequence number space left to
1366          * handle a few more records, so the sequence number
1367          * of the last record cannot be wrapped.
1368          */
1369         if ((connectionState < cs_ERROR) && !isOutboundDone()) {
1370             checkSequenceNumber(writeAuthenticator, eor.contentType());
1371         }
1372     }
1373 
1374     //
1375     // Close code
1376     //
1377 
1378     /**
1379      * Check the sequence number state
1380      *
1381      * RFC 4346 states that, "Sequence numbers are of type uint64 and
1382      * may not exceed 2^64-1.  Sequence numbers do not wrap. If a TLS
1383      * implementation would need to wrap a sequence number, it must
1384      * renegotiate instead."
1385      *
1386      * Return true if the handshake status may be changed.
1387      */
1388     private boolean checkSequenceNumber(Authenticator authenticator, byte type)
1389             throws IOException {
1390 
1391         /*
1392          * Don't bother to check the sequence number for error or
1393          * closed connections, or NULL MAC
1394          */
1395         if (connectionState >= cs_ERROR || authenticator == MAC.NULL) {
1396             return false;
1397         }
1398 
1399         /*
1400          * Conservatively, close the connection immediately when the
1401          * sequence number is close to overflow
1402          */
1403         if (authenticator.seqNumOverflow()) {
1404             /*
1405              * TLS protocols do not define a error alert for sequence
1406              * number overflow. We use handshake_failure error alert
1407              * for handshaking and bad_record_mac for other records.
1408              */
1409             if (debug != null && Debug.isOn("ssl")) {
1410                 System.out.println(Thread.currentThread().getName() +
1411                     ", sequence number extremely close to overflow " +
1412                     "(2^64-1 packets). Closing connection.");
1413             }
1414 
1415             fatal(Alerts.alert_handshake_failure, "sequence number overflow");
1416 
1417             return true; // make the compiler happy
1418         }
1419 
1420         /*
1421          * Ask for renegotiation when need to renew sequence number.
1422          *
1423          * Don't bother to kickstart the renegotiation when the local is
1424          * asking for it.
1425          */
1426         if ((type != Record.ct_handshake) && authenticator.seqNumIsHuge()) {
1427             if (debug != null && Debug.isOn("ssl")) {
1428                 System.out.println(Thread.currentThread().getName() +
1429                         ", request renegotiation " +
1430                         "to avoid sequence number overflow");
1431             }
1432 
1433             beginHandshake();
1434             return true;

1435         }

1436 
1437         return false;
1438     }
1439 













1440     /**
1441      * Signals that no more outbound application data will be sent
1442      * on this <code>SSLEngine</code>.
1443      */
1444     private void closeOutboundInternal() {
1445 
1446         if ((debug != null) && Debug.isOn("ssl")) {
1447             System.out.println(Thread.currentThread().getName() +
1448                                     ", closeOutboundInternal()");
1449         }
1450 
1451         /*
1452          * Already closed, ignore
1453          */
1454         if (writer.isOutboundDone()) {
1455             return;
1456         }
1457 
1458         switch (connectionState) {
1459 
1460         /*
1461          * If we haven't even started yet, don't bother reading inbound.
1462          */
1463         case cs_START:
1464             writer.closeOutbound();











1465             inboundDone = true;
1466             break;
1467 
1468         case cs_ERROR:
1469         case cs_CLOSED:
1470             break;
1471 
1472         /*
1473          * Otherwise we indicate clean termination.
1474          */
1475         // case cs_HANDSHAKE:
1476         // case cs_DATA:
1477         // case cs_RENEGOTIATE:
1478         default:
1479             warning(Alerts.alert_close_notify);
1480             writer.closeOutbound();





1481             break;
1482         }
1483 
1484         // See comment in changeReadCiphers()
1485         writeCipher.dispose();
1486 
1487         connectionState = cs_CLOSED;
1488     }
1489 
1490     @Override
1491     synchronized public void closeOutbound() {
1492         /*
1493          * Dump out a close_notify to the remote side
1494          */
1495         if ((debug != null) && Debug.isOn("ssl")) {
1496             System.out.println(Thread.currentThread().getName() +
1497                                     ", called closeOutbound()");
1498         }
1499 
1500         closeOutboundInternal();
1501     }
1502 
1503     /**
1504      * Returns the outbound application data closure state
1505      */
1506     @Override
1507     public boolean isOutboundDone() {
1508         return writer.isOutboundDone();
1509     }
1510 
1511     /**
1512      * Signals that no more inbound network data will be sent
1513      * to this <code>SSLEngine</code>.
1514      */
1515     private void closeInboundInternal() {
1516 
1517         if ((debug != null) && Debug.isOn("ssl")) {
1518             System.out.println(Thread.currentThread().getName() +
1519                                     ", closeInboundInternal()");
1520         }
1521 
1522         /*
1523          * Already closed, ignore
1524          */
1525         if (inboundDone) {
1526             return;
1527         }
1528 
1529         closeOutboundInternal();






1530         inboundDone = true;
1531 
1532         // See comment in changeReadCiphers()
1533         readCipher.dispose();
1534 
1535         connectionState = cs_CLOSED;
1536     }
1537 
1538     /*
1539      * Close the inbound side of the connection.  We grab the
1540      * lock here, and do the real work in the internal verison.
1541      * We do check for truncation attacks.
1542      */
1543     @Override
1544     synchronized public void closeInbound() throws SSLException {
1545         /*
1546          * Currently closes the outbound side as well.  The IETF TLS
1547          * working group has expressed the opinion that 1/2 open
1548          * connections are not allowed by the spec.  May change
1549          * someday in the future.
1550          */
1551         if ((debug != null) && Debug.isOn("ssl")) {
1552             System.out.println(Thread.currentThread().getName() +
1553                                     ", called closeInbound()");
1554         }


1585 
1586 
1587     /**
1588      * Returns the current <code>SSLSession</code> for this
1589      * <code>SSLEngine</code>
1590      * <P>
1591      * These can be long lived, and frequently correspond to an
1592      * entire login session for some user.
1593      */
1594     @Override
1595     synchronized public SSLSession getSession() {
1596         return sess;
1597     }
1598 
1599     @Override
1600     synchronized public SSLSession getHandshakeSession() {
1601         return handshakeSession;
1602     }
1603 
1604     synchronized void setHandshakeSession(SSLSessionImpl session) {




1605         handshakeSession = session;
1606     }
1607 
1608     /**
1609      * Returns a delegated <code>Runnable</code> task for
1610      * this <code>SSLEngine</code>.
1611      */
1612     @Override
1613     synchronized public Runnable getDelegatedTask() {
1614         if (handshaker != null) {
1615             return handshaker.getTask();
1616         }
1617         return null;
1618     }
1619 
1620 
1621     //
1622     // EXCEPTION AND ALERT HANDLING
1623     //
1624 


1684                 throw (RuntimeException)cause;
1685             } else if (cause instanceof SSLException) {
1686                 throw (SSLException)cause;
1687             } else if (cause instanceof Exception) {
1688                 throw new SSLException("fatal SSLEngine condition", cause);
1689             }
1690         }
1691 
1692         if ((debug != null) && Debug.isOn("ssl")) {
1693             System.out.println(Thread.currentThread().getName()
1694                         + ", fatal error: " + description +
1695                         ": " + diagnostic + "\n" + cause.toString());
1696         }
1697 
1698         /*
1699          * Ok, this engine's going down.
1700          */
1701         int oldState = connectionState;
1702         connectionState = cs_ERROR;
1703 





1704         inboundDone = true;
1705 
1706         sess.invalidate();
1707         if (handshakeSession != null) {
1708             handshakeSession.invalidate();
1709         }
1710 
1711         /*
1712          * If we haven't even started handshaking yet, no need
1713          * to generate the fatal close alert.
1714          */
1715         if (oldState != cs_START) {
1716             sendAlert(Alerts.alert_fatal, description);
1717         }
1718 
1719         if (cause instanceof SSLException) { // only true if != null
1720             closeReason = (SSLException)cause;
1721         } else {
1722             /*
1723              * Including RuntimeExceptions, but we'll throw those
1724              * down below.  The closeReason isn't used again,
1725              * except for null checks.
1726              */
1727             closeReason =
1728                 Alerts.getSSLException(description, cause, diagnostic);
1729         }
1730 
1731         writer.closeOutbound();





1732 
1733         connectionState = cs_CLOSED;
1734 
1735         // See comment in changeReadCiphers()
1736         readCipher.dispose();
1737         writeCipher.dispose();
1738 
1739         if (cause instanceof RuntimeException) {
1740             throw (RuntimeException)cause;
1741         } else {
1742             throw closeReason;
1743         }
1744     }
1745 
1746     /*
1747      * Process an incoming alert ... caller must already have synchronized
1748      * access to "this".
1749      */
1750     private void recvAlert() throws IOException {
1751         byte level = (byte)inputRecord.read();
1752         byte description = (byte)inputRecord.read();

1753         if (description == -1) { // check for short message
1754             fatal(Alerts.alert_illegal_parameter, "Short alert message");
1755         }
1756 
1757         if (debug != null && (Debug.isOn("record") ||
1758                 Debug.isOn("handshake"))) {
1759             synchronized (System.out) {
1760                 System.out.print(Thread.currentThread().getName());
1761                 System.out.print(", RECV " + protocolVersion + " ALERT:  ");
1762                 if (level == Alerts.alert_fatal) {
1763                     System.out.print("fatal, ");
1764                 } else if (level == Alerts.alert_warning) {
1765                     System.out.print("warning, ");
1766                 } else {
1767                     System.out.print("<level " + (0x0ff & level) + ">, ");
1768                 }
1769                 System.out.println(Alerts.alertDescription(description));
1770             }
1771         }
1772 


1796                 + Alerts.alertDescription(description);
1797             if (closeReason == null) {
1798                 closeReason = Alerts.getSSLException(description, reason);
1799             }
1800             fatal(Alerts.alert_unexpected_message, reason);
1801         }
1802     }
1803 
1804 
1805     /*
1806      * Emit alerts.  Caller must have synchronized with "this".
1807      */
1808     private void sendAlert(byte level, byte description) {
1809         // the connectionState cannot be cs_START
1810         if (connectionState >= cs_CLOSED) {
1811             return;
1812         }
1813 
1814         // For initial handshaking, don't send alert message to peer if
1815         // handshaker has not started.
1816         if (connectionState == cs_HANDSHAKE &&
1817             (handshaker == null || !handshaker.started())) {



1818             return;
1819         }
1820 
1821         EngineOutputRecord r = new EngineOutputRecord(Record.ct_alert, this);
1822         r.setVersion(protocolVersion);
1823 
1824         boolean useDebug = debug != null && Debug.isOn("ssl");
1825         if (useDebug) {
1826             synchronized (System.out) {
1827                 System.out.print(Thread.currentThread().getName());
1828                 System.out.print(", SEND " + protocolVersion + " ALERT:  ");
1829                 if (level == Alerts.alert_fatal) {
1830                     System.out.print("fatal, ");
1831                 } else if (level == Alerts.alert_warning) {
1832                     System.out.print("warning, ");
1833                 } else {
1834                     System.out.print("<level = " + (0x0ff & level) + ">, ");
1835                 }
1836                 System.out.println("description = "
1837                         + Alerts.alertDescription(description));
1838             }
1839         }
1840 
1841         r.write(level);
1842         r.write(description);
1843         try {
1844             writeRecord(r);
1845         } catch (IOException e) {
1846             if (useDebug) {
1847                 System.out.println(Thread.currentThread().getName() +
1848                     ", Exception sending alert: " + e);
1849             }
1850         }
1851     }
1852 
1853 
1854     //
1855     // VARIOUS OTHER METHODS (COMMON TO SSLSocket)
1856     //
1857 
1858 
1859     /**
1860      * Controls whether new connections may cause creation of new SSL
1861      * sessions.
1862      *
1863      * As long as handshaking has not started, we can change
1864      * whether we enable session creations.  Otherwise,
1865      * we will need to wait for the next handshake.
1866      */
1867     @Override
1868     synchronized public void setEnableSessionCreation(boolean flag) {
1869         enableSessionCreation = flag;
1870 
1871         if ((handshaker != null) && !handshaker.activated()) {


1877      * Returns true if new connections may cause creation of new SSL
1878      * sessions.
1879      */
1880     @Override
1881     synchronized public boolean getEnableSessionCreation() {
1882         return enableSessionCreation;
1883     }
1884 
1885 
1886     /**
1887      * Sets the flag controlling whether a server mode engine
1888      * *REQUIRES* SSL client authentication.
1889      *
1890      * As long as handshaking has not started, we can change
1891      * whether client authentication is needed.  Otherwise,
1892      * we will need to wait for the next handshake.
1893      */
1894     @Override
1895     synchronized public void setNeedClientAuth(boolean flag) {
1896         doClientAuth = (flag ?
1897             SSLEngineImpl.clauth_required : SSLEngineImpl.clauth_none);

1898 
1899         if ((handshaker != null) &&
1900                 (handshaker instanceof ServerHandshaker) &&
1901                 !handshaker.activated()) {
1902             ((ServerHandshaker) handshaker).setClientAuth(doClientAuth);
1903         }
1904     }
1905 
1906     @Override
1907     synchronized public boolean getNeedClientAuth() {
1908         return (doClientAuth == SSLEngineImpl.clauth_required);
1909     }
1910 
1911     /**
1912      * Sets the flag controlling whether a server mode engine
1913      * *REQUESTS* SSL client authentication.
1914      *
1915      * As long as handshaking has not started, we can change
1916      * whether client authentication is requested.  Otherwise,
1917      * we will need to wait for the next handshake.
1918      */
1919     @Override
1920     synchronized public void setWantClientAuth(boolean flag) {
1921         doClientAuth = (flag ?
1922             SSLEngineImpl.clauth_requested : SSLEngineImpl.clauth_none);

1923 
1924         if ((handshaker != null) &&
1925                 (handshaker instanceof ServerHandshaker) &&
1926                 !handshaker.activated()) {
1927             ((ServerHandshaker) handshaker).setClientAuth(doClientAuth);
1928         }
1929     }
1930 
1931     @Override
1932     synchronized public boolean getWantClientAuth() {
1933         return (doClientAuth == SSLEngineImpl.clauth_requested);
1934     }
1935 
1936 
1937     /**
1938      * Sets the flag controlling whether the engine is in SSL
1939      * client or server mode.  Must be called before any SSL
1940      * traffic has started.
1941      */
1942     @Override
1943     @SuppressWarnings("fallthrough")
1944     synchronized public void setUseClientMode(boolean flag) {
1945         switch (connectionState) {
1946 
1947         case cs_START:
1948             /*
1949              * If we need to change the engine mode and the enabled
1950              * protocols haven't specifically been set by the user,
1951              * change them to the corresponding default ones.

1952              */
1953             if (roleIsServer != (!flag) &&
1954                     sslContext.isDefaultProtocolList(enabledProtocols)) {
1955                 enabledProtocols = sslContext.getDefaultProtocolList(!flag);

1956             }
1957 






1958             roleIsServer = !flag;
1959             serverModeSet = true;
1960             break;
1961 
1962         case cs_HANDSHAKE:
1963             /*
1964              * If we have a handshaker, but haven't started
1965              * SSL traffic, we can throw away our current
1966              * handshaker, and start from scratch.  Don't
1967              * need to call doneConnect() again, we already
1968              * have the streams.
1969              */
1970             assert(handshaker != null);
1971             if (!handshaker.activated()) {
1972                 /*
1973                  * If we need to change the engine mode and the enabled
1974                  * protocols haven't specifically been set by the user,
1975                  * change them to the corresponding default ones.

1976                  */
1977                 if (roleIsServer != (!flag) &&
1978                         sslContext.isDefaultProtocolList(enabledProtocols)) {
1979                     enabledProtocols = sslContext.getDefaultProtocolList(!flag);

1980                 }
1981 







1982                 roleIsServer = !flag;
1983                 connectionState = cs_START;
1984                 initHandshaker();
1985                 break;
1986             }
1987 
1988             // If handshake has started, that's an error.  Fall through...
1989 
1990         default:
1991             if (debug != null && Debug.isOn("ssl")) {
1992                 System.out.println(Thread.currentThread().getName() +
1993                     ", setUseClientMode() invoked in state = " +
1994                     connectionState);
1995             }
1996 
1997             /*
1998              * We can let them continue if they catch this correctly,
1999              * we don't need to shut this down.
2000              */
2001             throw new IllegalArgumentException(


2085     }
2086 
2087     @Override
2088     synchronized public String[] getEnabledProtocols() {
2089         return enabledProtocols.toStringArray();
2090     }
2091 
2092     /**
2093      * Returns the SSLParameters in effect for this SSLEngine.
2094      */
2095     @Override
2096     synchronized public SSLParameters getSSLParameters() {
2097         SSLParameters params = super.getSSLParameters();
2098 
2099         // the super implementation does not handle the following parameters
2100         params.setEndpointIdentificationAlgorithm(identificationProtocol);
2101         params.setAlgorithmConstraints(algorithmConstraints);
2102         params.setSNIMatchers(sniMatchers);
2103         params.setServerNames(serverNames);
2104         params.setUseCipherSuitesOrder(preferLocalCipherSuites);


2105 
2106         return params;
2107     }
2108 
2109     /**
2110      * Applies SSLParameters to this engine.
2111      */
2112     @Override
2113     synchronized public void setSSLParameters(SSLParameters params) {
2114         super.setSSLParameters(params);
2115 
2116         // the super implementation does not handle the following parameters
2117         identificationProtocol = params.getEndpointIdentificationAlgorithm();
2118         algorithmConstraints = params.getAlgorithmConstraints();
2119         preferLocalCipherSuites = params.getUseCipherSuitesOrder();


2120 







2121         List<SNIServerName> sniNames = params.getServerNames();
2122         if (sniNames != null) {
2123             serverNames = sniNames;
2124         }
2125 
2126         Collection<SNIMatcher> matchers = params.getSNIMatchers();
2127         if (matchers != null) {
2128             sniMatchers = matchers;
2129         }
2130 
2131         if ((handshaker != null) && !handshaker.started()) {
2132             handshaker.setIdentificationProtocol(identificationProtocol);
2133             handshaker.setAlgorithmConstraints(algorithmConstraints);

2134             if (roleIsServer) {
2135                 handshaker.setSNIMatchers(sniMatchers);
2136                 handshaker.setUseCipherSuitesOrder(preferLocalCipherSuites);
2137             } else {
2138                 handshaker.setSNIServerNames(serverNames);
2139             }
2140         }
2141     }
2142 
2143     /**
2144      * Returns a boolean indicating whether the ChangeCipherSpec message
2145      * has been received for this handshake.
2146      */
2147     boolean receivedChangeCipherSpec() {
2148         return receivedCCS;
2149     }
2150 
2151     /**
2152      * Returns a printable representation of this end of the connection.
2153      */
2154     @Override
2155     public String toString() {
2156         StringBuilder retval = new StringBuilder(80);
2157 
2158         retval.append(Integer.toHexString(hashCode()));
2159         retval.append("[");
2160         retval.append("SSLEngine[hostname=");
2161         String host = getPeerHost();
2162         retval.append((host == null) ? "null" : host);
2163         retval.append(" port=");
2164         retval.append(Integer.toString(getPeerPort()));

2165         retval.append("] ");
2166         retval.append(getSession().getCipherSuite());
2167         retval.append("]");
2168 
2169         return retval.toString();
2170     }
2171 }


  37 
  38 /**
  39  * Implementation of an non-blocking SSLEngine.
  40  *
  41  * *Currently*, the SSLEngine code exists in parallel with the current
  42  * SSLSocket.  As such, the current implementation is using legacy code
  43  * with many of the same abstractions.  However, it varies in many
  44  * areas, most dramatically in the IO handling.
  45  *
  46  * There are three main I/O threads that can be existing in parallel:
  47  * wrap(), unwrap(), and beginHandshake().  We are encouraging users to
  48  * not call multiple instances of wrap or unwrap, because the data could
  49  * appear to flow out of the SSLEngine in a non-sequential order.  We
  50  * take all steps we can to at least make sure the ordering remains
  51  * consistent, but once the calls returns, anything can happen.  For
  52  * example, thread1 and thread2 both call wrap, thread1 gets the first
  53  * packet, thread2 gets the second packet, but thread2 gets control back
  54  * before thread1, and sends the data.  The receiving side would see an
  55  * out-of-order error.
  56  *



















































  57  * @author Brad Wetmore
  58  */
  59 final public class SSLEngineImpl extends SSLEngine {
  60 
  61     //
  62     // Fields and global comments
  63     //
  64 
  65     /*
  66      * There's a state machine associated with each connection, which
  67      * among other roles serves to negotiate session changes.
  68      *
  69      * - START with constructor, until the TCP connection's around.
  70      * - HANDSHAKE picks session parameters before allowing traffic.
  71      *          There are many substates due to sequencing requirements
  72      *          for handshake messages.
  73      * - DATA may be transmitted.
  74      * - RENEGOTIATE state allows concurrent data and handshaking
  75      *          traffic ("same" substates as HANDSHAKE), and terminates
  76      *          in selection of new session (and connection) parameters


 107      *                v                                     |
 108      *               ERROR>------>----->CLOSED<--------<----+
 109      *
 110      * ALSO, note that the purpose of handshaking (renegotiation is
 111      * included) is to assign a different, and perhaps new, session to
 112      * the connection.  The SSLv3 spec is a bit confusing on that new
 113      * protocol feature.
 114      */
 115     private int                 connectionState;
 116 
 117     private static final int    cs_START = 0;
 118     private static final int    cs_HANDSHAKE = 1;
 119     private static final int    cs_DATA = 2;
 120     private static final int    cs_RENEGOTIATE = 3;
 121     private static final int    cs_ERROR = 4;
 122     private static final int    cs_CLOSED = 6;
 123 
 124     /*
 125      * Once we're in state cs_CLOSED, we can continue to
 126      * wrap/unwrap until we finish sending/receiving the messages
 127      * for close_notify.
 128      */
 129     private boolean             inboundDone = false;
 130     private boolean             outboundDone = false;
 131 


 132     /*
 133      * The authentication context holds all information used to establish
 134      * who this end of the connection is (certificate chains, private keys,
 135      * etc) and who is trusted (e.g. as CAs or websites).
 136      */
 137     private SSLContextImpl      sslContext;
 138 
 139     /*
 140      * This connection is one of (potentially) many associated with
 141      * any given session.  The output of the handshake protocol is a
 142      * new session ... although all the protocol description talks
 143      * about changing the cipher spec (and it does change), in fact
 144      * that's incidental since it's done by changing everything that
 145      * is associated with a session at the same time.  (TLS/IETF may
 146      * change that to add client authentication w/o new key exchg.)
 147      */
 148     private Handshaker                  handshaker;
 149     private SSLSessionImpl              sess;
 150     private volatile SSLSessionImpl     handshakeSession;
 151 

 152     /*














 153      * Flag indicating if the next record we receive MUST be a Finished
 154      * message. Temporarily set during the handshake to ensure that
 155      * a change cipher spec message is followed by a finished message.
 156      */
 157     private boolean             expectingFinished;
 158 
 159 
 160     /*
 161      * If someone tries to closeInbound() (say at End-Of-Stream)
 162      * our engine having received a close_notify, we need to
 163      * notify the app that we may have a truncation attack underway.
 164      */
 165     private boolean             recvCN;
 166 
 167     /*
 168      * For improved diagnostics, we detail connection closure
 169      * If the engine is closed (connectionState >= cs_ERROR),
 170      * closeReason != null indicates if the engine was closed
 171      * because of an error or because or normal shutdown.
 172      */
 173     private SSLException        closeReason;
 174 
 175     /*
 176      * Per-connection private state that doesn't change when the
 177      * session is changed.
 178      */
 179     private ClientAuthType          doClientAuth =
 180                                             ClientAuthType.CLIENT_AUTH_NONE;
 181     private boolean                 enableSessionCreation = true;
 182     InputRecord                     inputRecord;
 183     OutputRecord                    outputRecord;
 184     private AccessControlContext    acc;
 185 
 186     // The cipher suites enabled for use on this connection.
 187     private CipherSuiteList             enabledCipherSuites;
 188 
 189     // the endpoint identification protocol
 190     private String                      identificationProtocol = null;
 191 
 192     // The cryptographic algorithm constraints
 193     private AlgorithmConstraints        algorithmConstraints = null;
 194 
 195     // The server name indication and matchers
 196     List<SNIServerName>         serverNames =
 197                                     Collections.<SNIServerName>emptyList();
 198     Collection<SNIMatcher>      sniMatchers =
 199                                     Collections.<SNIMatcher>emptyList();
 200 
 201     // Have we been told whether we're client or server?
 202     private boolean                     serverModeSet = false;
 203     private boolean                     roleIsServer;
 204 
 205     /*
 206      * The protocol versions enabled for use on this connection.
 207      *
 208      * Note: we support a pseudo protocol called SSLv2Hello which when
 209      * set will result in an SSL v2 Hello being sent with SSL (version 3.0)
 210      * or TLS (version 3.1, 3.2, etc.) version info.
 211      */
 212     private ProtocolList        enabledProtocols;
 213 
 214     /*
 215      * The SSL version associated with this connection.
 216      */
 217     private ProtocolVersion     protocolVersion;
 218 
 219     /*







 220      * security parameters for secure renegotiation.
 221      */
 222     private boolean             secureRenegotiation;
 223     private byte[]              clientVerifyData;
 224     private byte[]              serverVerifyData;
 225 
 226     /*
 227      * READ ME * READ ME * READ ME * READ ME * READ ME * READ ME *
 228      * IMPORTANT STUFF TO UNDERSTANDING THE SYNCHRONIZATION ISSUES.
 229      * READ ME * READ ME * READ ME * READ ME * READ ME * READ ME *
 230      *
 231      * There are several locks here.
 232      *
 233      * The primary lock is the per-instance lock used by
 234      * synchronized(this) and the synchronized methods.  It controls all
 235      * access to things such as the connection state and variables which
 236      * affect handshaking.  If we are inside a synchronized method, we
 237      * can access the state directly, otherwise, we must use the
 238      * synchronized equivalents.
 239      *
 240      * Note that we must never acquire the <code>this</code> lock after
 241      * <code>writeLock</code> or run the risk of deadlock.
 242      *
 243      * Grab some coffee, and be careful with any code changes.
 244      */
 245     private Object              wrapLock;
 246     private Object              unwrapLock;
 247     Object                      writeLock;
 248 
 249     /*





 250      * Whether local cipher suites preference in server side should be
 251      * honored during handshaking?
 252      */
 253     private boolean preferLocalCipherSuites = false;
 254 
 255     /*
 256      * whether DTLS handshake retransmissions should be enabled?
 257      */
 258     private boolean enableRetransmissions = false;
 259 
 260     /*
 261      * The maximum expected network packet size for SSL/TLS/DTLS records.
 262      */
 263     private int maximumPacketSize = 0;
 264 
 265     /*
 266      * Is this an instance for Datagram Transport Layer Security (DTLS)?
 267      */
 268     private final boolean isDTLS;
 269 
 270     /*
 271      * Class and subclass dynamic debugging support
 272      */
 273     private static final Debug debug = Debug.getInstance("ssl");
 274 
 275     //
 276     // Initialization/Constructors
 277     //
 278 
 279     /**
 280      * Constructor for an SSLEngine from SSLContext, without
 281      * host/port hints.  This Engine will not be able to cache
 282      * sessions, but must renegotiate everything by hand.
 283      */
 284     SSLEngineImpl(SSLContextImpl ctx, boolean isDTLS) {
 285         super();
 286         this.isDTLS = isDTLS;
 287         init(ctx, isDTLS);
 288     }
 289 
 290     /**
 291      * Constructor for an SSLEngine from SSLContext.
 292      */
 293     SSLEngineImpl(SSLContextImpl ctx, String host, int port, boolean isDTLS) {
 294         super(host, port);
 295         this.isDTLS = isDTLS;
 296         init(ctx, isDTLS);
 297     }
 298 
 299     /**
 300      * Initializes the Engine
 301      */
 302     private void init(SSLContextImpl ctx, boolean isDTLS) {
 303         if (debug != null && Debug.isOn("ssl")) {
 304             System.out.println("Using SSLEngineImpl.");
 305         }
 306 
 307         sslContext = ctx;
 308         sess = SSLSessionImpl.nullSession;
 309         handshakeSession = null;
 310         protocolVersion = isDTLS ?
 311                 ProtocolVersion.DEFAULT_DTLS : ProtocolVersion.DEFAULT_TLS;
 312 
 313         /*
 314          * State is cs_START until we initialize the handshaker.
 315          *
 316          * Apps using SSLEngine are probably going to be server.
 317          * Somewhat arbitrary choice.
 318          */
 319         roleIsServer = true;
 320         connectionState = cs_START;

 321 
 322         // default server name indication
 323         serverNames =
 324             Utilities.addToSNIServerNameList(serverNames, getPeerHost());
 325 










 326         // default security parameters for secure renegotiation
 327         secureRenegotiation = false;
 328         clientVerifyData = new byte[0];
 329         serverVerifyData = new byte[0];
 330 
 331         enabledCipherSuites =
 332                 sslContext.getDefaultCipherSuiteList(roleIsServer);
 333         enabledProtocols =
 334                 sslContext.getDefaultProtocolList(roleIsServer);
 335 
 336         wrapLock = new Object();
 337         unwrapLock = new Object();
 338         writeLock = new Object();
 339 
 340         /*
 341          * Save the Access Control Context.  This will be used later
 342          * for a couple of things, including providing a context to
 343          * run tasks in, and for determining which credentials
 344          * to use for Subject based (JAAS) decisions
 345          */
 346         acc = AccessController.getContext();
 347 
 348         /*
 349          * All outbound application data goes through this OutputRecord,
 350          * other data goes through their respective records created
 351          * elsewhere.  All inbound data goes through this one
 352          * input record.
 353          */
 354         if (isDTLS) {
 355             enableRetransmissions = true;


 356 
 357             // SSLEngine needs no record local buffer
 358             outputRecord = new DTLSOutputRecord();
 359             inputRecord = new DTLSInputRecord();
 360 
 361         } else {
 362             outputRecord = new SSLEngineOutputRecord();
 363             inputRecord = new SSLEngineInputRecord();
 364         }
 365 
 366         maximumPacketSize = outputRecord.getMaxPacketSize();
 367     }
 368 
 369     /**
 370      * Initialize the handshaker object. This means:
 371      *
 372      *  . if a handshake is already in progress (state is cs_HANDSHAKE
 373      *    or cs_RENEGOTIATE), do nothing and return
 374      *
 375      *  . if the engine is already closed, throw an Exception (internal error)
 376      *
 377      *  . otherwise (cs_START or cs_DATA), create the appropriate handshaker
 378      *    object and advance the connection state (to cs_HANDSHAKE or
 379      *    cs_RENEGOTIATE, respectively).
 380      *
 381      * This method is called right after a new engine is created, when
 382      * starting renegotiation, or when changing client/server mode of the
 383      * engine.
 384      */
 385     private void initHandshaker() {
 386         switch (connectionState) {
 387 
 388         //


 400             return;
 401 
 402         //
 403         // Anyone allowed to call this routine is required to
 404         // do so ONLY if the connection state is reasonable...
 405         //
 406         default:
 407             throw new IllegalStateException("Internal error");
 408         }
 409 
 410         // state is either cs_START or cs_DATA
 411         if (connectionState == cs_START) {
 412             connectionState = cs_HANDSHAKE;
 413         } else { // cs_DATA
 414             connectionState = cs_RENEGOTIATE;
 415         }
 416         if (roleIsServer) {
 417             handshaker = new ServerHandshaker(this, sslContext,
 418                     enabledProtocols, doClientAuth,
 419                     protocolVersion, connectionState == cs_HANDSHAKE,
 420                     secureRenegotiation, clientVerifyData, serverVerifyData,
 421                     isDTLS);
 422             handshaker.setSNIMatchers(sniMatchers);
 423             handshaker.setUseCipherSuitesOrder(preferLocalCipherSuites);
 424         } else {
 425             handshaker = new ClientHandshaker(this, sslContext,
 426                     enabledProtocols,
 427                     protocolVersion, connectionState == cs_HANDSHAKE,
 428                     secureRenegotiation, clientVerifyData, serverVerifyData,
 429                     isDTLS);
 430             handshaker.setSNIServerNames(serverNames);
 431         }
 432         handshaker.setMaximumPacketSize(maximumPacketSize);
 433         handshaker.setEnabledCipherSuites(enabledCipherSuites);
 434         handshaker.setEnableSessionCreation(enableSessionCreation);
 435 
 436         outputRecord.initHandshaker();
 437     }
 438 
 439     /*
 440      * Report the current status of the Handshaker
 441      */
 442     private HandshakeStatus getHSStatus(HandshakeStatus hss) {
 443 
 444         if (hss != null) {
 445             return hss;
 446         }
 447 
 448         synchronized (this) {
 449             if (!outputRecord.isEmpty()) {
 450                 // If no handshaking, special case to wrap alters.
 451                 return HandshakeStatus.NEED_WRAP;
 452             } else if (handshaker != null) {
 453                 if (handshaker.taskOutstanding()) {
 454                     return HandshakeStatus.NEED_TASK;
 455                 } else if (isDTLS && !inputRecord.isEmpty()) {
 456                     return HandshakeStatus.NEED_UNWRAP_AGAIN;
 457                 } else {
 458                     return HandshakeStatus.NEED_UNWRAP;
 459                 }
 460             } else if (connectionState == cs_CLOSED) {
 461                 /*
 462                  * Special case where we're closing, but
 463                  * still need the close_notify before we
 464                  * can officially be closed.
 465                  *
 466                  * Note isOutboundDone is taken care of by
 467                  * hasOutboundData() above.
 468                  */
 469                 if (!isInboundDone()) {
 470                     return HandshakeStatus.NEED_UNWRAP;
 471                 } // else not handshaking
 472             }
 473 
 474             return HandshakeStatus.NOT_HANDSHAKING;
 475         }
 476     }


 500     /*
 501      * Get the Access Control Context.
 502      *
 503      * Used for a known context to
 504      * run tasks in, and for determining which credentials
 505      * to use for Subject-based (JAAS) decisions.
 506      */
 507     AccessControlContext getAcc() {
 508         return acc;
 509     }
 510 
 511     /*
 512      * Is a handshake currently underway?
 513      */
 514     @Override
 515     public SSLEngineResult.HandshakeStatus getHandshakeStatus() {
 516         return getHSStatus(null);
 517     }
 518 
 519     /*













































 520      * used by Handshaker to change the active write cipher, follows
 521      * the output of the CCS message.
 522      *
 523      * Also synchronized on "this" from readRecord/delegatedTask.
 524      */
 525     void changeWriteCiphers() throws IOException {





 526 
 527         Authenticator writeAuthenticator;
 528         CipherBox writeCipher;


 529         try {
 530             writeCipher = handshaker.newWriteCipher();
 531             writeAuthenticator = handshaker.newWriteAuthenticator();
 532         } catch (GeneralSecurityException e) {
 533             // "can't happen"
 534             throw new SSLException("Algorithm missing:  ", e);
 535         }
 536 
 537         outputRecord.changeWriteCiphers(writeAuthenticator, writeCipher);




 538     }
 539 
 540     /*
 541      * Updates the SSL version associated with this connection.
 542      * Called from Handshaker once it has determined the negotiated version.
 543      */
 544     synchronized void setVersion(ProtocolVersion protocolVersion) {
 545         this.protocolVersion = protocolVersion;
 546         outputRecord.setVersion(protocolVersion);
 547     }
 548 
 549 
 550     /**
 551      * Kickstart the handshake if it is not already in progress.
 552      * This means:
 553      *
 554      *  . if handshaking is already underway, do nothing and return
 555      *
 556      *  . if the engine is not connected or already closed, throw an
 557      *    Exception.


 588                         "Warning: Using insecure renegotiation");
 589                 }
 590             }
 591 
 592             // initialize the handshaker, move to cs_RENEGOTIATE
 593             initHandshaker();
 594             break;
 595 
 596         case cs_RENEGOTIATE:
 597             // handshaking already in progress, return
 598             return;
 599 
 600         default:
 601             // cs_ERROR/cs_CLOSED
 602             throw new SSLException("SSLEngine is closing/closed");
 603         }
 604 
 605         //
 606         // Kickstart handshake state machine if we need to ...
 607         //




 608         if (!handshaker.activated()) {
 609              // prior to handshaking, activate the handshake
 610             if (connectionState == cs_RENEGOTIATE) {
 611                 // don't use SSLv2Hello when renegotiating
 612                 handshaker.activate(protocolVersion);
 613             } else {
 614                 handshaker.activate(null);
 615             }
 616 
 617             if (handshaker instanceof ClientHandshaker) {
 618                 // send client hello
 619                 handshaker.kickstart();
 620             } else {    // instanceof ServerHandshaker
 621                 if (connectionState == cs_HANDSHAKE) {
 622                     // initial handshake, no kickstart message to send
 623                 } else {
 624                     // we want to renegotiate, send hello request
 625                     handshaker.kickstart();




 626                 }
 627             }
 628         }
 629     }
 630 
 631     /*
 632      * Start a SSLEngine handshake
 633      */
 634     @Override
 635     public void beginHandshake() throws SSLException {
 636         try {
 637             kickstartHandshake();
 638         } catch (Exception e) {
 639             fatal(Alerts.alert_handshake_failure,
 640                 "Couldn't kickstart handshaking", e);
 641         }
 642     }
 643 
 644 
 645     //
 646     // Read/unwrap side
 647     //
 648 
 649 
 650     /**
 651      * Unwraps a buffer.  Does a variety of checks before grabbing
 652      * the unwrapLock, which blocks multiple unwraps from occurring.
 653      */
 654     @Override
 655     public SSLEngineResult unwrap(ByteBuffer netData, ByteBuffer[] appData,
 656             int offset, int length) throws SSLException {
 657 
 658         // check engine parameters
 659         checkEngineParas(netData, appData, offset, length, false);
 660 
 661         try {
 662             synchronized (unwrapLock) {
 663                 return readNetRecord(netData, appData, offset, length);
 664             }
 665         } catch (SSLProtocolException spe) {
 666             // may be an unexpected handshake message
 667             fatal(Alerts.alert_unexpected_message, spe.getMessage(), spe);
 668             return null;  // make compiler happy
 669         } catch (Exception e) {
 670             /*
 671              * Don't reset position so it looks like we didn't
 672              * consume anything.  We did consume something, and it
 673              * got us into this situation, so report that much back.
 674              * Our days of consuming are now over anyway.
 675              */
 676             fatal(Alerts.alert_internal_error,
 677                 "problem unwrapping net record", e);
 678             return null;  // make compiler happy
 679         }
 680     }
 681 
 682     private static void checkEngineParas(ByteBuffer netData,
 683             ByteBuffer[] appData, int offset, int len, boolean isForWrap) {
 684 
 685         if ((netData == null) || (appData == null)) {
 686             throw new IllegalArgumentException("src/dst is null");
 687         }
 688 
 689         if ((offset < 0) || (len < 0) || (offset > appData.length - len)) {
 690             throw new IndexOutOfBoundsException();
 691         }
 692 
 693         /*
 694          * If wrapping, make sure the destination bufffer is writable.
 695          */
 696         if (isForWrap && netData.isReadOnly()) {
 697             throw new ReadOnlyBufferException();
 698         }
 699 
 700         for (int i = offset; i < offset + len; i++) {
 701             if (appData[i] == null) {
 702                 throw new IllegalArgumentException(
 703                         "appData[" + i + "] == null");
 704             }
 705 
 706             /*
 707              * If unwrapping, make sure the destination bufffers are writable.
 708              */
 709             if (!isForWrap && appData[i].isReadOnly()) {
 710                 throw new ReadOnlyBufferException();
 711             }
 712         }
 713     }
 714 
 715     /*
 716      * Makes additional checks for unwrap, but this time more
 717      * specific to this packet and the current state of the machine.
 718      */
 719     private SSLEngineResult readNetRecord(ByteBuffer netData,
 720             ByteBuffer[] appData, int offset, int length) throws IOException {
 721 
 722         Status status = null;
 723         HandshakeStatus hsStatus = null;
 724 
 725         /*
 726          * See if the handshaker needs to report back some SSLException.
 727          */
 728         checkTaskThrown();
 729 
 730         /*
 731          * Check if we are closing/closed.
 732          */
 733         if (isInboundDone()) {
 734             return new SSLEngineResult(Status.CLOSED, getHSStatus(null), 0, 0);
 735         }
 736 
 737         /*
 738          * If we're still in cs_HANDSHAKE, make sure it's been
 739          * started.
 740          */


 755             }
 756         }
 757 
 758         /*
 759          * Grab a copy of this if it doesn't already exist,
 760          * and we can use it several places before anything major
 761          * happens on this side.  Races aren't critical
 762          * here.
 763          */
 764         if (hsStatus == null) {
 765             hsStatus = getHSStatus(null);
 766         }
 767 
 768         /*
 769          * If we have a task outstanding, this *MUST* be done before
 770          * doing any more unwrapping, because we could be in the middle
 771          * of receiving a handshake message, for example, a finished
 772          * message which would change the ciphers.
 773          */
 774         if (hsStatus == HandshakeStatus.NEED_TASK) {
 775             return new SSLEngineResult(Status.OK, hsStatus, 0, 0);
 776         }
 777 
 778         if (hsStatus == SSLEngineResult.HandshakeStatus.NEED_UNWRAP_AGAIN) {
 779             Plaintext plainText = null;
 780             try {
 781                 plainText = readRecord(null, null, 0, 0);
 782             } catch (SSLException e) {
 783                 throw e;
 784             } catch (IOException e) {
 785                 throw new SSLException("readRecord", e);
 786             }
 787 
 788             status = (isInboundDone() ? Status.CLOSED : Status.OK);
 789             hsStatus = getHSStatus(plainText.handshakeStatus);
 790 
 791             return new SSLEngineResult(
 792                     status, hsStatus, 0, 0, plainText.recordSN);
 793         }
 794 
 795         /*
 796          * Check the packet to make sure enough is here.
 797          * This will also indirectly check for 0 len packets.
 798          */
 799         int packetLen = 0;
 800         try {
 801             packetLen = inputRecord.bytesInCompletePacket(netData);
 802         } catch (SSLException ssle) {
 803             // Need to discard invalid records for DTLS protocols.
 804             if (isDTLS) {
 805                 if (debug != null && Debug.isOn("ssl")) {
 806                     System.out.println(
 807                         Thread.currentThread().getName() +
 808                         " discard invalid record: " + ssle);
 809                 }
 810 
 811                 // invalid, discard the entire data [section 4.1.2.7, RFC 6347]
 812                 int deltaNet = netData.remaining();
 813                 netData.position(netData.limit());
 814 
 815                 status = (isInboundDone() ? Status.CLOSED : Status.OK);
 816                 hsStatus = getHSStatus(hsStatus);
 817 
 818                 return new SSLEngineResult(status, hsStatus, deltaNet, 0, -1L);
 819             } else {
 820                 throw ssle;
 821             }
 822         }
 823 
 824         // Is this packet bigger than SSL/TLS normally allows?
 825         if (packetLen > sess.getPacketBufferSize()) {
 826             int largestRecordSize = isDTLS ?
 827                     DTLSRecord.maxRecordSize : SSLRecord.maxLargeRecordSize;
 828             if ((packetLen <= largestRecordSize) && !isDTLS) {



 829                 // Expand the expected maximum packet/application buffer
 830                 // sizes.
 831                 //
 832                 // Only apply to SSL/TLS protocols.
 833 
 834                 // Old behavior: shall we honor the System Property
 835                 // "jsse.SSLEngine.acceptLargeFragments" if it is "false"?
 836                 sess.expandBufferSizes();
 837             }
 838 
 839             // check the packet again
 840             largestRecordSize = sess.getPacketBufferSize();
 841             if (packetLen > largestRecordSize) {
 842                 throw new SSLProtocolException(
 843                         "Input record too big: max = " +
 844                         largestRecordSize + " len = " + packetLen);
 845             }
 846         }
 847 
 848         int netPos = netData.position();
 849         int appRemains = 0;
 850         for (int i = offset; i < offset + length; i++) {
 851             if (appData[i] == null) {
 852                 throw new IllegalArgumentException(
 853                         "appData[" + i + "] == null");
 854             }
 855             appRemains += appData[i].remaining();
 856         }
 857 
 858         /*
 859          * Check for OVERFLOW.
 860          *
 861          * Delay enforcing the application buffer free space requirement
 862          * until after the initial handshaking.
 863          */
 864         // synchronize connectionState?
 865         if ((connectionState == cs_DATA) ||
 866                 (connectionState == cs_RENEGOTIATE)) {
 867 
 868             int FragLen = inputRecord.estimateFragmentSize(packetLen);
 869             if (FragLen > appRemains) {
 870                 return new SSLEngineResult(
 871                         Status.BUFFER_OVERFLOW, hsStatus, 0, 0);
 872             }
 873         }
 874 
 875         // check for UNDERFLOW.
 876         if ((packetLen == -1) || (netData.remaining() < packetLen)) {
 877             return new SSLEngineResult(Status.BUFFER_UNDERFLOW, hsStatus, 0, 0);

 878         }
 879 
 880         /*
 881          * We're now ready to actually do the read.



 882          */
 883         Plaintext plainText = null;
 884         try {
 885             plainText = readRecord(netData, appData, offset, length);
 886         } catch (SSLException e) {
 887             throw e;
 888         } catch (IOException e) {
 889             throw new SSLException("readRecord", e);
 890         }
 891 
 892         /*
 893          * Check the various condition that we could be reporting.
 894          *
 895          * It's *possible* something might have happened between the
 896          * above and now, but it was better to minimally lock "this"
 897          * during the read process.  We'll return the current
 898          * status, which is more representative of the current state.
 899          *
 900          * status above should cover:  FINISHED, NEED_TASK
 901          */
 902         status = (isInboundDone() ? Status.CLOSED : Status.OK);
 903         hsStatus = getHSStatus(plainText.handshakeStatus);
 904 
 905         int deltaNet = netData.position() - netPos;
 906         int deltaApp = appRemains;
 907         for (int i = offset; i < offset + length; i++) {
 908             deltaApp -= appData[i].remaining();
 909         }
 910 
 911         return new SSLEngineResult(
 912                 status, hsStatus, deltaNet, deltaApp, plainText.recordSN);
 913     }
 914 
 915     // the caller have synchronized readLock
 916     void expectingFinishFlight() {
 917         inputRecord.expectingFinishFlight();
 918     }
 919 
 920     /*
 921      * Actually do the read record processing.
 922      *
 923      * Returns a Status if it can make specific determinations
 924      * of the engine state.  In particular, we need to signal
 925      * that a handshake just completed.
 926      *
 927      * It would be nice to be symmetrical with the write side and move
 928      * the majority of this to SSLInputRecord, but there's too much
 929      * SSLEngine state to do that cleanly.  It must still live here.
 930      */
 931     private Plaintext readRecord(ByteBuffer netData,
 932             ByteBuffer[] appData, int offset, int length) throws IOException {
 933 


 934         /*
 935          * The various operations will return new sliced BB's,
 936          * this will avoid having to worry about positions and
 937          * limits in the netBB.
 938          */
 939         Plaintext plainText = null;

 940 
 941         if (getConnectionState() == cs_ERROR) {
 942             return Plaintext.PLAINTEXT_NULL;
 943         }
 944 
 945         /*
 946          * Read a record ... maybe emitting an alert if we get a
 947          * comprehensible but unsupported "hello" message during
 948          * format checking (e.g. V2).
 949          */
 950         try {
 951             if (isDTLS) {
 952                 // Don't process the incoming record until all of the
 953                 // buffered records get handled.
 954                 plainText = inputRecord.acquirePlaintext();
 955             }
 956 
 957             if ((!isDTLS || plainText == null) && netData != null) {
 958                 plainText = inputRecord.decode(netData);
 959             }
 960         } catch (UnsupportedOperationException unsoe) {         // SSLv2Hello
 961             // Hack code to deliver SSLv2 error message for SSL/TLS connections.
 962             if (!isDTLS) {
 963                 outputRecord.encodeV2NoCipher();
 964             }
 965 
 966             fatal(Alerts.alert_unexpected_message, unsoe);
 967         } catch (BadPaddingException e) {
 968             /*
 969              * The basic SSLv3 record protection involves (optional)
 970              * encryption for privacy, and an integrity check ensuring
 971              * data origin authentication.  We do them both here, and
 972              * throw a fatal alert if the integrity check fails.
 973              */
 974             byte alertType = (connectionState != cs_DATA) ?





 975                     Alerts.alert_handshake_failure :
 976                     Alerts.alert_bad_record_mac;
 977             fatal(alertType, e.getMessage(), e);
 978         } catch (SSLHandshakeException she) {
 979             // may be record sequence number overflow
 980             fatal(Alerts.alert_handshake_failure, she);
 981         } catch (IOException ioe) {
 982             fatal(Alerts.alert_unexpected_message, ioe);
 983         }
 984 
 985         // plainText should never be null for TLS protocols
 986         HandshakeStatus hsStatus = null;
 987         if (!isDTLS || plainText != null) {
 988             hsStatus = processInputRecord(plainText, appData, offset, length);
 989         }
 990 
 991         if (hsStatus == null) {
 992             hsStatus = getHSStatus(null);
 993         }
 994 
 995         if (plainText == null) {
 996             plainText = new Plaintext();
 997         }
 998         plainText.handshakeStatus = hsStatus;
 999 
1000         return plainText;
1001     }
1002 
1003     /*
1004      * Process the record.
1005      */
1006     private synchronized HandshakeStatus processInputRecord(
1007             Plaintext plainText,
1008             ByteBuffer[] appData, int offset, int length) throws IOException {
1009 
1010         HandshakeStatus hsStatus = null;
1011         switch (plainText.contentType) {
1012             case Record.ct_handshake:
1013                 /*
1014                  * Handshake messages always go to a pending session
1015                  * handshaker ... if there isn't one, create one.  This
1016                  * must work asynchronously, for renegotiation.
1017                  *
1018                  * NOTE that handshaking will either resume a session
1019                  * which was in the cache (and which might have other
1020                  * connections in it already), or else will start a new
1021                  * session (new keys exchanged) with just this connection
1022                  * in it.
1023                  */
1024                 initHandshaker();
1025                 if (!handshaker.activated()) {
1026                     // prior to handshaking, activate the handshake
1027                     if (connectionState == cs_RENEGOTIATE) {
1028                         // don't use SSLv2Hello when renegotiating
1029                         handshaker.activate(protocolVersion);
1030                     } else {
1031                         handshaker.activate(null);
1032                     }
1033                 }
1034 
1035                 /*
1036                  * process the handshake record ... may contain just
1037                  * a partial handshake message or multiple messages.
1038                  *
1039                  * The handshaker state machine will ensure that it's
1040                  * a finished message.
1041                  */
1042                 handshaker.processRecord(plainText.fragment, expectingFinished);
1043                 expectingFinished = false;
1044 
1045                 if (handshaker.invalidated) {
1046                     finishHandshake();
1047 
1048                     // if state is cs_RENEGOTIATE, revert it to cs_DATA
1049                     if (connectionState == cs_RENEGOTIATE) {
1050                         connectionState = cs_DATA;
1051                     }
1052                 } else if (handshaker.isDone()) {
1053                     // reset the parameters for secure renegotiation.
1054                     secureRenegotiation =
1055                                 handshaker.isSecureRenegotiation();
1056                     clientVerifyData = handshaker.getClientVerifyData();
1057                     serverVerifyData = handshaker.getServerVerifyData();
1058 
1059                     sess = handshaker.getSession();
1060                     handshakeSession = null;
1061                     if (outputRecord.isEmpty()) {
1062                         hsStatus = finishHandshake();


1063                         connectionState = cs_DATA;
1064                     }
1065 
1066                     // No handshakeListeners here.  That's a
1067                     // SSLSocket thing.
1068                 } else if (handshaker.taskOutstanding()) {
1069                     hsStatus = HandshakeStatus.NEED_TASK;
1070                 }
1071                 break;
1072 
1073             case Record.ct_application_data:
1074                 // Pass this right back up to the application.
1075                 if ((connectionState != cs_DATA)
1076                         && (connectionState != cs_RENEGOTIATE)
1077                         && (connectionState != cs_CLOSED)) {
1078                     throw new SSLProtocolException(
1079                             "Data received in non-data state: " +
1080                             connectionState);
1081                 }
1082 
1083                 if (expectingFinished) {
1084                     throw new SSLProtocolException
1085                             ("Expecting finished message, received data");
1086                 }
1087 




1088                 if (!inboundDone) {
1089                     ByteBuffer fragment = plainText.fragment;
1090                     int remains = fragment.remaining();
1091 
1092                     // Should have enough room in appData.
1093                     for (int i = offset;
1094                             ((i < (offset + length)) && (remains > 0)); i++) {
1095                         int amount = Math.min(appData[i].remaining(), remains);
1096                         fragment.limit(fragment.position() + amount);
1097                         appData[i].put(fragment);
1098                         remains -= amount;
1099                     }
1100                 }
1101 
1102                 break;
1103 
1104             case Record.ct_alert:
1105                 recvAlert(plainText.fragment);
1106                 break;
1107 
1108             case Record.ct_change_cipher_spec:
1109                 if ((connectionState != cs_HANDSHAKE
1110                         && connectionState != cs_RENEGOTIATE)) {


1111                     // For the CCS message arriving in the wrong state
1112                     fatal(Alerts.alert_unexpected_message,
1113                             "illegal change cipher spec msg, conn state = "
1114                             + connectionState);
1115                 } else if (plainText.fragment.remaining() != 1
1116                         || plainText.fragment.get() != 1) {

1117                     // For structural/content issues with the CCS
1118                     fatal(Alerts.alert_unexpected_message,
1119                             "Malformed change cipher spec msg");
1120                 }
1121 





1122                 //
1123                 // The first message after a change_cipher_spec
1124                 // record MUST be a "Finished" handshake record,
1125                 // else it's a protocol violation.  We force this
1126                 // to be checked by a minor tweak to the state
1127                 // machine.
1128                 //
1129                 handshaker.receiveChangeCipherSpec();
1130 
1131                 CipherBox readCipher;
1132                 Authenticator readAuthenticator;
1133                 try {
1134                     readCipher = handshaker.newReadCipher();
1135                     readAuthenticator = handshaker.newReadAuthenticator();
1136                 } catch (GeneralSecurityException e) {
1137                     // can't happen
1138                     throw new SSLException("Algorithm missing:  ", e);
1139                 }
1140                 inputRecord.changeReadCiphers(readAuthenticator, readCipher);
1141 
1142                 // next message MUST be a finished message
1143                 expectingFinished = true;
1144                 break;
1145 
1146             default:
1147                 //
1148                 // TLS requires that unrecognized records be ignored.
1149                 //
1150                 if (debug != null && Debug.isOn("ssl")) {
1151                     System.out.println(Thread.currentThread().getName() +
1152                             ", Received record type: " + plainText.contentType);

1153                 }
1154                 break;
1155         } // switch
1156 
1157         /*
1158          * We only need to check the sequence number state for
1159          * non-handshaking record.
1160          *
1161          * Note that in order to maintain the handshake status
1162          * properly, we check the sequence number after the last
1163          * record reading process. As we request renegotiation
1164          * or close the connection for wrapped sequence number
1165          * when there is enough sequence number space left to
1166          * handle a few more records, so the sequence number
1167          * of the last record cannot be wrapped.
1168          */
1169         hsStatus = getHSStatus(hsStatus);
1170         if (connectionState < cs_ERROR && !isInboundDone() &&
1171                 (hsStatus == HandshakeStatus.NOT_HANDSHAKING) &&
1172                 (inputRecord.seqNumIsHuge())) {
1173             /*
1174              * Ask for renegotiation when need to renew sequence number.
1175              *
1176              * Don't bother to kickstart the renegotiation when the local is
1177              * asking for it.
1178              */
1179             if (debug != null && Debug.isOn("ssl")) {
1180                 System.out.println(Thread.currentThread().getName() +
1181                         ", request renegotiation " +
1182                         "to avoid sequence number overflow");
1183             }
1184 
1185             beginHandshake();
1186 
1187             hsStatus = getHSStatus(null);
1188         }



1189 
1190         return hsStatus;
1191     }
1192 
1193 
1194     //
1195     // write/wrap side
1196     //
1197 
1198 
1199     /**
1200      * Wraps a buffer.  Does a variety of checks before grabbing
1201      * the wrapLock, which blocks multiple wraps from occurring.
1202      */
1203     @Override
1204     public SSLEngineResult wrap(ByteBuffer[] appData,
1205             int offset, int length, ByteBuffer netData) throws SSLException {
1206 
1207         // check engine parameters
1208         checkEngineParas(netData, appData, offset, length, true);
1209 
1210         /*
1211          * We can be smarter about using smaller buffer sizes later.
1212          * For now, force it to be large enough to handle any valid record.

1213          */
1214         if (netData.remaining() < sess.getPacketBufferSize()) {
1215             return new SSLEngineResult(
1216                 Status.BUFFER_OVERFLOW, getHSStatus(null), 0, 0);
1217         }
1218 
1219         try {
1220             synchronized (wrapLock) {
1221                 return writeAppRecord(appData, offset, length, netData);
1222             }
1223         } catch (SSLProtocolException spe) {
1224             // may be an unexpected handshake message
1225             fatal(Alerts.alert_unexpected_message, spe.getMessage(), spe);
1226             return null;  // make compiler happy
1227         } catch (Exception e) {


1228             fatal(Alerts.alert_internal_error,
1229                 "problem wrapping app data", e);
1230             return null;  // make compiler happy





1231         }
1232     }
1233 
1234     /*
1235      * Makes additional checks for unwrap, but this time more
1236      * specific to this packet and the current state of the machine.
1237      */
1238     private SSLEngineResult writeAppRecord(ByteBuffer[] appData,
1239             int offset, int length, ByteBuffer netData) throws IOException {
1240 
1241         Status status = null;
1242         HandshakeStatus hsStatus = null;
1243 
1244         /*
1245          * See if the handshaker needs to report back some SSLException.
1246          */
1247         checkTaskThrown();
1248 
1249         /*
1250          * short circuit if we're closed/closing.
1251          */
1252         if (isOutboundDone()) {
1253             return new SSLEngineResult(Status.CLOSED, getHSStatus(null), 0, 0);
1254         }
1255 
1256         /*
1257          * If we're still in cs_HANDSHAKE, make sure it's been
1258          * started.
1259          */
1260         synchronized (this) {
1261             if ((connectionState == cs_HANDSHAKE) ||
1262                 (connectionState == cs_START)) {
1263 
1264                 kickstartHandshake();
1265 
1266                 /*
1267                  * If there's no HS data available to write, we can return
1268                  * without trying to wrap anything.
1269                  */
1270                 hsStatus = getHSStatus(null);

1271                 if (hsStatus == HandshakeStatus.NEED_UNWRAP) {
1272                     /*
1273                      * For DTLS, if the handshake state is
1274                      * HandshakeStatus.NEED_UNWRAP, a call to SSLEngine.wrap()
1275                      * means that the previous handshake packets (if delivered)
1276                      * get lost, and need retransmit the handshake messages.
1277                      */
1278                     if (!isDTLS || !enableRetransmissions ||
1279                             (handshaker == null) || outputRecord.firstMessage) {
1280 
1281                         return new SSLEngineResult(Status.OK, hsStatus, 0, 0);
1282                     }   // otherwise, need retransmission
1283                 }
1284             }
1285         }
1286 
1287         /*
1288          * Grab a copy of this if it doesn't already exist,
1289          * and we can use it several places before anything major
1290          * happens on this side.  Races aren't critical
1291          * here.
1292          */
1293         if (hsStatus == null) {
1294             hsStatus = getHSStatus(null);
1295         }
1296 
1297         /*
1298          * If we have a task outstanding, this *MUST* be done before
1299          * doing any more wrapping, because we could be in the middle
1300          * of receiving a handshake message, for example, a finished
1301          * message which would change the ciphers.
1302          */
1303         if (hsStatus == HandshakeStatus.NEED_TASK) {
1304             return new SSLEngineResult(Status.OK, hsStatus, 0, 0);

1305         }
1306 
1307         /*
1308          * This will obtain any waiting outbound data, or will
1309          * process the outbound appData.
1310          */
1311         int netPos = netData.position();
1312         int appRemains = 0;
1313         for (int i = offset; i < offset + length; i++) {
1314             if (appData[i] == null) {
1315                 throw new IllegalArgumentException(
1316                         "appData[" + i + "] == null");
1317             }
1318             appRemains += appData[i].remaining();
1319         }
1320 
1321         Ciphertext ciphertext = null;
1322         try {
1323             if (appRemains != 0) {
1324                 synchronized (writeLock) {
1325                     ciphertext = writeRecord(appData, offset, length, netData);
1326                 }
1327             } else {
1328                 synchronized (writeLock) {
1329                     ciphertext = writeRecord(null, 0, 0, netData);
1330                 }
1331             }
1332         } catch (SSLException e) {
1333             throw e;
1334         } catch (IOException e) {
1335             throw new SSLException("Write problems", e);
1336         }
1337 
1338         /*
1339          * writeRecord might have reported some status.
1340          * Now check for the remaining cases.
1341          *
1342          * status above should cover:  NEED_WRAP/FINISHED
1343          */
1344         status = (isOutboundDone() ? Status.CLOSED : Status.OK);
1345         hsStatus = getHSStatus(ciphertext.handshakeStatus);
1346 
1347         int deltaNet = netData.position() - netPos;
1348         int deltaApp = appRemains;
1349         for (int i = offset; i < offset + length; i++) {
1350             deltaApp -= appData[i].remaining();
1351         }
1352 
1353         return new SSLEngineResult(
1354                 status, hsStatus, deltaApp, deltaNet, ciphertext.recordSN);
1355     }
1356 
1357     /*
1358      * Central point to write/get all of the outgoing data.
1359      */
1360     private Ciphertext writeRecord(ByteBuffer[] appData,
1361             int offset, int length, ByteBuffer netData) throws IOException {
1362 
1363         Ciphertext ciphertext = null;
1364         try {
1365             // Acquire the buffered to-be-delivered records or retransmissions.
1366             //
1367             // May have buffered records, or need retransmission if handshaking.
1368             if (!outputRecord.isEmpty() || (handshaker != null)) {
1369                 ciphertext = outputRecord.acquireCiphertext(netData);














1370             }

1371 
1372             if ((ciphertext == null) && (appData != null)) {
1373                 ciphertext = outputRecord.encode(
1374                         appData, offset, length, netData);



1375             }
1376         } catch (SSLHandshakeException she) {
1377             // may be record sequence number overflow
1378             fatal(Alerts.alert_handshake_failure, she);
1379 
1380             return Ciphertext.CIPHERTEXT_NULL;   // make the complier happy
1381         } catch (IOException e) {
1382             fatal(Alerts.alert_unexpected_message, e);
1383 
1384             return Ciphertext.CIPHERTEXT_NULL;   // make the complier happy
1385         }
1386 
1387         if (ciphertext == null) {
1388             return Ciphertext.CIPHERTEXT_NULL;














1389         }
1390 
1391         HandshakeStatus hsStatus = null;
1392         Ciphertext.RecordType recordType = ciphertext.recordType;
1393         if ((handshaker != null) &&
1394                 (recordType.contentType == Record.ct_handshake) &&
1395                 (recordType.handshakeType == HandshakeMessage.ht_finished) &&
1396                 handshaker.isDone() && outputRecord.isEmpty()) {
1397 
1398             hsStatus = finishHandshake();
1399             connectionState = cs_DATA;
1400         }   // Otherwise, the followed call to getHSStatus() will help.
1401 
1402         /*
1403          * We only need to check the sequence number state for
1404          * non-handshaking record.
1405          *
1406          * Note that in order to maintain the handshake status
1407          * properly, we check the sequence number after the last
1408          * record writing process. As we request renegotiation
1409          * or close the connection for wrapped sequence number
1410          * when there is enough sequence number space left to
1411          * handle a few more records, so the sequence number
1412          * of the last record cannot be wrapped.
1413          */
1414         hsStatus = getHSStatus(hsStatus);
1415         if (connectionState < cs_ERROR && !isOutboundDone() &&
1416                 (hsStatus == HandshakeStatus.NOT_HANDSHAKING) &&
1417                 (outputRecord.seqNumIsHuge())) {


















1418             /*





























1419              * Ask for renegotiation when need to renew sequence number.
1420              *
1421              * Don't bother to kickstart the renegotiation when the local is
1422              * asking for it.
1423              */

1424             if (debug != null && Debug.isOn("ssl")) {
1425                 System.out.println(Thread.currentThread().getName() +
1426                         ", request renegotiation " +
1427                         "to avoid sequence number overflow");
1428             }
1429 
1430             beginHandshake();
1431 
1432             hsStatus = getHSStatus(null);
1433         }
1434         ciphertext.handshakeStatus = hsStatus;
1435 
1436         return ciphertext;
1437     }
1438 
1439     private HandshakeStatus finishHandshake() {
1440         handshaker = null;
1441         inputRecord.setHandshakeHash(null);
1442         outputRecord.setHandshakeHash(null);
1443         connectionState = cs_DATA;
1444 
1445        return HandshakeStatus.FINISHED;
1446    }
1447 
1448     //
1449     // Close code
1450     //
1451 
1452     /**
1453      * Signals that no more outbound application data will be sent
1454      * on this <code>SSLEngine</code>.
1455      */
1456     private void closeOutboundInternal() {
1457 
1458         if ((debug != null) && Debug.isOn("ssl")) {
1459             System.out.println(Thread.currentThread().getName() +
1460                                     ", closeOutboundInternal()");
1461         }
1462 
1463         /*
1464          * Already closed, ignore
1465          */
1466         if (outboundDone) {
1467             return;
1468         }
1469 
1470         switch (connectionState) {
1471 
1472         /*
1473          * If we haven't even started yet, don't bother reading inbound.
1474          */
1475         case cs_START:
1476             try {
1477                 outputRecord.close();
1478             } catch (IOException ioe) {
1479                // ignore
1480             }
1481             outboundDone = true;
1482 
1483             try {
1484                 inputRecord.close();
1485             } catch (IOException ioe) {
1486                // ignore
1487             }
1488             inboundDone = true;
1489             break;
1490 
1491         case cs_ERROR:
1492         case cs_CLOSED:
1493             break;
1494 
1495         /*
1496          * Otherwise we indicate clean termination.
1497          */
1498         // case cs_HANDSHAKE:
1499         // case cs_DATA:
1500         // case cs_RENEGOTIATE:
1501         default:
1502             warning(Alerts.alert_close_notify);
1503             try {
1504                 outputRecord.close();
1505             } catch (IOException ioe) {
1506                // ignore
1507             }
1508             outboundDone = true;
1509             break;
1510         }
1511 



1512         connectionState = cs_CLOSED;
1513     }
1514 
1515     @Override
1516     synchronized public void closeOutbound() {
1517         /*
1518          * Dump out a close_notify to the remote side
1519          */
1520         if ((debug != null) && Debug.isOn("ssl")) {
1521             System.out.println(Thread.currentThread().getName() +
1522                                     ", called closeOutbound()");
1523         }
1524 
1525         closeOutboundInternal();
1526     }
1527 
1528     /**
1529      * Returns the outbound application data closure state
1530      */
1531     @Override
1532     public boolean isOutboundDone() {
1533         return outboundDone && outputRecord.isEmpty();
1534     }
1535 
1536     /**
1537      * Signals that no more inbound network data will be sent
1538      * to this <code>SSLEngine</code>.
1539      */
1540     private void closeInboundInternal() {
1541 
1542         if ((debug != null) && Debug.isOn("ssl")) {
1543             System.out.println(Thread.currentThread().getName() +
1544                                     ", closeInboundInternal()");
1545         }
1546 
1547         /*
1548          * Already closed, ignore
1549          */
1550         if (inboundDone) {
1551             return;
1552         }
1553 
1554         closeOutboundInternal();
1555 
1556         try {
1557             inputRecord.close();
1558         } catch (IOException ioe) {
1559            // ignore
1560         }
1561         inboundDone = true;
1562 



1563         connectionState = cs_CLOSED;
1564     }
1565 
1566     /*
1567      * Close the inbound side of the connection.  We grab the
1568      * lock here, and do the real work in the internal verison.
1569      * We do check for truncation attacks.
1570      */
1571     @Override
1572     synchronized public void closeInbound() throws SSLException {
1573         /*
1574          * Currently closes the outbound side as well.  The IETF TLS
1575          * working group has expressed the opinion that 1/2 open
1576          * connections are not allowed by the spec.  May change
1577          * someday in the future.
1578          */
1579         if ((debug != null) && Debug.isOn("ssl")) {
1580             System.out.println(Thread.currentThread().getName() +
1581                                     ", called closeInbound()");
1582         }


1613 
1614 
1615     /**
1616      * Returns the current <code>SSLSession</code> for this
1617      * <code>SSLEngine</code>
1618      * <P>
1619      * These can be long lived, and frequently correspond to an
1620      * entire login session for some user.
1621      */
1622     @Override
1623     synchronized public SSLSession getSession() {
1624         return sess;
1625     }
1626 
1627     @Override
1628     synchronized public SSLSession getHandshakeSession() {
1629         return handshakeSession;
1630     }
1631 
1632     synchronized void setHandshakeSession(SSLSessionImpl session) {
1633         // update the fragment size, which may be negotiated during handshaking
1634         inputRecord.changeFragmentSize(session.getNegotiatedMaxFragSize());
1635         outputRecord.changeFragmentSize(session.getNegotiatedMaxFragSize());
1636 
1637         handshakeSession = session;
1638     }
1639 
1640     /**
1641      * Returns a delegated <code>Runnable</code> task for
1642      * this <code>SSLEngine</code>.
1643      */
1644     @Override
1645     synchronized public Runnable getDelegatedTask() {
1646         if (handshaker != null) {
1647             return handshaker.getTask();
1648         }
1649         return null;
1650     }
1651 
1652 
1653     //
1654     // EXCEPTION AND ALERT HANDLING
1655     //
1656 


1716                 throw (RuntimeException)cause;
1717             } else if (cause instanceof SSLException) {
1718                 throw (SSLException)cause;
1719             } else if (cause instanceof Exception) {
1720                 throw new SSLException("fatal SSLEngine condition", cause);
1721             }
1722         }
1723 
1724         if ((debug != null) && Debug.isOn("ssl")) {
1725             System.out.println(Thread.currentThread().getName()
1726                         + ", fatal error: " + description +
1727                         ": " + diagnostic + "\n" + cause.toString());
1728         }
1729 
1730         /*
1731          * Ok, this engine's going down.
1732          */
1733         int oldState = connectionState;
1734         connectionState = cs_ERROR;
1735 
1736         try {
1737             inputRecord.close();
1738         } catch (IOException ioe) {
1739            // ignore
1740         }
1741         inboundDone = true;
1742 
1743         sess.invalidate();
1744         if (handshakeSession != null) {
1745             handshakeSession.invalidate();
1746         }
1747 
1748         /*
1749          * If we haven't even started handshaking yet, no need
1750          * to generate the fatal close alert.
1751          */
1752         if (oldState != cs_START) {
1753             sendAlert(Alerts.alert_fatal, description);
1754         }
1755 
1756         if (cause instanceof SSLException) { // only true if != null
1757             closeReason = (SSLException)cause;
1758         } else {
1759             /*
1760              * Including RuntimeExceptions, but we'll throw those
1761              * down below.  The closeReason isn't used again,
1762              * except for null checks.
1763              */
1764             closeReason =
1765                 Alerts.getSSLException(description, cause, diagnostic);
1766         }
1767 
1768         try {
1769             outputRecord.close();
1770         } catch (IOException ioe) {
1771            // ignore
1772         }
1773         outboundDone = true;
1774 
1775         connectionState = cs_CLOSED;
1776 




1777         if (cause instanceof RuntimeException) {
1778             throw (RuntimeException)cause;
1779         } else {
1780             throw closeReason;
1781         }
1782     }
1783 
1784     /*
1785      * Process an incoming alert ... caller must already have synchronized
1786      * access to "this".
1787      */
1788     private void recvAlert(ByteBuffer fragment) throws IOException {
1789         byte level = fragment.get();
1790         byte description = fragment.get();
1791 
1792         if (description == -1) { // check for short message
1793             fatal(Alerts.alert_illegal_parameter, "Short alert message");
1794         }
1795 
1796         if (debug != null && (Debug.isOn("record") ||
1797                 Debug.isOn("handshake"))) {
1798             synchronized (System.out) {
1799                 System.out.print(Thread.currentThread().getName());
1800                 System.out.print(", RECV " + protocolVersion + " ALERT:  ");
1801                 if (level == Alerts.alert_fatal) {
1802                     System.out.print("fatal, ");
1803                 } else if (level == Alerts.alert_warning) {
1804                     System.out.print("warning, ");
1805                 } else {
1806                     System.out.print("<level " + (0x0ff & level) + ">, ");
1807                 }
1808                 System.out.println(Alerts.alertDescription(description));
1809             }
1810         }
1811 


1835                 + Alerts.alertDescription(description);
1836             if (closeReason == null) {
1837                 closeReason = Alerts.getSSLException(description, reason);
1838             }
1839             fatal(Alerts.alert_unexpected_message, reason);
1840         }
1841     }
1842 
1843 
1844     /*
1845      * Emit alerts.  Caller must have synchronized with "this".
1846      */
1847     private void sendAlert(byte level, byte description) {
1848         // the connectionState cannot be cs_START
1849         if (connectionState >= cs_CLOSED) {
1850             return;
1851         }
1852 
1853         // For initial handshaking, don't send alert message to peer if
1854         // handshaker has not started.
1855         //
1856         // Shall we send an fatal alter to terminate the connection gracefully?
1857         if (connectionState <= cs_HANDSHAKE &&
1858                 (handshaker == null || !handshaker.started() ||
1859                         !handshaker.activated())) {
1860             return;
1861         }
1862 






















1863         try {
1864             outputRecord.encodeAlert(level, description);
1865         } catch (IOException ioe) {
1866             // ignore


1867         }
1868     }

1869 
1870 
1871     //
1872     // VARIOUS OTHER METHODS (COMMON TO SSLSocket)
1873     //
1874 
1875 
1876     /**
1877      * Controls whether new connections may cause creation of new SSL
1878      * sessions.
1879      *
1880      * As long as handshaking has not started, we can change
1881      * whether we enable session creations.  Otherwise,
1882      * we will need to wait for the next handshake.
1883      */
1884     @Override
1885     synchronized public void setEnableSessionCreation(boolean flag) {
1886         enableSessionCreation = flag;
1887 
1888         if ((handshaker != null) && !handshaker.activated()) {


1894      * Returns true if new connections may cause creation of new SSL
1895      * sessions.
1896      */
1897     @Override
1898     synchronized public boolean getEnableSessionCreation() {
1899         return enableSessionCreation;
1900     }
1901 
1902 
1903     /**
1904      * Sets the flag controlling whether a server mode engine
1905      * *REQUIRES* SSL client authentication.
1906      *
1907      * As long as handshaking has not started, we can change
1908      * whether client authentication is needed.  Otherwise,
1909      * we will need to wait for the next handshake.
1910      */
1911     @Override
1912     synchronized public void setNeedClientAuth(boolean flag) {
1913         doClientAuth = (flag ?
1914                 ClientAuthType.CLIENT_AUTH_REQUIRED :
1915                 ClientAuthType.CLIENT_AUTH_NONE);
1916 
1917         if ((handshaker != null) &&
1918                 (handshaker instanceof ServerHandshaker) &&
1919                 !handshaker.activated()) {
1920             ((ServerHandshaker) handshaker).setClientAuth(doClientAuth);
1921         }
1922     }
1923 
1924     @Override
1925     synchronized public boolean getNeedClientAuth() {
1926         return (doClientAuth == ClientAuthType.CLIENT_AUTH_REQUIRED);
1927     }
1928 
1929     /**
1930      * Sets the flag controlling whether a server mode engine
1931      * *REQUESTS* SSL client authentication.
1932      *
1933      * As long as handshaking has not started, we can change
1934      * whether client authentication is requested.  Otherwise,
1935      * we will need to wait for the next handshake.
1936      */
1937     @Override
1938     synchronized public void setWantClientAuth(boolean flag) {
1939         doClientAuth = (flag ?
1940                 ClientAuthType.CLIENT_AUTH_REQUESTED :
1941                 ClientAuthType.CLIENT_AUTH_NONE);
1942 
1943         if ((handshaker != null) &&
1944                 (handshaker instanceof ServerHandshaker) &&
1945                 !handshaker.activated()) {
1946             ((ServerHandshaker) handshaker).setClientAuth(doClientAuth);
1947         }
1948     }
1949 
1950     @Override
1951     synchronized public boolean getWantClientAuth() {
1952         return (doClientAuth == ClientAuthType.CLIENT_AUTH_REQUESTED);
1953     }
1954 
1955 
1956     /**
1957      * Sets the flag controlling whether the engine is in SSL
1958      * client or server mode.  Must be called before any SSL
1959      * traffic has started.
1960      */
1961     @Override
1962     @SuppressWarnings("fallthrough")
1963     synchronized public void setUseClientMode(boolean flag) {
1964         switch (connectionState) {
1965 
1966         case cs_START:
1967             /*
1968              * If we need to change the socket mode and the enabled
1969              * protocols and cipher suites haven't specifically been
1970              * set by the user, change them to the corresponding
1971              * default ones.
1972              */
1973             if (roleIsServer != (!flag)) {
1974                 if (sslContext.isDefaultProtocolList(enabledProtocols)) {
1975                     enabledProtocols =
1976                             sslContext.getDefaultProtocolList(!flag);
1977                 }
1978 
1979                 if (sslContext.isDefaultCipherSuiteList(enabledCipherSuites)) {
1980                     enabledCipherSuites =
1981                             sslContext.getDefaultCipherSuiteList(!flag);
1982                 }
1983             }
1984 
1985             roleIsServer = !flag;
1986             serverModeSet = true;
1987             break;
1988 
1989         case cs_HANDSHAKE:
1990             /*
1991              * If we have a handshaker, but haven't started
1992              * SSL traffic, we can throw away our current
1993              * handshaker, and start from scratch.  Don't
1994              * need to call doneConnect() again, we already
1995              * have the streams.
1996              */
1997             assert(handshaker != null);
1998             if (!handshaker.activated()) {
1999                 /*
2000                  * If we need to change the socket mode and the enabled
2001                  * protocols and cipher suites haven't specifically been
2002                  * set by the user, change them to the corresponding
2003                  * default ones.
2004                  */
2005                 if (roleIsServer != (!flag)) {
2006                     if (sslContext.isDefaultProtocolList(enabledProtocols)) {
2007                         enabledProtocols =
2008                                 sslContext.getDefaultProtocolList(!flag);
2009                     }
2010 
2011                     if (sslContext.isDefaultCipherSuiteList(
2012                                                     enabledCipherSuites)) {
2013                         enabledCipherSuites =
2014                             sslContext.getDefaultCipherSuiteList(!flag);
2015                     }
2016                 }
2017 
2018                 roleIsServer = !flag;
2019                 connectionState = cs_START;
2020                 initHandshaker();
2021                 break;
2022             }
2023 
2024             // If handshake has started, that's an error.  Fall through...
2025 
2026         default:
2027             if (debug != null && Debug.isOn("ssl")) {
2028                 System.out.println(Thread.currentThread().getName() +
2029                     ", setUseClientMode() invoked in state = " +
2030                     connectionState);
2031             }
2032 
2033             /*
2034              * We can let them continue if they catch this correctly,
2035              * we don't need to shut this down.
2036              */
2037             throw new IllegalArgumentException(


2121     }
2122 
2123     @Override
2124     synchronized public String[] getEnabledProtocols() {
2125         return enabledProtocols.toStringArray();
2126     }
2127 
2128     /**
2129      * Returns the SSLParameters in effect for this SSLEngine.
2130      */
2131     @Override
2132     synchronized public SSLParameters getSSLParameters() {
2133         SSLParameters params = super.getSSLParameters();
2134 
2135         // the super implementation does not handle the following parameters
2136         params.setEndpointIdentificationAlgorithm(identificationProtocol);
2137         params.setAlgorithmConstraints(algorithmConstraints);
2138         params.setSNIMatchers(sniMatchers);
2139         params.setServerNames(serverNames);
2140         params.setUseCipherSuitesOrder(preferLocalCipherSuites);
2141         params.setEnableRetransmissions(enableRetransmissions);
2142         params.setMaximumPacketSize(maximumPacketSize);
2143 
2144         return params;
2145     }
2146 
2147     /**
2148      * Applies SSLParameters to this engine.
2149      */
2150     @Override
2151     synchronized public void setSSLParameters(SSLParameters params) {
2152         super.setSSLParameters(params);
2153 
2154         // the super implementation does not handle the following parameters
2155         identificationProtocol = params.getEndpointIdentificationAlgorithm();
2156         algorithmConstraints = params.getAlgorithmConstraints();
2157         preferLocalCipherSuites = params.getUseCipherSuitesOrder();
2158         enableRetransmissions = params.getEnableRetransmissions();
2159         maximumPacketSize = params.getMaximumPacketSize();
2160 
2161         if (maximumPacketSize != 0) {
2162             outputRecord.changePacketSize(maximumPacketSize);
2163         } else {
2164             // use the implicit maximum packet size.
2165             maximumPacketSize = outputRecord.getMaxPacketSize();
2166         }
2167 
2168         List<SNIServerName> sniNames = params.getServerNames();
2169         if (sniNames != null) {
2170             serverNames = sniNames;
2171         }
2172 
2173         Collection<SNIMatcher> matchers = params.getSNIMatchers();
2174         if (matchers != null) {
2175             sniMatchers = matchers;
2176         }
2177 
2178         if ((handshaker != null) && !handshaker.started()) {
2179             handshaker.setIdentificationProtocol(identificationProtocol);
2180             handshaker.setAlgorithmConstraints(algorithmConstraints);
2181             handshaker.setMaximumPacketSize(maximumPacketSize);
2182             if (roleIsServer) {
2183                 handshaker.setSNIMatchers(sniMatchers);
2184                 handshaker.setUseCipherSuitesOrder(preferLocalCipherSuites);
2185             } else {
2186                 handshaker.setSNIServerNames(serverNames);
2187             }
2188         }
2189     }
2190 
2191     /**








2192      * Returns a printable representation of this end of the connection.
2193      */
2194     @Override
2195     public String toString() {
2196         StringBuilder retval = new StringBuilder(80);
2197 
2198         retval.append(Integer.toHexString(hashCode()));
2199         retval.append("[");
2200         retval.append("SSLEngine[hostname=");
2201         String host = getPeerHost();
2202         retval.append((host == null) ? "null" : host);
2203         retval.append(" port=");
2204         retval.append(Integer.toString(getPeerPort()));
2205         retval.append(" role=" + (roleIsServer ? "Server" : "Client"));
2206         retval.append("] ");
2207         retval.append(getSession().getCipherSuite());
2208         retval.append("]");
2209 
2210         return retval.toString();
2211     }
2212 }