< prev index next >

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

Print this page




  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.access.JavaNetInetAddressAccess;
  52 import jdk.internal.access.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


  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,


 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 {


 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 


 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         // closing status
 830         private volatile boolean isClosing;
 831         private volatile boolean hasDepleted;
 832 
 833         AppInputStream() {
 834             this.appDataIsAvailable = false;
 835             this.buffer = ByteBuffer.allocate(4096);
 836         }
 837 
 838         /**
 839          * Return the minimum number of bytes that can be read
 840          * without blocking.
 841          */
 842         @Override
 843         public int available() throws IOException {
 844             // Currently not synchronized.
 845             if ((!appDataIsAvailable) || checkEOF()) {
 846                 return 0;
 847             }
 848 
 849             return buffer.remaining();
 850         }
 851 
 852         /**


 858             if (n <= 0) {   // EOF
 859                 return -1;
 860             }
 861 
 862             return oneByte[0] & 0xFF;
 863         }
 864 
 865         /**
 866          * Reads up to {@code len} bytes of data from the input stream
 867          * into an array of bytes.
 868          *
 869          * An attempt is made to read as many as {@code len} bytes, but a
 870          * smaller number may be read. The number of bytes actually read
 871          * is returned as an integer.
 872          *
 873          * If the layer above needs more data, it asks for more, so we
 874          * are responsible only for blocking to fill at most one buffer,
 875          * and returning "-1" on non-fault EOF status.
 876          */
 877         @Override
 878         public int read(byte[] b, int off, int len) throws IOException {

 879             if (b == null) {
 880                 throw new NullPointerException("the target buffer is null");
 881             } else if (off < 0 || len < 0 || len > b.length - off) {
 882                 throw new IndexOutOfBoundsException(
 883                         "buffer length: " + b.length + ", offset; " + off +
 884                         ", bytes to read:" + len);
 885             } else if (len == 0) {
 886                 return 0;
 887             }
 888 
 889             if (checkEOF()) {
 890                 return -1;
 891             }
 892 
 893             // start handshaking if the connection has not been negotiated.
 894             if (!conContext.isNegotiated && !conContext.isBroken &&
 895                     !conContext.isInboundClosed() &&
 896                     !conContext.isOutboundClosed()) {
 897                 ensureNegotiated();
 898             }
 899 
 900             // Check if the Socket is invalid (error or closed).
 901             if (!conContext.isNegotiated ||
 902                     conContext.isBroken || conContext.isInboundClosed()) {
 903                 throw new SocketException("Connection or inbound has closed");
 904             }
 905 
 906             // Check if the input stream has been depleted.
 907             //
 908             // Note that the "hasDepleted" rather than the isClosing
 909             // filed is checked here, in case the closing process is
 910             // still in progress.
 911             if (hasDepleted) {
 912                 if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
 913                     SSLLogger.fine("The input stream has been depleted");
 914                 }
 915 
 916                 return -1;
 917             }
 918 
 919             // Read the available bytes at first.
 920             //
 921             // Note that the receiving and processing of post-handshake message
 922             // are also synchronized with the read lock.
 923             readLock.lock();
 924             try {
 925                 // Double check if the Socket is invalid (error or closed).
 926                 if (conContext.isBroken || conContext.isInboundClosed()) {
 927                     throw new SocketException(
 928                             "Connection or inbound has closed");
 929                 }
 930 
 931                 // Double check if the input stream has been depleted.
 932                 if (hasDepleted) {
 933                     if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
 934                         SSLLogger.fine("The input stream is closing");
 935                     }
 936 
 937                     return -1;
 938                 }
 939 
 940                 int remains = available();
 941                 if (remains > 0) {
 942                     int howmany = Math.min(remains, len);
 943                     buffer.get(b, off, howmany);
 944 
 945                     return howmany;
 946                 }
 947 
 948                 appDataIsAvailable = false;
 949                 try {
 950                     ByteBuffer bb = readApplicationRecord(buffer);
 951                     if (bb == null) {   // EOF
 952                         return -1;
 953                     } else {
 954                         // The buffer may be reallocated for bigger capacity.
 955                         buffer = bb;
 956                     }
 957 
 958                     bb.flip();
 959                     int volume = Math.min(len, bb.remaining());
 960                     buffer.get(b, off, volume);
 961                     appDataIsAvailable = true;
 962 
 963                     return volume;
 964                 } catch (Exception e) {   // including RuntimeException
 965                     // shutdown and rethrow (wrapped) exception as appropriate
 966                     handleException(e);
 967 
 968                     // dummy for compiler
 969                     return -1;
 970                 }
 971             } finally {
 972                 // Check if the input stream is closing.
 973                 //
 974                 // If the deplete() did not hold the lock, clean up the
 975                 // input stream here.
 976                 try {
 977                     if (isClosing) {
 978                         readLockedDeplete();
 979                     }
 980                 } finally {
 981                     readLock.unlock();
 982                 }
 983             }
 984         }
 985 
 986         /**
 987          * Skip n bytes.
 988          *
 989          * This implementation is somewhat less efficient than possible, but
 990          * not badly so (redundant copy).  We reuse the read() code to keep
 991          * things simpler.
 992          */
 993         @Override
 994         public long skip(long n) throws IOException {
 995             // dummy array used to implement skip()
 996             byte[] skipArray = new byte[256];
 997             long skipped = 0;
 998 
 999             readLock.lock();
1000             try {
1001                 while (n > 0) {
1002                     int len = (int)Math.min(n, skipArray.length);
1003                     int r = read(skipArray, 0, len);
1004                     if (r <= 0) {
1005                         break;
1006                     }
1007                     n -= r;
1008                     skipped += r;
1009                 }
1010             } finally {
1011                 readLock.unlock();
1012             }
1013 
1014             return skipped;
1015         }
1016 
1017         @Override
1018         public void close() throws IOException {
1019             if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
1020                 SSLLogger.finest("Closing input stream");
1021             }
1022 
1023             try {
1024                 SSLSocketImpl.this.close();
1025             } catch (IOException ioe) {
1026                 // ignore the exception
1027                 if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
1028                     SSLLogger.warning("input stream close failed", ioe);
1029                 }
1030             }
1031         }
1032 
1033         /**
1034          * Return whether we have reached end-of-file.
1035          *
1036          * If the socket is not connected, has been shutdown because of an error
1037          * or has been closed, throw an Exception.
1038          */
1039         private boolean checkEOF() throws IOException {
1040             if (conContext.isInboundClosed()) {
1041                 return true;
1042             } else if (conContext.isInputCloseNotified || conContext.isBroken) {
1043                 if (conContext.closeReason == null) {
1044                     return true;
1045                 } else {
1046                     throw new SSLException(
1047                         "Connection has closed: " + conContext.closeReason,
1048                         conContext.closeReason);
1049                 }
1050             }
1051 
1052             return false;
1053         }
1054 
1055         /**
1056          * Try the best to use up the input records so as to close the
1057          * socket gracefully, without impact the performance too much.
1058          */
1059         private void deplete() {
1060             if (conContext.isInboundClosed() || isClosing) {
1061                 return;
1062             }
1063 
1064             isClosing = true;
1065             if (readLock.tryLock()) {
1066                 try {
1067                     readLockedDeplete();
1068                 } finally {
1069                     readLock.unlock();
1070                 }
1071             }
1072         }
1073 
1074         /**
1075          * Try to use up the input records.
1076          *
1077          * Please don't call this method unless the readLock is held by
1078          * the current thread.
1079          */
1080         private void readLockedDeplete() {
1081             // double check
1082             if (hasDepleted || conContext.isInboundClosed()) {
1083                 return;
1084             }
1085 
1086             if (!(conContext.inputRecord instanceof SSLSocketInputRecord)) {
1087                 return;
1088             }
1089 
1090             SSLSocketInputRecord socketInputRecord =
1091                     (SSLSocketInputRecord)conContext.inputRecord;
1092             try {
1093                 socketInputRecord.deplete(
1094                     conContext.isNegotiated && (getSoTimeout() > 0));
1095             } catch (Exception ex) {
1096                 if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
1097                     SSLLogger.warning(
1098                         "input stream close depletion failed", ex);

1099                 }
1100             } finally {
1101                 hasDepleted = true;
1102             }
1103         }
1104     }
1105 
1106     @Override
1107     public OutputStream getOutputStream() throws IOException {
1108         socketLock.lock();
1109         try {
1110             if (isClosed()) {
1111                 throw new SocketException("Socket is closed");
1112             }
1113 
1114             if (!isConnected) {
1115                 throw new SocketException("Socket is not connected");
1116             }
1117 
1118             if (conContext.isOutboundDone() || isOutputShutdown()) {
1119                 throw new SocketException("Socket output is already shutdown");
1120             }
1121 
1122             return appOutput;
1123         } finally {
1124             socketLock.unlock();
1125         }


1126     }
1127 
1128 
1129     /**
1130      * OutputStream for application data as returned by
1131      * SSLSocket.getOutputStream().
1132      */
1133     private class AppOutputStream extends OutputStream {
1134         // One element array used to implement the write(byte) method
1135         private final byte[] oneByte = new byte[1];
1136 
1137         @Override
1138         public void write(int i) throws IOException {
1139             oneByte[0] = (byte)i;
1140             write(oneByte, 0, 1);
1141         }
1142 
1143         @Override
1144         public void write(byte[] b,
1145                 int off, int len) throws IOException {


1184                 throw conContext.fatal(Alert.HANDSHAKE_FAILURE, she);
1185             } catch (IOException e) {
1186                 throw conContext.fatal(Alert.UNEXPECTED_MESSAGE, e);
1187             }
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;


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;


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.access.SharedSecrets
1471         InetAddress inetAddress = getInetAddress();
1472         if (inetAddress == null) {      // not connected
1473             return;
1474         }
1475 
1476         JavaNetInetAddressAccess jna =
1477                 SharedSecrets.getJavaNetInetAddressAccess();
1478         String originalHostname = jna.getOriginalHostName(inetAddress);
1479         if (originalHostname != null && !originalHostname.isEmpty()) {
1480 
1481             this.peerHost = originalHostname;


1487             }
1488 
1489             return;
1490         }
1491 
1492         // No explicitly specified hostname, no server name indication.
1493         if (!useNameService) {
1494             // The local name service is not trustworthy, use IP address.
1495             this.peerHost = inetAddress.getHostAddress();
1496         } else {
1497             // Use the underlying reverse host name resolution service.
1498             this.peerHost = getInetAddress().getHostName();
1499         }
1500     }
1501 
1502     // ONLY used by HttpsClient to setup the URI specified hostname
1503     //
1504     // Please NOTE that this method MUST be called before calling to
1505     // SSLSocket.setSSLParameters(). Otherwise, the {@code host} parameter
1506     // may override SNIHostName in the customized server name indication.
1507     public void setHost(String host) {
1508         socketLock.lock();
1509         try {
1510             this.peerHost = host;
1511             this.conContext.sslConfig.serverNames =
1512                     Utilities.addToSNIServerNameList(
1513                             conContext.sslConfig.serverNames, host);
1514         } finally {
1515             socketLock.unlock();
1516         }
1517     }
1518 
1519     /**
1520      * Handle an exception.
1521      *
1522      * This method is called by top level exception handlers (in read(),
1523      * write()) to make sure we always shutdown the connection correctly
1524      * and do not pass runtime exception to the application.
1525      *
1526      * This method never returns normally, it always throws an IOException.
1527      */
1528     private void handleException(Exception cause) throws IOException {
1529         if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
1530             SSLLogger.warning("handling exception", cause);
1531         }
1532 
1533         // Don't close the Socket in case of timeouts or interrupts.
1534         if (cause instanceof InterruptedIOException) {
1535             throw (IOException)cause;
1536         }




  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package sun.security.ssl;
  27 
  28 import java.io.EOFException;
  29 import java.io.IOException;
  30 import java.io.InputStream;
  31 import java.io.InterruptedIOException;
  32 import java.io.OutputStream;
  33 import java.net.InetAddress;
  34 import java.net.InetSocketAddress;
  35 import java.net.Socket;
  36 import java.net.SocketAddress;
  37 import java.net.SocketException;
  38 import java.net.UnknownHostException;
  39 import java.nio.ByteBuffer;
  40 import java.util.List;

  41 import java.util.function.BiFunction;
  42 import javax.net.ssl.HandshakeCompletedListener;
  43 import javax.net.ssl.SSLException;
  44 import javax.net.ssl.SSLHandshakeException;
  45 import javax.net.ssl.SSLParameters;
  46 import javax.net.ssl.SSLProtocolException;
  47 import javax.net.ssl.SSLServerSocket;
  48 import javax.net.ssl.SSLSession;
  49 import javax.net.ssl.SSLSocket;
  50 import jdk.internal.access.JavaNetInetAddressAccess;
  51 import jdk.internal.access.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


  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     /*
  88      * Is the local name service trustworthy?
  89      *
  90      * If the local name service is not trustworthy, reverse host name
  91      * resolution should not be performed for endpoint identification.
  92      */
  93     private static final boolean trustNameService =
  94             Utilities.getBooleanProperty("jdk.tls.trustNameService", false);
  95 
  96     /**
  97      * Package-private constructor used to instantiate an unconnected
  98      * socket.
  99      *
 100      * This instance is meant to set handshake state to use "client mode".
 101      */
 102     SSLSocketImpl(SSLContextImpl sslContext) {
 103         super();
 104         this.sslContext = sslContext;
 105         HandshakeHash handshakeHash = new HandshakeHash();
 106         this.conContext = new TransportContext(sslContext, this,


 275 
 276         if (isLayered()) {
 277             throw new SocketException("Already connected");
 278         }
 279 
 280         if (!(endpoint instanceof InetSocketAddress)) {
 281             throw new SocketException(
 282                     "Cannot handle non-Inet socket addresses.");
 283         }
 284 
 285         super.connect(endpoint, timeout);
 286         doneConnect();
 287     }
 288 
 289     @Override
 290     public String[] getSupportedCipherSuites() {
 291         return CipherSuite.namesOf(sslContext.getSupportedCipherSuites());
 292     }
 293 
 294     @Override
 295     public synchronized String[] getEnabledCipherSuites() {
 296         return CipherSuite.namesOf(conContext.sslConfig.enabledCipherSuites);






 297     }
 298 
 299     @Override
 300     public synchronized void setEnabledCipherSuites(String[] suites) {
 301         conContext.sslConfig.enabledCipherSuites =
 302                 CipherSuite.validValuesOf(suites);





 303     }
 304 
 305     @Override
 306     public String[] getSupportedProtocols() {
 307         return ProtocolVersion.toStringArray(
 308                 sslContext.getSupportedProtocolVersions());
 309     }
 310 
 311     @Override
 312     public synchronized String[] getEnabledProtocols() {
 313         return ProtocolVersion.toStringArray(
 314                 conContext.sslConfig.enabledProtocols);





 315     }
 316 
 317     @Override
 318     public synchronized void setEnabledProtocols(String[] protocols) {
 319         if (protocols == null) {
 320             throw new IllegalArgumentException("Protocols cannot be null");
 321         }
 322 
 323         conContext.sslConfig.enabledProtocols =
 324                 ProtocolVersion.namesOf(protocols);





 325     }
 326 
 327     @Override
 328     public SSLSession getSession() {
 329         try {
 330             // start handshaking, if failed, the connection will be closed.
 331             ensureNegotiated();
 332         } catch (IOException ioe) {
 333             if (SSLLogger.isOn && SSLLogger.isOn("handshake")) {
 334                 SSLLogger.severe("handshake failed", ioe);
 335             }
 336 
 337             return SSLSessionImpl.nullSession;
 338         }
 339 
 340         return conContext.conSession;
 341     }
 342 
 343     @Override
 344     public synchronized SSLSession getHandshakeSession() {
 345         return conContext.handshakeContext == null ?
 346                 null : conContext.handshakeContext.handshakeSession;





 347     }
 348 
 349     @Override
 350     public synchronized void addHandshakeCompletedListener(
 351             HandshakeCompletedListener listener) {
 352         if (listener == null) {
 353             throw new IllegalArgumentException("listener is null");
 354         }
 355 
 356         conContext.sslConfig.addHandshakeCompletedListener(listener);





 357     }
 358 
 359     @Override
 360     public synchronized void removeHandshakeCompletedListener(
 361             HandshakeCompletedListener listener) {
 362         if (listener == null) {
 363             throw new IllegalArgumentException("listener is null");
 364         }
 365 
 366         conContext.sslConfig.removeHandshakeCompletedListener(listener);





 367     }
 368 
 369     @Override
 370     public void startHandshake() throws IOException {
 371         if (!isConnected) {
 372             throw new SocketException("Socket is not connected");
 373         }
 374 
 375         if (conContext.isBroken || conContext.isInboundClosed() ||
 376                 conContext.isOutboundClosed()) {
 377             throw new SocketException("Socket has been closed or broken");
 378         }
 379 
 380         synchronized (conContext) {     // handshake lock

 381             // double check the context status
 382             if (conContext.isBroken || conContext.isInboundClosed() ||
 383                     conContext.isOutboundClosed()) {
 384                 throw new SocketException("Socket has been closed or broken");
 385             }
 386 
 387             try {
 388                 conContext.kickstart();
 389 
 390                 // All initial handshaking goes through this operation until we
 391                 // have a valid SSL connection.
 392                 //
 393                 // Handle handshake messages only, need no application data.
 394                 if (!conContext.isNegotiated) {
 395                     readHandshakeRecord();
 396                 }
 397             } catch (IOException ioe) {
 398                 throw conContext.fatal(Alert.HANDSHAKE_FAILURE,
 399                     "Couldn't kickstart handshaking", ioe);
 400             } catch (Exception oe) {    // including RuntimeException
 401                 handleException(oe);
 402             }


 403         }
 404     }
 405 
 406     @Override
 407     public synchronized void setUseClientMode(boolean mode) {
 408         conContext.setUseClientMode(mode);





 409     }
 410 
 411     @Override
 412     public synchronized boolean getUseClientMode() {
 413         return conContext.sslConfig.isClientMode;





 414     }
 415 
 416     @Override
 417     public synchronized void setNeedClientAuth(boolean need) {
 418         conContext.sslConfig.clientAuthType =
 419                 (need ? ClientAuthType.CLIENT_AUTH_REQUIRED :
 420                         ClientAuthType.CLIENT_AUTH_NONE);





 421     }
 422 
 423     @Override
 424     public synchronized boolean getNeedClientAuth() {
 425         return (conContext.sslConfig.clientAuthType ==


 426                         ClientAuthType.CLIENT_AUTH_REQUIRED);



 427     }
 428 
 429     @Override
 430     public synchronized void setWantClientAuth(boolean want) {
 431         conContext.sslConfig.clientAuthType =
 432                 (want ? ClientAuthType.CLIENT_AUTH_REQUESTED :
 433                         ClientAuthType.CLIENT_AUTH_NONE);





 434     }
 435 
 436     @Override
 437     public synchronized boolean getWantClientAuth() {
 438         return (conContext.sslConfig.clientAuthType ==


 439                         ClientAuthType.CLIENT_AUTH_REQUESTED);



 440     }
 441 
 442     @Override
 443     public synchronized void setEnableSessionCreation(boolean flag) {
 444         conContext.sslConfig.enableSessionCreation = flag;





 445     }
 446 
 447     @Override
 448     public synchronized boolean getEnableSessionCreation() {
 449         return conContext.sslConfig.enableSessionCreation;





 450     }
 451 
 452     @Override
 453     public boolean isClosed() {
 454         return tlsIsClosed;
 455     }
 456 
 457     // Please don't synchronized this method.  Otherwise, the read and close
 458     // locks may be deadlocked.
 459     @Override
 460     public void close() throws IOException {
 461         if (tlsIsClosed) {
 462             return;
 463         }
 464 
 465         if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
 466             SSLLogger.fine("duplex close of SSLSocket");
 467         }
 468 
 469         try {


 518         if (conContext.isNegotiated) {
 519             if (!conContext.protocolVersion.useTLS13PlusSpec()) {
 520                 hasCloseReceipt = true;
 521             } else {
 522                 // Use a user_canceled alert for TLS 1.3 duplex close.
 523                 useUserCanceled = true;
 524             }
 525         } else if (conContext.handshakeContext != null) {   // initial handshake
 526             // Use user_canceled alert regardless the protocol versions.
 527             useUserCanceled = true;
 528 
 529             // The protocol version may have been negotiated.
 530             ProtocolVersion pv = conContext.handshakeContext.negotiatedProtocol;
 531             if (pv == null || (!pv.useTLS13PlusSpec())) {
 532                 hasCloseReceipt = true;
 533             }
 534         }
 535 
 536         // Need a lock here so that the user_canceled alert and the
 537         // close_notify alert can be delivered together.

 538         try {
 539             synchronized (conContext.outputRecord) {
 540                 // send a user_canceled alert if needed.
 541                 if (useUserCanceled) {
 542                     conContext.warning(Alert.USER_CANCELED);
 543                 }
 544 
 545                 // send a close_notify alert
 546                 conContext.warning(Alert.CLOSE_NOTIFY);








 547             }
 548         } finally {
 549             if (!conContext.isOutboundClosed()) {
 550                 conContext.outputRecord.close();
 551             }
 552 
 553             if ((autoClose || !isLayered()) && !super.isOutputShutdown()) {
 554                 super.shutdownOutput();
 555             }
 556         }
 557 
 558         if (!isInputShutdown()) {
 559             bruteForceCloseInput(hasCloseReceipt);
 560         }
 561     }
 562 
 563     /**
 564      * Duplex close, start from closing inbound.
 565      *
 566      * This method should only be called when the outbound has been closed,
 567      * but the inbound is still open.
 568      */
 569     private void duplexCloseInput() throws IOException {
 570         boolean hasCloseReceipt = false;
 571         if (conContext.isNegotiated &&
 572                 !conContext.protocolVersion.useTLS13PlusSpec()) {
 573             hasCloseReceipt = true;
 574         }   // No close receipt if handshake has no completed.
 575 


 664             return;
 665         }
 666 
 667         if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
 668             SSLLogger.fine("close outbound of SSLSocket");
 669         }
 670         conContext.closeOutbound();
 671 
 672         if ((autoClose || !isLayered()) && !super.isOutputShutdown()) {
 673             super.shutdownOutput();
 674         }
 675     }
 676 
 677     @Override
 678     public boolean isOutputShutdown() {
 679         return conContext.isOutboundClosed() &&
 680                 ((autoClose || !isLayered()) ? super.isOutputShutdown(): true);
 681     }
 682 
 683     @Override
 684     public synchronized InputStream getInputStream() throws IOException {
 685         if (isClosed()) {
 686             throw new SocketException("Socket is closed");
 687         }






 688 
 689         if (!isConnected) {
 690             throw new SocketException("Socket is not connected");
 691         }
 692 
 693         if (conContext.isInboundClosed() || isInputShutdown()) {
 694             throw new SocketException("Socket input is already shutdown");

 695         }
 696 
 697         return appInput;
 698     }
 699 
 700     private void ensureNegotiated() throws IOException {
 701         if (conContext.isNegotiated || conContext.isBroken ||
 702                 conContext.isInboundClosed() || conContext.isOutboundClosed()) {
 703             return;
 704         }
 705 
 706         synchronized (conContext) {     // handshake lock

 707             // double check the context status
 708             if (conContext.isNegotiated || conContext.isBroken ||
 709                     conContext.isInboundClosed() ||
 710                     conContext.isOutboundClosed()) {
 711                 return;
 712             }
 713 
 714             startHandshake();


 715         }
 716     }
 717 
 718     /**
 719      * InputStream for application data as returned by
 720      * SSLSocket.getInputStream().
 721      */
 722     private class AppInputStream extends InputStream {
 723         // One element array used to implement the single byte read() method
 724         private final byte[] oneByte = new byte[1];
 725 
 726         // the temporary buffer used to read network
 727         private ByteBuffer buffer;
 728 
 729         // Is application data available in the stream?
 730         private volatile boolean appDataIsAvailable;
 731 







 732         AppInputStream() {
 733             this.appDataIsAvailable = false;
 734             this.buffer = ByteBuffer.allocate(4096);
 735         }
 736 
 737         /**
 738          * Return the minimum number of bytes that can be read
 739          * without blocking.
 740          */
 741         @Override
 742         public int available() throws IOException {
 743             // Currently not synchronized.
 744             if ((!appDataIsAvailable) || checkEOF()) {
 745                 return 0;
 746             }
 747 
 748             return buffer.remaining();
 749         }
 750 
 751         /**


 757             if (n <= 0) {   // EOF
 758                 return -1;
 759             }
 760 
 761             return oneByte[0] & 0xFF;
 762         }
 763 
 764         /**
 765          * Reads up to {@code len} bytes of data from the input stream
 766          * into an array of bytes.
 767          *
 768          * An attempt is made to read as many as {@code len} bytes, but a
 769          * smaller number may be read. The number of bytes actually read
 770          * is returned as an integer.
 771          *
 772          * If the layer above needs more data, it asks for more, so we
 773          * are responsible only for blocking to fill at most one buffer,
 774          * and returning "-1" on non-fault EOF status.
 775          */
 776         @Override
 777         public int read(byte[] b, int off, int len)
 778                 throws IOException {
 779             if (b == null) {
 780                 throw new NullPointerException("the target buffer is null");
 781             } else if (off < 0 || len < 0 || len > b.length - off) {
 782                 throw new IndexOutOfBoundsException(
 783                         "buffer length: " + b.length + ", offset; " + off +
 784                         ", bytes to read:" + len);
 785             } else if (len == 0) {
 786                 return 0;
 787             }
 788 
 789             if (checkEOF()) {
 790                 return -1;
 791             }
 792 
 793             // start handshaking if the connection has not been negotiated.
 794             if (!conContext.isNegotiated && !conContext.isBroken &&
 795                     !conContext.isInboundClosed() &&
 796                     !conContext.isOutboundClosed()) {
 797                 ensureNegotiated();
 798             }
 799 
 800             // Check if the Socket is invalid (error or closed).
 801             if (!conContext.isNegotiated ||
 802                     conContext.isBroken || conContext.isInboundClosed()) {
 803                 throw new SocketException("Connection or inbound has closed");
 804             }
 805 













 806             // Read the available bytes at first.
 807             //
 808             // Note that the receiving and processing of post-handshake message
 809             // are also synchronized with the read lock.
 810             synchronized (this) {
















 811                 int remains = available();
 812                 if (remains > 0) {
 813                     int howmany = Math.min(remains, len);
 814                     buffer.get(b, off, howmany);
 815 
 816                     return howmany;
 817                 }
 818 
 819                 appDataIsAvailable = false;
 820                 try {
 821                     ByteBuffer bb = readApplicationRecord(buffer);
 822                     if (bb == null) {   // EOF
 823                         return -1;
 824                     } else {
 825                         // The buffer may be reallocated for bigger capacity.
 826                         buffer = bb;
 827                     }
 828 
 829                     bb.flip();
 830                     int volume = Math.min(len, bb.remaining());
 831                     buffer.get(b, off, volume);
 832                     appDataIsAvailable = true;
 833 
 834                     return volume;
 835                 } catch (Exception e) {   // including RuntimeException
 836                     // shutdown and rethrow (wrapped) exception as appropriate
 837                     handleException(e);
 838 
 839                     // dummy for compiler
 840                     return -1;
 841                 }












 842             }
 843         }
 844 
 845         /**
 846          * Skip n bytes.
 847          *
 848          * This implementation is somewhat less efficient than possible, but
 849          * not badly so (redundant copy).  We reuse the read() code to keep
 850          * things simpler.
 851          */
 852         @Override
 853         public synchronized long skip(long n) throws IOException {
 854             // dummy array used to implement skip()
 855             byte[] skipArray = new byte[256];

 856 
 857             long skipped = 0;
 858             while (n > 0) {
 859                 int len = (int)Math.min(n, skipArray.length);
 860                 int r = read(skipArray, 0, len);
 861                 if (r <= 0) {
 862                     break;




 863                 }
 864                 n -= r;
 865                 skipped += r;
 866             }
 867 
 868             return skipped;
 869         }
 870 
 871         @Override
 872         public void close() throws IOException {
 873             if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
 874                 SSLLogger.finest("Closing input stream");
 875             }
 876 
 877             try {
 878                 shutdownInput(false);
 879             } catch (IOException ioe) {
 880                 // ignore the exception
 881                 if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
 882                     SSLLogger.warning("input stream close failed", ioe);
 883                 }
 884             }
 885         }
 886 
 887         /**
 888          * Return whether we have reached end-of-file.
 889          *
 890          * If the socket is not connected, has been shutdown because of an error
 891          * or has been closed, throw an Exception.
 892          */
 893         private boolean checkEOF() throws IOException {
 894             if (conContext.isInboundClosed()) {
 895                 return true;
 896             } else if (conContext.isInputCloseNotified || conContext.isBroken) {
 897                 if (conContext.closeReason == null) {
 898                     return true;
 899                 } else {
 900                     throw new SSLException(
 901                         "Connection has closed: " + conContext.closeReason,
 902                         conContext.closeReason);
 903                 }
 904             }
 905 
 906             return false;
 907         }
 908 
 909         /**
 910          * Try the best to use up the input records so as to close the
 911          * socket gracefully, without impact the performance too much.
 912          */
 913         private synchronized void deplete() {
 914             if (!conContext.isInboundClosed()) {
 915                 if (!(conContext.inputRecord instanceof SSLSocketInputRecord)) {
 916                     return;







 917                 }


















 918 
 919                 SSLSocketInputRecord socketInputRecord =
 920                         (SSLSocketInputRecord)conContext.inputRecord;
 921                 try {
 922                     socketInputRecord.deplete(
 923                         conContext.isNegotiated && (getSoTimeout() > 0));
 924                 } catch (IOException ioe) {
 925                     if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
 926                         SSLLogger.warning(
 927                             "input stream close depletion failed", ioe);
 928                     }
 929                 }


 930             }
 931         }
 932     }
 933 
 934     @Override
 935     public synchronized OutputStream getOutputStream() throws IOException {
 936         if (isClosed()) {
 937             throw new SocketException("Socket is closed");
 938         }






 939 
 940         if (!isConnected) {
 941             throw new SocketException("Socket is not connected");
 942         }
 943 
 944         if (conContext.isOutboundDone() || isOutputShutdown()) {
 945             throw new SocketException("Socket output is already shutdown");

 946         }
 947 
 948         return appOutput;
 949     }
 950 
 951 
 952     /**
 953      * OutputStream for application data as returned by
 954      * SSLSocket.getOutputStream().
 955      */
 956     private class AppOutputStream extends OutputStream {
 957         // One element array used to implement the write(byte) method
 958         private final byte[] oneByte = new byte[1];
 959 
 960         @Override
 961         public void write(int i) throws IOException {
 962             oneByte[0] = (byte)i;
 963             write(oneByte, 0, 1);
 964         }
 965 
 966         @Override
 967         public void write(byte[] b,
 968                 int off, int len) throws IOException {


1007                 throw conContext.fatal(Alert.HANDSHAKE_FAILURE, she);
1008             } catch (IOException e) {
1009                 throw conContext.fatal(Alert.UNEXPECTED_MESSAGE, e);
1010             }
1011 
1012             // Is the sequence number is nearly overflow, or has the key usage
1013             // limit been reached?
1014             if (conContext.outputRecord.seqNumIsHuge() ||
1015                     conContext.outputRecord.writeCipher.atKeyLimit()) {
1016                 tryKeyUpdate();
1017             }
1018         }
1019 
1020         @Override
1021         public void close() throws IOException {
1022             if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
1023                 SSLLogger.finest("Closing output stream");
1024             }
1025 
1026             try {
1027                 shutdownOutput();
1028             } catch (IOException ioe) {
1029                 // ignore the exception
1030                 if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
1031                     SSLLogger.warning("output stream close failed", ioe);
1032                 }
1033             }
1034         }
1035     }
1036 
1037     @Override
1038     public synchronized SSLParameters getSSLParameters() {
1039         return conContext.sslConfig.getSSLParameters();





1040     }
1041 
1042     @Override
1043     public synchronized void setSSLParameters(SSLParameters params) {
1044         conContext.sslConfig.setSSLParameters(params);


1045 
1046         if (conContext.sslConfig.maximumPacketSize != 0) {
1047             conContext.outputRecord.changePacketSize(
1048                     conContext.sslConfig.maximumPacketSize);



1049         }
1050     }
1051 
1052     @Override
1053     public synchronized String getApplicationProtocol() {
1054         return conContext.applicationProtocol;





1055     }
1056 
1057     @Override
1058     public synchronized String getHandshakeApplicationProtocol() {
1059         if (conContext.handshakeContext != null) {
1060             return conContext.handshakeContext.applicationProtocol;





1061         }
1062 
1063         return null;
1064     }
1065 
1066     @Override
1067     public synchronized void setHandshakeApplicationProtocolSelector(
1068             BiFunction<SSLSocket, List<String>, String> selector) {
1069         conContext.sslConfig.socketAPSelector = selector;





1070     }
1071 
1072     @Override
1073     public synchronized BiFunction<SSLSocket, List<String>, String>
1074             getHandshakeApplicationProtocolSelector() {
1075         return conContext.sslConfig.socketAPSelector;





1076     }
1077 
1078     /**
1079      * Read the initial handshake records.
1080      */
1081     private int readHandshakeRecord() throws IOException {
1082         while (!conContext.isInboundClosed()) {
1083             try {
1084                 Plaintext plainText = decode(null);
1085                 if ((plainText.contentType == ContentType.HANDSHAKE.id) &&
1086                         conContext.isNegotiated) {
1087                     return 0;
1088                 }
1089             } catch (SSLException ssle) {
1090                 throw ssle;
1091             } catch (IOException ioe) {
1092                 if (!(ioe instanceof SSLException)) {
1093                     throw new SSLException("readHandshakeRecord", ioe);
1094                 } else {
1095                     throw ioe;


1125             int inLen = conContext.inputRecord.bytesInCompletePacket();
1126             if (inLen < 0) {    // EOF
1127                 handleEOF(null);
1128 
1129                 // if no exception thrown
1130                 return null;
1131             }
1132 
1133             // Is this packet bigger than SSL/TLS normally allows?
1134             if (inLen > SSLRecord.maxLargeRecordSize) {
1135                 throw new SSLProtocolException(
1136                         "Illegal packet size: " + inLen);
1137             }
1138 
1139             if (inLen > buffer.remaining()) {
1140                 buffer = ByteBuffer.allocate(inLen);
1141             }
1142 
1143             try {
1144                 Plaintext plainText;
1145                 synchronized (this) {

1146                     plainText = decode(buffer);


1147                 }
1148                 if (plainText.contentType == ContentType.APPLICATION_DATA.id &&
1149                         buffer.position() > 0) {
1150                     return buffer;
1151                 }
1152             } catch (SSLException ssle) {
1153                 throw ssle;
1154             } catch (IOException ioe) {
1155                 if (!(ioe instanceof SSLException)) {
1156                     throw new SSLException("readApplicationRecord", ioe);
1157                 } else {
1158                     throw ioe;
1159                 }
1160             }
1161         }
1162 
1163         //
1164         // couldn't read, due to some kind of error
1165         //
1166         return null;


1205      */
1206     private void tryKeyUpdate() throws IOException {
1207         // Don't bother to kickstart if handshaking is in progress, or if the
1208         // connection is not duplex-open.
1209         if ((conContext.handshakeContext == null) &&
1210                 !conContext.isOutboundClosed() &&
1211                 !conContext.isInboundClosed() &&
1212                 !conContext.isBroken) {
1213             if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
1214                 SSLLogger.finest("trigger key update");
1215             }
1216             startHandshake();
1217         }
1218     }
1219 
1220     /**
1221      * Initialize the handshaker and socket streams.
1222      *
1223      * Called by connect, the layered constructor, and SSLServerSocket.
1224      */
1225     synchronized void doneConnect() throws IOException {
1226         // In server mode, it is not necessary to set host and serverNames.
1227         // Otherwise, would require a reverse DNS lookup to get the hostname.
1228         if (peerHost == null || peerHost.isEmpty()) {
1229             boolean useNameService =
1230                     trustNameService && conContext.sslConfig.isClientMode;
1231             useImplicitHost(useNameService);
1232         } else {
1233             conContext.sslConfig.serverNames =
1234                     Utilities.addToSNIServerNameList(
1235                             conContext.sslConfig.serverNames, peerHost);
1236         }



1237 
1238         InputStream sockInput = super.getInputStream();
1239         conContext.inputRecord.setReceiverStream(sockInput);
1240 
1241         OutputStream sockOutput = super.getOutputStream();
1242         conContext.inputRecord.setDeliverStream(sockOutput);
1243         conContext.outputRecord.setDeliverStream(sockOutput);
1244 
1245         this.isConnected = true;



1246     }
1247 
1248     private void useImplicitHost(boolean useNameService) {
1249         // Note: If the local name service is not trustworthy, reverse
1250         // host name resolution should not be performed for endpoint
1251         // identification.  Use the application original specified
1252         // hostname or IP address instead.
1253 
1254         // Get the original hostname via jdk.internal.access.SharedSecrets
1255         InetAddress inetAddress = getInetAddress();
1256         if (inetAddress == null) {      // not connected
1257             return;
1258         }
1259 
1260         JavaNetInetAddressAccess jna =
1261                 SharedSecrets.getJavaNetInetAddressAccess();
1262         String originalHostname = jna.getOriginalHostName(inetAddress);
1263         if (originalHostname != null && !originalHostname.isEmpty()) {
1264 
1265             this.peerHost = originalHostname;


1271             }
1272 
1273             return;
1274         }
1275 
1276         // No explicitly specified hostname, no server name indication.
1277         if (!useNameService) {
1278             // The local name service is not trustworthy, use IP address.
1279             this.peerHost = inetAddress.getHostAddress();
1280         } else {
1281             // Use the underlying reverse host name resolution service.
1282             this.peerHost = getInetAddress().getHostName();
1283         }
1284     }
1285 
1286     // ONLY used by HttpsClient to setup the URI specified hostname
1287     //
1288     // Please NOTE that this method MUST be called before calling to
1289     // SSLSocket.setSSLParameters(). Otherwise, the {@code host} parameter
1290     // may override SNIHostName in the customized server name indication.
1291     public synchronized void setHost(String host) {
1292         this.peerHost = host;
1293         this.conContext.sslConfig.serverNames =
1294                 Utilities.addToSNIServerNameList(
1295                         conContext.sslConfig.serverNames, host);





1296     }
1297 
1298     /**
1299      * Handle an exception.
1300      *
1301      * This method is called by top level exception handlers (in read(),
1302      * write()) to make sure we always shutdown the connection correctly
1303      * and do not pass runtime exception to the application.
1304      *
1305      * This method never returns normally, it always throws an IOException.
1306      */
1307     private void handleException(Exception cause) throws IOException {
1308         if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
1309             SSLLogger.warning("handling exception", cause);
1310         }
1311 
1312         // Don't close the Socket in case of timeouts or interrupts.
1313         if (cause instanceof InterruptedIOException) {
1314             throw (IOException)cause;
1315         }


< prev index next >