Skip to content

Commit

Permalink
cleaner passing of tls related pointers and initial tls_result handli…
Browse files Browse the repository at this point in the history
…ng for nw_socket
  • Loading branch information
sbSteveK committed Oct 24, 2024
1 parent 27dae96 commit 622fc7c
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 18 deletions.
7 changes: 7 additions & 0 deletions include/aws/io/private/tls_channel_handler_shared.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@ enum aws_tls_handler_read_state {
AWS_TLS_HANDLER_READ_SHUT_DOWN_COMPLETE,
};

struct tls_connection_context {
struct aws_string *host_name;
struct aws_tls_ctx *tls_ctx;
aws_tls_on_negotiation_result_fn *user_on_negotiation_result;
void *user_on_negotiation_result_user_data;
};

AWS_EXTERN_C_BEGIN

AWS_IO_API void aws_tls_channel_handler_shared_init(
Expand Down
3 changes: 2 additions & 1 deletion include/aws/io/socket.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ struct aws_socket_options {

struct aws_socket;
struct aws_event_loop;
struct tls_connection_context;

/**
* Called in client mode when an outgoing connection has succeeded or an error has occurred.
Expand All @@ -80,7 +81,7 @@ struct aws_tls_connection_options;
* the setup of TLS related parameters at creation of the connection as its internal framework
* handles both the socket connection and the TLS handshake.
*/
typedef void(aws_socket_retrieve_tls_options_fn)(struct aws_tls_connection_options **tls_ctx_options, void *user_data);
typedef void(aws_socket_retrieve_tls_options_fn)(struct tls_connection_context *context, void *user_data);

/**
* Called by a listening socket when either an incoming connection has been received or an error occurred.
Expand Down
19 changes: 17 additions & 2 deletions source/channel_bootstrap.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <aws/common/string.h>
#include <aws/io/event_loop.h>
#include <aws/io/logging.h>
#include <aws/io/private/tls_channel_handler_shared.h>
#include <aws/io/socket.h>
#include <aws/io/socket_channel_handler.h>
#include <aws/io/tls_channel_handler.h>
Expand Down Expand Up @@ -636,9 +637,13 @@ static void s_on_client_connection_established(struct aws_socket *socket, int er
/* Called when a socket connection attempt requires access to TLS options. Currently this is only necessary on
* iOS/tvOS where the parameters used to create the Apple Network Framework socket requires TLS options.
*/
static void s_retrieve_tls_options(struct aws_tls_connection_options **tls_ctx_options, void *user_data) {
static void s_retrieve_tls_options(struct tls_connection_context *context, void *user_data) {
struct client_connection_args *connection_args = user_data;
*tls_ctx_options = &connection_args->channel_data.tls_options;
AWS_ZERO_STRUCT(context);
context->host_name = connection_args->channel_data.tls_options.server_name;
context->tls_ctx = connection_args->channel_data.tls_options.ctx;
context->user_on_negotiation_result = connection_args->channel_data.user_on_negotiation_result;
context->user_on_negotiation_result_user_data = connection_args->channel_data.tls_user_data;
}

struct connection_task_data {
Expand Down Expand Up @@ -1165,6 +1170,10 @@ static void s_tls_server_on_error(
}
}

/* AWS_USE_SECITEM is using Apple Network Framework's implementation of TLS handling.
* The TCP and TLS handshake are both handled by the network parameters and its options and verification block.
* We do not need to set up a separate TLS slot in the channel for iOS. */
#if !defined(AWS_USE_SECITEM)
static inline int s_setup_server_tls(struct server_channel_data *channel_data, struct aws_channel *channel) {
struct aws_channel_slot *tls_slot = NULL;
struct aws_channel_handler *tls_handler = NULL;
Expand Down Expand Up @@ -1248,6 +1257,7 @@ static inline int s_setup_server_tls(struct server_channel_data *channel_data, s

return AWS_OP_SUCCESS;
}
#endif /* !AWS_USE_SECITEM */

static void s_on_server_channel_on_setup_completed(struct aws_channel *channel, int error_code, void *user_data) {
struct server_channel_data *channel_data = user_data;
Expand Down Expand Up @@ -1313,6 +1323,10 @@ static void s_on_server_channel_on_setup_completed(struct aws_channel *channel,
goto error;
}

/* AWS_USE_SECITEM is using Apple Network Framework's implementation of TLS handling.
* The TCP and TLS handshake are both handled by the network parameters and its options and verification block.
* We do not need to set up a separate TLS slot in the channel for iOS. */
#if !defined(AWS_USE_SECITEM)
if (channel_data->server_connection_args->use_tls) {
/* incoming callback will be invoked upon the negotiation completion so don't do it
* here. */
Expand All @@ -1323,6 +1337,7 @@ static void s_on_server_channel_on_setup_completed(struct aws_channel *channel,
} else {
s_server_incoming_callback(channel_data, AWS_OP_SUCCESS, channel);
}
#endif /* !AWS_USE_SECITEM */
return;

error:
Expand Down
78 changes: 63 additions & 15 deletions source/darwin/nw_socket.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ static int s_determine_socket_error(int error) {
// return AWS_IO_TLS_INVALID_CERTIFICATE_CHAIN;
case errSSLHostNameMismatch:
// return AWS_IO_TLS_HOST_NAME_MISSMATCH;
case errSecNotTrusted:
return AWS_IO_TLS_ERROR_NEGOTIATION_FAILURE;

default:
Expand Down Expand Up @@ -188,6 +189,8 @@ struct nw_socket {
struct nw_socket_timeout_args *timeout_args;
aws_socket_on_connection_result_fn *on_connection_result_fn;
void *connect_accept_user_data;
aws_tls_on_negotiation_result_fn *on_tls_negotiation_result_fn;
void *on_tls_negotiation_result_user_data;
struct aws_string *host_name;
struct aws_tls_ctx *tls_ctx;

Expand Down Expand Up @@ -325,6 +328,7 @@ static int s_setup_socket_params(struct nw_socket *nw_socket, const struct aws_s
}

CFErrorRef error = NULL;
int error_code = AWS_ERROR_SUCCESS;
SecTrustRef trust_ref = sec_trust_copy_ref(trust);
OSStatus status;
bool verification_successful = false;
Expand Down Expand Up @@ -411,8 +415,16 @@ static int s_setup_socket_params(struct nw_socket *nw_socket, const struct aws_s
verification_done:
CFRelease(trust_ref);
if (error) {
error_code = CFErrorGetCode(error);
error_code = s_determine_socket_error(error_code);
nw_socket->last_error = error_code;
aws_raise_error(error_code);
CFRelease(error);
}
// 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);
}
complete(verification_successful);
},
dispatch_loop->dispatch_queue);
Expand Down Expand Up @@ -645,7 +657,6 @@ int aws_socket_init(struct aws_socket *socket, struct aws_allocator *alloc, cons

aws_ref_count_init(&nw_socket->ref_count, nw_socket, s_socket_impl_destroy);

nw_socket->allocator = alloc;
aws_linked_list_init(&nw_socket->read_queue);

return AWS_OP_SUCCESS;
Expand Down Expand Up @@ -762,7 +773,7 @@ static void s_schedule_on_readable(struct nw_socket *nw_socket, int error_code,
aws_mutex_unlock(&nw_socket->synced_data.lock);
}

static void s_process_connection_success_task(struct aws_task *task, void *arg, enum aws_task_status status) {
static void s_process_connection_result_task(struct aws_task *task, void *arg, enum aws_task_status status) {
(void)status;

struct nw_socket_scheduled_task_args *task_args = arg;
Expand All @@ -781,7 +792,7 @@ static void s_process_connection_success_task(struct aws_task *task, void *arg,
aws_mem_release(task_args->allocator, task_args);
}

static void s_schedule_on_connection_success(struct nw_socket *nw_socket, int error_code) {
static void s_schedule_on_connection_result(struct nw_socket *nw_socket, int error_code) {

aws_mutex_lock(&nw_socket->synced_data.lock);
struct aws_socket *socket = nw_socket->synced_data.base_socket;
Expand All @@ -795,12 +806,13 @@ static void s_schedule_on_connection_success(struct nw_socket *nw_socket, int er
args->allocator = socket->allocator;
args->error_code = error_code;
aws_ref_count_acquire(&nw_socket->ref_count);
aws_task_init(task, s_process_connection_success_task, args, "connectionSuccessTask");
aws_task_init(task, s_process_connection_result_task, args, "connectionSuccessTask");
aws_event_loop_schedule_task_now(nw_socket->synced_data.event_loop, task);
}

aws_mutex_unlock(&nw_socket->synced_data.lock);
}
// DEBUG WIP might need to schedule a tls_result the same way we schedule a connection_result()

static void s_process_listener_success_task(struct aws_task *task, void *args, enum aws_task_status status) {
(void)status;
Expand Down Expand Up @@ -1015,30 +1027,63 @@ static int s_socket_connect_fn(
return aws_raise_error(AWS_IO_EVENT_LOOP_ALREADY_ASSIGNED);
}

struct aws_tls_connection_options *tls_connection_options = NULL;
struct tls_connection_context tls_connection_context;
if (retrieve_tls_options != NULL) {
retrieve_tls_options(&tls_connection_options, user_data);
if (tls_connection_options->server_name) {
retrieve_tls_options(&tls_connection_context, user_data);
if (tls_connection_context.host_name != NULL) {
if (nw_socket->host_name != NULL) {
aws_string_destroy(nw_socket->host_name);
nw_socket->host_name = NULL;
}
nw_socket->host_name = aws_string_new_from_string(
tls_connection_options->server_name->allocator, tls_connection_options->server_name);
tls_connection_context.host_name->allocator, tls_connection_context.host_name);
if (nw_socket->host_name == NULL) {
return AWS_OP_ERR;
}
}

if (tls_connection_options->ctx) {
if (tls_connection_context.tls_ctx) {
if (nw_socket->tls_ctx) {
aws_tls_ctx_release(nw_socket->tls_ctx);
nw_socket->tls_ctx = NULL;
}
nw_socket->tls_ctx = tls_connection_options->ctx;
nw_socket->tls_ctx = tls_connection_context.tls_ctx;
aws_tls_ctx_acquire(nw_socket->tls_ctx);
}
}

nw_socket->on_tls_negotiation_result_fn = tls_connection_context.user_on_negotiation_result;
nw_socket->on_tls_negotiation_result_user_data = tls_connection_context.user_on_negotiation_result_user_data;
}
/*
struct aws_tls_connection_options *tls_connection_options = NULL;
if (retrieve_tls_options != NULL) {
retrieve_tls_options(&tls_connection_options, user_data);
if (tls_connection_options->server_name) {
if (nw_socket->host_name != NULL) {
aws_string_destroy(nw_socket->host_name);
nw_socket->host_name = NULL;
}
nw_socket->host_name = aws_string_new_from_string(
tls_connection_options->server_name->allocator, tls_connection_options->server_name);
if (nw_socket->host_name == NULL) {
return AWS_OP_ERR;
}
}
if (tls_connection_options->ctx) {
if (nw_socket->tls_ctx) {
aws_tls_ctx_release(nw_socket->tls_ctx);
nw_socket->tls_ctx = NULL;
}
nw_socket->tls_ctx = tls_connection_options->ctx;
aws_tls_ctx_acquire(nw_socket->tls_ctx);
}
if (tls_connection_options->on_negotiation_result) {
nw_socket->on_tls_negotiation_result_fn = tls_connection_options->on_negotiation_result;
}
}
*/

aws_mutex_lock(&nw_socket->synced_data.lock);
nw_socket->synced_data.event_loop = event_loop;
Expand Down Expand Up @@ -1210,7 +1255,7 @@ static int s_socket_connect_fn(
socket->state = CONNECTED_WRITE | CONNECTED_READ;
nw_socket->setup_run = true;
aws_ref_count_acquire(&nw_socket->ref_count);
s_schedule_on_connection_success(nw_socket, AWS_OP_SUCCESS);
s_schedule_on_connection_result(nw_socket, AWS_OP_SUCCESS);
s_schedule_next_read(nw_socket);
aws_ref_count_release(&nw_socket->ref_count);

Expand All @@ -1233,7 +1278,10 @@ static int s_socket_connect_fn(
aws_raise_error(error_code);
socket->state = ERROR;
if (!nw_socket->setup_run) {
s_schedule_on_connection_success(nw_socket, error_code);
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);
Expand All @@ -1255,7 +1303,7 @@ static int s_socket_connect_fn(
socket->state = CLOSED;
aws_raise_error(AWS_IO_SOCKET_CLOSED);
if (!nw_socket->setup_run) {
s_schedule_on_connection_success(nw_socket, AWS_IO_SOCKET_CLOSED);
s_schedule_on_connection_result(nw_socket, AWS_IO_SOCKET_CLOSED);
nw_socket->setup_run = true;
} else if (socket->readable_fn) {
s_schedule_on_readable(nw_socket, AWS_IO_SOCKET_CLOSED, NULL);
Expand Down Expand Up @@ -1507,7 +1555,7 @@ static int s_socket_start_accept_fn(
} else if (state == nw_listener_state_ready) {
AWS_LOGF_DEBUG(
AWS_LS_IO_SOCKET,
"id=%p handle=%p: lisnter on port ready ",
"id=%p handle=%p: listener on port ready ",
(void *)socket,
(void *)nw_socket->nw_connection);

Expand Down

0 comments on commit 622fc7c

Please sign in to comment.