diff --git a/.gitignore b/.gitignore index 6a8a36868..2ef3eccf7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ # IDE Artifacts .metadata .build +.vscode .idea *.d Debug diff --git a/include/aws/io/io.h b/include/aws/io/io.h index fc9677fdb..011e1a779 100644 --- a/include/aws/io/io.h +++ b/include/aws/io/io.h @@ -252,6 +252,8 @@ enum aws_io_errors { AWS_IO_TLS_ERROR_READ_FAILURE, + AWS_ERROR_PEM_MALFORMED, + AWS_IO_ERROR_END_RANGE = AWS_ERROR_ENUM_END_RANGE(AWS_C_IO_PACKAGE_ID), AWS_IO_INVALID_FILE_HANDLE = AWS_ERROR_INVALID_FILE_HANDLE, }; diff --git a/include/aws/io/logging.h b/include/aws/io/logging.h index 5d8a144a0..a3bbee2fa 100644 --- a/include/aws/io/logging.h +++ b/include/aws/io/logging.h @@ -32,6 +32,7 @@ enum aws_io_log_subject { AWS_LS_IO_EXPONENTIAL_BACKOFF_RETRY_STRATEGY, AWS_LS_IO_STANDARD_RETRY_STRATEGY, AWS_LS_IO_PKCS11, + AWS_LS_IO_PEM, AWS_IO_LS_LAST = AWS_LOG_SUBJECT_END_RANGE(AWS_C_IO_PACKAGE_ID) }; AWS_POP_SANE_WARNING_LEVEL diff --git a/include/aws/io/pem.h b/include/aws/io/pem.h new file mode 100644 index 000000000..0a21cc0c6 --- /dev/null +++ b/include/aws/io/pem.h @@ -0,0 +1,99 @@ +#ifndef AWS_IO_PEM_H +#define AWS_IO_PEM_H + +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ +#include + +AWS_EXTERN_C_BEGIN + +/* + * Naming follows OpenSSL convention for PEM types. + * Refer to comment after each enum value for the type string it represents. + */ +enum aws_pem_object_type { + AWS_PEM_TYPE_UNKNOWN = 0, + AWS_PEM_TYPE_X509_OLD, /* X509 CERTIFICATE */ + AWS_PEM_TYPE_X509, /* CERTIFICATE */ + AWS_PEM_TYPE_X509_TRUSTED, /* TRUSTED CERTIFICATE */ + AWS_PEM_TYPE_X509_REQ_OLD, /* NEW CERTIFICATE REQUEST */ + AWS_PEM_TYPE_X509_REQ, /* CERTIFICATE REQUEST */ + AWS_PEM_TYPE_X509_CRL, /* X509 CRL */ + AWS_PEM_TYPE_EVP_PKEY, /* ANY PRIVATE KEY */ + AWS_PEM_TYPE_PUBLIC_PKCS8, /* PUBLIC KEY */ + AWS_PEM_TYPE_PRIVATE_RSA_PKCS1, /* RSA PRIVATE KEY */ + AWS_PEM_TYPE_PUBLIC_RSA_PKCS1, /* RSA PUBLIC KEY */ + AWS_PEM_TYPE_PRIVATE_DSA_PKCS1, /* RSA PRIVATE KEY */ + AWS_PEM_TYPE_PUBLIC_DSA_PKCS1, /* RSA PUBLIC KEY */ + AWS_PEM_TYPE_PKCS7, /* PKCS7 */ + AWS_PEM_TYPE_PKCS7_SIGNED_DATA, /* PKCS #7 SIGNED DATA */ + AWS_PEM_TYPE_PRIVATE_PKCS8_ENCRYPTED, /* ENCRYPTED PRIVATE KEY */ + AWS_PEM_TYPE_PRIVATE_PKCS8, /* PRIVATE KEY */ + AWS_PEM_TYPE_DH_PARAMETERS, /* X9.42 DH PARAMETERS */ + AWS_PEM_TYPE_DH_PARAMETERS_X942, /* X9.42 DH PARAMETERS */ + AWS_PEM_TYPE_SSL_SESSION_PARAMETERS, /* SSL SESSION PARAMETERS */ + AWS_PEM_TYPE_DSA_PARAMETERS, /* DSA PARAMETERS */ + AWS_PEM_TYPE_ECDSA_PUBLIC, /* ECDSA PUBLIC KEY */ + AWS_PEM_TYPE_EC_PARAMETERS, /* EC PARAMETERS */ + AWS_PEM_TYPE_EC_PRIVATE, /* EC PRIVATE KEY */ + AWS_PEM_TYPE_PARAMETERS, /* PARAMETERS */ + AWS_PEM_TYPE_CMS, /* CMS */ + AWS_PEM_TYPE_SM2_PARAMETERS /* SM2 PARAMETERS */ +}; + +/* + * Describes PEM object decoded from file. + * data points to raw data bytes of object (decoding will do additional base 64 + * decoding for each object). + * type will be set to object type or to AWS_PEM_TYPE_UNKNOWN if it could not + * figure out type. + * type_string is the string between -----BEGIN and ----- + */ +struct aws_pem_object { + enum aws_pem_object_type type; + struct aws_string *type_string; + struct aws_byte_buf data; +}; + +/** + * Cleans up elements of pem_objects list 'aws_pem_objects_init_from_file_contents()' + * and 'aws_pem_objects_init_from_file_path()'. + */ +AWS_IO_API void aws_pem_objects_clean_up(struct aws_array_list *pem_objects); + +/** + * Decodes PEM data and reads objects sequentially adding them to pem_objects. + * If it comes across an object it cannot read, list of all object read until + * that point is returned. + * If no objects can be read from PEM or objects could not be base 64 decoded, + * AWS_ERROR_PEM_MALFORMED is raised. + * out_pem_objects stores aws_pem_object struct by value. + * Function will initialize pem_objects list. + * This code is slow, and it allocates, so please try + * not to call this in the middle of something that needs to be fast or resource sensitive. + */ +AWS_IO_API int aws_pem_objects_init_from_file_contents( + struct aws_array_list *pem_objects, + struct aws_allocator *alloc, + struct aws_byte_cursor pem_cursor); + +/** + * Decodes PEM data from file and reads objects sequentially adding them to pem_objects. + * If it comes across an object it cannot read, list of all object read until + * that point is returned. + * If no objects can be read from PEM or objects could not be base 64 decoded, + * AWS_ERROR_PEM_MALFORMED is raised. + * out_pem_objects stores aws_pem_object struct by value. + * Function will initialize pem_objects list. + * This code is slow, and it allocates, so please try + * not to call this in the middle of something that needs to be fast or resource sensitive. + */ +AWS_IO_API int aws_pem_objects_init_from_file_path( + struct aws_array_list *pem_objects, + struct aws_allocator *allocator, + const char *filename); + +AWS_EXTERN_C_END +#endif /* AWS_IO_PEM_H */ diff --git a/include/aws/io/private/pki_utils.h b/include/aws/io/private/pki_utils.h index feb8d65ce..af0465560 100644 --- a/include/aws/io/private/pki_utils.h +++ b/include/aws/io/private/pki_utils.h @@ -21,23 +21,6 @@ struct aws_string; AWS_EXTERN_C_BEGIN -/** - * Cleans up and securely zeroes out the outputs of 'aws_decode_pem_to_buffer_list()' - * and 'aws_read_and_decode_pem_file_to_buffer_list()' - */ -AWS_IO_API void aws_cert_chain_clean_up(struct aws_array_list *cert_chain); - -/** - * Decodes a PEM file and adds the results to 'cert_chain_or_key' if successful. - * Otherwise, 'cert_chain_or_key' will be empty. The type stored in 'cert_chain_or_key' - * is 'struct aws_byte_buf' by value. This code is slow, and it allocates, so please try - * not to call this in the middle of something that needs to be fast or resource sensitive. - */ -AWS_IO_API int aws_decode_pem_to_buffer_list( - struct aws_allocator *alloc, - const struct aws_byte_cursor *pem_cursor, - struct aws_array_list *cert_chain_or_key); - /** * Returns the path to the directory and file, respectively, which holds the * SSL certificate trust store on the system. @@ -45,19 +28,6 @@ AWS_IO_API int aws_decode_pem_to_buffer_list( AWS_IO_API const char *aws_determine_default_pki_dir(void); AWS_IO_API const char *aws_determine_default_pki_ca_file(void); -/** - * Decodes a PEM file at 'filename' and adds the results to 'cert_chain_or_key' if successful. - * Otherwise, 'cert_chain_or_key' will be empty. - * The passed-in parameter 'cert_chain_or_key' should be empty and dynamically initialized array_list - * with item type 'struct aws_byte_buf' in value. - * This code is slow, and it allocates, so please try not to call this in the middle of - * something that needs to be fast or resource sensitive. - */ -AWS_IO_API int aws_read_and_decode_pem_file_to_buffer_list( - struct aws_allocator *alloc, - const char *filename, - struct aws_array_list *cert_chain_or_key); - #ifdef AWS_OS_APPLE # if !defined(AWS_OS_IOS) /** diff --git a/source/darwin/darwin_pki_utils.c b/source/darwin/darwin_pki_utils.c index 9d95fd1a9..7b60bab2c 100644 --- a/source/darwin/darwin_pki_utils.c +++ b/source/darwin/darwin_pki_utils.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -33,16 +34,13 @@ int aws_import_ecc_key_into_keychain( SecKeychainRef import_keychain) { // Ensure imported_keychain is not NULL AWS_PRECONDITION(import_keychain != NULL); + AWS_PRECONDITION(private_key != NULL); int result = AWS_OP_ERR; struct aws_array_list decoded_key_buffer_list; - /* Init empty array list, ideally, the PEM should only has one key included. */ - if (aws_array_list_init_dynamic(&decoded_key_buffer_list, alloc, 1, sizeof(struct aws_byte_buf))) { - return result; - } /* Decode PEM format file to DER format */ - if (aws_decode_pem_to_buffer_list(alloc, private_key, &decoded_key_buffer_list)) { + if (aws_pem_objects_init_from_file_contents(&decoded_key_buffer_list, alloc, *private_key)) { AWS_LOGF_ERROR(AWS_LS_IO_PKI, "static: Failed to decode PEM private key to DER format."); goto ecc_import_cleanup; } @@ -51,11 +49,11 @@ int aws_import_ecc_key_into_keychain( // A PEM file could contains multiple PEM data section. Try importing each PEM section until find the first // succeed key. for (size_t index = 0; index < aws_array_list_length(&decoded_key_buffer_list); index++) { - struct aws_byte_buf *decoded_key_buffer = NULL; + struct aws_pem_object *pem_object_ptr = NULL; /* We only check the first pem section. Currently, we dont support key with multiple pem section. */ - aws_array_list_get_at_ptr(&decoded_key_buffer_list, (void **)&decoded_key_buffer, index); + aws_array_list_get_at_ptr(&decoded_key_buffer_list, (void **)&pem_object_ptr, index); AWS_ASSERT(decoded_key_buffer); - CFDataRef key_data = CFDataCreate(cf_alloc, decoded_key_buffer->buffer, decoded_key_buffer->len); + CFDataRef key_data = CFDataCreate(cf_alloc, pem_object_ptr->data.buffer, pem_object_ptr->data.len); if (!key_data) { AWS_LOGF_ERROR(AWS_LS_IO_PKI, "static: error in creating ECC key data system call."); continue; @@ -68,6 +66,7 @@ int aws_import_ecc_key_into_keychain( AWS_ZERO_STRUCT(import_params); import_params.version = SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION; import_params.passphrase = CFSTR(""); + format = kSecFormatUnknown; OSStatus key_status = SecItemImport(key_data, NULL, &format, &item_type, 0, &import_params, import_keychain, NULL); @@ -87,8 +86,7 @@ int aws_import_ecc_key_into_keychain( ecc_import_cleanup: // Zero out the array list and release it - aws_cert_chain_clean_up(&decoded_key_buffer_list); - aws_array_list_clean_up(&decoded_key_buffer_list); + aws_pem_objects_clean_up(&decoded_key_buffer_list); return result; } @@ -99,6 +97,8 @@ int aws_import_public_and_private_keys_to_identity( const struct aws_byte_cursor *private_key, CFArrayRef *identity, const struct aws_string *keychain_path) { + AWS_PRECONDITION(public_cert_chain != NULL); + AWS_PRECONDITION(private_key != NULL); int result = AWS_OP_ERR; @@ -179,7 +179,7 @@ int aws_import_public_and_private_keys_to_identity( /* * If the key format is unknown, we tried to decode the key into DER format import it. - * The PEM file might contians multiple key sections, we will only add the first succeed key into the keychain. + * The PEM file might contains multiple key sections, we will only add the first succeed key into the keychain. */ if (key_status == errSecUnknownFormat) { AWS_LOGF_TRACE(AWS_LS_IO_PKI, "static: error reading private key format, try ECC key format."); @@ -203,30 +203,24 @@ int aws_import_public_and_private_keys_to_identity( "Using key from Keychain instead of the one provided."); struct aws_array_list cert_chain_list; - if (aws_array_list_init_dynamic(&cert_chain_list, alloc, 2, sizeof(struct aws_byte_buf))) { - result = AWS_OP_ERR; - goto done; - } - - if (aws_decode_pem_to_buffer_list(alloc, public_cert_chain, &cert_chain_list)) { + if (aws_pem_objects_init_from_file_contents(&cert_chain_list, alloc, *public_cert_chain)) { AWS_LOGF_ERROR(AWS_LS_IO_PKI, "static: decoding certificate PEM failed."); - aws_array_list_clean_up(&cert_chain_list); + aws_pem_objects_clean_up(&cert_chain_list); result = AWS_OP_ERR; goto done; } - struct aws_byte_buf *root_cert_ptr = NULL; + struct aws_pem_object *root_cert_ptr = NULL; aws_array_list_get_at_ptr(&cert_chain_list, (void **)&root_cert_ptr, 0); AWS_ASSERT(root_cert_ptr); - CFDataRef root_cert_data = CFDataCreate(cf_alloc, root_cert_ptr->buffer, root_cert_ptr->len); + CFDataRef root_cert_data = CFDataCreate(cf_alloc, root_cert_ptr->data.buffer, root_cert_ptr->data.len); if (root_cert_data) { certificate_ref = SecCertificateCreateWithData(cf_alloc, root_cert_data); CFRelease(root_cert_data); } - aws_cert_chain_clean_up(&cert_chain_list); - aws_array_list_clean_up(&cert_chain_list); + aws_pem_objects_clean_up(&cert_chain_list); } else { certificate_ref = (SecCertificateRef)CFArrayGetValueAtIndex(cert_import_output, 0); /* SecCertificateCreateWithData returns an object with +1 retain, so we need to match that behavior here */ @@ -316,13 +310,11 @@ int aws_import_trusted_certificates( CFAllocatorRef cf_alloc, const struct aws_byte_cursor *certificates_blob, CFArrayRef *certs) { - struct aws_array_list certificates; + AWS_PRECONDITION(certificates_blob != NULL); - if (aws_array_list_init_dynamic(&certificates, alloc, 2, sizeof(struct aws_byte_buf))) { - return AWS_OP_ERR; - } + struct aws_array_list certificates; - if (aws_decode_pem_to_buffer_list(alloc, certificates_blob, &certificates)) { + if (aws_pem_objects_init_from_file_contents(&certificates, alloc, *certificates_blob)) { AWS_LOGF_ERROR(AWS_LS_IO_PKI, "static: decoding CA PEM failed."); aws_array_list_clean_up(&certificates); return AWS_OP_ERR; @@ -334,10 +326,10 @@ int aws_import_trusted_certificates( int err = AWS_OP_SUCCESS; aws_mutex_lock(&s_sec_mutex); for (size_t i = 0; i < cert_count; ++i) { - struct aws_byte_buf *byte_buf_ptr = NULL; - aws_array_list_get_at_ptr(&certificates, (void **)&byte_buf_ptr, i); + struct aws_pem_object *pem_object_ptr = NULL; + aws_array_list_get_at_ptr(&certificates, (void **)&pem_object_ptr, i); - CFDataRef cert_blob = CFDataCreate(cf_alloc, byte_buf_ptr->buffer, byte_buf_ptr->len); + CFDataRef cert_blob = CFDataCreate(cf_alloc, pem_object_ptr->data.buffer, pem_object_ptr->data.len); if (cert_blob) { SecCertificateRef certificate_ref = SecCertificateCreateWithData(cf_alloc, cert_blob); @@ -351,7 +343,7 @@ int aws_import_trusted_certificates( aws_mutex_unlock(&s_sec_mutex); *certs = temp_cert_array; - aws_cert_chain_clean_up(&certificates); + aws_pem_objects_clean_up(&certificates); aws_array_list_clean_up(&certificates); return err; } diff --git a/source/io.c b/source/io.c index 701e580d1..c47ce97a9 100644 --- a/source/io.c +++ b/source/io.c @@ -304,6 +304,7 @@ static struct aws_error_info s_errors[] = { AWS_DEFINE_ERROR_INFO_IO( AWS_IO_TLS_ERROR_READ_FAILURE, "Failure during TLS read."), + AWS_DEFINE_ERROR_INFO_IO(AWS_ERROR_PEM_MALFORMED, "Malformed PEM object encountered."), }; /* clang-format on */ @@ -341,7 +342,7 @@ static struct aws_log_subject_info s_io_log_subject_infos[] = { "standard-retry-strategy", "Subject for standard retry strategy"), DEFINE_LOG_SUBJECT_INFO(AWS_LS_IO_PKCS11, "pkcs11", "Subject for PKCS#11 library operations"), -}; + DEFINE_LOG_SUBJECT_INFO(AWS_LS_IO_PEM, "pem", "Subject for pem operations")}; static struct aws_log_subject_info_list s_io_log_subject_list = { .subject_list = s_io_log_subject_infos, diff --git a/source/pem.c b/source/pem.c new file mode 100644 index 000000000..dd8eaf56a --- /dev/null +++ b/source/pem.c @@ -0,0 +1,437 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ +#include +#include +#include +#include + +#include + +enum aws_pem_parse_state { + BEGIN, + ON_DATA, + END, +}; + +static const struct aws_byte_cursor begin_header = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("-----BEGIN"); +static const struct aws_byte_cursor end_header = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("-----END"); +static const struct aws_byte_cursor dashes = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("-----"); + +int aws_sanitize_pem(struct aws_byte_buf *pem, struct aws_allocator *allocator) { + if (!pem->len) { + /* reject files with no PEM data */ + return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT); + } + struct aws_byte_buf clean_pem_buf; + if (aws_byte_buf_init(&clean_pem_buf, allocator, pem->len)) { + return AWS_OP_ERR; + } + struct aws_byte_cursor pem_cursor = aws_byte_cursor_from_buf(pem); + enum aws_pem_parse_state state = BEGIN; + + for (size_t i = 0; i < pem_cursor.len; i++) { + /* parse through the pem once */ + char current = *(pem_cursor.ptr + i); + switch (state) { + case BEGIN: + if (current == '-') { + struct aws_byte_cursor compare_cursor = pem_cursor; + compare_cursor.len = begin_header.len; + compare_cursor.ptr += i; + if (aws_byte_cursor_eq(&compare_cursor, &begin_header)) { + state = ON_DATA; + i--; + } + } + break; + case ON_DATA: + /* start copying everything */ + if (current == '-') { + struct aws_byte_cursor compare_cursor = pem_cursor; + compare_cursor.len = end_header.len; + compare_cursor.ptr += i; + if (aws_byte_cursor_eq(&compare_cursor, &end_header)) { + /* Copy the end header string and start to search for the end part of a pem */ + state = END; + aws_byte_buf_append(&clean_pem_buf, &end_header); + i += (end_header.len - 1); + break; + } + } + aws_byte_buf_append_byte_dynamic(&clean_pem_buf, (uint8_t)current); + break; + case END: + if (current == '-') { + struct aws_byte_cursor compare_cursor = pem_cursor; + compare_cursor.len = dashes.len; + compare_cursor.ptr += i; + if (aws_byte_cursor_eq(&compare_cursor, &dashes)) { + /* End part of a pem, copy the last 5 dashes and a new line, then ignore everything before next + * begin header */ + state = BEGIN; + aws_byte_buf_append(&clean_pem_buf, &dashes); + i += (dashes.len - 1); + aws_byte_buf_append_byte_dynamic(&clean_pem_buf, (uint8_t)'\n'); + break; + } + } + aws_byte_buf_append_byte_dynamic(&clean_pem_buf, (uint8_t)current); + break; + default: + break; + } + } + + if (clean_pem_buf.len == 0) { + /* No valid data remains after sanitization. File might have been the wrong format */ + aws_raise_error(AWS_ERROR_INVALID_ARGUMENT); + goto error; + } + + struct aws_byte_cursor clean_pem_cursor = aws_byte_cursor_from_buf(&clean_pem_buf); + aws_byte_buf_reset(pem, true); + aws_byte_buf_append_dynamic(pem, &clean_pem_cursor); + aws_byte_buf_clean_up(&clean_pem_buf); + return AWS_OP_SUCCESS; + +error: + aws_byte_buf_clean_up(&clean_pem_buf); + return AWS_OP_ERR; +} + +/* + * Possible PEM object types. openssl/pem.h used as a source of truth for + * possible types. + */ +static struct aws_byte_cursor s_pem_type_x509_old_cur = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("X509 CERTIFICATE"); +static struct aws_byte_cursor s_pem_type_x509_cur = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("CERTIFICATE"); +static struct aws_byte_cursor s_pem_type_x509_trusted_cur = + AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("TRUSTED CERTIFICATE"); +static struct aws_byte_cursor s_pem_type_x509_req_old_cur = + AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("NEW CERTIFICATE REQUEST"); +static struct aws_byte_cursor s_pem_type_x509_req_cur = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("CERTIFICATE REQUEST"); +static struct aws_byte_cursor s_pem_type_x509_crl_cur = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("X509 CRL"); +static struct aws_byte_cursor s_pem_type_evp_pkey_cur = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("ANY PRIVATE KEY"); +static struct aws_byte_cursor s_pem_type_public_pkcs8_cur = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("PUBLIC KEY"); +static struct aws_byte_cursor s_pem_type_private_rsa_pkcs1_cur = + AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("RSA PRIVATE KEY"); +static struct aws_byte_cursor s_pem_type_public_rsa_pkcs1_cur = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("RSA PUBLIC KEY"); +static struct aws_byte_cursor s_pem_type_private_dsa_pkcs1_cur = + AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("RSA PRIVATE KEY"); +static struct aws_byte_cursor s_pem_type_public_dsa_pkcs1_cur = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("RSA PUBLIC KEY"); +static struct aws_byte_cursor s_pem_type_pkcs7_cur = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("PKCS7"); +static struct aws_byte_cursor s_pem_type_pkcs7_signed_data_cur = + AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("PKCS #7 SIGNED DATA"); +static struct aws_byte_cursor s_pem_type_private_pkcs8_encrypted_cur = + AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("ENCRYPTED PRIVATE KEY"); +static struct aws_byte_cursor s_pem_type_private_pkcs8_cur = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("PRIVATE KEY"); +static struct aws_byte_cursor s_pem_type_dh_parameters_cur = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("DH PARAMETERS"); +static struct aws_byte_cursor s_pem_type_dh_parameters_x942_cur = + AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("X9.42 DH PARAMETERS"); +static struct aws_byte_cursor s_pem_type_ssl_session_parameters_cur = + AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("SSL SESSION PARAMETERS"); +static struct aws_byte_cursor s_pem_type_dsa_parameters_cur = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("DSA PARAMETERS"); +static struct aws_byte_cursor s_pem_type_ecdsa_public_cur = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("ECDSA PUBLIC KEY"); +static struct aws_byte_cursor s_pem_type_ec_parameters_cur = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("EC PARAMETERS"); +static struct aws_byte_cursor s_pem_type_ec_private_cur = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("EC PRIVATE KEY"); +static struct aws_byte_cursor s_pem_type_parameters_cur = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("PARAMETERS"); +static struct aws_byte_cursor s_pem_type_cms_cur = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("CMS"); +static struct aws_byte_cursor s_pem_type_sm2_parameters_cur = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("SM2 PARAMETERS"); + +void aws_pem_objects_clean_up(struct aws_array_list *pem_objects) { + for (size_t i = 0; i < aws_array_list_length(pem_objects); ++i) { + struct aws_pem_object *pem_obj_ptr = NULL; + aws_array_list_get_at_ptr(pem_objects, (void **)&pem_obj_ptr, i); + + if (pem_obj_ptr != NULL) { + aws_byte_buf_clean_up_secure(&pem_obj_ptr->data); + aws_string_destroy(pem_obj_ptr->type_string); + } + } + + aws_array_list_clear(pem_objects); + aws_array_list_clean_up(pem_objects); +} + +enum aws_pem_object_type s_map_type_cur_to_type(struct aws_byte_cursor type_cur) { + /* + * Putting all those in a hash table might be a bit faster depending on + * hashing function cost, but it complicates code considerably for a + * potential small gain. PEM parsing is already slow due to multiple + * allocations and should not be used in perf critical places. + * So choosing dumb and easy approach over something more complicated and we + * can reevaluate decision in the future. + */ + if (aws_byte_cursor_eq(&type_cur, &s_pem_type_x509_old_cur)) { + return AWS_PEM_TYPE_X509_OLD; + } else if (aws_byte_cursor_eq(&type_cur, &s_pem_type_x509_cur)) { + return AWS_PEM_TYPE_X509; + } else if (aws_byte_cursor_eq(&type_cur, &s_pem_type_x509_trusted_cur)) { + return AWS_PEM_TYPE_X509_TRUSTED; + } else if (aws_byte_cursor_eq(&type_cur, &s_pem_type_x509_req_old_cur)) { + return AWS_PEM_TYPE_X509_REQ_OLD; + } else if (aws_byte_cursor_eq(&type_cur, &s_pem_type_x509_req_cur)) { + return AWS_PEM_TYPE_X509_REQ; + } else if (aws_byte_cursor_eq(&type_cur, &s_pem_type_x509_crl_cur)) { + return AWS_PEM_TYPE_X509_CRL; + } else if (aws_byte_cursor_eq(&type_cur, &s_pem_type_evp_pkey_cur)) { + return AWS_PEM_TYPE_EVP_PKEY; + } else if (aws_byte_cursor_eq(&type_cur, &s_pem_type_public_pkcs8_cur)) { + return AWS_PEM_TYPE_PUBLIC_PKCS8; + } else if (aws_byte_cursor_eq(&type_cur, &s_pem_type_private_rsa_pkcs1_cur)) { + return AWS_PEM_TYPE_PRIVATE_RSA_PKCS1; + } else if (aws_byte_cursor_eq(&type_cur, &s_pem_type_public_rsa_pkcs1_cur)) { + return AWS_PEM_TYPE_PUBLIC_RSA_PKCS1; + } else if (aws_byte_cursor_eq(&type_cur, &s_pem_type_private_dsa_pkcs1_cur)) { + return AWS_PEM_TYPE_PRIVATE_DSA_PKCS1; + } else if (aws_byte_cursor_eq(&type_cur, &s_pem_type_public_dsa_pkcs1_cur)) { + return AWS_PEM_TYPE_PUBLIC_DSA_PKCS1; + } else if (aws_byte_cursor_eq(&type_cur, &s_pem_type_pkcs7_cur)) { + return AWS_PEM_TYPE_PKCS7; + } else if (aws_byte_cursor_eq(&type_cur, &s_pem_type_pkcs7_signed_data_cur)) { + return AWS_PEM_TYPE_PKCS7_SIGNED_DATA; + } else if (aws_byte_cursor_eq(&type_cur, &s_pem_type_private_pkcs8_encrypted_cur)) { + return AWS_PEM_TYPE_PRIVATE_PKCS8_ENCRYPTED; + } else if (aws_byte_cursor_eq(&type_cur, &s_pem_type_private_pkcs8_cur)) { + return AWS_PEM_TYPE_PRIVATE_PKCS8; + } else if (aws_byte_cursor_eq(&type_cur, &s_pem_type_dh_parameters_cur)) { + return AWS_PEM_TYPE_DH_PARAMETERS; + } else if (aws_byte_cursor_eq(&type_cur, &s_pem_type_dh_parameters_x942_cur)) { + return AWS_PEM_TYPE_DH_PARAMETERS_X942; + } else if (aws_byte_cursor_eq(&type_cur, &s_pem_type_ssl_session_parameters_cur)) { + return AWS_PEM_TYPE_SSL_SESSION_PARAMETERS; + } else if (aws_byte_cursor_eq(&type_cur, &s_pem_type_dsa_parameters_cur)) { + return AWS_PEM_TYPE_DSA_PARAMETERS; + } else if (aws_byte_cursor_eq(&type_cur, &s_pem_type_ecdsa_public_cur)) { + return AWS_PEM_TYPE_ECDSA_PUBLIC; + } else if (aws_byte_cursor_eq(&type_cur, &s_pem_type_ec_parameters_cur)) { + return AWS_PEM_TYPE_EC_PARAMETERS; + } else if (aws_byte_cursor_eq(&type_cur, &s_pem_type_ec_private_cur)) { + return AWS_PEM_TYPE_EC_PRIVATE; + } else if (aws_byte_cursor_eq(&type_cur, &s_pem_type_parameters_cur)) { + return AWS_PEM_TYPE_PARAMETERS; + } else if (aws_byte_cursor_eq(&type_cur, &s_pem_type_cms_cur)) { + return AWS_PEM_TYPE_CMS; + } else if (aws_byte_cursor_eq(&type_cur, &s_pem_type_sm2_parameters_cur)) { + return AWS_PEM_TYPE_SM2_PARAMETERS; + } + + return AWS_PEM_TYPE_UNKNOWN; +} + +static struct aws_byte_cursor s_begin_header_cur = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("-----BEGIN"); +static struct aws_byte_cursor s_end_header_cur = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("-----END"); +static struct aws_byte_cursor s_delim_cur = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("-----"); + +int s_extract_header_type_cur(struct aws_byte_cursor cur, struct aws_byte_cursor *out) { + if (!aws_byte_cursor_starts_with(&cur, &s_begin_header_cur)) { + AWS_LOGF_ERROR(AWS_LS_IO_PEM, "Invalid PEM buffer: invalid begin token"); + return aws_raise_error(AWS_ERROR_PEM_MALFORMED); + } + + aws_byte_cursor_advance(&cur, s_begin_header_cur.len); + aws_byte_cursor_advance(&cur, 1); // space after begin + struct aws_byte_cursor type_cur = aws_byte_cursor_advance(&cur, cur.len - s_delim_cur.len); + + if (!aws_byte_cursor_eq(&cur, &s_delim_cur)) { + AWS_LOGF_ERROR(AWS_LS_IO_PEM, "Invalid PEM buffer: invalid end token"); + return aws_raise_error(AWS_ERROR_PEM_MALFORMED); + } + + *out = type_cur; + return AWS_OP_SUCCESS; +} + +static int s_convert_pem_to_raw_base64( + struct aws_allocator *allocator, + struct aws_byte_cursor pem, + struct aws_array_list *pem_objects) { + + struct aws_array_list split_buffers; + if (aws_array_list_init_dynamic(&split_buffers, allocator, 16, sizeof(struct aws_byte_cursor))) { + return AWS_OP_ERR; + } + + if (aws_byte_cursor_split_on_char(&pem, '\n', &split_buffers)) { + aws_array_list_clean_up(&split_buffers); + AWS_LOGF_ERROR(AWS_LS_IO_PEM, "Invalid PEM buffer: failed to split on newline"); + return aws_raise_error(AWS_ERROR_PEM_MALFORMED); + } + + enum aws_pem_parse_state state = BEGIN; + bool on_length_calc = true; + size_t current_obj_len = 0; + size_t current_obj_start_index = 0; + struct aws_byte_buf current_obj_buf; + AWS_ZERO_STRUCT(current_obj_buf); + struct aws_byte_cursor current_obj_type_cur; + AWS_ZERO_STRUCT(current_obj_type_cur); + enum aws_pem_object_type current_obj_type = AWS_PEM_TYPE_UNKNOWN; + + size_t split_count = aws_array_list_length(&split_buffers); + size_t i = 0; + + while (i < split_count) { + struct aws_byte_cursor *line_cur_ptr = NULL; + int error = aws_array_list_get_at_ptr(&split_buffers, (void **)&line_cur_ptr, i); + /* should never fail as we control array size and how we index into list */ + AWS_FATAL_ASSERT(error == AWS_OP_SUCCESS); + + /* Burn off the padding in the buffer first. + * Worst case we'll only have to do this once per line in the buffer. */ + *line_cur_ptr = aws_byte_cursor_left_trim_pred(line_cur_ptr, aws_isspace); + + /* handle CRLF on Windows by burning '\r' off the end of the buffer */ + if (line_cur_ptr->len > 0 && (line_cur_ptr->ptr[line_cur_ptr->len - 1] == '\r')) { + --line_cur_ptr->len; + } + + switch (state) { + case BEGIN: + if (aws_byte_cursor_starts_with(line_cur_ptr, &s_begin_header_cur)) { + if (s_extract_header_type_cur(*line_cur_ptr, ¤t_obj_type_cur)) { + goto on_end_of_loop; + } + current_obj_type = s_map_type_cur_to_type(current_obj_type_cur); + current_obj_start_index = i + 1; + state = ON_DATA; + } + ++i; + break; + /* this loops through the lines containing data twice. First to figure out the length, a second + * time to actually copy the data. */ + case ON_DATA: + /* Found end tag. */ + if (aws_byte_cursor_starts_with(line_cur_ptr, &s_end_header_cur)) { + if (on_length_calc) { + on_length_calc = false; + state = ON_DATA; + i = current_obj_start_index; + aws_byte_buf_init(¤t_obj_buf, allocator, current_obj_len); + + } else { + struct aws_pem_object pem_object = { + .data = current_obj_buf, + .type_string = aws_string_new_from_cursor(allocator, ¤t_obj_type_cur), + .type = current_obj_type, + }; + + if (aws_array_list_push_back(pem_objects, &pem_object)) { + goto on_end_of_loop; + } + state = BEGIN; + on_length_calc = true; + current_obj_len = 0; + ++i; + AWS_ZERO_STRUCT(current_obj_buf); + AWS_ZERO_STRUCT(current_obj_type_cur); + current_obj_type = AWS_PEM_TYPE_UNKNOWN; + } + /* actually on a line with data in it. */ + } else { + if (on_length_calc) { + current_obj_len += line_cur_ptr->len; + } else { + if (aws_byte_buf_append(¤t_obj_buf, line_cur_ptr)) { + goto on_end_of_loop; + } + } + ++i; + } + break; + default: + AWS_FATAL_ASSERT(false); + } + } + +/* + * Note: this function only hard error if nothing can be parsed out of file. + * Otherwise it succeeds and returns whatever was parsed successfully. + */ +on_end_of_loop: + aws_array_list_clean_up(&split_buffers); + aws_byte_buf_clean_up_secure(¤t_obj_buf); + + if (state == BEGIN && aws_array_list_length(pem_objects) > 0) { + return AWS_OP_SUCCESS; + } + + AWS_LOGF_ERROR(AWS_LS_IO_PEM, "Invalid PEM buffer."); + aws_pem_objects_clean_up(pem_objects); + return aws_raise_error(AWS_ERROR_PEM_MALFORMED); +} + +int aws_pem_objects_init_from_file_contents( + struct aws_array_list *pem_objects, + struct aws_allocator *allocator, + struct aws_byte_cursor pem_cursor) { + AWS_PRECONDITION(allocator); + AWS_PRECONDITION(pem_objects != NULL); + + /* Init empty array list, ideally, the PEM should only has one key included. */ + if (aws_array_list_init_dynamic(pem_objects, allocator, 1, sizeof(struct aws_pem_object))) { + return AWS_OP_ERR; + } + + if (s_convert_pem_to_raw_base64(allocator, pem_cursor, pem_objects)) { + goto on_error; + } + + for (size_t i = 0; i < aws_array_list_length(pem_objects); ++i) { + struct aws_pem_object *pem_obj_ptr = NULL; + aws_array_list_get_at_ptr(pem_objects, (void **)&pem_obj_ptr, i); + struct aws_byte_cursor byte_cur = aws_byte_cursor_from_buf(&pem_obj_ptr->data); + + size_t decoded_len = 0; + if (aws_base64_compute_decoded_len(&byte_cur, &decoded_len)) { + AWS_LOGF_ERROR(AWS_LS_IO_PEM, "Failed to get length for decoded base64 pem object."); + aws_raise_error(AWS_ERROR_PEM_MALFORMED); + goto on_error; + } + + struct aws_byte_buf decoded_buffer; + aws_byte_buf_init(&decoded_buffer, allocator, decoded_len); + + if (aws_base64_decode(&byte_cur, &decoded_buffer)) { + AWS_LOGF_ERROR(AWS_LS_IO_PEM, "Failed to base 64 decode pem object."); + aws_raise_error(AWS_ERROR_PEM_MALFORMED); + aws_byte_buf_clean_up_secure(&decoded_buffer); + goto on_error; + } + + aws_byte_buf_clean_up_secure(&pem_obj_ptr->data); + pem_obj_ptr->data = decoded_buffer; + } + + return AWS_OP_SUCCESS; + +on_error: + aws_pem_objects_clean_up(pem_objects); + return AWS_OP_ERR; +} + +int aws_pem_objects_init_from_file_path( + struct aws_array_list *pem_objects, + struct aws_allocator *allocator, + const char *filename) { + + struct aws_byte_buf raw_file_buffer; + if (aws_byte_buf_init_from_file(&raw_file_buffer, allocator, filename)) { + AWS_LOGF_ERROR(AWS_LS_IO_PEM, "Failed to read file %s.", filename); + return AWS_OP_ERR; + } + AWS_ASSERT(raw_file_buffer.buffer); + + struct aws_byte_cursor file_cursor = aws_byte_cursor_from_buf(&raw_file_buffer); + if (aws_pem_objects_init_from_file_contents(pem_objects, allocator, file_cursor)) { + aws_byte_buf_clean_up_secure(&raw_file_buffer); + AWS_LOGF_ERROR(AWS_LS_IO_PEM, "Failed to decode PEM file %s.", filename); + return AWS_OP_ERR; + } + + aws_byte_buf_clean_up_secure(&raw_file_buffer); + + return AWS_OP_SUCCESS; +} diff --git a/source/pem_utils.c b/source/pem_utils.c deleted file mode 100644 index c3843ffd4..000000000 --- a/source/pem_utils.c +++ /dev/null @@ -1,98 +0,0 @@ -/** - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0. - */ -#include -#include - -enum aws_pem_util_state { - BEGIN, - ON_DATA, - END, -}; - -static const struct aws_byte_cursor begin_header = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("-----BEGIN"); -static const struct aws_byte_cursor end_header = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("-----END"); -static const struct aws_byte_cursor dashes = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("-----"); - -int aws_sanitize_pem(struct aws_byte_buf *pem, struct aws_allocator *allocator) { - if (!pem->len) { - /* reject files with no PEM data */ - return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT); - } - struct aws_byte_buf clean_pem_buf; - if (aws_byte_buf_init(&clean_pem_buf, allocator, pem->len)) { - return AWS_OP_ERR; - } - struct aws_byte_cursor pem_cursor = aws_byte_cursor_from_buf(pem); - int state = BEGIN; - - for (size_t i = 0; i < pem_cursor.len; i++) { - /* parse through the pem once */ - char current = *(pem_cursor.ptr + i); - switch (state) { - case BEGIN: - if (current == '-') { - struct aws_byte_cursor compare_cursor = pem_cursor; - compare_cursor.len = begin_header.len; - compare_cursor.ptr += i; - if (aws_byte_cursor_eq(&compare_cursor, &begin_header)) { - state = ON_DATA; - i--; - } - } - break; - case ON_DATA: - /* start copying everything */ - if (current == '-') { - struct aws_byte_cursor compare_cursor = pem_cursor; - compare_cursor.len = end_header.len; - compare_cursor.ptr += i; - if (aws_byte_cursor_eq(&compare_cursor, &end_header)) { - /* Copy the end header string and start to search for the end part of a pem */ - state = END; - aws_byte_buf_append(&clean_pem_buf, &end_header); - i += (end_header.len - 1); - break; - } - } - aws_byte_buf_append_byte_dynamic(&clean_pem_buf, (uint8_t)current); - break; - case END: - if (current == '-') { - struct aws_byte_cursor compare_cursor = pem_cursor; - compare_cursor.len = dashes.len; - compare_cursor.ptr += i; - if (aws_byte_cursor_eq(&compare_cursor, &dashes)) { - /* End part of a pem, copy the last 5 dashes and a new line, then ignore everything before next - * begin header */ - state = BEGIN; - aws_byte_buf_append(&clean_pem_buf, &dashes); - i += (dashes.len - 1); - aws_byte_buf_append_byte_dynamic(&clean_pem_buf, (uint8_t)'\n'); - break; - } - } - aws_byte_buf_append_byte_dynamic(&clean_pem_buf, (uint8_t)current); - break; - default: - break; - } - } - - if (clean_pem_buf.len == 0) { - /* No valid data remains after sanitization. File might have been the wrong format */ - aws_raise_error(AWS_ERROR_INVALID_ARGUMENT); - goto error; - } - - struct aws_byte_cursor clean_pem_cursor = aws_byte_cursor_from_buf(&clean_pem_buf); - aws_byte_buf_reset(pem, true); - aws_byte_buf_append_dynamic(pem, &clean_pem_cursor); - aws_byte_buf_clean_up(&clean_pem_buf); - return AWS_OP_SUCCESS; - -error: - aws_byte_buf_clean_up(&clean_pem_buf); - return AWS_OP_ERR; -} diff --git a/source/pki_utils.c b/source/pki_utils.c deleted file mode 100644 index 7da9dc9af..000000000 --- a/source/pki_utils.c +++ /dev/null @@ -1,224 +0,0 @@ -/** - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0. - */ -#include - -#include - -#include -#include - -#include -#include -#include - -enum PEM_PARSE_STATE { - BEGIN, - ON_DATA, -}; - -void aws_cert_chain_clean_up(struct aws_array_list *cert_chain) { - for (size_t i = 0; i < aws_array_list_length(cert_chain); ++i) { - struct aws_byte_buf *decoded_buffer_ptr = NULL; - aws_array_list_get_at_ptr(cert_chain, (void **)&decoded_buffer_ptr, i); - - if (decoded_buffer_ptr) { - aws_secure_zero(decoded_buffer_ptr->buffer, decoded_buffer_ptr->len); - aws_byte_buf_clean_up(decoded_buffer_ptr); - } - } - - /* remember, we don't own it so we don't free it, just undo whatever mutations we've done at this point. */ - aws_array_list_clear(cert_chain); -} - -static int s_convert_pem_to_raw_base64( - struct aws_allocator *allocator, - const struct aws_byte_cursor *pem, - struct aws_array_list *cert_chain_or_key) { - enum PEM_PARSE_STATE state = BEGIN; - - struct aws_byte_buf current_cert; - const char *begin_header = "-----BEGIN"; - const char *end_header = "-----END"; - size_t begin_header_len = strlen(begin_header); - size_t end_header_len = strlen(end_header); - bool on_length_calc = true; - - struct aws_array_list split_buffers; - if (aws_array_list_init_dynamic(&split_buffers, allocator, 16, sizeof(struct aws_byte_cursor))) { - return AWS_OP_ERR; - } - - if (aws_byte_cursor_split_on_char(pem, '\n', &split_buffers)) { - aws_array_list_clean_up(&split_buffers); - AWS_LOGF_ERROR(AWS_LS_IO_PKI, "static: Invalid PEM buffer: failed to split on newline"); - return AWS_OP_ERR; - } - - size_t split_count = aws_array_list_length(&split_buffers); - size_t i = 0; - size_t index_of_current_cert_start = 0; - size_t current_cert_len = 0; - - while (i < split_count) { - struct aws_byte_cursor *current_cur_ptr = NULL; - aws_array_list_get_at_ptr(&split_buffers, (void **)¤t_cur_ptr, i); - - /* burn off the padding in the buffer first. - * Worst case we'll only have to do this once per line in the buffer. */ - while (current_cur_ptr->len && aws_isspace(*current_cur_ptr->ptr)) { - aws_byte_cursor_advance(current_cur_ptr, 1); - } - - /* handle CRLF on Windows by burning '\r' off the end of the buffer */ - if (current_cur_ptr->len && (current_cur_ptr->ptr[current_cur_ptr->len - 1] == '\r')) { - current_cur_ptr->len--; - } - - switch (state) { - case BEGIN: - if (current_cur_ptr->len > begin_header_len && - !strncmp((const char *)current_cur_ptr->ptr, begin_header, begin_header_len)) { - state = ON_DATA; - index_of_current_cert_start = i + 1; - } - ++i; - break; - /* this loops through the lines containing data twice. First to figure out the length, a second - * time to actually copy the data. */ - case ON_DATA: - /* Found end tag. */ - if (current_cur_ptr->len > end_header_len && - !strncmp((const char *)current_cur_ptr->ptr, end_header, end_header_len)) { - if (on_length_calc) { - on_length_calc = false; - state = ON_DATA; - i = index_of_current_cert_start; - - if (aws_byte_buf_init(¤t_cert, allocator, current_cert_len)) { - goto end_of_loop; - } - - } else { - if (aws_array_list_push_back(cert_chain_or_key, ¤t_cert)) { - aws_secure_zero(¤t_cert.buffer, current_cert.len); - aws_byte_buf_clean_up(¤t_cert); - goto end_of_loop; - } - state = BEGIN; - on_length_calc = true; - current_cert_len = 0; - ++i; - } - /* actually on a line with data in it. */ - } else { - if (!on_length_calc) { - aws_byte_buf_write(¤t_cert, current_cur_ptr->ptr, current_cur_ptr->len); - } else { - current_cert_len += current_cur_ptr->len; - } - ++i; - } - break; - } - } - -end_of_loop: - aws_array_list_clean_up(&split_buffers); - - if (state == BEGIN && aws_array_list_length(cert_chain_or_key) > 0) { - return AWS_OP_SUCCESS; - } - - AWS_LOGF_ERROR(AWS_LS_IO_PKI, "static: Invalid PEM buffer."); - aws_cert_chain_clean_up(cert_chain_or_key); - return aws_raise_error(AWS_IO_FILE_VALIDATION_FAILURE); -} - -int aws_decode_pem_to_buffer_list( - struct aws_allocator *alloc, - const struct aws_byte_cursor *pem_cursor, - struct aws_array_list *cert_chain_or_key) { - AWS_ASSERT(aws_array_list_length(cert_chain_or_key) == 0); - struct aws_array_list base_64_buffer_list; - - if (aws_array_list_init_dynamic(&base_64_buffer_list, alloc, 2, sizeof(struct aws_byte_buf))) { - return AWS_OP_ERR; - } - - int err_code = AWS_OP_ERR; - - if (s_convert_pem_to_raw_base64(alloc, pem_cursor, &base_64_buffer_list)) { - goto cleanup_base64_buffer_list; - } - - for (size_t i = 0; i < aws_array_list_length(&base_64_buffer_list); ++i) { - size_t decoded_len = 0; - struct aws_byte_buf *byte_buf_ptr = NULL; - aws_array_list_get_at_ptr(&base_64_buffer_list, (void **)&byte_buf_ptr, i); - struct aws_byte_cursor byte_cur = aws_byte_cursor_from_buf(byte_buf_ptr); - - if (aws_base64_compute_decoded_len(&byte_cur, &decoded_len)) { - aws_raise_error(AWS_IO_FILE_VALIDATION_FAILURE); - goto cleanup_all; - } - - struct aws_byte_buf decoded_buffer; - if (aws_byte_buf_init(&decoded_buffer, alloc, decoded_len)) { - goto cleanup_all; - } - - if (aws_base64_decode(&byte_cur, &decoded_buffer)) { - aws_raise_error(AWS_IO_FILE_VALIDATION_FAILURE); - aws_byte_buf_clean_up_secure(&decoded_buffer); - goto cleanup_all; - } - - if (aws_array_list_push_back(cert_chain_or_key, &decoded_buffer)) { - aws_byte_buf_clean_up_secure(&decoded_buffer); - goto cleanup_all; - } - } - - err_code = AWS_OP_SUCCESS; - -cleanup_all: - if (err_code != AWS_OP_SUCCESS) { - AWS_LOGF_ERROR(AWS_LS_IO_PKI, "static: Invalid PEM buffer."); - aws_cert_chain_clean_up(cert_chain_or_key); - } - -cleanup_base64_buffer_list: - aws_cert_chain_clean_up(&base_64_buffer_list); - aws_array_list_clean_up(&base_64_buffer_list); - - return err_code; -} - -int aws_read_and_decode_pem_file_to_buffer_list( - struct aws_allocator *alloc, - const char *filename, - struct aws_array_list *cert_chain_or_key) { - - struct aws_byte_buf raw_file_buffer; - if (aws_byte_buf_init_from_file(&raw_file_buffer, alloc, filename)) { - AWS_LOGF_ERROR(AWS_LS_IO_PKI, "static: Failed to read file %s.", filename); - return AWS_OP_ERR; - } - AWS_ASSERT(raw_file_buffer.buffer); - - struct aws_byte_cursor file_cursor = aws_byte_cursor_from_buf(&raw_file_buffer); - if (aws_decode_pem_to_buffer_list(alloc, &file_cursor, cert_chain_or_key)) { - aws_secure_zero(raw_file_buffer.buffer, raw_file_buffer.len); - aws_byte_buf_clean_up(&raw_file_buffer); - AWS_LOGF_ERROR(AWS_LS_IO_PKI, "static: Failed to decode PEM file %s.", filename); - return AWS_OP_ERR; - } - - aws_secure_zero(raw_file_buffer.buffer, raw_file_buffer.len); - aws_byte_buf_clean_up(&raw_file_buffer); - - return AWS_OP_SUCCESS; -} diff --git a/source/windows/windows_pki_utils.c b/source/windows/windows_pki_utils.c index 921b1cc5a..e1c47d548 100644 --- a/source/windows/windows_pki_utils.c +++ b/source/windows/windows_pki_utils.c @@ -3,6 +3,7 @@ * SPDX-License-Identifier: Apache-2.0. */ +#include #include #include @@ -183,11 +184,7 @@ int aws_import_trusted_certificates( *cert_store = NULL; int result = AWS_OP_ERR; - if (aws_array_list_init_dynamic(&certificates, alloc, 2, sizeof(struct aws_byte_buf))) { - return AWS_OP_ERR; - } - - if (aws_decode_pem_to_buffer_list(alloc, certificates_blob, &certificates)) { + if (aws_pem_objects_init_from_file_contents(&certificates, alloc, *certificates_blob)) { goto clean_up; } @@ -210,14 +207,14 @@ int aws_import_trusted_certificates( AWS_LOGF_INFO(AWS_LS_IO_PKI, "static: loading %d certificates in cert chain for use as a CA", (int)cert_count); for (size_t i = 0; i < cert_count; ++i) { - struct aws_byte_buf *byte_buf_ptr = NULL; - aws_array_list_get_at_ptr(&certificates, (void **)&byte_buf_ptr, i); + struct aws_pem_object *pem_object_ptr = NULL; + aws_array_list_get_at_ptr(&certificates, (void **)&pem_object_ptr, i); CERT_BLOB cert_blob; CERT_CONTEXT *cert_context = NULL; - cert_blob.pbData = byte_buf_ptr->buffer; - cert_blob.cbData = (DWORD)byte_buf_ptr->len; + cert_blob.pbData = pem_object_ptr->data.buffer; + cert_blob.cbData = (DWORD)pem_object_ptr->data.len; DWORD content_type = 0; BOOL query_res = CryptQueryObject( @@ -258,8 +255,7 @@ int aws_import_trusted_certificates( clean_up: - aws_cert_chain_clean_up(&certificates); - aws_array_list_clean_up(&certificates); + aws_pem_objects_clean_up(&certificates); if (result == AWS_OP_ERR && *cert_store) { aws_close_cert_store(*cert_store); @@ -564,21 +560,13 @@ int aws_import_key_pair_to_cert_context( int result = AWS_OP_ERR; BYTE *key = NULL; - if (aws_array_list_init_dynamic(&certificates, alloc, 2, sizeof(struct aws_byte_buf))) { - return AWS_OP_ERR; - } - - if (aws_decode_pem_to_buffer_list(alloc, public_cert_chain, &certificates)) { + if (aws_pem_objects_init_from_file_contents(&certificates, alloc, *public_cert_chain)) { AWS_LOGF_ERROR( AWS_LS_IO_PKI, "static: failed to decode cert pem to buffer list with error %d", (int)aws_last_error()); goto clean_up; } - if (aws_array_list_init_dynamic(&private_keys, alloc, 1, sizeof(struct aws_byte_buf))) { - goto clean_up; - } - - if (aws_decode_pem_to_buffer_list(alloc, private_key, &private_keys)) { + if (aws_pem_objects_init_from_file_contents(&private_keys, alloc, *private_key)) { AWS_LOGF_ERROR( AWS_LS_IO_PKI, "static: failed to decode key pem to buffer list with error %d", (int)aws_last_error()); goto clean_up; @@ -598,13 +586,13 @@ int aws_import_key_pair_to_cert_context( } for (size_t i = 0; i < cert_count; ++i) { - struct aws_byte_buf *byte_buf_ptr = NULL; - aws_array_list_get_at_ptr(&certificates, (void **)&byte_buf_ptr, i); + struct aws_pem_object *pem_object_ptr = NULL; + aws_array_list_get_at_ptr(&certificates, (void **)&pem_object_ptr, i); CERT_BLOB cert_blob; - cert_blob.pbData = byte_buf_ptr->buffer; - cert_blob.cbData = (DWORD)byte_buf_ptr->len; + cert_blob.pbData = pem_object_ptr->data.buffer; + cert_blob.cbData = (DWORD)pem_object_ptr->data.len; DWORD content_type = 0; PCERT_CONTEXT cert_context = NULL; @@ -650,7 +638,7 @@ int aws_import_key_pair_to_cert_context( goto clean_up; } - struct aws_byte_buf *private_key_ptr = NULL; + struct aws_pem_object *private_key_ptr = NULL; DWORD decoded_len = 0; enum aws_certificate_type cert_type = AWS_CT_X509_UNKNOWN; size_t private_key_count = aws_array_list_length(&private_keys); @@ -660,8 +648,8 @@ int aws_import_key_pair_to_cert_context( if (CryptDecodeObjectEx( X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, PKCS_RSA_PRIVATE_KEY, - private_key_ptr->buffer, - (DWORD)private_key_ptr->len, + private_key_ptr->data.buffer, + (DWORD)private_key_ptr->data.len, CRYPT_DECODE_ALLOC_FLAG, 0, &key, @@ -672,8 +660,8 @@ int aws_import_key_pair_to_cert_context( else if (CryptDecodeObjectEx( X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, X509_ECC_PRIVATE_KEY, - private_key_ptr->buffer, - (DWORD)private_key_ptr->len, + private_key_ptr->data.buffer, + (DWORD)private_key_ptr->data.len, CRYPT_DECODE_ALLOC_FLAG, NULL, &key, @@ -729,10 +717,8 @@ int aws_import_key_pair_to_cert_context( } clean_up: - aws_cert_chain_clean_up(&certificates); - aws_array_list_clean_up(&certificates); - aws_cert_chain_clean_up(&private_keys); - aws_array_list_clean_up(&private_keys); + aws_pem_objects_clean_up(&certificates); + aws_pem_objects_clean_up(&private_keys); LocalFree(key); diff --git a/tests/pki_utils_test.c b/tests/pem_test.c similarity index 83% rename from tests/pki_utils_test.c rename to tests/pem_test.c index 584e4b0dc..767ef04a0 100644 --- a/tests/pki_utils_test.c +++ b/tests/pem_test.c @@ -2,10 +2,316 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ +#include +#include +#include #include -#include +static int s_check_clean_pem_result( + struct aws_byte_cursor dirty_pem, + struct aws_byte_cursor expected_clean_pem, + struct aws_allocator *allocator) { + struct aws_byte_buf pem_buf; + ASSERT_SUCCESS(aws_byte_buf_init_copy_from_cursor(&pem_buf, allocator, dirty_pem)); + ASSERT_SUCCESS(aws_sanitize_pem(&pem_buf, allocator)); + ASSERT_TRUE(aws_byte_cursor_eq_byte_buf(&expected_clean_pem, &pem_buf)); + aws_byte_buf_clean_up(&pem_buf); + return AWS_OP_SUCCESS; +} + +static int s_test_pem_sanitize_comments_around_pem_object_removed(struct aws_allocator *allocator, void *ctx) { + (void)ctx; + /* comments around pem object will be removed */ + struct aws_byte_cursor dirty_pem = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("# comments\r\n" + "-----BEGIN CERTIFICATE-----\n" + "CERTIFICATES\n" + "-----END CERTIFICATE-----\n" + "# another comments\r\n" + "-----BEGIN CERTIFICATE-----\n" + "CERTIFICATES\n" + "-----END CERTIFICATE-----\n" + "# final comments\r\n"); + + struct aws_byte_cursor expected_clean_pem = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("-----BEGIN CERTIFICATE-----\n" + "CERTIFICATES\n" + "-----END CERTIFICATE-----\n" + "-----BEGIN CERTIFICATE-----\n" + "CERTIFICATES\n" + "-----END CERTIFICATE-----\n"); + + return s_check_clean_pem_result(dirty_pem, expected_clean_pem, allocator); +} + +AWS_TEST_CASE(pem_sanitize_comments_around_pem_object_removed, s_test_pem_sanitize_comments_around_pem_object_removed); + +static int s_test_pem_sanitize_empty_file_rejected(struct aws_allocator *allocator, void *ctx) { + (void)ctx; + /* We don't allow empty files. */ + struct aws_byte_buf pem; + ASSERT_SUCCESS(aws_byte_buf_init(&pem, allocator, 512)); + + ASSERT_ERROR(AWS_ERROR_INVALID_ARGUMENT, aws_sanitize_pem(&pem, allocator)); + + aws_byte_buf_clean_up(&pem); + return AWS_OP_SUCCESS; +} + +AWS_TEST_CASE(pem_sanitize_empty_file_rejected, s_test_pem_sanitize_empty_file_rejected) + +AWS_TEST_CASE(pem_sanitize_wrong_format_rejected, s_test_pem_sanitize_wrong_format_rejected) +static int s_test_pem_sanitize_wrong_format_rejected(struct aws_allocator *allocator, void *ctx) { + (void)ctx; + /* A file with the wrong format will "sanitize" to an empty PEM file, which we do not accept */ + + /* This is not a PEM file, it's a DER encoded binary x.509 certificate */ + const uint8_t not_a_pem_src[] = { + 0x30, 0x82, 0x04, 0xD3, 0x30, 0x82, 0x03, 0xBB, 0xA0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x18, 0xDA, 0xD1, + 0x9E, 0x26, 0x7D, 0xE8, 0xBB, 0x4A, 0x21, 0x58, 0xCD, 0xCC, 0x6B, 0x3B, 0x4A, 0x30, 0x0D, 0x06, 0x09, 0x2A, + 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x81, 0xCA, 0x31, 0x0B, 0x30, 0x09, 0x06, + 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, + 0x0E, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6E, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x1F, 0x30, + 0x1D, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x16, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x54, + 0x72, 0x75, 0x73, 0x74, 0x20, 0x4E, 0x65, 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x31, 0x3A, 0x30, 0x38, 0x06, 0x03, + 0x55, 0x04, 0x0B, 0x13, 0x31, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x36, 0x20, 0x56, 0x65, 0x72, 0x69, + 0x53, 0x69, 0x67, 0x6E, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x20, 0x2D, 0x20, 0x46, 0x6F, 0x72, 0x20, 0x61, + 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x7A, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65, 0x20, 0x6F, 0x6E, 0x6C, 0x79, + 0x31, 0x45, 0x30, 0x43, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x3C, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, + 0x6E, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x50, 0x75, 0x62, 0x6C, 0x69, 0x63, 0x20, 0x50, + 0x72, 0x69, 0x6D, 0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2D, 0x20, 0x47, 0x35, 0x30, + 0x1E, 0x17, 0x0D, 0x30, 0x36, 0x31, 0x31, 0x30, 0x38, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5A, 0x17, 0x0D, + 0x33, 0x36, 0x30, 0x37, 0x31, 0x36, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5A, 0x30, 0x81, 0xCA, 0x31, 0x0B, + 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, + 0x04, 0x0A, 0x13, 0x0E, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6E, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, + 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x16, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, + 0x6E, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x4E, 0x65, 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x31, 0x3A, 0x30, + 0x38, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x31, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x36, 0x20, 0x56, + 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6E, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x20, 0x2D, 0x20, 0x46, 0x6F, + 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x7A, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65, 0x20, 0x6F, + 0x6E, 0x6C, 0x79, 0x31, 0x45, 0x30, 0x43, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x3C, 0x56, 0x65, 0x72, 0x69, + 0x53, 0x69, 0x67, 0x6E, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x50, 0x75, 0x62, 0x6C, 0x69, + 0x63, 0x20, 0x50, 0x72, 0x69, 0x6D, 0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2D, 0x20, + 0x47, 0x35, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, + 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0F, 0x00, 0x30, 0x82, 0x01, 0x0A, 0x02, 0x82, 0x01, 0x01, 0x00, 0xAF, + 0x24, 0x08, 0x08, 0x29, 0x7A, 0x35, 0x9E, 0x60, 0x0C, 0xAA, 0xE7, 0x4B, 0x3B, 0x4E, 0xDC, 0x7C, 0xBC, 0x3C, + 0x45, 0x1C, 0xBB, 0x2B, 0xE0, 0xFE, 0x29, 0x02, 0xF9, 0x57, 0x08, 0xA3, 0x64, 0x85, 0x15, 0x27, 0xF5, 0xF1, + 0xAD, 0xC8, 0x31, 0x89, 0x5D, 0x22, 0xE8, 0x2A, 0xAA, 0xA6, 0x42, 0xB3, 0x8F, 0xF8, 0xB9, 0x55, 0xB7, 0xB1, + 0xB7, 0x4B, 0xB3, 0xFE, 0x8F, 0x7E, 0x07, 0x57, 0xEC, 0xEF, 0x43, 0xDB, 0x66, 0x62, 0x15, 0x61, 0xCF, 0x60, + 0x0D, 0xA4, 0xD8, 0xDE, 0xF8, 0xE0, 0xC3, 0x62, 0x08, 0x3D, 0x54, 0x13, 0xEB, 0x49, 0xCA, 0x59, 0x54, 0x85, + 0x26, 0xE5, 0x2B, 0x8F, 0x1B, 0x9F, 0xEB, 0xF5, 0xA1, 0x91, 0xC2, 0x33, 0x49, 0xD8, 0x43, 0x63, 0x6A, 0x52, + 0x4B, 0xD2, 0x8F, 0xE8, 0x70, 0x51, 0x4D, 0xD1, 0x89, 0x69, 0x7B, 0xC7, 0x70, 0xF6, 0xB3, 0xDC, 0x12, 0x74, + 0xDB, 0x7B, 0x5D, 0x4B, 0x56, 0xD3, 0x96, 0xBF, 0x15, 0x77, 0xA1, 0xB0, 0xF4, 0xA2, 0x25, 0xF2, 0xAF, 0x1C, + 0x92, 0x67, 0x18, 0xE5, 0xF4, 0x06, 0x04, 0xEF, 0x90, 0xB9, 0xE4, 0x00, 0xE4, 0xDD, 0x3A, 0xB5, 0x19, 0xFF, + 0x02, 0xBA, 0xF4, 0x3C, 0xEE, 0xE0, 0x8B, 0xEB, 0x37, 0x8B, 0xEC, 0xF4, 0xD7, 0xAC, 0xF2, 0xF6, 0xF0, 0x3D, + 0xAF, 0xDD, 0x75, 0x91, 0x33, 0x19, 0x1D, 0x1C, 0x40, 0xCB, 0x74, 0x24, 0x19, 0x21, 0x93, 0xD9, 0x14, 0xFE, + 0xAC, 0x2A, 0x52, 0xC7, 0x8F, 0xD5, 0x04, 0x49, 0xE4, 0x8D, 0x63, 0x47, 0x88, 0x3C, 0x69, 0x83, 0xCB, 0xFE, + 0x47, 0xBD, 0x2B, 0x7E, 0x4F, 0xC5, 0x95, 0xAE, 0x0E, 0x9D, 0xD4, 0xD1, 0x43, 0xC0, 0x67, 0x73, 0xE3, 0x14, + 0x08, 0x7E, 0xE5, 0x3F, 0x9F, 0x73, 0xB8, 0x33, 0x0A, 0xCF, 0x5D, 0x3F, 0x34, 0x87, 0x96, 0x8A, 0xEE, 0x53, + 0xE8, 0x25, 0x15, 0x02, 0x03, 0x01, 0x00, 0x01, 0xA3, 0x81, 0xB2, 0x30, 0x81, 0xAF, 0x30, 0x0F, 0x06, 0x03, + 0x55, 0x1D, 0x13, 0x01, 0x01, 0xFF, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xFF, 0x30, 0x0E, 0x06, 0x03, 0x55, + 0x1D, 0x0F, 0x01, 0x01, 0xFF, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x6D, 0x06, 0x08, 0x2B, 0x06, 0x01, + 0x05, 0x05, 0x07, 0x01, 0x0C, 0x04, 0x61, 0x30, 0x5F, 0xA1, 0x5D, 0xA0, 0x5B, 0x30, 0x59, 0x30, 0x57, 0x30, + 0x55, 0x16, 0x09, 0x69, 0x6D, 0x61, 0x67, 0x65, 0x2F, 0x67, 0x69, 0x66, 0x30, 0x21, 0x30, 0x1F, 0x30, 0x07, + 0x06, 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1A, 0x04, 0x14, 0x8F, 0xE5, 0xD3, 0x1A, 0x86, 0xAC, 0x8D, 0x8E, 0x6B, + 0xC3, 0xCF, 0x80, 0x6A, 0xD4, 0x48, 0x18, 0x2C, 0x7B, 0x19, 0x2E, 0x30, 0x25, 0x16, 0x23, 0x68, 0x74, 0x74, + 0x70, 0x3A, 0x2F, 0x2F, 0x6C, 0x6F, 0x67, 0x6F, 0x2E, 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6E, 0x2E, + 0x63, 0x6F, 0x6D, 0x2F, 0x76, 0x73, 0x6C, 0x6F, 0x67, 0x6F, 0x2E, 0x67, 0x69, 0x66, 0x30, 0x1D, 0x06, 0x03, + 0x55, 0x1D, 0x0E, 0x04, 0x16, 0x04, 0x14, 0x7F, 0xD3, 0x65, 0xA7, 0xC2, 0xDD, 0xEC, 0xBB, 0xF0, 0x30, 0x09, + 0xF3, 0x43, 0x39, 0xFA, 0x02, 0xAF, 0x33, 0x31, 0x33, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, + 0x0D, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x93, 0x24, 0x4A, 0x30, 0x5F, 0x62, 0xCF, + 0xD8, 0x1A, 0x98, 0x2F, 0x3D, 0xEA, 0xDC, 0x99, 0x2D, 0xBD, 0x77, 0xF6, 0xA5, 0x79, 0x22, 0x38, 0xEC, 0xC4, + 0xA7, 0xA0, 0x78, 0x12, 0xAD, 0x62, 0x0E, 0x45, 0x70, 0x64, 0xC5, 0xE7, 0x97, 0x66, 0x2D, 0x98, 0x09, 0x7E, + 0x5F, 0xAF, 0xD6, 0xCC, 0x28, 0x65, 0xF2, 0x01, 0xAA, 0x08, 0x1A, 0x47, 0xDE, 0xF9, 0xF9, 0x7C, 0x92, 0x5A, + 0x08, 0x69, 0x20, 0x0D, 0xD9, 0x3E, 0x6D, 0x6E, 0x3C, 0x0D, 0x6E, 0xD8, 0xE6, 0x06, 0x91, 0x40, 0x18, 0xB9, + 0xF8, 0xC1, 0xED, 0xDF, 0xDB, 0x41, 0xAA, 0xE0, 0x96, 0x20, 0xC9, 0xCD, 0x64, 0x15, 0x38, 0x81, 0xC9, 0x94, + 0xEE, 0xA2, 0x84, 0x29, 0x0B, 0x13, 0x6F, 0x8E, 0xDB, 0x0C, 0xDD, 0x25, 0x02, 0xDB, 0xA4, 0x8B, 0x19, 0x44, + 0xD2, 0x41, 0x7A, 0x05, 0x69, 0x4A, 0x58, 0x4F, 0x60, 0xCA, 0x7E, 0x82, 0x6A, 0x0B, 0x02, 0xAA, 0x25, 0x17, + 0x39, 0xB5, 0xDB, 0x7F, 0xE7, 0x84, 0x65, 0x2A, 0x95, 0x8A, 0xBD, 0x86, 0xDE, 0x5E, 0x81, 0x16, 0x83, 0x2D, + 0x10, 0xCC, 0xDE, 0xFD, 0xA8, 0x82, 0x2A, 0x6D, 0x28, 0x1F, 0x0D, 0x0B, 0xC4, 0xE5, 0xE7, 0x1A, 0x26, 0x19, + 0xE1, 0xF4, 0x11, 0x6F, 0x10, 0xB5, 0x95, 0xFC, 0xE7, 0x42, 0x05, 0x32, 0xDB, 0xCE, 0x9D, 0x51, 0x5E, 0x28, + 0xB6, 0x9E, 0x85, 0xD3, 0x5B, 0xEF, 0xA5, 0x7D, 0x45, 0x40, 0x72, 0x8E, 0xB7, 0x0E, 0x6B, 0x0E, 0x06, 0xFB, + 0x33, 0x35, 0x48, 0x71, 0xB8, 0x9D, 0x27, 0x8B, 0xC4, 0x65, 0x5F, 0x0D, 0x86, 0x76, 0x9C, 0x44, 0x7A, 0xF6, + 0x95, 0x5C, 0xF6, 0x5D, 0x32, 0x08, 0x33, 0xA4, 0x54, 0xB6, 0x18, 0x3F, 0x68, 0x5C, 0xF2, 0x42, 0x4A, 0x85, + 0x38, 0x54, 0x83, 0x5F, 0xD1, 0xE8, 0x2C, 0xF2, 0xAC, 0x11, 0xD6, 0xA8, 0xED, 0x63, 0x6A}; + struct aws_byte_cursor not_a_pem_cursor = aws_byte_cursor_from_array(not_a_pem_src, sizeof(not_a_pem_src)); + struct aws_byte_buf not_a_pem; + ASSERT_SUCCESS(aws_byte_buf_init_copy_from_cursor(¬_a_pem, allocator, not_a_pem_cursor)); + + ASSERT_ERROR(AWS_ERROR_INVALID_ARGUMENT, aws_sanitize_pem(¬_a_pem, allocator)); + + aws_byte_buf_clean_up(¬_a_pem); + return AWS_OP_SUCCESS; +} + +static int s_test_pem_cert_parse_from_file(struct aws_allocator *allocator, void *ctx) { + (void)ctx; + + static const uint8_t s_expected[] = { + 0x30, 0x82, 0x03, 0xec, 0x30, 0x82, 0x02, 0xd4, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x09, 0x00, 0x84, 0x7d, + 0x2e, 0xed, 0x4d, 0xfc, 0x26, 0x87, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, + 0x0b, 0x05, 0x00, 0x30, 0x81, 0x9a, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, + 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, + 0x67, 0x74, 0x6f, 0x6e, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x07, 0x53, 0x65, 0x61, + 0x74, 0x74, 0x6c, 0x65, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x06, 0x41, 0x6d, 0x61, + 0x7a, 0x6f, 0x6e, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x04, 0x53, 0x44, 0x4b, 0x73, + 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, + 0x73, 0x74, 0x31, 0x30, 0x30, 0x2e, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, + 0x21, 0x61, 0x77, 0x73, 0x2d, 0x73, 0x64, 0x6b, 0x2d, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2d, 0x72, 0x75, + 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x40, 0x61, 0x6d, 0x61, 0x7a, 0x6f, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1e, + 0x17, 0x0d, 0x32, 0x31, 0x30, 0x36, 0x31, 0x36, 0x30, 0x36, 0x31, 0x37, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, + 0x33, 0x30, 0x39, 0x31, 0x38, 0x30, 0x36, 0x31, 0x37, 0x30, 0x30, 0x5a, 0x30, 0x81, 0x9a, 0x31, 0x0b, 0x30, + 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x0c, 0x0a, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x74, 0x6f, 0x6e, 0x31, 0x10, 0x30, 0x0e, 0x06, + 0x03, 0x55, 0x04, 0x07, 0x0c, 0x07, 0x53, 0x65, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x31, 0x0f, 0x30, 0x0d, 0x06, + 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x06, 0x41, 0x6d, 0x61, 0x7a, 0x6f, 0x6e, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, + 0x55, 0x04, 0x0b, 0x0c, 0x04, 0x53, 0x44, 0x4b, 0x73, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x0c, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x31, 0x30, 0x30, 0x2e, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x21, 0x61, 0x77, 0x73, 0x2d, 0x73, 0x64, 0x6b, 0x2d, + 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2d, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x40, 0x61, 0x6d, 0x61, + 0x7a, 0x6f, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, + 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, + 0x82, 0x01, 0x01, 0x00, 0xd7, 0x6a, 0x57, 0x48, 0xf8, 0x0e, 0x44, 0x03, 0x25, 0x42, 0xd6, 0x11, 0x6f, 0x1b, + 0xb3, 0xfc, 0xe7, 0x1a, 0xa2, 0xb6, 0xa7, 0xdc, 0x2d, 0x85, 0x8f, 0x28, 0xe1, 0xbb, 0x4b, 0xee, 0x71, 0x21, + 0x19, 0x4b, 0x0c, 0x43, 0x26, 0x9e, 0xf9, 0x4c, 0x14, 0x04, 0x31, 0xa7, 0xd2, 0xa5, 0x21, 0x0a, 0x01, 0x02, + 0xde, 0x0e, 0xde, 0xf1, 0xb8, 0x34, 0x43, 0x62, 0x7e, 0x76, 0x57, 0x85, 0x04, 0xe9, 0xc1, 0x7e, 0xc5, 0x35, + 0xa1, 0xb7, 0x3b, 0x1f, 0xee, 0x68, 0x4d, 0xfe, 0x51, 0xda, 0x0c, 0xf7, 0x2f, 0x47, 0x60, 0x12, 0x3c, 0x01, + 0x24, 0xce, 0x48, 0xa5, 0xf0, 0xa0, 0x8b, 0x63, 0x87, 0xba, 0xb5, 0x3c, 0x52, 0xc1, 0x0f, 0x7b, 0xb2, 0x99, + 0x4d, 0xb8, 0x46, 0x74, 0xf7, 0xd1, 0xe8, 0x25, 0x84, 0xd3, 0x2c, 0x56, 0x91, 0x78, 0x87, 0xdd, 0xd4, 0x3d, + 0xf3, 0x67, 0x51, 0x18, 0x71, 0x2c, 0x3c, 0xc3, 0xe1, 0x99, 0xd9, 0x2c, 0x44, 0x51, 0xf6, 0x14, 0x48, 0xbd, + 0x82, 0x16, 0x62, 0x18, 0x4a, 0x44, 0x23, 0x9e, 0x5b, 0x09, 0x08, 0x8a, 0x42, 0xa0, 0x68, 0x03, 0x88, 0x10, + 0x0f, 0x6c, 0x85, 0x09, 0x3b, 0x72, 0x96, 0x04, 0x35, 0xf4, 0x26, 0x01, 0x83, 0x6f, 0x1d, 0xd6, 0x7f, 0x78, + 0xd7, 0x1b, 0xf6, 0x3a, 0x4f, 0xad, 0xcb, 0x3e, 0xc3, 0xbe, 0x01, 0x2d, 0xb4, 0x44, 0x2b, 0xdc, 0x10, 0x5d, + 0x05, 0xfe, 0xb9, 0x43, 0x20, 0xdc, 0xc8, 0xe4, 0x40, 0x07, 0x3b, 0x54, 0xce, 0x11, 0xdf, 0x5f, 0x28, 0xeb, + 0xbe, 0x24, 0x02, 0xb4, 0xe8, 0xfc, 0x35, 0x9b, 0xbe, 0xc1, 0x80, 0xea, 0xc4, 0xec, 0x5b, 0x6f, 0x20, 0x6e, + 0xe4, 0x60, 0xd5, 0x6e, 0x38, 0x43, 0xde, 0x22, 0x73, 0x87, 0x90, 0xeb, 0xaa, 0xaf, 0x20, 0xe2, 0xb0, 0x1d, + 0x4f, 0xc2, 0x2c, 0x8f, 0x34, 0x86, 0xea, 0x75, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x33, 0x30, 0x31, 0x30, + 0x13, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x0c, 0x30, 0x0a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, + 0x03, 0x01, 0x30, 0x1a, 0x06, 0x03, 0x55, 0x1d, 0x11, 0x04, 0x13, 0x30, 0x11, 0x82, 0x09, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x87, 0x04, 0x7f, 0x00, 0x00, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x07, 0xb4, 0x9a, 0x48, + 0x4e, 0x6d, 0x71, 0x32, 0xf4, 0x35, 0x89, 0xf5, 0xe1, 0xe8, 0x27, 0x5e, 0xe3, 0x51, 0x0d, 0x54, 0xf2, 0xde, + 0x1e, 0x2f, 0x9a, 0x0d, 0xdd, 0x02, 0xd4, 0xce, 0x15, 0x93, 0x8b, 0xe6, 0x75, 0x77, 0xc2, 0x41, 0xf6, 0xbf, + 0xfc, 0xac, 0x25, 0x96, 0xea, 0x80, 0x38, 0x68, 0xe2, 0xa5, 0x72, 0x9a, 0x31, 0xa2, 0x95, 0x43, 0xa9, 0x90, + 0x39, 0x64, 0xe3, 0x6c, 0x29, 0x37, 0x0c, 0x7a, 0xb7, 0x18, 0x97, 0x47, 0x0e, 0x16, 0x79, 0x2f, 0x9a, 0x92, + 0x7b, 0x51, 0xac, 0xe4, 0x4c, 0x70, 0xc2, 0xe4, 0xf3, 0x7f, 0x2b, 0x63, 0x53, 0x2c, 0x3b, 0xdb, 0xf1, 0xef, + 0x84, 0xda, 0xf3, 0x71, 0x6c, 0x6e, 0xb8, 0x41, 0x48, 0xae, 0xb5, 0x12, 0x1b, 0x20, 0xec, 0xdf, 0xff, 0x9f, + 0x2b, 0x2d, 0x66, 0x52, 0x0a, 0x72, 0x17, 0x99, 0xa5, 0x4d, 0x28, 0x29, 0x8a, 0x9c, 0xc8, 0x51, 0xd0, 0xe8, + 0x5c, 0x42, 0x66, 0x3e, 0xef, 0x06, 0xda, 0x72, 0xea, 0xa8, 0x5a, 0x5a, 0x02, 0x0f, 0xa2, 0x68, 0x80, 0xa9, + 0x9a, 0xa4, 0x30, 0x8c, 0x9e, 0x69, 0x75, 0xa5, 0x5c, 0x34, 0x8b, 0x71, 0x49, 0xe5, 0x3a, 0x1a, 0x74, 0xa9, + 0x51, 0x86, 0xee, 0x06, 0xf9, 0x54, 0x37, 0x0c, 0xf6, 0x17, 0x8a, 0x1e, 0xc3, 0x54, 0x6d, 0xa9, 0x52, 0x4a, + 0x2f, 0xf8, 0xd0, 0xe3, 0x56, 0xc2, 0x61, 0x14, 0xfd, 0x7c, 0x77, 0x2b, 0x5b, 0x8b, 0x93, 0x2c, 0x6e, 0x76, + 0x46, 0xa9, 0x00, 0x34, 0x8d, 0x55, 0x42, 0x6a, 0xe2, 0x6b, 0xa3, 0xd8, 0xe6, 0x5a, 0x5b, 0x65, 0x98, 0xa8, + 0xb1, 0x85, 0x01, 0x92, 0x42, 0xf4, 0xd6, 0x73, 0x4d, 0xc6, 0xf6, 0xf1, 0x34, 0x36, 0x16, 0x44, 0xc6, 0x09, + 0xc7, 0x94, 0x46, 0x1c, 0x06, 0x94, 0x84, 0xa9, 0x4f, 0x41, 0x0b, 0x46, 0xa6, 0xb4, 0x48, 0x1a, 0x14, 0x45, + }; + + struct aws_array_list output_list; + ASSERT_SUCCESS(aws_pem_objects_init_from_file_path(&output_list, allocator, "testparse.crt")); + ASSERT_UINT_EQUALS(1, aws_array_list_length(&output_list)); + + struct aws_pem_object *pem_object = NULL; + aws_array_list_get_at_ptr(&output_list, (void **)&pem_object, 0); + ASSERT_BIN_ARRAYS_EQUALS(s_expected, sizeof(s_expected), pem_object->data.buffer, pem_object->data.len); + ASSERT_CURSOR_VALUE_CSTRING_EQUALS(aws_byte_cursor_from_string(pem_object->type_string), "CERTIFICATE"); + ASSERT_INT_EQUALS(AWS_PEM_TYPE_X509, pem_object->type); + + aws_pem_objects_clean_up(&output_list); + + return AWS_OP_SUCCESS; +} +AWS_TEST_CASE(test_pem_cert_parse_from_file, s_test_pem_cert_parse_from_file) + +static int s_test_pem_private_key_parse_from_file(struct aws_allocator *allocator, void *ctx) { + (void)ctx; + + static const uint8_t s_expected[] = { + 0x30, 0x82, 0x04, 0xa4, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, 0x01, 0x00, 0xd7, 0x6a, 0x57, 0x48, 0xf8, 0x0e, + 0x44, 0x03, 0x25, 0x42, 0xd6, 0x11, 0x6f, 0x1b, 0xb3, 0xfc, 0xe7, 0x1a, 0xa2, 0xb6, 0xa7, 0xdc, 0x2d, 0x85, + 0x8f, 0x28, 0xe1, 0xbb, 0x4b, 0xee, 0x71, 0x21, 0x19, 0x4b, 0x0c, 0x43, 0x26, 0x9e, 0xf9, 0x4c, 0x14, 0x04, + 0x31, 0xa7, 0xd2, 0xa5, 0x21, 0x0a, 0x01, 0x02, 0xde, 0x0e, 0xde, 0xf1, 0xb8, 0x34, 0x43, 0x62, 0x7e, 0x76, + 0x57, 0x85, 0x04, 0xe9, 0xc1, 0x7e, 0xc5, 0x35, 0xa1, 0xb7, 0x3b, 0x1f, 0xee, 0x68, 0x4d, 0xfe, 0x51, 0xda, + 0x0c, 0xf7, 0x2f, 0x47, 0x60, 0x12, 0x3c, 0x01, 0x24, 0xce, 0x48, 0xa5, 0xf0, 0xa0, 0x8b, 0x63, 0x87, 0xba, + 0xb5, 0x3c, 0x52, 0xc1, 0x0f, 0x7b, 0xb2, 0x99, 0x4d, 0xb8, 0x46, 0x74, 0xf7, 0xd1, 0xe8, 0x25, 0x84, 0xd3, + 0x2c, 0x56, 0x91, 0x78, 0x87, 0xdd, 0xd4, 0x3d, 0xf3, 0x67, 0x51, 0x18, 0x71, 0x2c, 0x3c, 0xc3, 0xe1, 0x99, + 0xd9, 0x2c, 0x44, 0x51, 0xf6, 0x14, 0x48, 0xbd, 0x82, 0x16, 0x62, 0x18, 0x4a, 0x44, 0x23, 0x9e, 0x5b, 0x09, + 0x08, 0x8a, 0x42, 0xa0, 0x68, 0x03, 0x88, 0x10, 0x0f, 0x6c, 0x85, 0x09, 0x3b, 0x72, 0x96, 0x04, 0x35, 0xf4, + 0x26, 0x01, 0x83, 0x6f, 0x1d, 0xd6, 0x7f, 0x78, 0xd7, 0x1b, 0xf6, 0x3a, 0x4f, 0xad, 0xcb, 0x3e, 0xc3, 0xbe, + 0x01, 0x2d, 0xb4, 0x44, 0x2b, 0xdc, 0x10, 0x5d, 0x05, 0xfe, 0xb9, 0x43, 0x20, 0xdc, 0xc8, 0xe4, 0x40, 0x07, + 0x3b, 0x54, 0xce, 0x11, 0xdf, 0x5f, 0x28, 0xeb, 0xbe, 0x24, 0x02, 0xb4, 0xe8, 0xfc, 0x35, 0x9b, 0xbe, 0xc1, + 0x80, 0xea, 0xc4, 0xec, 0x5b, 0x6f, 0x20, 0x6e, 0xe4, 0x60, 0xd5, 0x6e, 0x38, 0x43, 0xde, 0x22, 0x73, 0x87, + 0x90, 0xeb, 0xaa, 0xaf, 0x20, 0xe2, 0xb0, 0x1d, 0x4f, 0xc2, 0x2c, 0x8f, 0x34, 0x86, 0xea, 0x75, 0x02, 0x03, + 0x01, 0x00, 0x01, 0x02, 0x82, 0x01, 0x00, 0x44, 0x90, 0xb8, 0x8f, 0xa5, 0x45, 0x05, 0x28, 0xeb, 0x27, 0x46, + 0xf3, 0xed, 0xa5, 0xa7, 0xb8, 0x8b, 0xe6, 0xd2, 0x7b, 0xc9, 0x1a, 0x2f, 0xf3, 0x1f, 0x0a, 0x28, 0x2f, 0x71, + 0x8f, 0xc7, 0xba, 0x7d, 0x4e, 0x81, 0xec, 0xad, 0xd2, 0x54, 0x0f, 0x7f, 0x1f, 0x86, 0x9e, 0xa0, 0x51, 0xa7, + 0x1e, 0x84, 0x0b, 0xe1, 0x9a, 0x62, 0x24, 0x16, 0x39, 0xac, 0x69, 0x21, 0x4f, 0x91, 0xb3, 0xe9, 0x48, 0x6e, + 0x2a, 0x67, 0xa3, 0x16, 0x82, 0x37, 0xf3, 0x85, 0xf2, 0xf5, 0x40, 0x49, 0xd5, 0x59, 0xe3, 0x23, 0xcd, 0x58, + 0x2a, 0xf5, 0xa6, 0x77, 0x8c, 0xa1, 0x5b, 0x10, 0x28, 0x49, 0xb5, 0xb8, 0x72, 0x19, 0x55, 0xc6, 0x11, 0x65, + 0x58, 0x3e, 0x14, 0xc5, 0xc4, 0x2d, 0xc8, 0xf5, 0x48, 0x7e, 0xd7, 0xd2, 0x5b, 0x54, 0xf5, 0x89, 0x00, 0x10, + 0x5e, 0xef, 0x3b, 0x78, 0xca, 0x1d, 0xe9, 0xe5, 0xbb, 0x55, 0x69, 0x72, 0x30, 0xa8, 0x9c, 0x62, 0x40, 0x46, + 0x07, 0x6a, 0x21, 0x23, 0x48, 0x56, 0xf1, 0xc8, 0x71, 0xdf, 0xad, 0x73, 0xf7, 0xa4, 0x1c, 0xa7, 0x18, 0x40, + 0xc8, 0x10, 0x1f, 0x9e, 0x1c, 0x6e, 0x4e, 0x02, 0x85, 0x61, 0x24, 0x55, 0x7f, 0x06, 0x12, 0x3a, 0x31, 0xd8, + 0x3c, 0xeb, 0xe8, 0xce, 0x65, 0x3b, 0x5a, 0x3d, 0x22, 0x51, 0x14, 0xfe, 0xd4, 0xc3, 0x38, 0x88, 0xef, 0x18, + 0x94, 0x10, 0xee, 0x64, 0x42, 0x40, 0xae, 0xcd, 0xd6, 0x01, 0xd2, 0x1e, 0xa6, 0x60, 0xaa, 0xea, 0xc9, 0xf3, + 0x38, 0x02, 0x7a, 0x63, 0xd8, 0x84, 0xd0, 0x41, 0xad, 0x8b, 0xd4, 0x06, 0x88, 0x0a, 0x3a, 0x9d, 0xaf, 0xe7, + 0x58, 0x07, 0xd5, 0x95, 0x14, 0x8c, 0xc9, 0x2f, 0xc2, 0xd4, 0x60, 0xb4, 0xa0, 0xcd, 0x0c, 0x9e, 0x94, 0x4a, + 0x48, 0xb5, 0xb4, 0xb6, 0xf2, 0xd5, 0xbe, 0xd2, 0x46, 0xf3, 0x51, 0x02, 0x81, 0x81, 0x00, 0xee, 0x5c, 0xc6, + 0xa5, 0xd9, 0x40, 0x2b, 0x05, 0x8d, 0x28, 0xf7, 0x36, 0x60, 0x86, 0xed, 0x50, 0xda, 0x26, 0x0f, 0xf7, 0x8e, + 0xaf, 0xb4, 0xf3, 0x61, 0xe7, 0x58, 0xc4, 0x9f, 0x3c, 0x48, 0x6e, 0x76, 0x4c, 0x78, 0xe0, 0x13, 0x73, 0xee, + 0xa6, 0x81, 0x77, 0xc1, 0x91, 0x63, 0x76, 0xd9, 0x70, 0xc7, 0x5b, 0xb8, 0x9e, 0xcc, 0x65, 0x55, 0xee, 0x74, + 0x14, 0x14, 0xc2, 0x37, 0x9b, 0x36, 0x15, 0x5e, 0x3f, 0xf1, 0x83, 0xfd, 0xf3, 0x4c, 0xe2, 0xb3, 0xe1, 0xed, + 0x50, 0x2e, 0x69, 0x58, 0x23, 0xb7, 0x3b, 0x2e, 0xbe, 0x0e, 0x34, 0xa3, 0x2b, 0xdb, 0x2d, 0xfa, 0x61, 0xb2, + 0xcd, 0x88, 0xe5, 0xde, 0x8a, 0x55, 0xa9, 0xc4, 0x19, 0x90, 0x78, 0xf5, 0x2c, 0xfa, 0x8d, 0xc4, 0x19, 0xaf, + 0x16, 0x90, 0xe0, 0x02, 0xd5, 0x59, 0x7d, 0xd2, 0x92, 0x77, 0x2b, 0xb3, 0x66, 0x98, 0xfc, 0xb3, 0x9b, 0x02, + 0x81, 0x81, 0x00, 0xe7, 0x5a, 0xe3, 0x10, 0x56, 0xbf, 0x8a, 0x32, 0x0b, 0xa7, 0x53, 0xf9, 0xbc, 0xa9, 0xfc, + 0x6f, 0x7a, 0x48, 0x7d, 0x01, 0x52, 0xb1, 0x4b, 0x17, 0xe4, 0xd5, 0xd3, 0xcb, 0x7d, 0x5f, 0xff, 0x65, 0x30, + 0x55, 0x5e, 0x3d, 0xd5, 0xd8, 0xcc, 0xc8, 0xdc, 0xa1, 0xb5, 0xa4, 0x5c, 0xad, 0x73, 0xfd, 0x09, 0x8a, 0x6a, + 0xdf, 0xca, 0x35, 0xc6, 0xf5, 0x1a, 0xc5, 0xed, 0xa1, 0x94, 0xd0, 0xff, 0x8e, 0x20, 0x63, 0x04, 0x77, 0xec, + 0x0b, 0x5d, 0xe8, 0x50, 0xe5, 0x73, 0xf1, 0x3a, 0xc0, 0xcf, 0x10, 0xca, 0x03, 0x36, 0xc6, 0x2d, 0xc3, 0x93, + 0xda, 0xda, 0xe0, 0xc4, 0xc1, 0x5b, 0x47, 0xc1, 0x33, 0xfa, 0x3b, 0xab, 0xd7, 0x24, 0x1b, 0x3e, 0x7a, 0x0a, + 0x66, 0xb0, 0x7b, 0x4a, 0x8a, 0x40, 0x91, 0xc5, 0x6a, 0x66, 0xfe, 0x24, 0xb3, 0x42, 0xcb, 0xbb, 0xe0, 0x4b, + 0x7c, 0x41, 0x57, 0x63, 0x2f, 0x02, 0x81, 0x81, 0x00, 0xa4, 0xdf, 0x31, 0x5c, 0x38, 0x28, 0x45, 0x59, 0xc2, + 0xa9, 0x0a, 0x4d, 0xe7, 0x78, 0x8c, 0x9f, 0xf7, 0x34, 0x8a, 0xa8, 0xce, 0x5e, 0x44, 0xc8, 0x6f, 0xf8, 0xc8, + 0x92, 0xc0, 0x1d, 0xbf, 0x70, 0x00, 0x8d, 0xa6, 0xb2, 0x3f, 0x62, 0x5a, 0x39, 0x7b, 0xa5, 0xed, 0x12, 0xf6, + 0x7c, 0x97, 0xac, 0x85, 0x88, 0xb0, 0xeb, 0xce, 0x2f, 0x6d, 0xbf, 0xd1, 0x34, 0xae, 0xa3, 0x24, 0x39, 0x4c, + 0xb0, 0x7d, 0x0f, 0xb7, 0xab, 0x77, 0xb5, 0x99, 0x81, 0xd9, 0xb0, 0xb5, 0x28, 0x57, 0xe1, 0xef, 0xe0, 0x4c, + 0x76, 0x38, 0x3f, 0xa7, 0xad, 0xcb, 0x0b, 0xa3, 0xc0, 0x6a, 0xc6, 0xb7, 0x19, 0xa9, 0xce, 0x6e, 0x1e, 0xbb, + 0x60, 0x00, 0xcf, 0x39, 0xfa, 0x20, 0x84, 0x2b, 0x0e, 0x72, 0x0c, 0xdd, 0xe9, 0xba, 0xed, 0xe7, 0xa7, 0xd1, + 0x0d, 0xd1, 0xe0, 0x13, 0x63, 0xfb, 0xe4, 0x44, 0x7f, 0xce, 0x6f, 0x02, 0x81, 0x81, 0x00, 0xac, 0x0c, 0x71, + 0xe9, 0xb7, 0xa9, 0x4f, 0x7b, 0x32, 0x21, 0x68, 0x98, 0xc3, 0x0d, 0xe2, 0xb5, 0x80, 0x49, 0xa1, 0xf4, 0xb6, + 0xeb, 0x33, 0xfd, 0xfb, 0xe6, 0x6c, 0x4f, 0xda, 0xd7, 0xe6, 0x14, 0xf9, 0x21, 0xb3, 0x28, 0xe6, 0xfc, 0x08, + 0x26, 0xa3, 0xb4, 0xfa, 0x60, 0xd5, 0xaf, 0x04, 0x1f, 0xbb, 0xd5, 0x9c, 0xee, 0xf9, 0xf0, 0x8e, 0x19, 0xbe, + 0xa4, 0x4c, 0xb8, 0xa9, 0xf3, 0xd6, 0xe8, 0x79, 0xfb, 0x48, 0xda, 0x69, 0xc6, 0x76, 0x3a, 0x8a, 0xd6, 0x68, + 0x27, 0x8f, 0xda, 0xcc, 0xe2, 0x1e, 0x68, 0xcf, 0x76, 0x07, 0x98, 0x77, 0x3e, 0xfd, 0x20, 0xc4, 0x11, 0x4a, + 0xf1, 0x8c, 0xa3, 0x3b, 0xc6, 0xde, 0x5e, 0xea, 0xf1, 0xfb, 0xbf, 0x44, 0x36, 0xe3, 0xad, 0x7c, 0x5c, 0x5d, + 0xf2, 0x49, 0xce, 0x7b, 0xf3, 0x29, 0x95, 0xc9, 0xe9, 0xba, 0xb8, 0xed, 0x49, 0xe5, 0x49, 0xb8, 0x6f, 0x02, + 0x81, 0x80, 0x71, 0x11, 0x8a, 0x2e, 0x38, 0xcf, 0x54, 0xb9, 0x99, 0x5b, 0x95, 0x74, 0x17, 0x7e, 0xe7, 0x53, + 0x59, 0x67, 0xfe, 0xc7, 0x90, 0x84, 0x5b, 0x1c, 0x89, 0x80, 0xa6, 0xa4, 0xb4, 0x71, 0x21, 0xde, 0x27, 0x9e, + 0xb3, 0x58, 0x01, 0xed, 0x93, 0xdb, 0x39, 0xec, 0x0b, 0x6b, 0xc0, 0x18, 0x56, 0x3a, 0x9b, 0x36, 0x04, 0xbf, + 0xaf, 0xf6, 0x94, 0x16, 0x3a, 0x41, 0x6c, 0x2a, 0x2f, 0xf0, 0x80, 0xb1, 0x73, 0x2f, 0x3a, 0x4a, 0xe1, 0x9d, + 0x6b, 0x5d, 0x0b, 0x0c, 0x55, 0xfc, 0xde, 0xc6, 0xf2, 0x32, 0x6f, 0x17, 0x86, 0x4b, 0x5f, 0xc8, 0x2d, 0xcb, + 0xe7, 0x88, 0xab, 0x55, 0x6e, 0x66, 0x35, 0x40, 0xdc, 0x03, 0xcb, 0x3d, 0xf8, 0x39, 0x68, 0x79, 0x39, 0x54, + 0x94, 0x92, 0x2b, 0xf0, 0x9f, 0xd1, 0x00, 0x30, 0xbd, 0xae, 0x9a, 0x87, 0x2d, 0xa6, 0x73, 0x71, 0xdb, 0xe9, + 0x20, 0xc8, 0x55, 0xb3, + }; + + struct aws_array_list output_list; + + ASSERT_SUCCESS(aws_pem_objects_init_from_file_path(&output_list, allocator, "unittests.key")); + ASSERT_UINT_EQUALS(1, aws_array_list_length(&output_list)); + + struct aws_pem_object *pem_object = NULL; + aws_array_list_get_at_ptr(&output_list, (void **)&pem_object, 0); + ASSERT_BIN_ARRAYS_EQUALS(s_expected, sizeof(s_expected), pem_object->data.buffer, pem_object->data.len); + ASSERT_CURSOR_VALUE_CSTRING_EQUALS(aws_byte_cursor_from_string(pem_object->type_string), "RSA PRIVATE KEY"); + ASSERT_INT_EQUALS(AWS_PEM_TYPE_PRIVATE_RSA_PKCS1, pem_object->type); + + aws_pem_objects_clean_up(&output_list); + + return AWS_OP_SUCCESS; +} +AWS_TEST_CASE(test_pem_private_key_parse_from_file, s_test_pem_private_key_parse_from_file) static int s_test_pem_single_cert_parse(struct aws_allocator *allocator, void *ctx) { (void)ctx; @@ -68,20 +374,19 @@ static int s_test_pem_single_cert_parse(struct aws_allocator *allocator, void *c struct aws_byte_cursor pem_data = aws_byte_cursor_from_c_str(s_rsa_1024_sha224_client_crt_pem); struct aws_array_list output_list; - ASSERT_SUCCESS(aws_array_list_init_dynamic(&output_list, allocator, 1, sizeof(struct aws_byte_buf))); - ASSERT_SUCCESS(aws_decode_pem_to_buffer_list(allocator, &pem_data, &output_list)); + ASSERT_SUCCESS(aws_pem_objects_init_from_file_contents(&output_list, allocator, pem_data)); ASSERT_UINT_EQUALS(1, aws_array_list_length(&output_list)); - struct aws_byte_buf *cert_data = NULL; - aws_array_list_get_at_ptr(&output_list, (void **)&cert_data, 0); - ASSERT_BIN_ARRAYS_EQUALS(s_expected, sizeof(s_expected), cert_data->buffer, cert_data->len); + struct aws_pem_object *pem_object = NULL; + aws_array_list_get_at_ptr(&output_list, (void **)&pem_object, 0); + ASSERT_BIN_ARRAYS_EQUALS(s_expected, sizeof(s_expected), pem_object->data.buffer, pem_object->data.len); + ASSERT_CURSOR_VALUE_CSTRING_EQUALS(aws_byte_cursor_from_string(pem_object->type_string), "CERTIFICATE"); + ASSERT_INT_EQUALS(AWS_PEM_TYPE_X509, pem_object->type); - aws_cert_chain_clean_up(&output_list); - aws_array_list_clean_up(&output_list); + aws_pem_objects_clean_up(&output_list); return AWS_OP_SUCCESS; } - AWS_TEST_CASE(test_pem_single_cert_parse, s_test_pem_single_cert_parse) static int s_test_pem_cert_chain_parse(struct aws_allocator *allocator, void *ctx) { @@ -281,26 +586,29 @@ static int s_test_pem_cert_chain_parse(struct aws_allocator *allocator, void *ct struct aws_byte_cursor pem_data = aws_byte_cursor_from_c_str(s_rsa_2048_pkcs1_crt_pem); struct aws_array_list output_list; - ASSERT_SUCCESS(aws_array_list_init_dynamic(&output_list, allocator, 1, sizeof(struct aws_byte_buf))); - ASSERT_SUCCESS(aws_decode_pem_to_buffer_list(allocator, &pem_data, &output_list)); + ASSERT_SUCCESS(aws_pem_objects_init_from_file_contents(&output_list, allocator, pem_data)); ASSERT_UINT_EQUALS(3, aws_array_list_length(&output_list)); - struct aws_byte_buf *cert_data = NULL; - aws_array_list_get_at_ptr(&output_list, (void **)&cert_data, 0); + struct aws_pem_object *pem_object = NULL; + aws_array_list_get_at_ptr(&output_list, (void **)&pem_object, 0); ASSERT_BIN_ARRAYS_EQUALS( - s_expected_intermediate_1, sizeof(s_expected_intermediate_1), cert_data->buffer, cert_data->len); - aws_array_list_get_at_ptr(&output_list, (void **)&cert_data, 1); + s_expected_intermediate_1, sizeof(s_expected_intermediate_1), pem_object->data.buffer, pem_object->data.len); + ASSERT_CURSOR_VALUE_CSTRING_EQUALS(aws_byte_cursor_from_string(pem_object->type_string), "CERTIFICATE"); + ASSERT_INT_EQUALS(AWS_PEM_TYPE_X509, pem_object->type); + aws_array_list_get_at_ptr(&output_list, (void **)&pem_object, 1); ASSERT_BIN_ARRAYS_EQUALS( - s_expected_intermediate_2, sizeof(s_expected_intermediate_2), cert_data->buffer, cert_data->len); - aws_array_list_get_at_ptr(&output_list, (void **)&cert_data, 2); - ASSERT_BIN_ARRAYS_EQUALS(s_expected_leaf, sizeof(s_expected_leaf), cert_data->buffer, cert_data->len); + s_expected_intermediate_2, sizeof(s_expected_intermediate_2), pem_object->data.buffer, pem_object->data.len); + ASSERT_CURSOR_VALUE_CSTRING_EQUALS(aws_byte_cursor_from_string(pem_object->type_string), "CERTIFICATE"); + ASSERT_INT_EQUALS(AWS_PEM_TYPE_X509, pem_object->type); + aws_array_list_get_at_ptr(&output_list, (void **)&pem_object, 2); + ASSERT_BIN_ARRAYS_EQUALS(s_expected_leaf, sizeof(s_expected_leaf), pem_object->data.buffer, pem_object->data.len); + ASSERT_CURSOR_VALUE_CSTRING_EQUALS(aws_byte_cursor_from_string(pem_object->type_string), "CERTIFICATE"); + ASSERT_INT_EQUALS(AWS_PEM_TYPE_X509, pem_object->type); - aws_cert_chain_clean_up(&output_list); - aws_array_list_clean_up(&output_list); + aws_pem_objects_clean_up(&output_list); return AWS_OP_SUCCESS; } - AWS_TEST_CASE(test_pem_cert_chain_parse, s_test_pem_cert_chain_parse) static int s_test_pem_private_key_parse(struct aws_allocator *allocator, void *ctx) { @@ -406,193 +714,21 @@ static int s_test_pem_private_key_parse(struct aws_allocator *allocator, void *c struct aws_byte_cursor pem_data = aws_byte_cursor_from_c_str(s_private_key_pem); struct aws_array_list output_list; - ASSERT_SUCCESS(aws_array_list_init_dynamic(&output_list, allocator, 1, sizeof(struct aws_byte_buf))); - ASSERT_SUCCESS(aws_decode_pem_to_buffer_list(allocator, &pem_data, &output_list)); + ASSERT_SUCCESS(aws_pem_objects_init_from_file_contents(&output_list, allocator, pem_data)); ASSERT_UINT_EQUALS(1, aws_array_list_length(&output_list)); - struct aws_byte_buf *cert_data = NULL; - aws_array_list_get_at_ptr(&output_list, (void **)&cert_data, 0); - ASSERT_BIN_ARRAYS_EQUALS(s_expected, sizeof(s_expected), cert_data->buffer, cert_data->len); + struct aws_pem_object *pem_object = NULL; + aws_array_list_get_at_ptr(&output_list, (void **)&pem_object, 0); + ASSERT_BIN_ARRAYS_EQUALS(s_expected, sizeof(s_expected), pem_object->data.buffer, pem_object->data.len); + ASSERT_CURSOR_VALUE_CSTRING_EQUALS(aws_byte_cursor_from_string(pem_object->type_string), "RSA PRIVATE KEY"); + ASSERT_INT_EQUALS(AWS_PEM_TYPE_PRIVATE_RSA_PKCS1, pem_object->type); - aws_cert_chain_clean_up(&output_list); - aws_array_list_clean_up(&output_list); + aws_pem_objects_clean_up(&output_list); return AWS_OP_SUCCESS; } - AWS_TEST_CASE(test_pem_private_key_parse, s_test_pem_private_key_parse) -static int s_test_pem_cert_parse_from_file(struct aws_allocator *allocator, void *ctx) { - (void)ctx; - - static const uint8_t s_expected[] = { - 0x30, 0x82, 0x03, 0xec, 0x30, 0x82, 0x02, 0xd4, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x09, 0x00, 0x84, 0x7d, - 0x2e, 0xed, 0x4d, 0xfc, 0x26, 0x87, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, - 0x0b, 0x05, 0x00, 0x30, 0x81, 0x9a, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, - 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, - 0x67, 0x74, 0x6f, 0x6e, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x07, 0x53, 0x65, 0x61, - 0x74, 0x74, 0x6c, 0x65, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x06, 0x41, 0x6d, 0x61, - 0x7a, 0x6f, 0x6e, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x04, 0x53, 0x44, 0x4b, 0x73, - 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, - 0x73, 0x74, 0x31, 0x30, 0x30, 0x2e, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, - 0x21, 0x61, 0x77, 0x73, 0x2d, 0x73, 0x64, 0x6b, 0x2d, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2d, 0x72, 0x75, - 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x40, 0x61, 0x6d, 0x61, 0x7a, 0x6f, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1e, - 0x17, 0x0d, 0x32, 0x31, 0x30, 0x36, 0x31, 0x36, 0x30, 0x36, 0x31, 0x37, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, - 0x33, 0x30, 0x39, 0x31, 0x38, 0x30, 0x36, 0x31, 0x37, 0x30, 0x30, 0x5a, 0x30, 0x81, 0x9a, 0x31, 0x0b, 0x30, - 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, - 0x08, 0x0c, 0x0a, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x74, 0x6f, 0x6e, 0x31, 0x10, 0x30, 0x0e, 0x06, - 0x03, 0x55, 0x04, 0x07, 0x0c, 0x07, 0x53, 0x65, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x31, 0x0f, 0x30, 0x0d, 0x06, - 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x06, 0x41, 0x6d, 0x61, 0x7a, 0x6f, 0x6e, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, - 0x55, 0x04, 0x0b, 0x0c, 0x04, 0x53, 0x44, 0x4b, 0x73, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, - 0x0c, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x31, 0x30, 0x30, 0x2e, 0x06, 0x09, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x21, 0x61, 0x77, 0x73, 0x2d, 0x73, 0x64, 0x6b, 0x2d, - 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2d, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x40, 0x61, 0x6d, 0x61, - 0x7a, 0x6f, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, - 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, - 0x82, 0x01, 0x01, 0x00, 0xd7, 0x6a, 0x57, 0x48, 0xf8, 0x0e, 0x44, 0x03, 0x25, 0x42, 0xd6, 0x11, 0x6f, 0x1b, - 0xb3, 0xfc, 0xe7, 0x1a, 0xa2, 0xb6, 0xa7, 0xdc, 0x2d, 0x85, 0x8f, 0x28, 0xe1, 0xbb, 0x4b, 0xee, 0x71, 0x21, - 0x19, 0x4b, 0x0c, 0x43, 0x26, 0x9e, 0xf9, 0x4c, 0x14, 0x04, 0x31, 0xa7, 0xd2, 0xa5, 0x21, 0x0a, 0x01, 0x02, - 0xde, 0x0e, 0xde, 0xf1, 0xb8, 0x34, 0x43, 0x62, 0x7e, 0x76, 0x57, 0x85, 0x04, 0xe9, 0xc1, 0x7e, 0xc5, 0x35, - 0xa1, 0xb7, 0x3b, 0x1f, 0xee, 0x68, 0x4d, 0xfe, 0x51, 0xda, 0x0c, 0xf7, 0x2f, 0x47, 0x60, 0x12, 0x3c, 0x01, - 0x24, 0xce, 0x48, 0xa5, 0xf0, 0xa0, 0x8b, 0x63, 0x87, 0xba, 0xb5, 0x3c, 0x52, 0xc1, 0x0f, 0x7b, 0xb2, 0x99, - 0x4d, 0xb8, 0x46, 0x74, 0xf7, 0xd1, 0xe8, 0x25, 0x84, 0xd3, 0x2c, 0x56, 0x91, 0x78, 0x87, 0xdd, 0xd4, 0x3d, - 0xf3, 0x67, 0x51, 0x18, 0x71, 0x2c, 0x3c, 0xc3, 0xe1, 0x99, 0xd9, 0x2c, 0x44, 0x51, 0xf6, 0x14, 0x48, 0xbd, - 0x82, 0x16, 0x62, 0x18, 0x4a, 0x44, 0x23, 0x9e, 0x5b, 0x09, 0x08, 0x8a, 0x42, 0xa0, 0x68, 0x03, 0x88, 0x10, - 0x0f, 0x6c, 0x85, 0x09, 0x3b, 0x72, 0x96, 0x04, 0x35, 0xf4, 0x26, 0x01, 0x83, 0x6f, 0x1d, 0xd6, 0x7f, 0x78, - 0xd7, 0x1b, 0xf6, 0x3a, 0x4f, 0xad, 0xcb, 0x3e, 0xc3, 0xbe, 0x01, 0x2d, 0xb4, 0x44, 0x2b, 0xdc, 0x10, 0x5d, - 0x05, 0xfe, 0xb9, 0x43, 0x20, 0xdc, 0xc8, 0xe4, 0x40, 0x07, 0x3b, 0x54, 0xce, 0x11, 0xdf, 0x5f, 0x28, 0xeb, - 0xbe, 0x24, 0x02, 0xb4, 0xe8, 0xfc, 0x35, 0x9b, 0xbe, 0xc1, 0x80, 0xea, 0xc4, 0xec, 0x5b, 0x6f, 0x20, 0x6e, - 0xe4, 0x60, 0xd5, 0x6e, 0x38, 0x43, 0xde, 0x22, 0x73, 0x87, 0x90, 0xeb, 0xaa, 0xaf, 0x20, 0xe2, 0xb0, 0x1d, - 0x4f, 0xc2, 0x2c, 0x8f, 0x34, 0x86, 0xea, 0x75, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x33, 0x30, 0x31, 0x30, - 0x13, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x0c, 0x30, 0x0a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, - 0x03, 0x01, 0x30, 0x1a, 0x06, 0x03, 0x55, 0x1d, 0x11, 0x04, 0x13, 0x30, 0x11, 0x82, 0x09, 0x6c, 0x6f, 0x63, - 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x87, 0x04, 0x7f, 0x00, 0x00, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, - 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x07, 0xb4, 0x9a, 0x48, - 0x4e, 0x6d, 0x71, 0x32, 0xf4, 0x35, 0x89, 0xf5, 0xe1, 0xe8, 0x27, 0x5e, 0xe3, 0x51, 0x0d, 0x54, 0xf2, 0xde, - 0x1e, 0x2f, 0x9a, 0x0d, 0xdd, 0x02, 0xd4, 0xce, 0x15, 0x93, 0x8b, 0xe6, 0x75, 0x77, 0xc2, 0x41, 0xf6, 0xbf, - 0xfc, 0xac, 0x25, 0x96, 0xea, 0x80, 0x38, 0x68, 0xe2, 0xa5, 0x72, 0x9a, 0x31, 0xa2, 0x95, 0x43, 0xa9, 0x90, - 0x39, 0x64, 0xe3, 0x6c, 0x29, 0x37, 0x0c, 0x7a, 0xb7, 0x18, 0x97, 0x47, 0x0e, 0x16, 0x79, 0x2f, 0x9a, 0x92, - 0x7b, 0x51, 0xac, 0xe4, 0x4c, 0x70, 0xc2, 0xe4, 0xf3, 0x7f, 0x2b, 0x63, 0x53, 0x2c, 0x3b, 0xdb, 0xf1, 0xef, - 0x84, 0xda, 0xf3, 0x71, 0x6c, 0x6e, 0xb8, 0x41, 0x48, 0xae, 0xb5, 0x12, 0x1b, 0x20, 0xec, 0xdf, 0xff, 0x9f, - 0x2b, 0x2d, 0x66, 0x52, 0x0a, 0x72, 0x17, 0x99, 0xa5, 0x4d, 0x28, 0x29, 0x8a, 0x9c, 0xc8, 0x51, 0xd0, 0xe8, - 0x5c, 0x42, 0x66, 0x3e, 0xef, 0x06, 0xda, 0x72, 0xea, 0xa8, 0x5a, 0x5a, 0x02, 0x0f, 0xa2, 0x68, 0x80, 0xa9, - 0x9a, 0xa4, 0x30, 0x8c, 0x9e, 0x69, 0x75, 0xa5, 0x5c, 0x34, 0x8b, 0x71, 0x49, 0xe5, 0x3a, 0x1a, 0x74, 0xa9, - 0x51, 0x86, 0xee, 0x06, 0xf9, 0x54, 0x37, 0x0c, 0xf6, 0x17, 0x8a, 0x1e, 0xc3, 0x54, 0x6d, 0xa9, 0x52, 0x4a, - 0x2f, 0xf8, 0xd0, 0xe3, 0x56, 0xc2, 0x61, 0x14, 0xfd, 0x7c, 0x77, 0x2b, 0x5b, 0x8b, 0x93, 0x2c, 0x6e, 0x76, - 0x46, 0xa9, 0x00, 0x34, 0x8d, 0x55, 0x42, 0x6a, 0xe2, 0x6b, 0xa3, 0xd8, 0xe6, 0x5a, 0x5b, 0x65, 0x98, 0xa8, - 0xb1, 0x85, 0x01, 0x92, 0x42, 0xf4, 0xd6, 0x73, 0x4d, 0xc6, 0xf6, 0xf1, 0x34, 0x36, 0x16, 0x44, 0xc6, 0x09, - 0xc7, 0x94, 0x46, 0x1c, 0x06, 0x94, 0x84, 0xa9, 0x4f, 0x41, 0x0b, 0x46, 0xa6, 0xb4, 0x48, 0x1a, 0x14, 0x45, - }; - - struct aws_array_list output_list; - - ASSERT_SUCCESS(aws_array_list_init_dynamic(&output_list, allocator, 1, sizeof(struct aws_byte_buf))); - ASSERT_SUCCESS(aws_read_and_decode_pem_file_to_buffer_list(allocator, "testparse.crt", &output_list)); - ASSERT_UINT_EQUALS(1, aws_array_list_length(&output_list)); - - struct aws_byte_buf *cert_data = NULL; - aws_array_list_get_at_ptr(&output_list, (void **)&cert_data, 0); - ASSERT_BIN_ARRAYS_EQUALS(s_expected, sizeof(s_expected), cert_data->buffer, cert_data->len); - - aws_cert_chain_clean_up(&output_list); - aws_array_list_clean_up(&output_list); - - return AWS_OP_SUCCESS; -} - -AWS_TEST_CASE(test_pem_cert_parse_from_file, s_test_pem_cert_parse_from_file) - -static int s_test_pem_private_key_parse_from_file(struct aws_allocator *allocator, void *ctx) { - (void)ctx; - - static const uint8_t s_expected[] = { - 0x30, 0x82, 0x04, 0xa4, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, 0x01, 0x00, 0xd7, 0x6a, 0x57, 0x48, 0xf8, 0x0e, - 0x44, 0x03, 0x25, 0x42, 0xd6, 0x11, 0x6f, 0x1b, 0xb3, 0xfc, 0xe7, 0x1a, 0xa2, 0xb6, 0xa7, 0xdc, 0x2d, 0x85, - 0x8f, 0x28, 0xe1, 0xbb, 0x4b, 0xee, 0x71, 0x21, 0x19, 0x4b, 0x0c, 0x43, 0x26, 0x9e, 0xf9, 0x4c, 0x14, 0x04, - 0x31, 0xa7, 0xd2, 0xa5, 0x21, 0x0a, 0x01, 0x02, 0xde, 0x0e, 0xde, 0xf1, 0xb8, 0x34, 0x43, 0x62, 0x7e, 0x76, - 0x57, 0x85, 0x04, 0xe9, 0xc1, 0x7e, 0xc5, 0x35, 0xa1, 0xb7, 0x3b, 0x1f, 0xee, 0x68, 0x4d, 0xfe, 0x51, 0xda, - 0x0c, 0xf7, 0x2f, 0x47, 0x60, 0x12, 0x3c, 0x01, 0x24, 0xce, 0x48, 0xa5, 0xf0, 0xa0, 0x8b, 0x63, 0x87, 0xba, - 0xb5, 0x3c, 0x52, 0xc1, 0x0f, 0x7b, 0xb2, 0x99, 0x4d, 0xb8, 0x46, 0x74, 0xf7, 0xd1, 0xe8, 0x25, 0x84, 0xd3, - 0x2c, 0x56, 0x91, 0x78, 0x87, 0xdd, 0xd4, 0x3d, 0xf3, 0x67, 0x51, 0x18, 0x71, 0x2c, 0x3c, 0xc3, 0xe1, 0x99, - 0xd9, 0x2c, 0x44, 0x51, 0xf6, 0x14, 0x48, 0xbd, 0x82, 0x16, 0x62, 0x18, 0x4a, 0x44, 0x23, 0x9e, 0x5b, 0x09, - 0x08, 0x8a, 0x42, 0xa0, 0x68, 0x03, 0x88, 0x10, 0x0f, 0x6c, 0x85, 0x09, 0x3b, 0x72, 0x96, 0x04, 0x35, 0xf4, - 0x26, 0x01, 0x83, 0x6f, 0x1d, 0xd6, 0x7f, 0x78, 0xd7, 0x1b, 0xf6, 0x3a, 0x4f, 0xad, 0xcb, 0x3e, 0xc3, 0xbe, - 0x01, 0x2d, 0xb4, 0x44, 0x2b, 0xdc, 0x10, 0x5d, 0x05, 0xfe, 0xb9, 0x43, 0x20, 0xdc, 0xc8, 0xe4, 0x40, 0x07, - 0x3b, 0x54, 0xce, 0x11, 0xdf, 0x5f, 0x28, 0xeb, 0xbe, 0x24, 0x02, 0xb4, 0xe8, 0xfc, 0x35, 0x9b, 0xbe, 0xc1, - 0x80, 0xea, 0xc4, 0xec, 0x5b, 0x6f, 0x20, 0x6e, 0xe4, 0x60, 0xd5, 0x6e, 0x38, 0x43, 0xde, 0x22, 0x73, 0x87, - 0x90, 0xeb, 0xaa, 0xaf, 0x20, 0xe2, 0xb0, 0x1d, 0x4f, 0xc2, 0x2c, 0x8f, 0x34, 0x86, 0xea, 0x75, 0x02, 0x03, - 0x01, 0x00, 0x01, 0x02, 0x82, 0x01, 0x00, 0x44, 0x90, 0xb8, 0x8f, 0xa5, 0x45, 0x05, 0x28, 0xeb, 0x27, 0x46, - 0xf3, 0xed, 0xa5, 0xa7, 0xb8, 0x8b, 0xe6, 0xd2, 0x7b, 0xc9, 0x1a, 0x2f, 0xf3, 0x1f, 0x0a, 0x28, 0x2f, 0x71, - 0x8f, 0xc7, 0xba, 0x7d, 0x4e, 0x81, 0xec, 0xad, 0xd2, 0x54, 0x0f, 0x7f, 0x1f, 0x86, 0x9e, 0xa0, 0x51, 0xa7, - 0x1e, 0x84, 0x0b, 0xe1, 0x9a, 0x62, 0x24, 0x16, 0x39, 0xac, 0x69, 0x21, 0x4f, 0x91, 0xb3, 0xe9, 0x48, 0x6e, - 0x2a, 0x67, 0xa3, 0x16, 0x82, 0x37, 0xf3, 0x85, 0xf2, 0xf5, 0x40, 0x49, 0xd5, 0x59, 0xe3, 0x23, 0xcd, 0x58, - 0x2a, 0xf5, 0xa6, 0x77, 0x8c, 0xa1, 0x5b, 0x10, 0x28, 0x49, 0xb5, 0xb8, 0x72, 0x19, 0x55, 0xc6, 0x11, 0x65, - 0x58, 0x3e, 0x14, 0xc5, 0xc4, 0x2d, 0xc8, 0xf5, 0x48, 0x7e, 0xd7, 0xd2, 0x5b, 0x54, 0xf5, 0x89, 0x00, 0x10, - 0x5e, 0xef, 0x3b, 0x78, 0xca, 0x1d, 0xe9, 0xe5, 0xbb, 0x55, 0x69, 0x72, 0x30, 0xa8, 0x9c, 0x62, 0x40, 0x46, - 0x07, 0x6a, 0x21, 0x23, 0x48, 0x56, 0xf1, 0xc8, 0x71, 0xdf, 0xad, 0x73, 0xf7, 0xa4, 0x1c, 0xa7, 0x18, 0x40, - 0xc8, 0x10, 0x1f, 0x9e, 0x1c, 0x6e, 0x4e, 0x02, 0x85, 0x61, 0x24, 0x55, 0x7f, 0x06, 0x12, 0x3a, 0x31, 0xd8, - 0x3c, 0xeb, 0xe8, 0xce, 0x65, 0x3b, 0x5a, 0x3d, 0x22, 0x51, 0x14, 0xfe, 0xd4, 0xc3, 0x38, 0x88, 0xef, 0x18, - 0x94, 0x10, 0xee, 0x64, 0x42, 0x40, 0xae, 0xcd, 0xd6, 0x01, 0xd2, 0x1e, 0xa6, 0x60, 0xaa, 0xea, 0xc9, 0xf3, - 0x38, 0x02, 0x7a, 0x63, 0xd8, 0x84, 0xd0, 0x41, 0xad, 0x8b, 0xd4, 0x06, 0x88, 0x0a, 0x3a, 0x9d, 0xaf, 0xe7, - 0x58, 0x07, 0xd5, 0x95, 0x14, 0x8c, 0xc9, 0x2f, 0xc2, 0xd4, 0x60, 0xb4, 0xa0, 0xcd, 0x0c, 0x9e, 0x94, 0x4a, - 0x48, 0xb5, 0xb4, 0xb6, 0xf2, 0xd5, 0xbe, 0xd2, 0x46, 0xf3, 0x51, 0x02, 0x81, 0x81, 0x00, 0xee, 0x5c, 0xc6, - 0xa5, 0xd9, 0x40, 0x2b, 0x05, 0x8d, 0x28, 0xf7, 0x36, 0x60, 0x86, 0xed, 0x50, 0xda, 0x26, 0x0f, 0xf7, 0x8e, - 0xaf, 0xb4, 0xf3, 0x61, 0xe7, 0x58, 0xc4, 0x9f, 0x3c, 0x48, 0x6e, 0x76, 0x4c, 0x78, 0xe0, 0x13, 0x73, 0xee, - 0xa6, 0x81, 0x77, 0xc1, 0x91, 0x63, 0x76, 0xd9, 0x70, 0xc7, 0x5b, 0xb8, 0x9e, 0xcc, 0x65, 0x55, 0xee, 0x74, - 0x14, 0x14, 0xc2, 0x37, 0x9b, 0x36, 0x15, 0x5e, 0x3f, 0xf1, 0x83, 0xfd, 0xf3, 0x4c, 0xe2, 0xb3, 0xe1, 0xed, - 0x50, 0x2e, 0x69, 0x58, 0x23, 0xb7, 0x3b, 0x2e, 0xbe, 0x0e, 0x34, 0xa3, 0x2b, 0xdb, 0x2d, 0xfa, 0x61, 0xb2, - 0xcd, 0x88, 0xe5, 0xde, 0x8a, 0x55, 0xa9, 0xc4, 0x19, 0x90, 0x78, 0xf5, 0x2c, 0xfa, 0x8d, 0xc4, 0x19, 0xaf, - 0x16, 0x90, 0xe0, 0x02, 0xd5, 0x59, 0x7d, 0xd2, 0x92, 0x77, 0x2b, 0xb3, 0x66, 0x98, 0xfc, 0xb3, 0x9b, 0x02, - 0x81, 0x81, 0x00, 0xe7, 0x5a, 0xe3, 0x10, 0x56, 0xbf, 0x8a, 0x32, 0x0b, 0xa7, 0x53, 0xf9, 0xbc, 0xa9, 0xfc, - 0x6f, 0x7a, 0x48, 0x7d, 0x01, 0x52, 0xb1, 0x4b, 0x17, 0xe4, 0xd5, 0xd3, 0xcb, 0x7d, 0x5f, 0xff, 0x65, 0x30, - 0x55, 0x5e, 0x3d, 0xd5, 0xd8, 0xcc, 0xc8, 0xdc, 0xa1, 0xb5, 0xa4, 0x5c, 0xad, 0x73, 0xfd, 0x09, 0x8a, 0x6a, - 0xdf, 0xca, 0x35, 0xc6, 0xf5, 0x1a, 0xc5, 0xed, 0xa1, 0x94, 0xd0, 0xff, 0x8e, 0x20, 0x63, 0x04, 0x77, 0xec, - 0x0b, 0x5d, 0xe8, 0x50, 0xe5, 0x73, 0xf1, 0x3a, 0xc0, 0xcf, 0x10, 0xca, 0x03, 0x36, 0xc6, 0x2d, 0xc3, 0x93, - 0xda, 0xda, 0xe0, 0xc4, 0xc1, 0x5b, 0x47, 0xc1, 0x33, 0xfa, 0x3b, 0xab, 0xd7, 0x24, 0x1b, 0x3e, 0x7a, 0x0a, - 0x66, 0xb0, 0x7b, 0x4a, 0x8a, 0x40, 0x91, 0xc5, 0x6a, 0x66, 0xfe, 0x24, 0xb3, 0x42, 0xcb, 0xbb, 0xe0, 0x4b, - 0x7c, 0x41, 0x57, 0x63, 0x2f, 0x02, 0x81, 0x81, 0x00, 0xa4, 0xdf, 0x31, 0x5c, 0x38, 0x28, 0x45, 0x59, 0xc2, - 0xa9, 0x0a, 0x4d, 0xe7, 0x78, 0x8c, 0x9f, 0xf7, 0x34, 0x8a, 0xa8, 0xce, 0x5e, 0x44, 0xc8, 0x6f, 0xf8, 0xc8, - 0x92, 0xc0, 0x1d, 0xbf, 0x70, 0x00, 0x8d, 0xa6, 0xb2, 0x3f, 0x62, 0x5a, 0x39, 0x7b, 0xa5, 0xed, 0x12, 0xf6, - 0x7c, 0x97, 0xac, 0x85, 0x88, 0xb0, 0xeb, 0xce, 0x2f, 0x6d, 0xbf, 0xd1, 0x34, 0xae, 0xa3, 0x24, 0x39, 0x4c, - 0xb0, 0x7d, 0x0f, 0xb7, 0xab, 0x77, 0xb5, 0x99, 0x81, 0xd9, 0xb0, 0xb5, 0x28, 0x57, 0xe1, 0xef, 0xe0, 0x4c, - 0x76, 0x38, 0x3f, 0xa7, 0xad, 0xcb, 0x0b, 0xa3, 0xc0, 0x6a, 0xc6, 0xb7, 0x19, 0xa9, 0xce, 0x6e, 0x1e, 0xbb, - 0x60, 0x00, 0xcf, 0x39, 0xfa, 0x20, 0x84, 0x2b, 0x0e, 0x72, 0x0c, 0xdd, 0xe9, 0xba, 0xed, 0xe7, 0xa7, 0xd1, - 0x0d, 0xd1, 0xe0, 0x13, 0x63, 0xfb, 0xe4, 0x44, 0x7f, 0xce, 0x6f, 0x02, 0x81, 0x81, 0x00, 0xac, 0x0c, 0x71, - 0xe9, 0xb7, 0xa9, 0x4f, 0x7b, 0x32, 0x21, 0x68, 0x98, 0xc3, 0x0d, 0xe2, 0xb5, 0x80, 0x49, 0xa1, 0xf4, 0xb6, - 0xeb, 0x33, 0xfd, 0xfb, 0xe6, 0x6c, 0x4f, 0xda, 0xd7, 0xe6, 0x14, 0xf9, 0x21, 0xb3, 0x28, 0xe6, 0xfc, 0x08, - 0x26, 0xa3, 0xb4, 0xfa, 0x60, 0xd5, 0xaf, 0x04, 0x1f, 0xbb, 0xd5, 0x9c, 0xee, 0xf9, 0xf0, 0x8e, 0x19, 0xbe, - 0xa4, 0x4c, 0xb8, 0xa9, 0xf3, 0xd6, 0xe8, 0x79, 0xfb, 0x48, 0xda, 0x69, 0xc6, 0x76, 0x3a, 0x8a, 0xd6, 0x68, - 0x27, 0x8f, 0xda, 0xcc, 0xe2, 0x1e, 0x68, 0xcf, 0x76, 0x07, 0x98, 0x77, 0x3e, 0xfd, 0x20, 0xc4, 0x11, 0x4a, - 0xf1, 0x8c, 0xa3, 0x3b, 0xc6, 0xde, 0x5e, 0xea, 0xf1, 0xfb, 0xbf, 0x44, 0x36, 0xe3, 0xad, 0x7c, 0x5c, 0x5d, - 0xf2, 0x49, 0xce, 0x7b, 0xf3, 0x29, 0x95, 0xc9, 0xe9, 0xba, 0xb8, 0xed, 0x49, 0xe5, 0x49, 0xb8, 0x6f, 0x02, - 0x81, 0x80, 0x71, 0x11, 0x8a, 0x2e, 0x38, 0xcf, 0x54, 0xb9, 0x99, 0x5b, 0x95, 0x74, 0x17, 0x7e, 0xe7, 0x53, - 0x59, 0x67, 0xfe, 0xc7, 0x90, 0x84, 0x5b, 0x1c, 0x89, 0x80, 0xa6, 0xa4, 0xb4, 0x71, 0x21, 0xde, 0x27, 0x9e, - 0xb3, 0x58, 0x01, 0xed, 0x93, 0xdb, 0x39, 0xec, 0x0b, 0x6b, 0xc0, 0x18, 0x56, 0x3a, 0x9b, 0x36, 0x04, 0xbf, - 0xaf, 0xf6, 0x94, 0x16, 0x3a, 0x41, 0x6c, 0x2a, 0x2f, 0xf0, 0x80, 0xb1, 0x73, 0x2f, 0x3a, 0x4a, 0xe1, 0x9d, - 0x6b, 0x5d, 0x0b, 0x0c, 0x55, 0xfc, 0xde, 0xc6, 0xf2, 0x32, 0x6f, 0x17, 0x86, 0x4b, 0x5f, 0xc8, 0x2d, 0xcb, - 0xe7, 0x88, 0xab, 0x55, 0x6e, 0x66, 0x35, 0x40, 0xdc, 0x03, 0xcb, 0x3d, 0xf8, 0x39, 0x68, 0x79, 0x39, 0x54, - 0x94, 0x92, 0x2b, 0xf0, 0x9f, 0xd1, 0x00, 0x30, 0xbd, 0xae, 0x9a, 0x87, 0x2d, 0xa6, 0x73, 0x71, 0xdb, 0xe9, - 0x20, 0xc8, 0x55, 0xb3, - }; - - struct aws_array_list output_list; - - ASSERT_SUCCESS(aws_array_list_init_dynamic(&output_list, allocator, 1, sizeof(struct aws_byte_buf))); - ASSERT_SUCCESS(aws_read_and_decode_pem_file_to_buffer_list(allocator, "unittests.key", &output_list)); - ASSERT_UINT_EQUALS(1, aws_array_list_length(&output_list)); - - struct aws_byte_buf *cert_data = NULL; - aws_array_list_get_at_ptr(&output_list, (void **)&cert_data, 0); - ASSERT_BIN_ARRAYS_EQUALS(s_expected, sizeof(s_expected), cert_data->buffer, cert_data->len); - - aws_cert_chain_clean_up(&output_list); - aws_array_list_clean_up(&output_list); - - return AWS_OP_SUCCESS; -} - -AWS_TEST_CASE(test_pem_private_key_parse_from_file, s_test_pem_private_key_parse_from_file) - static int s_test_pem_cert_chain_comments_and_whitespace(struct aws_allocator *allocator, void *ctx) { (void)ctx; @@ -806,26 +942,29 @@ static int s_test_pem_cert_chain_comments_and_whitespace(struct aws_allocator *a struct aws_byte_cursor pem_data = aws_byte_cursor_from_c_str(s_pem_data_str); struct aws_array_list output_list; - ASSERT_SUCCESS(aws_array_list_init_dynamic(&output_list, allocator, 1, sizeof(struct aws_byte_buf))); - ASSERT_SUCCESS(aws_decode_pem_to_buffer_list(allocator, &pem_data, &output_list)); + ASSERT_SUCCESS(aws_pem_objects_init_from_file_contents(&output_list, allocator, pem_data)); ASSERT_UINT_EQUALS(3, aws_array_list_length(&output_list)); - struct aws_byte_buf *cert_data = NULL; - aws_array_list_get_at_ptr(&output_list, (void **)&cert_data, 0); + struct aws_pem_object *pem_object = NULL; + aws_array_list_get_at_ptr(&output_list, (void **)&pem_object, 0); ASSERT_BIN_ARRAYS_EQUALS( - s_expected_intermediate_1, sizeof(s_expected_intermediate_1), cert_data->buffer, cert_data->len); - aws_array_list_get_at_ptr(&output_list, (void **)&cert_data, 1); + s_expected_intermediate_1, sizeof(s_expected_intermediate_1), pem_object->data.buffer, pem_object->data.len); + ASSERT_CURSOR_VALUE_CSTRING_EQUALS(aws_byte_cursor_from_string(pem_object->type_string), "CERTIFICATE"); + ASSERT_INT_EQUALS(AWS_PEM_TYPE_X509, pem_object->type); + aws_array_list_get_at_ptr(&output_list, (void **)&pem_object, 1); ASSERT_BIN_ARRAYS_EQUALS( - s_expected_intermediate_2, sizeof(s_expected_intermediate_2), cert_data->buffer, cert_data->len); - aws_array_list_get_at_ptr(&output_list, (void **)&cert_data, 2); - ASSERT_BIN_ARRAYS_EQUALS(s_expected_leaf, sizeof(s_expected_leaf), cert_data->buffer, cert_data->len); + s_expected_intermediate_2, sizeof(s_expected_intermediate_2), pem_object->data.buffer, pem_object->data.len); + ASSERT_CURSOR_VALUE_CSTRING_EQUALS(aws_byte_cursor_from_string(pem_object->type_string), "CERTIFICATE"); + ASSERT_INT_EQUALS(AWS_PEM_TYPE_X509, pem_object->type); + aws_array_list_get_at_ptr(&output_list, (void **)&pem_object, 2); + ASSERT_BIN_ARRAYS_EQUALS(s_expected_leaf, sizeof(s_expected_leaf), pem_object->data.buffer, pem_object->data.len); + ASSERT_CURSOR_VALUE_CSTRING_EQUALS(aws_byte_cursor_from_string(pem_object->type_string), "CERTIFICATE"); + ASSERT_INT_EQUALS(AWS_PEM_TYPE_X509, pem_object->type); - aws_cert_chain_clean_up(&output_list); - aws_array_list_clean_up(&output_list); + aws_pem_objects_clean_up(&output_list); return AWS_OP_SUCCESS; } - AWS_TEST_CASE(test_pem_cert_chain_comments_and_whitespace, s_test_pem_cert_chain_comments_and_whitespace) static int s_test_pem_invalid_parse(struct aws_allocator *allocator, void *ctx) { @@ -851,15 +990,13 @@ static int s_test_pem_invalid_parse(struct aws_allocator *allocator, void *ctx) struct aws_byte_cursor pem_data = aws_byte_cursor_from_c_str(s_invalid_pem); struct aws_array_list output_list; - ASSERT_SUCCESS(aws_array_list_init_dynamic(&output_list, allocator, 1, sizeof(struct aws_byte_buf))); - ASSERT_ERROR(AWS_IO_FILE_VALIDATION_FAILURE, aws_decode_pem_to_buffer_list(allocator, &pem_data, &output_list)); + ASSERT_ERROR(AWS_ERROR_PEM_MALFORMED, aws_pem_objects_init_from_file_contents(&output_list, allocator, pem_data)); ASSERT_UINT_EQUALS(0, aws_array_list_length(&output_list)); aws_array_list_clean_up(&output_list); return AWS_OP_SUCCESS; } - AWS_TEST_CASE(test_pem_invalid_parse, s_test_pem_invalid_parse) static int s_test_pem_valid_data_invalid_parse(struct aws_allocator *allocator, void *ctx) { @@ -885,15 +1022,13 @@ static int s_test_pem_valid_data_invalid_parse(struct aws_allocator *allocator, struct aws_byte_cursor pem_data = aws_byte_cursor_from_c_str(s_invalid_data); struct aws_array_list output_list; - ASSERT_SUCCESS(aws_array_list_init_dynamic(&output_list, allocator, 1, sizeof(struct aws_byte_buf))); - ASSERT_ERROR(AWS_IO_FILE_VALIDATION_FAILURE, aws_decode_pem_to_buffer_list(allocator, &pem_data, &output_list)); + ASSERT_ERROR(AWS_ERROR_PEM_MALFORMED, aws_pem_objects_init_from_file_contents(&output_list, allocator, pem_data)); ASSERT_UINT_EQUALS(0, aws_array_list_length(&output_list)); aws_array_list_clean_up(&output_list); return AWS_OP_SUCCESS; } - AWS_TEST_CASE(test_pem_valid_data_invalid_parse, s_test_pem_valid_data_invalid_parse) static int s_test_pem_invalid_in_chain_parse(struct aws_allocator *allocator, void *ctx) { @@ -958,8 +1093,7 @@ static int s_test_pem_invalid_in_chain_parse(struct aws_allocator *allocator, vo struct aws_byte_cursor pem_data = aws_byte_cursor_from_c_str(s_invalid_data); struct aws_array_list output_list; - ASSERT_SUCCESS(aws_array_list_init_dynamic(&output_list, allocator, 1, sizeof(struct aws_byte_buf))); - ASSERT_ERROR(AWS_IO_FILE_VALIDATION_FAILURE, aws_decode_pem_to_buffer_list(allocator, &pem_data, &output_list)); + ASSERT_ERROR(AWS_ERROR_PEM_MALFORMED, aws_pem_objects_init_from_file_contents(&output_list, allocator, pem_data)); ASSERT_UINT_EQUALS(0, aws_array_list_length(&output_list)); aws_array_list_clean_up(&output_list); diff --git a/tests/pem_utils_test.c b/tests/pem_utils_test.c deleted file mode 100644 index 4e19aec66..000000000 --- a/tests/pem_utils_test.c +++ /dev/null @@ -1,145 +0,0 @@ -/** - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0. - */ -#include -#include - -#include - -static int s_check_clean_pem_result( - struct aws_byte_cursor dirty_pem, - struct aws_byte_cursor expected_clean_pem, - struct aws_allocator *allocator) { - struct aws_byte_buf pem_buf; - ASSERT_SUCCESS(aws_byte_buf_init_copy_from_cursor(&pem_buf, allocator, dirty_pem)); - ASSERT_SUCCESS(aws_sanitize_pem(&pem_buf, allocator)); - ASSERT_TRUE(aws_byte_cursor_eq_byte_buf(&expected_clean_pem, &pem_buf)); - aws_byte_buf_clean_up(&pem_buf); - return AWS_OP_SUCCESS; -} - -static int s_test_pem_sanitize_comments_around_pem_object_removed(struct aws_allocator *allocator, void *ctx) { - (void)ctx; - /* comments around pem object will be removed */ - struct aws_byte_cursor dirty_pem = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("# comments\r\n" - "-----BEGIN CERTIFICATE-----\n" - "CERTIFICATES\n" - "-----END CERTIFICATE-----\n" - "# another comments\r\n" - "-----BEGIN CERTIFICATE-----\n" - "CERTIFICATES\n" - "-----END CERTIFICATE-----\n" - "# final comments\r\n"); - - struct aws_byte_cursor expected_clean_pem = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("-----BEGIN CERTIFICATE-----\n" - "CERTIFICATES\n" - "-----END CERTIFICATE-----\n" - "-----BEGIN CERTIFICATE-----\n" - "CERTIFICATES\n" - "-----END CERTIFICATE-----\n"); - - return s_check_clean_pem_result(dirty_pem, expected_clean_pem, allocator); -} - -AWS_TEST_CASE(pem_sanitize_comments_around_pem_object_removed, s_test_pem_sanitize_comments_around_pem_object_removed); - -static int s_test_pem_sanitize_empty_file_rejected(struct aws_allocator *allocator, void *ctx) { - (void)ctx; - /* We don't allow empty files. */ - struct aws_byte_buf pem; - ASSERT_SUCCESS(aws_byte_buf_init(&pem, allocator, 512)); - - ASSERT_ERROR(AWS_ERROR_INVALID_ARGUMENT, aws_sanitize_pem(&pem, allocator)); - - aws_byte_buf_clean_up(&pem); - return AWS_OP_SUCCESS; -} - -AWS_TEST_CASE(pem_sanitize_empty_file_rejected, s_test_pem_sanitize_empty_file_rejected) - -AWS_TEST_CASE(pem_sanitize_wrong_format_rejected, s_test_pem_sanitize_wrong_format_rejected) -static int s_test_pem_sanitize_wrong_format_rejected(struct aws_allocator *allocator, void *ctx) { - (void)ctx; - /* A file with the wrong format will "sanitize" to an empty PEM file, which we do not accept */ - - /* This is not a PEM file, it's a DER encoded binary x.509 certificate */ - const uint8_t not_a_pem_src[] = { - 0x30, 0x82, 0x04, 0xD3, 0x30, 0x82, 0x03, 0xBB, 0xA0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x18, 0xDA, 0xD1, - 0x9E, 0x26, 0x7D, 0xE8, 0xBB, 0x4A, 0x21, 0x58, 0xCD, 0xCC, 0x6B, 0x3B, 0x4A, 0x30, 0x0D, 0x06, 0x09, 0x2A, - 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x81, 0xCA, 0x31, 0x0B, 0x30, 0x09, 0x06, - 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, - 0x0E, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6E, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x1F, 0x30, - 0x1D, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x16, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x54, - 0x72, 0x75, 0x73, 0x74, 0x20, 0x4E, 0x65, 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x31, 0x3A, 0x30, 0x38, 0x06, 0x03, - 0x55, 0x04, 0x0B, 0x13, 0x31, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x36, 0x20, 0x56, 0x65, 0x72, 0x69, - 0x53, 0x69, 0x67, 0x6E, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x20, 0x2D, 0x20, 0x46, 0x6F, 0x72, 0x20, 0x61, - 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x7A, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65, 0x20, 0x6F, 0x6E, 0x6C, 0x79, - 0x31, 0x45, 0x30, 0x43, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x3C, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, - 0x6E, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x50, 0x75, 0x62, 0x6C, 0x69, 0x63, 0x20, 0x50, - 0x72, 0x69, 0x6D, 0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, - 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2D, 0x20, 0x47, 0x35, 0x30, - 0x1E, 0x17, 0x0D, 0x30, 0x36, 0x31, 0x31, 0x30, 0x38, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5A, 0x17, 0x0D, - 0x33, 0x36, 0x30, 0x37, 0x31, 0x36, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5A, 0x30, 0x81, 0xCA, 0x31, 0x0B, - 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, - 0x04, 0x0A, 0x13, 0x0E, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6E, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, - 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x16, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, - 0x6E, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x4E, 0x65, 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x31, 0x3A, 0x30, - 0x38, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x31, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x36, 0x20, 0x56, - 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6E, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x20, 0x2D, 0x20, 0x46, 0x6F, - 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x7A, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65, 0x20, 0x6F, - 0x6E, 0x6C, 0x79, 0x31, 0x45, 0x30, 0x43, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x3C, 0x56, 0x65, 0x72, 0x69, - 0x53, 0x69, 0x67, 0x6E, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x50, 0x75, 0x62, 0x6C, 0x69, - 0x63, 0x20, 0x50, 0x72, 0x69, 0x6D, 0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, - 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2D, 0x20, - 0x47, 0x35, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, - 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0F, 0x00, 0x30, 0x82, 0x01, 0x0A, 0x02, 0x82, 0x01, 0x01, 0x00, 0xAF, - 0x24, 0x08, 0x08, 0x29, 0x7A, 0x35, 0x9E, 0x60, 0x0C, 0xAA, 0xE7, 0x4B, 0x3B, 0x4E, 0xDC, 0x7C, 0xBC, 0x3C, - 0x45, 0x1C, 0xBB, 0x2B, 0xE0, 0xFE, 0x29, 0x02, 0xF9, 0x57, 0x08, 0xA3, 0x64, 0x85, 0x15, 0x27, 0xF5, 0xF1, - 0xAD, 0xC8, 0x31, 0x89, 0x5D, 0x22, 0xE8, 0x2A, 0xAA, 0xA6, 0x42, 0xB3, 0x8F, 0xF8, 0xB9, 0x55, 0xB7, 0xB1, - 0xB7, 0x4B, 0xB3, 0xFE, 0x8F, 0x7E, 0x07, 0x57, 0xEC, 0xEF, 0x43, 0xDB, 0x66, 0x62, 0x15, 0x61, 0xCF, 0x60, - 0x0D, 0xA4, 0xD8, 0xDE, 0xF8, 0xE0, 0xC3, 0x62, 0x08, 0x3D, 0x54, 0x13, 0xEB, 0x49, 0xCA, 0x59, 0x54, 0x85, - 0x26, 0xE5, 0x2B, 0x8F, 0x1B, 0x9F, 0xEB, 0xF5, 0xA1, 0x91, 0xC2, 0x33, 0x49, 0xD8, 0x43, 0x63, 0x6A, 0x52, - 0x4B, 0xD2, 0x8F, 0xE8, 0x70, 0x51, 0x4D, 0xD1, 0x89, 0x69, 0x7B, 0xC7, 0x70, 0xF6, 0xB3, 0xDC, 0x12, 0x74, - 0xDB, 0x7B, 0x5D, 0x4B, 0x56, 0xD3, 0x96, 0xBF, 0x15, 0x77, 0xA1, 0xB0, 0xF4, 0xA2, 0x25, 0xF2, 0xAF, 0x1C, - 0x92, 0x67, 0x18, 0xE5, 0xF4, 0x06, 0x04, 0xEF, 0x90, 0xB9, 0xE4, 0x00, 0xE4, 0xDD, 0x3A, 0xB5, 0x19, 0xFF, - 0x02, 0xBA, 0xF4, 0x3C, 0xEE, 0xE0, 0x8B, 0xEB, 0x37, 0x8B, 0xEC, 0xF4, 0xD7, 0xAC, 0xF2, 0xF6, 0xF0, 0x3D, - 0xAF, 0xDD, 0x75, 0x91, 0x33, 0x19, 0x1D, 0x1C, 0x40, 0xCB, 0x74, 0x24, 0x19, 0x21, 0x93, 0xD9, 0x14, 0xFE, - 0xAC, 0x2A, 0x52, 0xC7, 0x8F, 0xD5, 0x04, 0x49, 0xE4, 0x8D, 0x63, 0x47, 0x88, 0x3C, 0x69, 0x83, 0xCB, 0xFE, - 0x47, 0xBD, 0x2B, 0x7E, 0x4F, 0xC5, 0x95, 0xAE, 0x0E, 0x9D, 0xD4, 0xD1, 0x43, 0xC0, 0x67, 0x73, 0xE3, 0x14, - 0x08, 0x7E, 0xE5, 0x3F, 0x9F, 0x73, 0xB8, 0x33, 0x0A, 0xCF, 0x5D, 0x3F, 0x34, 0x87, 0x96, 0x8A, 0xEE, 0x53, - 0xE8, 0x25, 0x15, 0x02, 0x03, 0x01, 0x00, 0x01, 0xA3, 0x81, 0xB2, 0x30, 0x81, 0xAF, 0x30, 0x0F, 0x06, 0x03, - 0x55, 0x1D, 0x13, 0x01, 0x01, 0xFF, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xFF, 0x30, 0x0E, 0x06, 0x03, 0x55, - 0x1D, 0x0F, 0x01, 0x01, 0xFF, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x6D, 0x06, 0x08, 0x2B, 0x06, 0x01, - 0x05, 0x05, 0x07, 0x01, 0x0C, 0x04, 0x61, 0x30, 0x5F, 0xA1, 0x5D, 0xA0, 0x5B, 0x30, 0x59, 0x30, 0x57, 0x30, - 0x55, 0x16, 0x09, 0x69, 0x6D, 0x61, 0x67, 0x65, 0x2F, 0x67, 0x69, 0x66, 0x30, 0x21, 0x30, 0x1F, 0x30, 0x07, - 0x06, 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1A, 0x04, 0x14, 0x8F, 0xE5, 0xD3, 0x1A, 0x86, 0xAC, 0x8D, 0x8E, 0x6B, - 0xC3, 0xCF, 0x80, 0x6A, 0xD4, 0x48, 0x18, 0x2C, 0x7B, 0x19, 0x2E, 0x30, 0x25, 0x16, 0x23, 0x68, 0x74, 0x74, - 0x70, 0x3A, 0x2F, 0x2F, 0x6C, 0x6F, 0x67, 0x6F, 0x2E, 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6E, 0x2E, - 0x63, 0x6F, 0x6D, 0x2F, 0x76, 0x73, 0x6C, 0x6F, 0x67, 0x6F, 0x2E, 0x67, 0x69, 0x66, 0x30, 0x1D, 0x06, 0x03, - 0x55, 0x1D, 0x0E, 0x04, 0x16, 0x04, 0x14, 0x7F, 0xD3, 0x65, 0xA7, 0xC2, 0xDD, 0xEC, 0xBB, 0xF0, 0x30, 0x09, - 0xF3, 0x43, 0x39, 0xFA, 0x02, 0xAF, 0x33, 0x31, 0x33, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, - 0x0D, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x93, 0x24, 0x4A, 0x30, 0x5F, 0x62, 0xCF, - 0xD8, 0x1A, 0x98, 0x2F, 0x3D, 0xEA, 0xDC, 0x99, 0x2D, 0xBD, 0x77, 0xF6, 0xA5, 0x79, 0x22, 0x38, 0xEC, 0xC4, - 0xA7, 0xA0, 0x78, 0x12, 0xAD, 0x62, 0x0E, 0x45, 0x70, 0x64, 0xC5, 0xE7, 0x97, 0x66, 0x2D, 0x98, 0x09, 0x7E, - 0x5F, 0xAF, 0xD6, 0xCC, 0x28, 0x65, 0xF2, 0x01, 0xAA, 0x08, 0x1A, 0x47, 0xDE, 0xF9, 0xF9, 0x7C, 0x92, 0x5A, - 0x08, 0x69, 0x20, 0x0D, 0xD9, 0x3E, 0x6D, 0x6E, 0x3C, 0x0D, 0x6E, 0xD8, 0xE6, 0x06, 0x91, 0x40, 0x18, 0xB9, - 0xF8, 0xC1, 0xED, 0xDF, 0xDB, 0x41, 0xAA, 0xE0, 0x96, 0x20, 0xC9, 0xCD, 0x64, 0x15, 0x38, 0x81, 0xC9, 0x94, - 0xEE, 0xA2, 0x84, 0x29, 0x0B, 0x13, 0x6F, 0x8E, 0xDB, 0x0C, 0xDD, 0x25, 0x02, 0xDB, 0xA4, 0x8B, 0x19, 0x44, - 0xD2, 0x41, 0x7A, 0x05, 0x69, 0x4A, 0x58, 0x4F, 0x60, 0xCA, 0x7E, 0x82, 0x6A, 0x0B, 0x02, 0xAA, 0x25, 0x17, - 0x39, 0xB5, 0xDB, 0x7F, 0xE7, 0x84, 0x65, 0x2A, 0x95, 0x8A, 0xBD, 0x86, 0xDE, 0x5E, 0x81, 0x16, 0x83, 0x2D, - 0x10, 0xCC, 0xDE, 0xFD, 0xA8, 0x82, 0x2A, 0x6D, 0x28, 0x1F, 0x0D, 0x0B, 0xC4, 0xE5, 0xE7, 0x1A, 0x26, 0x19, - 0xE1, 0xF4, 0x11, 0x6F, 0x10, 0xB5, 0x95, 0xFC, 0xE7, 0x42, 0x05, 0x32, 0xDB, 0xCE, 0x9D, 0x51, 0x5E, 0x28, - 0xB6, 0x9E, 0x85, 0xD3, 0x5B, 0xEF, 0xA5, 0x7D, 0x45, 0x40, 0x72, 0x8E, 0xB7, 0x0E, 0x6B, 0x0E, 0x06, 0xFB, - 0x33, 0x35, 0x48, 0x71, 0xB8, 0x9D, 0x27, 0x8B, 0xC4, 0x65, 0x5F, 0x0D, 0x86, 0x76, 0x9C, 0x44, 0x7A, 0xF6, - 0x95, 0x5C, 0xF6, 0x5D, 0x32, 0x08, 0x33, 0xA4, 0x54, 0xB6, 0x18, 0x3F, 0x68, 0x5C, 0xF2, 0x42, 0x4A, 0x85, - 0x38, 0x54, 0x83, 0x5F, 0xD1, 0xE8, 0x2C, 0xF2, 0xAC, 0x11, 0xD6, 0xA8, 0xED, 0x63, 0x6A}; - struct aws_byte_cursor not_a_pem_cursor = aws_byte_cursor_from_array(not_a_pem_src, sizeof(not_a_pem_src)); - struct aws_byte_buf not_a_pem; - ASSERT_SUCCESS(aws_byte_buf_init_copy_from_cursor(¬_a_pem, allocator, not_a_pem_cursor)); - - ASSERT_ERROR(AWS_ERROR_INVALID_ARGUMENT, aws_sanitize_pem(¬_a_pem, allocator)); - - aws_byte_buf_clean_up(¬_a_pem); - return AWS_OP_SUCCESS; -}