1 /*
   2  * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package sun.security.ssl;
  27 
  28 import java.io.EOFException;
  29 import java.io.IOException;
  30 import java.io.InputStream;
  31 import java.io.InterruptedIOException;
  32 import java.io.OutputStream;
  33 import java.net.InetAddress;
  34 import java.net.InetSocketAddress;
  35 import java.net.Socket;
  36 import java.net.SocketAddress;
  37 import java.net.SocketException;
  38 import java.net.UnknownHostException;
  39 import java.nio.ByteBuffer;
  40 import java.util.List;
  41 import java.util.function.BiFunction;
  42 import javax.net.ssl.HandshakeCompletedListener;
  43 import javax.net.ssl.SSLException;
  44 import javax.net.ssl.SSLHandshakeException;
  45 import javax.net.ssl.SSLParameters;
  46 import javax.net.ssl.SSLProtocolException;
  47 import javax.net.ssl.SSLServerSocket;
  48 import javax.net.ssl.SSLSession;
  49 import javax.net.ssl.SSLSocket;
  50 import sun.misc.SharedSecrets;
  51 
  52 /**
  53  * Implementation of an SSL socket.
  54  * <P>
  55  * This is a normal connection type socket, implementing SSL over some lower
  56  * level socket, such as TCP.  Because it is layered over some lower level
  57  * socket, it MUST override all default socket methods.
  58  * <P>
  59  * This API offers a non-traditional option for establishing SSL
  60  * connections.  You may first establish the connection directly, then pass
  61  * that connection to the SSL socket constructor with a flag saying which
  62  * role should be taken in the handshake protocol.  (The two ends of the
  63  * connection must not choose the same role!)  This allows setup of SSL
  64  * proxying or tunneling, and also allows the kind of "role reversal"
  65  * that is required for most FTP data transfers.
  66  *
  67  * @see javax.net.ssl.SSLSocket
  68  * @see SSLServerSocket
  69  *
  70  * @author David Brownell
  71  */
  72 public final class SSLSocketImpl
  73         extends BaseSSLSocketImpl implements SSLTransport {
  74 
  75     final SSLContextImpl            sslContext;
  76     final TransportContext          conContext;
  77 
  78     private final AppInputStream    appInput = new AppInputStream();
  79     private final AppOutputStream   appOutput = new AppOutputStream();
  80 
  81     private String                  peerHost;
  82     private boolean                 autoClose;
  83     private boolean                 isConnected = false;
  84     private volatile boolean        tlsIsClosed = false;
  85 
  86     /*
  87      * Is the local name service trustworthy?
  88      *
  89      * If the local name service is not trustworthy, reverse host name
  90      * resolution should not be performed for endpoint identification.
  91      */
  92     private static final boolean trustNameService =
  93             Utilities.getBooleanProperty("jdk.tls.trustNameService", false);
  94 
  95     /**
  96      * Package-private constructor used to instantiate an unconnected
  97      * socket.
  98      *
  99      * This instance is meant to set handshake state to use "client mode".
 100      */
 101     SSLSocketImpl(SSLContextImpl sslContext) {
 102         super();
 103         this.sslContext = sslContext;
 104         HandshakeHash handshakeHash = new HandshakeHash();
 105         this.conContext = new TransportContext(sslContext, this,
 106                 new SSLSocketInputRecord(handshakeHash),
 107                 new SSLSocketOutputRecord(handshakeHash), true);
 108     }
 109 
 110     /**
 111      * Package-private constructor used to instantiate a server socket.
 112      *
 113      * This instance is meant to set handshake state to use "server mode".
 114      */
 115     SSLSocketImpl(SSLContextImpl sslContext, SSLConfiguration sslConfig) {
 116         super();
 117         this.sslContext = sslContext;
 118         HandshakeHash handshakeHash = new HandshakeHash();
 119         this.conContext = new TransportContext(sslContext, this, sslConfig,
 120                 new SSLSocketInputRecord(handshakeHash),
 121                 new SSLSocketOutputRecord(handshakeHash));
 122     }
 123 
 124     /**
 125      * Constructs an SSL connection to a named host at a specified
 126      * port, using the authentication context provided.
 127      *
 128      * This endpoint acts as the client, and may rejoin an existing SSL session
 129      * if appropriate.
 130      */
 131     SSLSocketImpl(SSLContextImpl sslContext, String peerHost,
 132             int peerPort) throws IOException, UnknownHostException {
 133         super();
 134         this.sslContext = sslContext;
 135         HandshakeHash handshakeHash = new HandshakeHash();
 136         this.conContext = new TransportContext(sslContext, this,
 137                 new SSLSocketInputRecord(handshakeHash),
 138                 new SSLSocketOutputRecord(handshakeHash), true);
 139         this.peerHost = peerHost;
 140         SocketAddress socketAddress =
 141                peerHost != null ? new InetSocketAddress(peerHost, peerPort) :
 142                new InetSocketAddress(InetAddress.getByName(null), peerPort);
 143         connect(socketAddress, 0);
 144     }
 145 
 146     /**
 147      * Constructs an SSL connection to a server at a specified
 148      * address, and TCP port, using the authentication context
 149      * provided.
 150      *
 151      * This endpoint acts as the client, and may rejoin an existing SSL
 152      * session if appropriate.
 153      */
 154     SSLSocketImpl(SSLContextImpl sslContext,
 155             InetAddress address, int peerPort) throws IOException {
 156         super();
 157         this.sslContext = sslContext;
 158         HandshakeHash handshakeHash = new HandshakeHash();
 159         this.conContext = new TransportContext(sslContext, this,
 160                 new SSLSocketInputRecord(handshakeHash),
 161                 new SSLSocketOutputRecord(handshakeHash), true);
 162 
 163         SocketAddress socketAddress = new InetSocketAddress(address, peerPort);
 164         connect(socketAddress, 0);
 165     }
 166 
 167     /**
 168      * Constructs an SSL connection to a named host at a specified
 169      * port, using the authentication context provided.
 170      *
 171      * This endpoint acts as the client, and may rejoin an existing SSL
 172      * session if appropriate.
 173      */
 174     SSLSocketImpl(SSLContextImpl sslContext,
 175             String peerHost, int peerPort, InetAddress localAddr,
 176             int localPort) throws IOException, UnknownHostException {
 177         super();
 178         this.sslContext = sslContext;
 179         HandshakeHash handshakeHash = new HandshakeHash();
 180         this.conContext = new TransportContext(sslContext, this,
 181                 new SSLSocketInputRecord(handshakeHash),
 182                 new SSLSocketOutputRecord(handshakeHash), true);
 183         this.peerHost = peerHost;
 184 
 185         bind(new InetSocketAddress(localAddr, localPort));
 186         SocketAddress socketAddress =
 187                peerHost != null ? new InetSocketAddress(peerHost, peerPort) :
 188                new InetSocketAddress(InetAddress.getByName(null), peerPort);
 189         connect(socketAddress, 0);
 190     }
 191 
 192     /**
 193      * Constructs an SSL connection to a server at a specified
 194      * address, and TCP port, using the authentication context
 195      * provided.
 196      *
 197      * This endpoint acts as the client, and may rejoin an existing SSL
 198      * session if appropriate.
 199      */
 200     SSLSocketImpl(SSLContextImpl sslContext,
 201             InetAddress peerAddr, int peerPort,
 202             InetAddress localAddr, int localPort) throws IOException {
 203         super();
 204         this.sslContext = sslContext;
 205         HandshakeHash handshakeHash = new HandshakeHash();
 206         this.conContext = new TransportContext(sslContext, this,
 207                 new SSLSocketInputRecord(handshakeHash),
 208                 new SSLSocketOutputRecord(handshakeHash), true);
 209 
 210         bind(new InetSocketAddress(localAddr, localPort));
 211         SocketAddress socketAddress = new InetSocketAddress(peerAddr, peerPort);
 212         connect(socketAddress, 0);
 213     }
 214 
 215     /**
 216      * Creates a server mode {@link Socket} layered over an
 217      * existing connected socket, and is able to read data which has
 218      * already been consumed/removed from the {@link Socket}'s
 219      * underlying {@link InputStream}.
 220      */
 221     SSLSocketImpl(SSLContextImpl sslContext, Socket sock,
 222             InputStream consumed, boolean autoClose) throws IOException {
 223         super(sock, consumed);
 224         // We always layer over a connected socket
 225         if (!sock.isConnected()) {
 226             throw new SocketException("Underlying socket is not connected");
 227         }
 228 
 229         this.sslContext = sslContext;
 230         HandshakeHash handshakeHash = new HandshakeHash();
 231         this.conContext = new TransportContext(sslContext, this,
 232                 new SSLSocketInputRecord(handshakeHash),
 233                 new SSLSocketOutputRecord(handshakeHash), false);
 234         this.autoClose = autoClose;
 235         doneConnect();
 236     }
 237 
 238     /**
 239      * Layer SSL traffic over an existing connection, rather than
 240      * creating a new connection.
 241      *
 242      * The existing connection may be used only for SSL traffic (using this
 243      * SSLSocket) until the SSLSocket.close() call returns. However, if a
 244      * protocol error is detected, that existing connection is automatically
 245      * closed.
 246      * <p>
 247      * This particular constructor always uses the socket in the
 248      * role of an SSL client. It may be useful in cases which start
 249      * using SSL after some initial data transfers, for example in some
 250      * SSL tunneling applications or as part of some kinds of application
 251      * protocols which negotiate use of a SSL based security.
 252      */
 253     SSLSocketImpl(SSLContextImpl sslContext, Socket sock,
 254             String peerHost, int port, boolean autoClose) throws IOException {
 255         super(sock);
 256         // We always layer over a connected socket
 257         if (!sock.isConnected()) {
 258             throw new SocketException("Underlying socket is not connected");
 259         }
 260 
 261         this.sslContext = sslContext;
 262         HandshakeHash handshakeHash = new HandshakeHash();
 263         this.conContext = new TransportContext(sslContext, this,
 264                 new SSLSocketInputRecord(handshakeHash),
 265                 new SSLSocketOutputRecord(handshakeHash), true);
 266         this.peerHost = peerHost;
 267         this.autoClose = autoClose;
 268         doneConnect();
 269     }
 270 
 271     @Override
 272     public void connect(SocketAddress endpoint,
 273             int timeout) throws IOException {
 274 
 275         if (isLayered()) {
 276             throw new SocketException("Already connected");
 277         }
 278 
 279         if (!(endpoint instanceof InetSocketAddress)) {
 280             throw new SocketException(
 281                     "Cannot handle non-Inet socket addresses.");
 282         }
 283 
 284         super.connect(endpoint, timeout);
 285         doneConnect();
 286     }
 287 
 288     @Override
 289     public String[] getSupportedCipherSuites() {
 290         return CipherSuite.namesOf(sslContext.getSupportedCipherSuites());
 291     }
 292 
 293     @Override
 294     public synchronized String[] getEnabledCipherSuites() {
 295         return CipherSuite.namesOf(conContext.sslConfig.enabledCipherSuites);
 296     }
 297 
 298     @Override
 299     public synchronized void setEnabledCipherSuites(String[] suites) {
 300         conContext.sslConfig.enabledCipherSuites =
 301                 CipherSuite.validValuesOf(suites);
 302     }
 303 
 304     @Override
 305     public String[] getSupportedProtocols() {
 306         return ProtocolVersion.toStringArray(
 307                 sslContext.getSupportedProtocolVersions());
 308     }
 309 
 310     @Override
 311     public synchronized String[] getEnabledProtocols() {
 312         return ProtocolVersion.toStringArray(
 313                 conContext.sslConfig.enabledProtocols);
 314     }
 315 
 316     @Override
 317     public synchronized void setEnabledProtocols(String[] protocols) {
 318         if (protocols == null) {
 319             throw new IllegalArgumentException("Protocols cannot be null");
 320         }
 321 
 322         conContext.sslConfig.enabledProtocols =
 323                 ProtocolVersion.namesOf(protocols);
 324     }
 325 
 326     @Override
 327     public SSLSession getSession() {
 328         try {
 329             // start handshaking, if failed, the connection will be closed.
 330             ensureNegotiated();
 331         } catch (IOException ioe) {
 332             if (SSLLogger.isOn && SSLLogger.isOn("handshake")) {
 333                 SSLLogger.severe("handshake failed", ioe);
 334             }
 335 
 336             return new SSLSessionImpl();
 337         }
 338 
 339         return conContext.conSession;
 340     }
 341 
 342     @Override
 343     public synchronized SSLSession getHandshakeSession() {
 344         return conContext.handshakeContext == null ?
 345                 null : conContext.handshakeContext.handshakeSession;
 346     }
 347 
 348     @Override
 349     public synchronized void addHandshakeCompletedListener(
 350             HandshakeCompletedListener listener) {
 351         if (listener == null) {
 352             throw new IllegalArgumentException("listener is null");
 353         }
 354 
 355         conContext.sslConfig.addHandshakeCompletedListener(listener);
 356     }
 357 
 358     @Override
 359     public synchronized void removeHandshakeCompletedListener(
 360             HandshakeCompletedListener listener) {
 361         if (listener == null) {
 362             throw new IllegalArgumentException("listener is null");
 363         }
 364 
 365         conContext.sslConfig.removeHandshakeCompletedListener(listener);
 366     }
 367 
 368     @Override
 369     public void startHandshake() throws IOException {
 370         if (!isConnected) {
 371             throw new SocketException("Socket is not connected");
 372         }
 373 
 374         if (conContext.isBroken || conContext.isInboundClosed() ||
 375                 conContext.isOutboundClosed()) {
 376             throw new SocketException("Socket has been closed or broken");
 377         }
 378 
 379         synchronized (conContext) {     // handshake lock
 380             // double check the context status
 381             if (conContext.isBroken || conContext.isInboundClosed() ||
 382                     conContext.isOutboundClosed()) {
 383                 throw new SocketException("Socket has been closed or broken");
 384             }
 385 
 386             try {
 387                 conContext.kickstart();
 388 
 389                 // All initial handshaking goes through this operation until we
 390                 // have a valid SSL connection.
 391                 //
 392                 // Handle handshake messages only, need no application data.
 393                 if (!conContext.isNegotiated) {
 394                     readHandshakeRecord();
 395                 }
 396             } catch (IOException ioe) {
 397                 throw conContext.fatal(Alert.HANDSHAKE_FAILURE,
 398                     "Couldn't kickstart handshaking", ioe);
 399             } catch (Exception oe) {    // including RuntimeException
 400                 handleException(oe);
 401             }
 402         }
 403     }
 404 
 405     @Override
 406     public synchronized void setUseClientMode(boolean mode) {
 407         conContext.setUseClientMode(mode);
 408     }
 409 
 410     @Override
 411     public synchronized boolean getUseClientMode() {
 412         return conContext.sslConfig.isClientMode;
 413     }
 414 
 415     @Override
 416     public synchronized void setNeedClientAuth(boolean need) {
 417         conContext.sslConfig.clientAuthType =
 418                 (need ? ClientAuthType.CLIENT_AUTH_REQUIRED :
 419                         ClientAuthType.CLIENT_AUTH_NONE);
 420     }
 421 
 422     @Override
 423     public synchronized boolean getNeedClientAuth() {
 424         return (conContext.sslConfig.clientAuthType ==
 425                         ClientAuthType.CLIENT_AUTH_REQUIRED);
 426     }
 427 
 428     @Override
 429     public synchronized void setWantClientAuth(boolean want) {
 430         conContext.sslConfig.clientAuthType =
 431                 (want ? ClientAuthType.CLIENT_AUTH_REQUESTED :
 432                         ClientAuthType.CLIENT_AUTH_NONE);
 433     }
 434 
 435     @Override
 436     public synchronized boolean getWantClientAuth() {
 437         return (conContext.sslConfig.clientAuthType ==
 438                         ClientAuthType.CLIENT_AUTH_REQUESTED);
 439     }
 440 
 441     @Override
 442     public synchronized void setEnableSessionCreation(boolean flag) {
 443         conContext.sslConfig.enableSessionCreation = flag;
 444     }
 445 
 446     @Override
 447     public synchronized boolean getEnableSessionCreation() {
 448         return conContext.sslConfig.enableSessionCreation;
 449     }
 450 
 451     @Override
 452     public boolean isClosed() {
 453         return tlsIsClosed;
 454     }
 455 
 456     // Please don't synchronized this method.  Otherwise, the read and close
 457     // locks may be deadlocked.
 458     @Override
 459     public void close() throws IOException {
 460         if (tlsIsClosed) {
 461             return;
 462         }
 463 
 464         if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
 465             SSLLogger.fine("duplex close of SSLSocket");
 466         }
 467 
 468         try {
 469             // shutdown output bound, which may have been closed previously.
 470             if (!isOutputShutdown()) {
 471                 duplexCloseOutput();
 472             }
 473 
 474             // shutdown input bound, which may have been closed previously.
 475             if (!isInputShutdown()) {
 476                 duplexCloseInput();
 477             }
 478 
 479             if (!isClosed()) {
 480                 // close the connection directly
 481                 closeSocket(false);
 482             }
 483         } catch (IOException ioe) {
 484             // ignore the exception
 485             if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
 486                 SSLLogger.warning("SSLSocket duplex close failed", ioe);
 487             }
 488         } finally {
 489             tlsIsClosed = true;
 490         }
 491     }
 492 
 493     /**
 494      * Duplex close, start from closing outbound.
 495      *
 496      * For TLS 1.2 [RFC 5246], unless some other fatal alert has been
 497      * transmitted, each party is required to send a close_notify alert
 498      * before closing the write side of the connection.  The other party
 499      * MUST respond with a close_notify alert of its own and close down
 500      * the connection immediately, discarding any pending writes.  It is
 501      * not required for the initiator of the close to wait for the responding
 502      * close_notify alert before closing the read side of the connection.
 503      *
 504      * For TLS 1.3, Each party MUST send a close_notify alert before
 505      * closing its write side of the connection, unless it has already sent
 506      * some error alert.  This does not have any effect on its read side of
 507      * the connection.  Both parties need not wait to receive a close_notify
 508      * alert before closing their read side of the connection, though doing
 509      * so would introduce the possibility of truncation.
 510      *
 511      * In order to support user initiated duplex-close for TLS 1.3 connections,
 512      * the user_canceled alert is used together with the close_notify alert.
 513      */
 514     private void duplexCloseOutput() throws IOException {
 515         boolean useUserCanceled = false;
 516         boolean hasCloseReceipt = false;
 517         if (conContext.isNegotiated) {
 518             if (!conContext.protocolVersion.useTLS13PlusSpec()) {
 519                 hasCloseReceipt = true;
 520             } else {
 521                 // Use a user_canceled alert for TLS 1.3 duplex close.
 522                 useUserCanceled = true;
 523             }
 524         } else if (conContext.handshakeContext != null) {   // initial handshake
 525             // Use user_canceled alert regardless the protocol versions.
 526             useUserCanceled = true;
 527 
 528             // The protocol version may have been negotiated.
 529             ProtocolVersion pv = conContext.handshakeContext.negotiatedProtocol;
 530             if (pv == null || (!pv.useTLS13PlusSpec())) {
 531                 hasCloseReceipt = true;
 532             }
 533         }
 534 
 535         // Need a lock here so that the user_canceled alert and the
 536         // close_notify alert can be delivered together.
 537         try {
 538             synchronized (conContext.outputRecord) {
 539                 // send a user_canceled alert if needed.
 540                 if (useUserCanceled) {
 541                     conContext.warning(Alert.USER_CANCELED);
 542                 }
 543 
 544                 // send a close_notify alert
 545                 conContext.warning(Alert.CLOSE_NOTIFY);
 546             }
 547         } finally {
 548             if (!conContext.isOutboundClosed()) {
 549                 conContext.outputRecord.close();
 550             }
 551 
 552             if ((autoClose || !isLayered()) && !super.isOutputShutdown()) {
 553                 super.shutdownOutput();
 554             }
 555         }
 556 
 557         if (!isInputShutdown()) {
 558             bruteForceCloseInput(hasCloseReceipt);
 559         }
 560     }
 561 
 562     /**
 563      * Duplex close, start from closing inbound.
 564      *
 565      * This method should only be called when the outbound has been closed,
 566      * but the inbound is still open.
 567      */
 568     private void duplexCloseInput() throws IOException {
 569         boolean hasCloseReceipt = false;
 570         if (conContext.isNegotiated &&
 571                 !conContext.protocolVersion.useTLS13PlusSpec()) {
 572             hasCloseReceipt = true;
 573         }   // No close receipt if handshake has no completed.
 574 
 575         bruteForceCloseInput(hasCloseReceipt);
 576     }
 577 
 578     /**
 579      * Brute force close the input bound.
 580      *
 581      * This method should only be called when the outbound has been closed,
 582      * but the inbound is still open.
 583      */
 584     @SuppressWarnings("try")
 585     private void bruteForceCloseInput(
 586             boolean hasCloseReceipt) throws IOException {
 587         if (hasCloseReceipt) {
 588             // It is not required for the initiator of the close to wait for
 589             // the responding close_notify alert before closing the read side
 590             // of the connection.  However, if the application protocol using
 591             // TLS provides that any data may be carried over the underlying
 592             // transport after the TLS connection is closed, the TLS
 593             // implementation MUST receive a "close_notify" alert before
 594             // indicating end-of-data to the application-layer.
 595             try {
 596                 this.shutdown();
 597             } finally {
 598                 if (!isInputShutdown()) {
 599                     shutdownInput(false);
 600                 }
 601             }
 602         } else {
 603             if (!conContext.isInboundClosed()) {
 604                 try (InputRecord ir = conContext.inputRecord) {
 605                     // Try the best to use up the input records and close the
 606                     // socket gracefully, without impact the performance too
 607                     // much.
 608                     appInput.deplete();
 609                 }
 610             }
 611 
 612             if ((autoClose || !isLayered()) && !super.isInputShutdown()) {
 613                 super.shutdownInput();
 614             }
 615         }
 616     }
 617 
 618     // Please don't synchronized this method.  Otherwise, the read and close
 619     // locks may be deadlocked.
 620     @Override
 621     public void shutdownInput() throws IOException {
 622         shutdownInput(true);
 623     }
 624 
 625     // It is not required to check the close_notify receipt unless an
 626     // application call shutdownInput() explicitly.
 627     private void shutdownInput(
 628             boolean checkCloseNotify) throws IOException {
 629         if (isInputShutdown()) {
 630             return;
 631         }
 632 
 633         if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
 634             SSLLogger.fine("close inbound of SSLSocket");
 635         }
 636 
 637         // Is it ready to close inbound?
 638         //
 639         // No need to throw exception if the initial handshake is not started.
 640         if (checkCloseNotify && !conContext.isInputCloseNotified &&
 641             (conContext.isNegotiated || conContext.handshakeContext != null)) {
 642 
 643             throw conContext.fatal(Alert.INTERNAL_ERROR,
 644                     "closing inbound before receiving peer's close_notify");
 645         }
 646 
 647         conContext.closeInbound();
 648         if ((autoClose || !isLayered()) && !super.isInputShutdown()) {
 649             super.shutdownInput();
 650         }
 651     }
 652 
 653     @Override
 654     public boolean isInputShutdown() {
 655         return conContext.isInboundClosed() &&
 656                 ((autoClose || !isLayered()) ? super.isInputShutdown(): true);
 657     }
 658 
 659     // Please don't synchronized this method.  Otherwise, the read and close
 660     // locks may be deadlocked.
 661     @Override
 662     public void shutdownOutput() throws IOException {
 663         if (isOutputShutdown()) {
 664             return;
 665         }
 666 
 667         if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
 668             SSLLogger.fine("close outbound of SSLSocket");
 669         }
 670         conContext.closeOutbound();
 671 
 672         if ((autoClose || !isLayered()) && !super.isOutputShutdown()) {
 673             super.shutdownOutput();
 674         }
 675     }
 676 
 677     @Override
 678     public boolean isOutputShutdown() {
 679         return conContext.isOutboundClosed() &&
 680                 ((autoClose || !isLayered()) ? super.isOutputShutdown(): true);
 681     }
 682 
 683     @Override
 684     public synchronized InputStream getInputStream() throws IOException {
 685         if (isClosed()) {
 686             throw new SocketException("Socket is closed");
 687         }
 688 
 689         if (!isConnected) {
 690             throw new SocketException("Socket is not connected");
 691         }
 692 
 693         if (conContext.isInboundClosed() || isInputShutdown()) {
 694             throw new SocketException("Socket input is already shutdown");
 695         }
 696 
 697         return appInput;
 698     }
 699 
 700     private void ensureNegotiated() throws IOException {
 701         if (conContext.isNegotiated || conContext.isBroken ||
 702                 conContext.isInboundClosed() || conContext.isOutboundClosed()) {
 703             return;
 704         }
 705 
 706         synchronized (conContext) {     // handshake lock
 707             // double check the context status
 708             if (conContext.isNegotiated || conContext.isBroken ||
 709                     conContext.isInboundClosed() ||
 710                     conContext.isOutboundClosed()) {
 711                 return;
 712             }
 713 
 714             startHandshake();
 715         }
 716     }
 717 
 718     /**
 719      * InputStream for application data as returned by
 720      * SSLSocket.getInputStream().
 721      */
 722     private class AppInputStream extends InputStream {
 723         // One element array used to implement the single byte read() method
 724         private final byte[] oneByte = new byte[1];
 725 
 726         // the temporary buffer used to read network
 727         private ByteBuffer buffer;
 728 
 729         // Is application data available in the stream?
 730         private volatile boolean appDataIsAvailable;
 731 
 732         AppInputStream() {
 733             this.appDataIsAvailable = false;
 734             this.buffer = ByteBuffer.allocate(4096);
 735         }
 736 
 737         /**
 738          * Return the minimum number of bytes that can be read
 739          * without blocking.
 740          */
 741         @Override
 742         public int available() throws IOException {
 743             // Currently not synchronized.
 744             if ((!appDataIsAvailable) || checkEOF()) {
 745                 return 0;
 746             }
 747 
 748             return buffer.remaining();
 749         }
 750 
 751         /**
 752          * Read a single byte, returning -1 on non-fault EOF status.
 753          */
 754         @Override
 755         public int read() throws IOException {
 756             int n = read(oneByte, 0, 1);
 757             if (n <= 0) {   // EOF
 758                 return -1;
 759             }
 760 
 761             return oneByte[0] & 0xFF;
 762         }
 763 
 764         /**
 765          * Reads up to {@code len} bytes of data from the input stream
 766          * into an array of bytes.
 767          *
 768          * An attempt is made to read as many as {@code len} bytes, but a
 769          * smaller number may be read. The number of bytes actually read
 770          * is returned as an integer.
 771          *
 772          * If the layer above needs more data, it asks for more, so we
 773          * are responsible only for blocking to fill at most one buffer,
 774          * and returning "-1" on non-fault EOF status.
 775          */
 776         @Override
 777         public int read(byte[] b, int off, int len)
 778                 throws IOException {
 779             if (b == null) {
 780                 throw new NullPointerException("the target buffer is null");
 781             } else if (off < 0 || len < 0 || len > b.length - off) {
 782                 throw new IndexOutOfBoundsException(
 783                         "buffer length: " + b.length + ", offset; " + off +
 784                         ", bytes to read:" + len);
 785             } else if (len == 0) {
 786                 return 0;
 787             }
 788 
 789             if (checkEOF()) {
 790                 return -1;
 791             }
 792 
 793             // start handshaking if the connection has not been negotiated.
 794             if (!conContext.isNegotiated && !conContext.isBroken &&
 795                     !conContext.isInboundClosed() &&
 796                     !conContext.isOutboundClosed()) {
 797                 ensureNegotiated();
 798             }
 799 
 800             // Check if the Socket is invalid (error or closed).
 801             if (!conContext.isNegotiated ||
 802                     conContext.isBroken || conContext.isInboundClosed()) {
 803                 throw new SocketException("Connection or inbound has closed");
 804             }
 805 
 806             // Read the available bytes at first.
 807             //
 808             // Note that the receiving and processing of post-handshake message
 809             // are also synchronized with the read lock.
 810             synchronized (this) {
 811                 int remains = available();
 812                 if (remains > 0) {
 813                     int howmany = Math.min(remains, len);
 814                     buffer.get(b, off, howmany);
 815 
 816                     return howmany;
 817                 }
 818 
 819                 appDataIsAvailable = false;
 820                 try {
 821                     ByteBuffer bb = readApplicationRecord(buffer);
 822                     if (bb == null) {   // EOF
 823                         return -1;
 824                     } else {
 825                         // The buffer may be reallocated for bigger capacity.
 826                         buffer = bb;
 827                     }
 828 
 829                     bb.flip();
 830                     int volume = Math.min(len, bb.remaining());
 831                     buffer.get(b, off, volume);
 832                     appDataIsAvailable = true;
 833 
 834                     return volume;
 835                 } catch (Exception e) {   // including RuntimeException
 836                     // shutdown and rethrow (wrapped) exception as appropriate
 837                     handleException(e);
 838 
 839                     // dummy for compiler
 840                     return -1;
 841                 }
 842             }
 843         }
 844 
 845         /**
 846          * Skip n bytes.
 847          *
 848          * This implementation is somewhat less efficient than possible, but
 849          * not badly so (redundant copy).  We reuse the read() code to keep
 850          * things simpler.
 851          */
 852         @Override
 853         public synchronized long skip(long n) throws IOException {
 854             // dummy array used to implement skip()
 855             byte[] skipArray = new byte[256];
 856 
 857             long skipped = 0;
 858             while (n > 0) {
 859                 int len = (int)Math.min(n, skipArray.length);
 860                 int r = read(skipArray, 0, len);
 861                 if (r <= 0) {
 862                     break;
 863                 }
 864                 n -= r;
 865                 skipped += r;
 866             }
 867 
 868             return skipped;
 869         }
 870 
 871         @Override
 872         public void close() throws IOException {
 873             if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
 874                 SSLLogger.finest("Closing input stream");
 875             }
 876 
 877             try {
 878                 SSLSocketImpl.this.close();
 879             } catch (IOException ioe) {
 880                 // ignore the exception
 881                 if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
 882                     SSLLogger.warning("input stream close failed", ioe);
 883                 }
 884             }
 885         }
 886 
 887         /**
 888          * Return whether we have reached end-of-file.
 889          *
 890          * If the socket is not connected, has been shutdown because of an error
 891          * or has been closed, throw an Exception.
 892          */
 893         private boolean checkEOF() throws IOException {
 894             if (conContext.isInboundClosed()) {
 895                 return true;
 896             } else if (conContext.isInputCloseNotified || conContext.isBroken) {
 897                 if (conContext.closeReason == null) {
 898                     return true;
 899                 } else {
 900                     throw new SSLException(
 901                         "Connection has closed: " + conContext.closeReason,
 902                         conContext.closeReason);
 903                 }
 904             }
 905 
 906             return false;
 907         }
 908 
 909         /**
 910          * Try the best to use up the input records so as to close the
 911          * socket gracefully, without impact the performance too much.
 912          */
 913         private synchronized void deplete() {
 914             if (!conContext.isInboundClosed()) {
 915                 if (!(conContext.inputRecord instanceof SSLSocketInputRecord)) {
 916                     return;
 917                 }
 918 
 919                 SSLSocketInputRecord socketInputRecord =
 920                         (SSLSocketInputRecord)conContext.inputRecord;
 921                 try {
 922                     socketInputRecord.deplete(
 923                         conContext.isNegotiated && (getSoTimeout() > 0));
 924                 } catch (IOException ioe) {
 925                     if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
 926                         SSLLogger.warning(
 927                             "input stream close depletion failed", ioe);
 928                     }
 929                 }
 930             }
 931         }
 932     }
 933 
 934     @Override
 935     public synchronized OutputStream getOutputStream() throws IOException {
 936         if (isClosed()) {
 937             throw new SocketException("Socket is closed");
 938         }
 939 
 940         if (!isConnected) {
 941             throw new SocketException("Socket is not connected");
 942         }
 943 
 944         if (conContext.isOutboundDone() || isOutputShutdown()) {
 945             throw new SocketException("Socket output is already shutdown");
 946         }
 947 
 948         return appOutput;
 949     }
 950 
 951 
 952     /**
 953      * OutputStream for application data as returned by
 954      * SSLSocket.getOutputStream().
 955      */
 956     private class AppOutputStream extends OutputStream {
 957         // One element array used to implement the write(byte) method
 958         private final byte[] oneByte = new byte[1];
 959 
 960         @Override
 961         public void write(int i) throws IOException {
 962             oneByte[0] = (byte)i;
 963             write(oneByte, 0, 1);
 964         }
 965 
 966         @Override
 967         public void write(byte[] b,
 968                 int off, int len) throws IOException {
 969             if (b == null) {
 970                 throw new NullPointerException("the source buffer is null");
 971             } else if (off < 0 || len < 0 || len > b.length - off) {
 972                 throw new IndexOutOfBoundsException(
 973                         "buffer length: " + b.length + ", offset; " + off +
 974                         ", bytes to read:" + len);
 975             } else if (len == 0) {
 976                 //
 977                 // Don't bother to really write empty records.  We went this
 978                 // far to drive the handshake machinery, for correctness; not
 979                 // writing empty records improves performance by cutting CPU
 980                 // time and network resource usage.  However, some protocol
 981                 // implementations are fragile and don't like to see empty
 982                 // records, so this also increases robustness.
 983                 //
 984                 return;
 985             }
 986 
 987             // Start handshaking if the connection has not been negotiated.
 988             if (!conContext.isNegotiated && !conContext.isBroken &&
 989                     !conContext.isInboundClosed() &&
 990                     !conContext.isOutboundClosed()) {
 991                 ensureNegotiated();
 992             }
 993 
 994             // Check if the Socket is invalid (error or closed).
 995             if (!conContext.isNegotiated ||
 996                     conContext.isBroken || conContext.isOutboundClosed()) {
 997                 throw new SocketException("Connection or outbound has closed");
 998             }
 999 
1000             //
1001 
1002             // Delegate the writing to the underlying socket.
1003             try {
1004                 conContext.outputRecord.deliver(b, off, len);
1005             } catch (SSLHandshakeException she) {
1006                 // may be record sequence number overflow
1007                 throw conContext.fatal(Alert.HANDSHAKE_FAILURE, she);
1008             } catch (IOException e) {
1009                 throw conContext.fatal(Alert.UNEXPECTED_MESSAGE, e);
1010             }
1011 
1012             // Is the sequence number is nearly overflow, or has the key usage
1013             // limit been reached?
1014             if (conContext.outputRecord.seqNumIsHuge() ||
1015                     conContext.outputRecord.writeCipher.atKeyLimit()) {
1016                 tryKeyUpdate();
1017             }
1018         }
1019 
1020         @Override
1021         public void close() throws IOException {
1022             if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
1023                 SSLLogger.finest("Closing output stream");
1024             }
1025 
1026             try {
1027                 SSLSocketImpl.this.close();
1028             } catch (IOException ioe) {
1029                 // ignore the exception
1030                 if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
1031                     SSLLogger.warning("output stream close failed", ioe);
1032                 }
1033             }
1034         }
1035     }
1036 
1037     @Override
1038     public synchronized SSLParameters getSSLParameters() {
1039         return conContext.sslConfig.getSSLParameters();
1040     }
1041 
1042     @Override
1043     public synchronized void setSSLParameters(SSLParameters params) {
1044         conContext.sslConfig.setSSLParameters(params);
1045 
1046         if (conContext.sslConfig.maximumPacketSize != 0) {
1047             conContext.outputRecord.changePacketSize(
1048                     conContext.sslConfig.maximumPacketSize);
1049         }
1050     }
1051 
1052     @Override
1053     public synchronized String getApplicationProtocol() {
1054         return conContext.applicationProtocol;
1055     }
1056 
1057     @Override
1058     public synchronized String getHandshakeApplicationProtocol() {
1059         if (conContext.handshakeContext != null) {
1060             return conContext.handshakeContext.applicationProtocol;
1061         }
1062 
1063         return null;
1064     }
1065 
1066     @Override
1067     public synchronized void setHandshakeApplicationProtocolSelector(
1068             BiFunction<SSLSocket, List<String>, String> selector) {
1069         conContext.sslConfig.socketAPSelector = selector;
1070     }
1071 
1072     @Override
1073     public synchronized BiFunction<SSLSocket, List<String>, String>
1074             getHandshakeApplicationProtocolSelector() {
1075         return conContext.sslConfig.socketAPSelector;
1076     }
1077 
1078     /**
1079      * Read the initial handshake records.
1080      */
1081     private int readHandshakeRecord() throws IOException {
1082         while (!conContext.isInboundClosed()) {
1083             try {
1084                 Plaintext plainText = decode(null);
1085                 if ((plainText.contentType == ContentType.HANDSHAKE.id) &&
1086                         conContext.isNegotiated) {
1087                     return 0;
1088                 }
1089             } catch (SSLException ssle) {
1090                 throw ssle;
1091             } catch (IOException ioe) {
1092                 if (!(ioe instanceof SSLException)) {
1093                     throw new SSLException("readHandshakeRecord", ioe);
1094                 } else {
1095                     throw ioe;
1096                 }
1097             }
1098         }
1099 
1100         return -1;
1101     }
1102 
1103     /**
1104      * Read application data record. Used by AppInputStream only, but defined
1105      * here so as to use the socket level synchronization.
1106      *
1107      * Note that the connection guarantees that handshake, alert, and change
1108      * cipher spec data streams are handled as they arrive, so we never see
1109      * them here.
1110      *
1111      * Note: Please be careful about the synchronization, and don't use this
1112      * method other than in the AppInputStream class!
1113      */
1114     private ByteBuffer readApplicationRecord(
1115             ByteBuffer buffer) throws IOException {
1116         while (!conContext.isInboundClosed()) {
1117             /*
1118              * clean the buffer and check if it is too small, e.g. because
1119              * the AppInputStream did not have the chance to see the
1120              * current packet length but rather something like that of the
1121              * handshake before. In that case we return 0 at this point to
1122              * give the caller the chance to adjust the buffer.
1123              */
1124             buffer.clear();
1125             int inLen = conContext.inputRecord.bytesInCompletePacket();
1126             if (inLen < 0) {    // EOF
1127                 handleEOF(null);
1128 
1129                 // if no exception thrown
1130                 return null;
1131             }
1132 
1133             // Is this packet bigger than SSL/TLS normally allows?
1134             if (inLen > SSLRecord.maxLargeRecordSize) {
1135                 throw new SSLProtocolException(
1136                         "Illegal packet size: " + inLen);
1137             }
1138 
1139             if (inLen > buffer.remaining()) {
1140                 buffer = ByteBuffer.allocate(inLen);
1141             }
1142 
1143             try {
1144                 Plaintext plainText;
1145                 synchronized (this) {
1146                     plainText = decode(buffer);
1147                 }
1148                 if (plainText.contentType == ContentType.APPLICATION_DATA.id &&
1149                         buffer.position() > 0) {
1150                     return buffer;
1151                 }
1152             } catch (SSLException ssle) {
1153                 throw ssle;
1154             } catch (IOException ioe) {
1155                 if (!(ioe instanceof SSLException)) {
1156                     throw new SSLException("readApplicationRecord", ioe);
1157                 } else {
1158                     throw ioe;
1159                 }
1160             }
1161         }
1162 
1163         //
1164         // couldn't read, due to some kind of error
1165         //
1166         return null;
1167     }
1168 
1169     private Plaintext decode(ByteBuffer destination) throws IOException {
1170         Plaintext plainText;
1171         try {
1172             if (destination == null) {
1173                 plainText = SSLTransport.decode(conContext,
1174                         null, 0, 0, null, 0, 0);
1175             } else {
1176                 plainText = SSLTransport.decode(conContext,
1177                         null, 0, 0, new ByteBuffer[]{destination}, 0, 1);
1178             }
1179         } catch (EOFException eofe) {
1180             // EOFException is special as it is related to close_notify.
1181             plainText = handleEOF(eofe);
1182         }
1183 
1184         // Is the sequence number is nearly overflow?
1185         if (plainText != Plaintext.PLAINTEXT_NULL &&
1186                 (conContext.inputRecord.seqNumIsHuge() ||
1187                 conContext.inputRecord.readCipher.atKeyLimit())) {
1188             tryKeyUpdate();
1189         }
1190 
1191         return plainText;
1192     }
1193 
1194     /**
1195      * Try key update for sequence number wrap or key usage limit.
1196      *
1197      * Note that in order to maintain the handshake status properly, we check
1198      * the sequence number and key usage limit after the last record
1199      * reading/writing process.
1200      *
1201      * As we request renegotiation or close the connection for wrapped sequence
1202      * number when there is enough sequence number space left to handle a few
1203      * more records, so the sequence number of the last record cannot be
1204      * wrapped.
1205      */
1206     private void tryKeyUpdate() throws IOException {
1207         // Don't bother to kickstart if handshaking is in progress, or if the
1208         // connection is not duplex-open.
1209         if ((conContext.handshakeContext == null) &&
1210                 !conContext.isOutboundClosed() &&
1211                 !conContext.isInboundClosed() &&
1212                 !conContext.isBroken) {
1213             if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
1214                 SSLLogger.finest("trigger key update");
1215             }
1216             startHandshake();
1217         }
1218     }
1219 
1220     /**
1221      * Initialize the handshaker and socket streams.
1222      *
1223      * Called by connect, the layered constructor, and SSLServerSocket.
1224      */
1225     synchronized void doneConnect() throws IOException {
1226         // In server mode, it is not necessary to set host and serverNames.
1227         // Otherwise, would require a reverse DNS lookup to get the hostname.
1228         if (peerHost == null || peerHost.isEmpty()) {
1229             boolean useNameService =
1230                     trustNameService && conContext.sslConfig.isClientMode;
1231             useImplicitHost(useNameService);
1232         } else {
1233             conContext.sslConfig.serverNames =
1234                     Utilities.addToSNIServerNameList(
1235                             conContext.sslConfig.serverNames, peerHost);
1236         }
1237 
1238         InputStream sockInput = super.getInputStream();
1239         conContext.inputRecord.setReceiverStream(sockInput);
1240 
1241         OutputStream sockOutput = super.getOutputStream();
1242         conContext.inputRecord.setDeliverStream(sockOutput);
1243         conContext.outputRecord.setDeliverStream(sockOutput);
1244 
1245         this.isConnected = true;
1246     }
1247 
1248     private void useImplicitHost(boolean useNameService) {
1249         // Note: If the local name service is not trustworthy, reverse
1250         // host name resolution should not be performed for endpoint
1251         // identification.  Use the application original specified
1252         // hostname or IP address instead.
1253 
1254         // Get the original hostname via jdk.internal.misc.SharedSecrets
1255         InetAddress inetAddress = getInetAddress();
1256         if (inetAddress == null) {      // not connected
1257             return;
1258         }
1259 
1260         String originalHostname = SharedSecrets.getJavaNetAccess().getOriginalHostName(inetAddress);
1261         if (originalHostname != null && !originalHostname.isEmpty()) {
1262 
1263             this.peerHost = originalHostname;
1264             if (conContext.sslConfig.serverNames.isEmpty() &&
1265                     !conContext.sslConfig.noSniExtension) {
1266                 conContext.sslConfig.serverNames =
1267                         Utilities.addToSNIServerNameList(
1268                                 conContext.sslConfig.serverNames, peerHost);
1269             }
1270 
1271             return;
1272         }
1273 
1274         // No explicitly specified hostname, no server name indication.
1275         if (!useNameService) {
1276             // The local name service is not trustworthy, use IP address.
1277             this.peerHost = inetAddress.getHostAddress();
1278         } else {
1279             // Use the underlying reverse host name resolution service.
1280             this.peerHost = getInetAddress().getHostName();
1281         }
1282     }
1283 
1284     // ONLY used by HttpsClient to setup the URI specified hostname
1285     //
1286     // Please NOTE that this method MUST be called before calling to
1287     // SSLSocket.setSSLParameters(). Otherwise, the {@code host} parameter
1288     // may override SNIHostName in the customized server name indication.
1289     public synchronized void setHost(String host) {
1290         this.peerHost = host;
1291         this.conContext.sslConfig.serverNames =
1292                 Utilities.addToSNIServerNameList(
1293                         conContext.sslConfig.serverNames, host);
1294     }
1295 
1296     /**
1297      * Handle an exception.
1298      *
1299      * This method is called by top level exception handlers (in read(),
1300      * write()) to make sure we always shutdown the connection correctly
1301      * and do not pass runtime exception to the application.
1302      *
1303      * This method never returns normally, it always throws an IOException.
1304      */
1305     private void handleException(Exception cause) throws IOException {
1306         if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
1307             SSLLogger.warning("handling exception", cause);
1308         }
1309 
1310         // Don't close the Socket in case of timeouts or interrupts.
1311         if (cause instanceof InterruptedIOException) {
1312             throw (IOException)cause;
1313         }
1314 
1315         // need to perform error shutdown
1316         boolean isSSLException = (cause instanceof SSLException);
1317         Alert alert;
1318         if (isSSLException) {
1319             if (cause instanceof SSLHandshakeException) {
1320                 alert = Alert.HANDSHAKE_FAILURE;
1321             } else {
1322                 alert = Alert.UNEXPECTED_MESSAGE;
1323             }
1324         } else {
1325             if (cause instanceof IOException) {
1326                 alert = Alert.UNEXPECTED_MESSAGE;
1327             } else {
1328                 // RuntimeException
1329                 alert = Alert.INTERNAL_ERROR;
1330             }
1331         }
1332 
1333         throw conContext.fatal(alert, cause);
1334     }
1335 
1336     private Plaintext handleEOF(EOFException eofe) throws IOException {
1337         if (requireCloseNotify || conContext.handshakeContext != null) {
1338             SSLException ssle;
1339             if (conContext.handshakeContext != null) {
1340                 ssle = new SSLHandshakeException(
1341                         "Remote host terminated the handshake");
1342             } else {
1343                 ssle = new SSLProtocolException(
1344                         "Remote host terminated the connection");
1345             }
1346 
1347             if (eofe != null) {
1348                 ssle.initCause(eofe);
1349             }
1350             throw ssle;
1351         } else {
1352             // treat as if we had received a close_notify
1353             conContext.isInputCloseNotified = true;
1354             shutdownInput();
1355 
1356             return Plaintext.PLAINTEXT_NULL;
1357         }
1358     }
1359 
1360 
1361     @Override
1362     public String getPeerHost() {
1363         return peerHost;
1364     }
1365 
1366     @Override
1367     public int getPeerPort() {
1368         return getPort();
1369     }
1370 
1371     @Override
1372     public boolean useDelegatedTask() {
1373         return false;
1374     }
1375 
1376     @Override
1377     public void shutdown() throws IOException {
1378         if (!isClosed()) {
1379             if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
1380                 SSLLogger.fine("close the underlying socket");
1381             }
1382 
1383             try {
1384                 if (conContext.isInputCloseNotified) {
1385                     // Close the connection, no wait for more peer response.
1386                     closeSocket(false);
1387                 } else {
1388                     // Close the connection, may wait for peer close_notify.
1389                     closeSocket(true);
1390                 }
1391             } finally {
1392                 tlsIsClosed = true;
1393             }
1394         }
1395     }
1396 
1397     private void closeSocket(boolean selfInitiated) throws IOException {
1398         if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
1399             SSLLogger.fine("close the SSL connection " +
1400                 (selfInitiated ? "(initiative)" : "(passive)"));
1401         }
1402 
1403         if (autoClose || !isLayered()) {
1404             super.close();
1405         } else if (selfInitiated) {
1406             if (!conContext.isInboundClosed() && !isInputShutdown()) {
1407                 // wait for close_notify alert to clear input stream.
1408                 waitForClose();
1409             }
1410         }
1411     }
1412 
1413    /**
1414     * Wait for close_notify alert for a graceful closure.
1415     *
1416     * [RFC 5246] If the application protocol using TLS provides that any
1417     * data may be carried over the underlying transport after the TLS
1418     * connection is closed, the TLS implementation must receive the responding
1419     * close_notify alert before indicating to the application layer that
1420     * the TLS connection has ended.  If the application protocol will not
1421     * transfer any additional data, but will only close the underlying
1422     * transport connection, then the implementation MAY choose to close the
1423     * transport without waiting for the responding close_notify.
1424     */
1425     private void waitForClose() throws IOException {
1426         if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
1427             SSLLogger.fine("wait for close_notify or alert");
1428         }
1429 
1430         while (!conContext.isInboundClosed()) {
1431             try {
1432                 Plaintext plainText = decode(null);
1433                 // discard and continue
1434                 if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
1435                     SSLLogger.finest(
1436                         "discard plaintext while waiting for close", plainText);
1437                 }
1438             } catch (Exception e) {   // including RuntimeException
1439                 handleException(e);
1440             }
1441         }
1442     }
1443 }