Is this the correct way to do error handling in OpenSSL?
And what is the difference between SSL_get_error
and ERR_get_error
?
The docs are quite vague in this regard.
int ssl_shutdown(SSL *ssl_connection)
{
int rv, err;
ERR_clear_error();
rv = SSL_shutdown(ssl_connection);
if (rv == 0)
SSL_shutdown(ssl_connection);
if (rv < 0)
{
err = SSL_get_error(ssl_connection, rv);
if (err == SSL_ERROR_SSL)
fprintf(stderr, "%s\n", ERR_error_string(ERR_get_error(), NULL));
fprintf(stderr, "%s\n", SSL_state_string(ssl_connection));
return 1;
}
SSL_free(ssl_connection);
return 0;
}
SSL_get_error:
ERR_get_error:
So the latter is for more general use and those shouldn't be used together, because:
So you have to read all of the errors using ERR_get_error and handle them (or ignore them by removal as you did in your code sample with
ERR_clear_error
) and then perform the IO operation. Your approach seems to be correct, although I can't check all aspects of it by myself at the moment.Refer to this answer and this post for more information.
EDIT: according to this tutorial, BIO_ routines may generate an error and affect error queue:
There are two logical parts to OpenSSL. First is the SSL library,
libssl.a
(andlibssl.so
), and it includes the communication related stuff. Second is the cryptography library,libcrypto.a
(andlibcrypto.so
), and it includes big numbers, configuration, input/output, etc.libssl.a
depends uponlibcrypto.a
, and its why the link command is ordered as-lssl -lcrypto
.You use
SSL_get_error
to retrieve most errors from the SSL portion library, and you useERR_get_error
to retrieve errors not in the SSL portion of the library.The code you showed is closer to "how do you shutdown a SSL socket". Ultimately, the gyrations control two cases. First is a half open connection, when the client shutdowns without sending the close notify message. The second is your program's behavior when sending the close notify message.
Its hard to answer "is it correct" because we don't know the behavior you want. If you don't care if the close notify is sent, then I believe you only need to call
SSL_shutdown
once, regardless of what the client does.