Skip to content

Commit

Permalink
Clear SSL error stacks before performing SSL I/O. (grpc#26834)
Browse files Browse the repository at this point in the history
* Clear SSL error stacks before performing SSL I/O.
  • Loading branch information
bdhess authored Sep 2, 2021
1 parent 999e36f commit b082fbe
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 6 deletions.
14 changes: 8 additions & 6 deletions src/core/tsi/ssl_transport_security.cc
Original file line number Diff line number Diff line change
Expand Up @@ -503,10 +503,10 @@ static void log_ssl_error_stack(void) {
/* Performs an SSL_read and handle errors. */
static tsi_result do_ssl_read(SSL* ssl, unsigned char* unprotected_bytes,
size_t* unprotected_bytes_size) {
int read_from_ssl;
GPR_ASSERT(*unprotected_bytes_size <= INT_MAX);
read_from_ssl = SSL_read(ssl, unprotected_bytes,
static_cast<int>(*unprotected_bytes_size));
ERR_clear_error();
int read_from_ssl = SSL_read(ssl, unprotected_bytes,
static_cast<int>(*unprotected_bytes_size));
if (read_from_ssl <= 0) {
read_from_ssl = SSL_get_error(ssl, read_from_ssl);
switch (read_from_ssl) {
Expand Down Expand Up @@ -536,10 +536,10 @@ static tsi_result do_ssl_read(SSL* ssl, unsigned char* unprotected_bytes,
/* Performs an SSL_write and handle errors. */
static tsi_result do_ssl_write(SSL* ssl, unsigned char* unprotected_bytes,
size_t unprotected_bytes_size) {
int ssl_write_result;
GPR_ASSERT(unprotected_bytes_size <= INT_MAX);
ssl_write_result = SSL_write(ssl, unprotected_bytes,
static_cast<int>(unprotected_bytes_size));
ERR_clear_error();
int ssl_write_result = SSL_write(ssl, unprotected_bytes,
static_cast<int>(unprotected_bytes_size));
if (ssl_write_result < 0) {
ssl_write_result = SSL_get_error(ssl, ssl_write_result);
if (ssl_write_result == SSL_ERROR_WANT_READ) {
Expand Down Expand Up @@ -1449,6 +1449,7 @@ static tsi_result ssl_handshaker_process_bytes_from_peer(
impl->result = TSI_OK;
return impl->result;
} else {
ERR_clear_error();
/* Get ready to get some bytes from SSL. */
int ssl_result = SSL_do_handshake(impl->ssl);
ssl_result = SSL_get_error(impl->ssl, ssl_result);
Expand Down Expand Up @@ -1645,6 +1646,7 @@ static tsi_result create_tsi_ssl_handshaker(SSL_CTX* ctx, int is_client,
tsi_ssl_handshaker_resume_session(ssl,
client_factory->session_cache.get());
}
ERR_clear_error();
ssl_result = SSL_do_handshake(ssl);
ssl_result = SSL_get_error(ssl, ssl_result);
if (ssl_result != SSL_ERROR_WANT_READ) {
Expand Down
13 changes: 13 additions & 0 deletions test/core/tsi/ssl_transport_security_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@

extern "C" {
#include <openssl/crypto.h>
#include <openssl/err.h>
#include <openssl/pem.h>
}

Expand Down Expand Up @@ -705,6 +706,17 @@ void ssl_tsi_test_do_round_trip_for_all_configs() {
gpr_free(bit_array);
}

void ssl_tsi_test_do_round_trip_with_error_on_stack() {
gpr_log(GPR_INFO, "ssl_tsi_test_do_round_trip_with_error_on_stack");
// Invoke an SSL function that causes an error, and ensure the error
// makes it to the stack.
GPR_ASSERT(!EC_KEY_new_by_curve_name(NID_rsa));
GPR_ASSERT(ERR_peek_error() != 0);
tsi_test_fixture* fixture = ssl_tsi_test_fixture_create();
tsi_test_do_round_trip(fixture);
tsi_test_fixture_destroy(fixture);
}

static bool is_slow_build() {
#if defined(GPR_ARCH_32) || defined(__APPLE__)
return true;
Expand Down Expand Up @@ -1035,6 +1047,7 @@ int main(int argc, char** argv) {
ssl_tsi_test_do_handshake_alpn_client_server_ok();
ssl_tsi_test_do_handshake_session_cache();
ssl_tsi_test_do_round_trip_for_all_configs();
ssl_tsi_test_do_round_trip_with_error_on_stack();
ssl_tsi_test_do_round_trip_odd_buffer_size();
ssl_tsi_test_handshaker_factory_internals();
ssl_tsi_test_duplicate_root_certificates();
Expand Down

0 comments on commit b082fbe

Please sign in to comment.