David Schwartz wrote:
Which is pretty much the same as every other operation. If you call 'send'
or 'write' on a blocking TCP socket, and you get a zero return, does that
mean the data has been sent? No. It means the data is queued and the send is
in progress. If you call 'shutdown' on a blocking socket and get a zero
return, does that mean the connection has finished shutting down? No. It
means the shutdown is in progress.

I take point with DS on this single aspect. Please name the implementation of send() or write() that uses a zero return code to mean "the data is queued and the send is in progress". I know of no such implementation.

A non-zero positive error return is always used to indicate that situation in all implementations of send() and write() I have come across.


The interpretation of what zero means in respect of SSL_shutdown() is a matter for the OpenSSL documentation to clarify.

I myself can not see the parallel that DS can see in respect of the send/write APIs - so please ignore this confusion DS introduces.



Documentation tells me that the shutdown will not return until
the shutdown is completed (return code= 1) or an error condition
is detected (return code= -1) if the SSL handle is blocking.

I'm not sure what documentation that is, but it's incorrect.

So now I am confused. How can I test the SSL handle to find
out if it is blocking or not?

The operation will only block if it has to. Operations won't gratuitously
block. Specifically, operations try as hard as they can *not* to block until
the other side does things unless that is necessary to take the data passed
or give the data that needs to be returned.

You call the SSL_shutdown() twice. I'm sure that must be documented somewhere!

The first call sends your "shutdown notify packet" (and also marks the SSL * as closed for sending, i.e. using SSL_write() should now error).

The second call waits and therefore blocks (if you are in blocking socket mode) for the far end to acknowledge your "shutdown notify packet" and also perform its shutdown.



There is a loophole in the OpenSSL API here. The far end will only acknowledge your "shutdown notify packet" once it has finished flushing the application data and once the application accepts the acknowledgment and calls SSL_shutdown() itself.

It is possible for an SSL socket to receive notification of an incoming shutdown but continue to keep sending application data. This is allowed by the spec and allowed by OpenSSL (a half-open transport).

Until these things happen infinite amounts of encrypted application data can proceed the acknowledgment packet.

In practice most people have control of both ends and the possibility of abuse/DoS is pretty limited on a modern kernel with kernel memory resource management.


One possible implementation of the SSL_shutdown() sequence might look like this (you might want to place some way of triggering a timeout event so a blocked socket doesn't become stuck because of a bad peer seeing the shutdown but never hanging up the socket) :


if(SSL_shutdown(ssl) < 0)
        return -1;      /* error the SSL_shutdown() did not take, try again 
later */

for(;;) {
        int err;
        int n;
        char buf[4096];

        if((err = SSL_shutdown(ssl)) == 1)
                break;

        /* Check for socket close / socket API errors */
        if(check_for_errors)
                goto forced_shutdown_due_error;

        n = SSL_read(ssl, buf, sizeof(buf));    // sink application data

        /* Optionally decode application data and do something with it
         *  but remember we can never call SSL_write() again!  So maybe
* you would decode expected data and once that arrives you * should force a socket close
         */
        if(we_did_not_expect_this_data) {
                // Do forced socket close - we did our best here
                goto forced_shutdown;
        }

        /* else we just sink data to /dev/null */
}

/* we were clean! */
return 0;

forced_shutdown:
        /* we didn't like something during our attempt at a clean shutdown */
        return -1;

forced_shutdown_due_error:
        /* some error occured during our attempt at a clean shutdown */
        return -1;

______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    openssl-users@openssl.org
Automated List Manager                           [EMAIL PROTECTED]

Reply via email to