handle EOFException for SSLSocket JDK-8145252-TLS13-branch
authorxuelei
Fri, 08 Jun 2018 19:43:11 -0700
branchJDK-8145252-TLS13-branch
changeset 56712 bad9f4c7eeec
parent 56711 ad4c1c488574
child 56713 a02692615745
handle EOFException for SSLSocket
src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java
src/java.base/share/classes/sun/security/ssl/SSLSocketInputRecord.java
src/java.base/share/classes/sun/security/ssl/SSLTransport.java
--- a/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java	Fri Jun 08 16:51:30 2018 -0700
+++ b/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java	Fri Jun 08 19:43:11 2018 -0700
@@ -25,6 +25,7 @@
 
 package sun.security.ssl;
 
+import java.io.EOFException;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InterruptedIOException;
@@ -577,9 +578,9 @@
                     // grow the buffer if needed
                     int inLen = conContext.inputRecord.bytesInCompletePacket();
                     if (inLen < 0) {    // EOF
-                        // treat like receiving a close_notify warning message.
-                        conContext.isInputCloseNotified = true;
-                        conContext.closeInbound();
+                        handleEOF(null);
+
+                        // if no exceptio thrown
                         return -1;
                     }
 
@@ -804,7 +805,11 @@
             } catch (SSLException ssle) {
                 throw ssle;
             } catch (IOException ioe) {
-                throw new SSLException("readRecord", ioe);
+                if (!(ioe instanceof SSLException)) {
+                    throw new SSLException("readRecord", ioe);
+                } else {
+                    throw ioe;
+                }
             }
         }
 
@@ -823,6 +828,9 @@
             buffer.clear();
             int inLen = conContext.inputRecord.bytesInCompletePacket();
             if (inLen < 0) {    // EOF
+                handleEOF(null);
+
+                // if no exceptio thrown
                 return -1;
             }
 
@@ -838,7 +846,11 @@
             } catch (SSLException ssle) {
                 throw ssle;
             } catch (IOException ioe) {
-                throw new SSLException("readRecord", ioe);
+                if (!(ioe instanceof SSLException)) {
+                    throw new SSLException("readRecord", ioe);
+                } else {
+                    throw ioe;
+                }
             }
         }
 
@@ -850,12 +862,17 @@
 
     private Plaintext decode(ByteBuffer destination) throws IOException {
         Plaintext plainText;
-        if (destination == null) {
-            plainText = SSLTransport.decode(conContext,
-                    null, 0, 0, null, 0, 0);
-        } else {
-            plainText = SSLTransport.decode(conContext,
-                    null, 0, 0, new ByteBuffer[]{destination}, 0, 1);
+        try {
+            if (destination == null) {
+                plainText = SSLTransport.decode(conContext,
+                        null, 0, 0, null, 0, 0);
+            } else {
+                plainText = SSLTransport.decode(conContext,
+                        null, 0, 0, new ByteBuffer[]{destination}, 0, 1);
+            }
+        } catch (EOFException eofe) {
+            // EOFException is special as it is related to close_notify.
+            plainText = handleEOF(eofe);
         }
 
         // Is the sequence number is nearly overflow?
@@ -1088,6 +1105,31 @@
         conContext.fatal(alert, cause);
     }
 
+    private Plaintext handleEOF(EOFException eofe) throws IOException {
+        if (requireCloseNotify || conContext.handshakeContext != null) {
+            SSLException ssle;
+            if (conContext.handshakeContext != null) {
+                ssle = new SSLHandshakeException(
+                        "Remote host terminated the handshake");
+            } else {
+                ssle = new SSLProtocolException(
+                        "Remote host terminated the connection");
+            }
+
+            if (eofe != null) {
+                ssle.initCause(eofe);
+            }
+            throw ssle;
+        } else {
+            // treat as if we had received a close_notify
+            conContext.isInputCloseNotified = true;
+            conContext.transport.shutdown();
+
+            return Plaintext.PLAINTEXT_NULL;
+        }
+    }
+
+
     @Override
     public String getPeerHost() {
         return peerHost;
--- a/src/java.base/share/classes/sun/security/ssl/SSLSocketInputRecord.java	Fri Jun 08 16:51:30 2018 -0700
+++ b/src/java.base/share/classes/sun/security/ssl/SSLSocketInputRecord.java	Fri Jun 08 19:43:11 2018 -0700
@@ -62,12 +62,16 @@
 
     @Override
     int bytesInCompletePacket() throws IOException {
-
         if (!hasHeader) {
             // read exactly one record
-            int really = read(is, temporary, 0, headerSize);
-            if (really < 0) {
-                // EOF: peer shut down incorrectly
+            try {
+                int really = read(is, temporary, 0, headerSize);
+                if (really < 0) {
+                    // EOF: peer shut down incorrectly
+                    return -1;
+                }
+            } catch (EOFException eofe) {
+                // The caller will handle EOF.
                 return -1;
             }
             hasHeader = true;
--- a/src/java.base/share/classes/sun/security/ssl/SSLTransport.java	Fri Jun 08 16:51:30 2018 -0700
+++ b/src/java.base/share/classes/sun/security/ssl/SSLTransport.java	Fri Jun 08 19:43:11 2018 -0700
@@ -25,6 +25,7 @@
 
 package sun.security.ssl;
 
+import java.io.EOFException;
 import java.io.IOException;
 import java.nio.ByteBuffer;
 import javax.crypto.BadPaddingException;
@@ -129,6 +130,9 @@
         } catch (SSLHandshakeException she) {
             // may be record sequence number overflow
             context.fatal(Alert.HANDSHAKE_FAILURE, she);
+        } catch (EOFException eofe) {
+            // rethrow EOFException, the call will handle it if neede.
+            throw eofe;
         } catch (IOException ioe) {
             context.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
         }