diff --git a/source/windows/windows_pki_utils.c b/source/windows/windows_pki_utils.c index e1c47d548..716fed016 100644 --- a/source/windows/windows_pki_utils.c +++ b/source/windows/windows_pki_utils.c @@ -558,7 +558,6 @@ int aws_import_key_pair_to_cert_context( *private_key_handle = 0; int result = AWS_OP_ERR; - BYTE *key = NULL; if (aws_pem_objects_init_from_file_contents(&certificates, alloc, *public_cert_chain)) { AWS_LOGF_ERROR( @@ -639,7 +638,10 @@ int aws_import_key_pair_to_cert_context( } struct aws_pem_object *private_key_ptr = NULL; + BYTE *key = NULL; DWORD decoded_len = 0; + BYTE *key_wrapper = NULL; + DWORD decoded_wrapper_len = 0; enum aws_certificate_type cert_type = AWS_CT_X509_UNKNOWN; size_t private_key_count = aws_array_list_length(&private_keys); for (size_t i = 0; i < private_key_count; ++i) { @@ -655,6 +657,28 @@ int aws_import_key_pair_to_cert_context( &key, &decoded_len)) { cert_type = AWS_CT_X509_RSA; + } else if (CryptDecodeObjectEx( + X509_ASN_ENCODING, + PKCS_PRIVATE_KEY_INFO, + private_key_ptr->data.buffer, + (DWORD)private_key_ptr->data.len, + CRYPT_DECODE_ALLOC_FLAG, + 0, + &key_wrapper, + &decoded_wrapper_len)) { + CRYPT_PRIVATE_KEY_INFO *pPrivateKeyInfoStruct = (CRYPT_PRIVATE_KEY_INFO *)key_wrapper; + if (CryptDecodeObjectEx( + X509_ASN_ENCODING, + PKCS_RSA_PRIVATE_KEY, + pPrivateKeyInfoStruct->PrivateKey.pbData, + pPrivateKeyInfoStruct->PrivateKey.cbData, + CRYPT_DECODE_ALLOC_FLAG, + 0, + &key, + &decoded_len)) { + cert_type = AWS_CT_X509_RSA; + } + LocalFree(key_wrapper); } #ifndef AWS_SUPPORT_WIN7 else if (CryptDecodeObjectEx( diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index d6ab13f4b..8a5362c41 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -246,6 +246,7 @@ if(NOT BYO_CRYPTO) add_net_test_case(alpn_successfully_negotiates) add_net_test_case(alpn_no_protocol_message) add_net_test_case(test_ecc_cert_import) + add_net_test_case(test_pkcs8_import) add_test_case(alpn_error_creating_handler) add_test_case(tls_destroy_null_context) diff --git a/tests/tls_handler_test.c b/tests/tls_handler_test.c index 0b0f5c88c..a55d26077 100644 --- a/tests/tls_handler_test.c +++ b/tests/tls_handler_test.c @@ -2503,4 +2503,40 @@ static int s_test_ecc_cert_import(struct aws_allocator *allocator, void *ctx) { AWS_TEST_CASE(test_ecc_cert_import, s_test_ecc_cert_import) +static int s_test_pkcs8_import(struct aws_allocator *allocator, void *ctx) { + (void)ctx; + (void)allocator; + + aws_io_library_init(allocator); + + struct aws_byte_buf cert_buf; + struct aws_byte_buf key_buf; + + ASSERT_SUCCESS(aws_byte_buf_init_from_file(&cert_buf, allocator, "unittests.crt")); + ASSERT_SUCCESS(aws_byte_buf_init_from_file(&key_buf, allocator, "unittests.p8")); + + struct aws_byte_cursor cert_cur = aws_byte_cursor_from_buf(&cert_buf); + struct aws_byte_cursor key_cur = aws_byte_cursor_from_buf(&key_buf); + struct aws_tls_ctx_options tls_options = {0}; + AWS_FATAL_ASSERT( + AWS_OP_SUCCESS == aws_tls_ctx_options_init_client_mtls(&tls_options, allocator, &cert_cur, &key_cur)); + + /* import happens in here */ + struct aws_tls_ctx *tls_context = aws_tls_client_ctx_new(allocator, &tls_options); + ASSERT_NOT_NULL(tls_context); + + aws_tls_ctx_release(tls_context); + + aws_tls_ctx_options_clean_up(&tls_options); + + aws_byte_buf_clean_up(&cert_buf); + aws_byte_buf_clean_up(&key_buf); + + aws_io_library_clean_up(); + + return AWS_OP_SUCCESS; +} + +AWS_TEST_CASE(test_pkcs8_import, s_test_pkcs8_import) + #endif /* BYO_CRYPTO */