Priyaranjan Nayak wrote:
I am using openssl-1.0.1c in our project.when SSL_shutdown(ssl)
get executed it returns 0.If I get return value zero then calling the
same SSL_shutdown(ssl) again.In 2nd time it return -1. Can any one tell
me how to shutdown ssl context ? How can I execute SSL_shutdown(ssl) ,
so that it will return 0 .
SSL_shutdown() will only return 1 when it has completed a 2 stream (send
stream and receive stream) cryptographically secure shutdown.
When you call it you are only able to shutdown the 'send stream' that
you control, you can not influence if or when the remote end will
provide you indication of the receive stream shutdown; that is
completely a software/programming matter of the implementation of the
far end, not one enforced by SSL protocol specification.
It has to willingly decide to perform an SSL shutdown on its sending
stream (your receiving stream), it could if it wanted keep the socket
open forever, and still continue to send data (your received data) and
this would not violate SSL protocol specification.
The fact that you have observed a 0 return value from SSL_shutdown()
means that your end (the local end) has done everything it can and you
wait for network and remote end to comply with your decision to shutdown.
If you are seeing a 0 return value, then a -1, then you have
-1/WANT_READ condition see below.
If you treat the -1 return value you see like other OpenSSL API calls
that operate on (SSL *) type, by using SSL_get_error(ssl) and confirm
what value or error code is provided.
-1/SSL_ERROR_WANT_WRITE means the 'SSL close notify' packet has not been
committed to the kernel. To resolve this you must ensure your BIO layer
and below flush their data downwards when they can. You might not be
able to flush data down if there is flow control in force blocking this
scenario. For example write() system call returns -1/EAGAIN because the
network socket write buffer is full.
If you see -1/SSL_ERROR_WANT_WRITE then your local end still has work to
do, to wait for flow control to clear to allow you to commit data to the
kernel and then flush your outstanding data (this data is buffered
internally in OpenSSL) to kernel.
If you see SSL_shutdown(ssl) == 0, then you can call shutdown(fd,
SHUT_WR) on the socket if you wish. Because the SSL protocol stack
never needs to write(fd, ...) any data in the future with that socket.
NOTE: this comment presumes you are using a direct socket BIO layer.
-1/SSL_ERROR_WANT_READ means that the SSL_shutdown() API is waiting for
the remote end to send its 'SSL close notify' packet. As stated above
you have no control over when or if the remote end does this.
The -1/SSL_ERROR_WANT_READ is the generic 'waiting for more data' error
code you get from non-blocking SSL_read() API and it has exactly the
same meaning in respect of SSL shutdown, since we are waiting for data
from the remote end to complete the shutdown of both streams (send and
receive).
The other end does not have to send the 'SSL shutdown notify' packet and
a lot of 'other ends' simply disconnect/close socket on receiving the
'SSL close notify' you sent.
If you care about a cryptographically secure shutdown you need to fix
the software at the 'other end' to ensure it:
* notices it receives a secure shutdown from the remote end
* finishes up whatever it maybe in the middle of doing, like sending data
* makes a decision to comply with the shutdown scenario
* sends its 'SSL close notify' packet,
* ensure it flushed the packet to the kernel and over the network, and
* keeps the socket open waiting for you to be the first mover in
closing the socket. However SO_LINGER may help and maybe you need an
application level timer for really bad software that fails to close().
* as a short-circuit the 'other end' can close() if it can ask the
kernel if all pending data has been ACKed on the wire. Such as the
value of the TCP SendQ in the kernel is now at a 0 value.
In reality the above never happens, unless you have some kind of high
security environment since doing all that requires understanding,
additional work and lowers performances (a host will have more sockets
open longer).
In reality implementations are more a best-effort to be correct, rather
than assured of being correct.
If you can not control or fix the other software and your application
may choose not to consider this an error condition, but more a 'we did
our best to be correct here, but the ignorant other end software was not
such a good SSL citizen as we are, since it did not provide us with the
SSL close notify packet we expected before it abruptly cause a TCP
disconnection of the stream'.
Many applications do not require a cryptographic secure end-of-stream
indication due to the way the application protocol works. For example
HTTP/1.1 which is a request/response protocol where the client is in
charge of what the responses the s