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