Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-6618387

SSL client sessions do not close cleanly. A TCP reset occurs instead of a close_notify alert.

    XMLWordPrintable

Details

    • b25
    • sparc
    • solaris_7
    • Verified

    Backports

      Description

        Note, this bug is being reported agains 1.5.

        We are trying to make a connection to a web server using httpsURLConnection.
        However when we close the SSL session. A close_notify message is not generated.
        [
        SSL 3.0 specification
        5.4.1 Closure alerts

           The client and the server must share knowledge that the connection
           is ending in order to avoid a truncation attack. Either party may
           initiate the exchange of closing messages.

             close_notify This message notifies the recipient that the
                               sender will not send any more messages on this
                               connection. The session becomes unresumable if
                               any connection is terminated without proper
                               close_notify messages with level equal to
                               warning.

           Either party may initiate a close by sending a close_notify alert.
           Any data received after a closure alert is ignored.

           Each party is required to send a close_notify alert before closing
           the write side of the connection. It is required that the other
           party respond with a close_notify alert of its own and close down
           the connection immediately, discarding any pending writes. It is
           not required for the initiator of the close to wait for the
           responding close_notify alert before closing the read side of the
           connection.

           NB: It is assumed that closing a connection reliably delivers
           pending data before destroying the transport.

        http://java.sun.com/j2se/1.5.0/docs/guide/security/jsse/JSSERefGuide.html#SSLOverview
        < http://java.sun.com/j2se/1.5.0/docs/guide/security/jsse/JSSERefGuide.html>

        For an orderly shutdown of an SSL/TLS connection, the SSL/TLS protocols require
        transmission of close messages. Therefore, when an application is done with
        the SSL/TLS connection, it should first obtain the close messages from the SSLEngine,
        then transmit them to the peer using its transport mechanism, and finally shut
        down the transport mechanism.


        JavaTM Secure Socket Extension (JSSE)Reference Guidefor the JavaTM 2 Platform Standard Edition 5
        Close Messages - At the end of the connection, each side will send a close_notify message to inform the peer that the connection is closed.

        Analysis

        During the close,if the KeepAliveConnections(maxRequest) is 0 or if the value of the Connection is close, close_notify message is generated.However when we try to close, with the KeepAliveConnections >0. Then there is no close_notify message

        Looking into the KeepAliveStream.java file and HttpClient.java, and have observed that while closing this stream if the KeepAliveConnections>0 . The value is stored in the cache.

        KeepAliveConnection.java
        if (closed) {
                    return;
                }

                // Skip past the data that's left in the Inputstream because
                // some sort of error may have occurred.
                // Do this ONLY if the skip won't block. The stream may have
                // been closed at the beginning of a big file and we don't want
                // to hang around for nothing. So if we can't skip without blocking
                // we just close the socket and, therefore, terminate the keepAlive
                // NOTE: Don't close super class
                try {
                       
                    if (expected > count) {
                        long nskip = (long) (expected - count);
                        if (nskip <= available()) {
                            long n = 0;
                            while (n < nskip) {
                                nskip = nskip - n;
                                n = skip(nskip);
                            }
                        } else {
                            hc.closeServer();
                        }
                    }
                    if (!closed && !hurried) {
                        hc.finished();
                    }
                } finally {
                    if (pi != null)
                        pi.finishTracking();
               
                    // nulling out the underlying inputstream as well as
                    // httpClient to let gc collect the memories faster
                        in = null;
                        hc = null;
                        closed = true;
                }


        HttpClient.java
        if (keepAliveConnections > 0 && isKeepingAlive() &&
                       !(serverOutput.checkError())) {
                    /* This connection is keepingAlive && still valid.
                     * Return it to the cache.
                     */
                    putInKeepAliveCache();
                } else {
                            closeServer();
                }
         

        Looking into the code of sun.net.www.protocol.http.HttpURLConnection.java for the disconnect method to find whether it had any code which could do a proper SSL shutdown. It has code for the purpose mentioned in it’s comment

        if (http != null) {
                    /*
                     * If we have an input stream this means we received a response
                     * from the server. That stream may have been read to EOF and
                     * dependening on the stream type may already be closed or the
                     * the http client may be returned to the keep-alive cache.
                     * If the http client has been returned to the keep-alive cache
                     * it may be closed (idle timeout) or may be allocated to
                     * another request.
                     *
                     * In other to avoid timing issues we close the input stream
                     * which will either close the underlying connection or return
                     * the client to the cache. If there's a possibility that the
                     * client has been returned to the cache (ie: stream is a keep
                     * alive stream or a chunked input stream) then we remove an
                     * idle connection to the server. Note that this approach
                     * can be considered an approximation in that we may close a
                     * different idle connection to that used by the request.
                     * Additionally it's possible that we close two connections
                     * - the first becuase it wasn't an EOF (and couldn't be
                     * hurried) - the second, another idle connection to the
                     * same server. The is okay because "disconnect" is an
                     * indication that the application doesn't intend to access
                     * this http server for a while.
                     */

        In our case the value of http is null. As a result of which it does not enter the loop. Hence no code is executed to do the proper SSL Shutdown.

        We require a close_notify alert to have a orderly shutdown of an SSL/TLS connection, which is not observed in the above case.

        Attachments

          Issue Links

            Activity

              People

                xuelei Xuelei Fan
                kevibrow Kevin Brown
                Votes:
                0 Vote for this issue
                Watchers:
                1 Start watching this issue

                Dates

                  Created:
                  Updated:
                  Resolved:
                  Imported:
                  Indexed: