diff --git a/include/aws/io/stream.h b/include/aws/io/stream.h index 44e8b393a..f86042fd4 100644 --- a/include/aws/io/stream.h +++ b/include/aws/io/stream.h @@ -59,35 +59,38 @@ AWS_EXTERN_C_BEGIN /* * Seek to a position within a stream; analagous to fseek() and its relatives */ -int aws_input_stream_seek(struct aws_input_stream *stream, aws_off_t offset, enum aws_stream_seek_basis basis); +AWS_IO_API int aws_input_stream_seek( + struct aws_input_stream *stream, + aws_off_t offset, + enum aws_stream_seek_basis basis); /* * Read data from a stream. If data is available, will read up to the (capacity - len) open bytes * in the destination buffer. */ -int aws_input_stream_read(struct aws_input_stream *stream, struct aws_byte_buf *dest, size_t *amount_read); +AWS_IO_API int aws_input_stream_read(struct aws_input_stream *stream, struct aws_byte_buf *dest, size_t *amount_read); /* * Queries miscellaneous properties of the stream */ -int aws_input_stream_get_status(struct aws_input_stream *stream, struct aws_stream_status *status); +AWS_IO_API int aws_input_stream_get_status(struct aws_input_stream *stream, struct aws_stream_status *status); /* * Returns the total stream length, if able, regardless of current stream position. Under certain conditions, * a valid stream may return an error instead when there is not a good answer (socket stream, for example). * */ -int aws_input_stream_get_length(struct aws_input_stream *stream, int64_t *out_length); +AWS_IO_API int aws_input_stream_get_length(struct aws_input_stream *stream, int64_t *out_length); /* * Tears down the stream */ -void aws_input_stream_destroy(struct aws_input_stream *stream); +AWS_IO_API void aws_input_stream_destroy(struct aws_input_stream *stream); /* * Creates a stream that operates on a range of bytes */ -struct aws_input_stream *aws_input_stream_new_from_cursor( +AWS_IO_API struct aws_input_stream *aws_input_stream_new_from_cursor( struct aws_allocator *allocator, const struct aws_byte_cursor *cursor); @@ -95,13 +98,15 @@ struct aws_input_stream *aws_input_stream_new_from_cursor( * Creates a stream that operates on a (not-yet-opened) file. * Destruction closes the file. */ -struct aws_input_stream *aws_input_stream_new_from_file(struct aws_allocator *allocator, const char *file_name); +AWS_IO_API struct aws_input_stream *aws_input_stream_new_from_file( + struct aws_allocator *allocator, + const char *file_name); /* * Creates an input stream that reads from an already opened file. * Destruction does not close the file. */ -struct aws_input_stream *aws_input_stream_new_from_open_file(struct aws_allocator *allocator, FILE *file); +AWS_IO_API struct aws_input_stream *aws_input_stream_new_from_open_file(struct aws_allocator *allocator, FILE *file); AWS_EXTERN_C_END diff --git a/source/tls_channel_handler.c b/source/tls_channel_handler.c index b8330b492..1ca8499cf 100644 --- a/source/tls_channel_handler.c +++ b/source/tls_channel_handler.c @@ -59,6 +59,29 @@ void aws_tls_ctx_options_clean_up(struct aws_tls_ctx_options *options) { AWS_ZERO_STRUCT(*options); } +static int s_load_null_terminated_buffer_from_cursor( + struct aws_byte_buf *load_into, + struct aws_allocator *allocator, + struct aws_byte_cursor *from) { + if (from->ptr[from->len - 1] == 0) { + if (aws_byte_buf_init_copy_from_cursor(load_into, allocator, *from)) { + return AWS_OP_ERR; + } + + load_into->len -= 1; + } else { + if (aws_byte_buf_init(load_into, allocator, from->len + 1)) { + return AWS_OP_ERR; + } + + memcpy(load_into->buffer, from->ptr, from->len); + load_into->buffer[from->len] = 0; + load_into->len = from->len; + } + + return AWS_OP_SUCCESS; +} + int aws_tls_ctx_options_init_client_mtls( struct aws_tls_ctx_options *options, struct aws_allocator *allocator, @@ -70,11 +93,14 @@ int aws_tls_ctx_options_init_client_mtls( options->allocator = allocator; options->max_fragment_size = g_aws_channel_max_fragment_size; - if (aws_byte_buf_init_copy_from_cursor(&options->certificate, allocator, *cert)) { + /* s2n relies on null terminated c_strings, so we need to make sure we're properly + * terminated, but we don't want length to reflect the terminator because + * Apple and Windows will fail hard if you use a null terminator. */ + if (s_load_null_terminated_buffer_from_cursor(&options->certificate, allocator, cert)) { return AWS_OP_ERR; } - if (aws_byte_buf_init_copy_from_cursor(&options->private_key, allocator, *pkey)) { + if (s_load_null_terminated_buffer_from_cursor(&options->private_key, allocator, pkey)) { aws_byte_buf_clean_up(&options->certificate); return AWS_OP_ERR; } @@ -162,11 +188,11 @@ int aws_tls_ctx_options_init_client_mtls_pkcs12( options->allocator = allocator; options->max_fragment_size = g_aws_channel_max_fragment_size; - if (aws_byte_buf_init_copy_from_cursor(&options->pkcs12, allocator, *pkcs12)) { + if (s_load_null_terminated_buffer_from_cursor(&options->pkcs12, allocator, pkcs12)) { return AWS_OP_ERR; } - if (aws_byte_buf_init_copy_from_cursor(&options->pkcs12_password, allocator, *pkcs_pwd)) { + if (s_load_null_terminated_buffer_from_cursor(&options->pkcs12_password, allocator, pkcs_pwd)) { aws_byte_buf_clean_up_secure(&options->pkcs12); return AWS_OP_ERR; } @@ -266,7 +292,10 @@ int aws_tls_ctx_options_override_default_trust_store( struct aws_tls_ctx_options *options, struct aws_byte_cursor *ca_file) { - if (aws_byte_buf_init_copy_from_cursor(&options->ca_file, options->allocator, *ca_file)) { + /* s2n relies on null terminated c_strings, so we need to make sure we're properly + * terminated, but we don't want length to reflect the terminator because + * Apple and Windows will fail hard if you use a null terminator. */ + if (s_load_null_terminated_buffer_from_cursor(&options->ca_file, options->allocator, ca_file)) { return AWS_OP_ERR; }