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