Skip to content

Commit

Permalink
more consistent signature mismatch error on mac (#167)
Browse files Browse the repository at this point in the history
  • Loading branch information
DmitriyMusatkin committed Oct 13, 2023
1 parent b0219ca commit 49e2e25
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 1 deletion.
27 changes: 26 additions & 1 deletion source/darwin/securityframework_rsa.c
Expand Up @@ -56,9 +56,34 @@ static int s_reinterpret_sec_error_as_crt(CFErrorRef error, const char *function
CFIndex error_code = CFErrorGetCode(error);
CFStringRef error_message = CFErrorCopyDescription(error); /* This function never returns NULL */

const char *error_cstr = CFStringGetCStringPtr(error_message, kCFStringEncodingASCII);
/*
* Note: CFStringGetCStringPtr returns NULL quite often.
* Refer to writeup at the start of CFString.h as to why.
* To reliably get an error message we need to use the following function
* that will copy error string into our buffer.
*/
const char *error_cstr = NULL;
char buffer[128];
if (CFStringGetCString(error_message, buffer, 128, kCFStringEncodingUTF8)) {
error_cstr = buffer;
}

int crt_error = AWS_ERROR_CAL_CRYPTO_OPERATION_FAILED;

/*
* Mac seems throws errSecVerifyFailed for any signature verification
* failures (based on testing and not review of their code).
* Which makes it impossible to distinguish between signature validation
* failure and api call failure.
* So let errSecVerifyFailed as signature validation failure, rather than a
* more generic Crypto Failure as it seems more intuitive to caller that
* signature cannot be verified, rather than something wrong with crypto (and
* in most cases crypto is working correctly, but returning non-specific error).
*/
if (error_code == errSecVerifyFailed) {
crt_error = AWS_ERROR_CAL_SIGNATURE_VALIDATION_FAILED;
}

AWS_LOGF_ERROR(
AWS_LS_CAL_RSA,
"%s() failed. CFError:%ld(%s) aws_error:%s",
Expand Down
1 change: 1 addition & 0 deletions tests/CMakeLists.txt
Expand Up @@ -85,6 +85,7 @@ add_test_case(rsa_verify_signing_pss_sha256)
add_test_case(rsa_decrypt_pkcs1)
add_test_case(rsa_decrypt_oaep256)
add_test_case(rsa_decrypt_oaep512)
add_test_case(rsa_signing_mismatch_pkcs1_sha256)

add_test_case(aes_cbc_NIST_CBCGFSbox256_case_1)
add_test_case(aes_cbc_NIST_CBCVarKey256_case_254)
Expand Down
50 changes: 50 additions & 0 deletions tests/rsa_test.c
Expand Up @@ -689,3 +689,53 @@ static int s_rsa_public_pkcs1_der_parsing(struct aws_allocator *allocator, void
return AWS_OP_SUCCESS;
}
AWS_TEST_CASE(rsa_public_pkcs1_der_parsing, s_rsa_public_pkcs1_der_parsing);

static int s_rsa_signing_mismatch_pkcs1_sha256(struct aws_allocator *allocator, void *ctx) {
(void)ctx;
struct aws_byte_cursor message = aws_byte_cursor_from_c_str(TEST_ENCRYPTION_STRING);

aws_cal_library_init(allocator);

struct aws_byte_buf public_key_buf;
ASSERT_SUCCESS(s_byte_buf_decoded_from_base64_cur(
allocator, aws_byte_cursor_from_c_str(TEST_PKCS1_RSA_PRIVATE_KEY_1024), &public_key_buf));
struct aws_rsa_key_pair *key_pair_private =
aws_rsa_key_pair_new_from_private_key_pkcs1(allocator, aws_byte_cursor_from_buf(&public_key_buf));
ASSERT_NOT_NULL(key_pair_private);

uint8_t hash[AWS_SHA256_LEN];
AWS_ZERO_ARRAY(hash);
struct aws_byte_buf hash_value = aws_byte_buf_from_empty_array(hash, sizeof(hash));
aws_sha256_compute(allocator, &message, &hash_value, 0);
struct aws_byte_cursor hash_cur = aws_byte_cursor_from_buf(&hash_value);

struct aws_byte_buf signature_buf;
ASSERT_SUCCESS(aws_byte_buf_init(&signature_buf, allocator, aws_rsa_key_pair_signature_length(key_pair_private)));
ASSERT_SUCCESS(aws_rsa_key_pair_sign_message(
key_pair_private, AWS_CAL_RSA_SIGNATURE_PKCS1_5_SHA256, hash_cur, &signature_buf));
struct aws_byte_cursor signature_cur = aws_byte_cursor_from_buf(&signature_buf);

hash[5] += 59; /* modify digest to force signature mismatch */

ASSERT_ERROR(
AWS_ERROR_CAL_SIGNATURE_VALIDATION_FAILED,
aws_rsa_key_pair_verify_signature(
key_pair_private, AWS_CAL_RSA_SIGNATURE_PKCS1_5_SHA256, hash_cur, signature_cur));

hash[5] -= 59; /* undo digest modification and corrupt signature */
signature_buf.buffer[5] += 59;
ASSERT_ERROR(
AWS_ERROR_CAL_SIGNATURE_VALIDATION_FAILED,
aws_rsa_key_pair_verify_signature(
key_pair_private, AWS_CAL_RSA_SIGNATURE_PKCS1_5_SHA256, hash_cur, signature_cur));

aws_byte_buf_clean_up(&hash_value);
aws_byte_buf_clean_up(&signature_buf);
aws_byte_buf_clean_up(&public_key_buf);
aws_rsa_key_pair_release(key_pair_private);

aws_cal_library_clean_up();

return AWS_OP_SUCCESS;
}
AWS_TEST_CASE(rsa_signing_mismatch_pkcs1_sha256, s_rsa_signing_mismatch_pkcs1_sha256);

0 comments on commit 49e2e25

Please sign in to comment.