From fab363dbed037332e5508f7b83f1fd86241fdccc Mon Sep 17 00:00:00 2001 From: Steve Kim Date: Thu, 24 Oct 2024 13:20:04 -0700 Subject: [PATCH] restore granular TLS errors and include an error check for TLS errors --- include/aws/io/tls_channel_handler.h | 6 +++++ source/darwin/nw_socket.c | 40 +++++++++++++--------------- source/tls_channel_handler.c | 34 +++++++++++++++++++++++ tests/tls_handler_test.c | 2 +- 4 files changed, 60 insertions(+), 22 deletions(-) diff --git a/include/aws/io/tls_channel_handler.h b/include/aws/io/tls_channel_handler.h index 8828a1b08..d7c517f8b 100644 --- a/include/aws/io/tls_channel_handler.h +++ b/include/aws/io/tls_channel_handler.h @@ -941,6 +941,12 @@ const char *aws_tls_signature_algorithm_str(enum aws_tls_signature_algorithm sig AWS_IO_API const char *aws_tls_key_operation_type_str(enum aws_tls_key_operation_type operation_type); +/** + * Returns true if provided error_code is a TLS Negotiation related error. Use this to determine if + * the cause related to an error originated from a TLS handshake. + */ +AWS_IO_API bool aws_tls_error_code_check(int error_code); + AWS_EXTERN_C_END AWS_POP_SANE_WARNING_LEVEL diff --git a/source/darwin/nw_socket.c b/source/darwin/nw_socket.c index 46ac51a6e..2d11d80f8 100644 --- a/source/darwin/nw_socket.c +++ b/source/darwin/nw_socket.c @@ -76,35 +76,35 @@ static int s_determine_socket_error(int error) { /* SSL/TLS Errors */ case errSSLUnknownRootCert: - // return AWS_IO_TLS_UNKNOWN_ROOT_CERTIFICATE; + return AWS_IO_TLS_UNKNOWN_ROOT_CERTIFICATE; case errSSLNoRootCert: - // return AWS_IO_TLS_NO_ROOT_CERTIFICATE_FOUND; + return AWS_IO_TLS_NO_ROOT_CERTIFICATE_FOUND; case errSSLCertExpired: - // return AWS_IO_TLS_CERTIFICATE_EXPIRED; + return AWS_IO_TLS_CERTIFICATE_EXPIRED; case errSSLCertNotYetValid: - // return AWS_IO_TLS_CERTIFICATE_NOT_YET_VALID; + return AWS_IO_TLS_CERTIFICATE_NOT_YET_VALID; case errSSLPeerHandshakeFail: - // return AWS_IO_TLS_ERROR_NEGOTIATION_FAILURE; + return AWS_IO_TLS_ERROR_NEGOTIATION_FAILURE; case errSSLBadCert: - // return AWS_IO_TLS_BAD_CERTIFICATE; + return AWS_IO_TLS_BAD_CERTIFICATE; case errSSLPeerCertExpired: - // return AWS_IO_TLS_PEER_CERTIFICATE_EXPIRED; + return AWS_IO_TLS_PEER_CERTIFICATE_EXPIRED; case errSSLPeerBadCert: - // return AWS_IO_TLS_BAD_PEER_CERTIFICATE; + return AWS_IO_TLS_BAD_PEER_CERTIFICATE; case errSSLPeerCertRevoked: - // return AWS_IO_TLS_PEER_CERTIFICATE_REVOKED; + return AWS_IO_TLS_PEER_CERTIFICATE_REVOKED; case errSSLPeerCertUnknown: - // return AWS_IO_TLS_PEER_CERTIFICATE_UNKNOWN; + return AWS_IO_TLS_PEER_CERTIFICATE_UNKNOWN; case errSSLInternal: - // return AWS_IO_TLS_INTERNAL_ERROR; + return AWS_IO_TLS_INTERNAL_ERROR; case errSSLClosedGraceful: - // return AWS_IO_TLS_CLOSED_GRACEFUL; + return AWS_IO_TLS_CLOSED_GRACEFUL; case errSSLClosedAbort: - // return AWS_IO_TLS_CLOSED_ABORT; + return AWS_IO_TLS_CLOSED_ABORT; case errSSLXCertChainInvalid: - // return AWS_IO_TLS_INVALID_CERTIFICATE_CHAIN; + return AWS_IO_TLS_INVALID_CERTIFICATE_CHAIN; case errSSLHostNameMismatch: - // return AWS_IO_TLS_HOST_NAME_MISSMATCH; + return AWS_IO_TLS_HOST_NAME_MISSMATCH; case errSecNotTrusted: return AWS_IO_TLS_ERROR_NEGOTIATION_FAILURE; @@ -423,7 +423,8 @@ static int s_setup_socket_params(struct nw_socket *nw_socket, const struct aws_s } // DEBUG WIP trigger the on_negotiation_result func w/error here? if (nw_socket->on_tls_negotiation_result_fn) { - // nw_socket->on_tls_negotiation_result_fn(NULL, NULL, error_code, NULL); + nw_socket->on_tls_negotiation_result_fn( + NULL, NULL, error_code, nw_socket->on_tls_negotiation_result_user_data); } complete(verification_successful); }, @@ -806,7 +807,7 @@ static void s_schedule_on_connection_result(struct nw_socket *nw_socket, int err args->allocator = socket->allocator; args->error_code = error_code; aws_ref_count_acquire(&nw_socket->ref_count); - aws_task_init(task, s_process_connection_result_task, args, "connectionSuccessTask"); + aws_task_init(task, s_process_connection_result_task, args, "connectionResultTask"); aws_event_loop_schedule_task_now(nw_socket->synced_data.event_loop, task); } @@ -955,7 +956,7 @@ static void s_schedule_cancel_task(struct nw_socket *nw_socket, struct aws_task args->allocator = nw_socket->allocator; args->task_to_cancel = task_to_cancel; aws_ref_count_acquire(&nw_socket->ref_count); - aws_task_init(task, s_process_cancel_task, args, "cancelTaskTask"); + aws_task_init(task, s_process_cancel_task, args, "cancelTask"); AWS_LOGF_TRACE(AWS_LS_IO_SOCKET, "id=%p: Schedule cancel %s task", (void *)task_to_cancel, task->type_tag); aws_event_loop_schedule_task_now(nw_socket->synced_data.event_loop, task); } @@ -1280,9 +1281,6 @@ static int s_socket_connect_fn( socket->state = ERROR; if (!nw_socket->setup_run) { s_schedule_on_connection_result(nw_socket, error_code); - // DEBUG WIP we need to call the Tls handler callback from tls_ctx - // Maybe schedule this from within the verification block where the TLS handhake error is origianting - // s_schedule_on_negotiation_result() nw_socket->setup_run = true; } else if (socket->readable_fn) { s_schedule_on_readable(nw_socket, nw_socket->last_error, NULL); diff --git a/source/tls_channel_handler.c b/source/tls_channel_handler.c index 04781a357..2b45412a4 100644 --- a/source/tls_channel_handler.c +++ b/source/tls_channel_handler.c @@ -923,3 +923,37 @@ void aws_custom_key_op_handler_perform_operation( struct aws_tls_key_operation *operation) { key_op_handler->vtable->on_key_operation(key_op_handler, operation); } + +bool aws_tls_error_code_check(int error_code) { + switch (error_code) { + case AWS_IO_TLS_ERROR_NEGOTIATION_FAILURE: + case AWS_IO_TLS_ERROR_NOT_NEGOTIATED: + case AWS_IO_TLS_ERROR_WRITE_FAILURE: + case AWS_IO_TLS_ERROR_ALERT_RECEIVED: + case AWS_IO_TLS_CTX_ERROR: + case AWS_IO_TLS_VERSION_UNSUPPORTED: + case AWS_IO_TLS_CIPHER_PREF_UNSUPPORTED: + case AWS_IO_TLS_NEGOTIATION_TIMEOUT: + case AWS_IO_TLS_ALERT_NOT_GRACEFUL: + case AWS_IO_TLS_DIGEST_ALGORITHM_UNSUPPORTED: + case AWS_IO_TLS_SIGNATURE_ALGORITHM_UNSUPPORTED: + case AWS_IO_TLS_ERROR_READ_FAILURE: + case AWS_IO_TLS_UNKNOWN_ROOT_CERTIFICATE: + case AWS_IO_TLS_NO_ROOT_CERTIFICATE_FOUND: + case AWS_IO_TLS_CERTIFICATE_EXPIRED: + case AWS_IO_TLS_CERTIFICATE_NOT_YET_VALID: + case AWS_IO_TLS_BAD_CERTIFICATE: + case AWS_IO_TLS_PEER_CERTIFICATE_EXPIRED: + case AWS_IO_TLS_BAD_PEER_CERTIFICATE: + case AWS_IO_TLS_PEER_CERTIFICATE_REVOKED: + case AWS_IO_TLS_PEER_CERTIFICATE_UNKNOWN: + case AWS_IO_TLS_INTERNAL_ERROR: + case AWS_IO_TLS_CLOSED_GRACEFUL: + case AWS_IO_TLS_CLOSED_ABORT: + case AWS_IO_TLS_INVALID_CERTIFICATE_CHAIN: + case AWS_IO_TLS_HOST_NAME_MISSMATCH: + return true; + default: + return false; + } +} diff --git a/tests/tls_handler_test.c b/tests/tls_handler_test.c index b7d0c0027..b2d61ceeb 100644 --- a/tests/tls_handler_test.c +++ b/tests/tls_handler_test.c @@ -995,7 +995,7 @@ static int s_verify_negotiation_fails_helper( return AWS_OP_SKIP; } - ASSERT_INT_EQUALS(AWS_IO_TLS_ERROR_NEGOTIATION_FAILURE, outgoing_args.last_error_code); + ASSERT_TRUE(aws_tls_error_code_check(outgoing_args.last_error_code)); aws_client_bootstrap_release(client_bootstrap);