Clear SSL Error Queue
The OpenSSL documentation states that the error queue for the current thread needs to be emptied prior to the next TLS/SSL I/O operation, or the call to SSL_get_error() will not be reliable.
This commit is contained in:
parent
d0a56f4235
commit
416e244b31
|
|
@ -310,6 +310,19 @@ int SSL_use_certificate_file(SSL *ssl, const char *file, int type)
|
|||
return func(ssl, file, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the SSL error queue
|
||||
* @return void
|
||||
*/
|
||||
void ERR_clear_error()
|
||||
{
|
||||
// create a function
|
||||
static Function<decltype(::ERR_clear_error)> func(handle, "ERR_clear_error");
|
||||
|
||||
// call the openssl function
|
||||
return func();
|
||||
}
|
||||
|
||||
/**
|
||||
* End of namespace
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
* Dependencies
|
||||
*/
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
/**
|
||||
* Begin of namespace
|
||||
|
|
@ -49,6 +50,7 @@ void SSL_set_connect_state(SSL *ssl);
|
|||
void SSL_CTX_free(SSL_CTX *ctx);
|
||||
void SSL_free(SSL *ssl);
|
||||
long SSL_ctrl(SSL *ssl, int cmd, long larg, void *parg);
|
||||
void ERR_clear_error(void);
|
||||
|
||||
/**
|
||||
* End of namespace
|
||||
|
|
|
|||
|
|
@ -270,8 +270,12 @@ private:
|
|||
// we may have to repeat the operation on failure
|
||||
if (result > 0) continue;
|
||||
|
||||
// Check for error and clear the error queue before the next TLS/SSL I/O operation
|
||||
auto error = OpenSSL::SSL_get_error(_ssl, result);
|
||||
OpenSSL::ERR_clear_error();
|
||||
|
||||
// the operation failed, we may have to repeat our call
|
||||
return repeat(monitor, state_sending, OpenSSL::SSL_get_error(_ssl, result));
|
||||
return repeat(monitor, state_sending, error);
|
||||
}
|
||||
while (_out && !readable);
|
||||
|
||||
|
|
@ -297,8 +301,14 @@ private:
|
|||
auto result = _in.receivefrom(_ssl, _connection->expected());
|
||||
|
||||
// if this is a failure, we are going to repeat the operation
|
||||
if (result <= 0) return repeat(monitor, state_receiving, OpenSSL::SSL_get_error(_ssl, result));
|
||||
|
||||
if (result <= 0)
|
||||
{
|
||||
// Check for error and clear the error queue before the next TLS/SSL I/O operation
|
||||
auto error = OpenSSL::SSL_get_error(_ssl, result);
|
||||
OpenSSL::ERR_clear_error();
|
||||
|
||||
return repeat(monitor, state_receiving, error);
|
||||
}
|
||||
// go process the received data
|
||||
auto *nextstate = parse(monitor, result);
|
||||
|
||||
|
|
@ -419,6 +429,9 @@ public:
|
|||
{
|
||||
// error was returned, so we must investigate what is going on
|
||||
auto error = OpenSSL::SSL_get_error(_ssl, result);
|
||||
|
||||
// clear the error queue before the next TLS/SSL I/O operation
|
||||
OpenSSL::ERR_clear_error();
|
||||
|
||||
// get the next state given the error
|
||||
auto *nextstate = repeat(monitor, state_sending, error);
|
||||
|
|
|
|||
Loading…
Reference in New Issue