diff --git a/src/lib/rnp.cpp b/src/lib/rnp.cpp index 7b7b96183b..d90c32083a 100644 --- a/src/lib/rnp.cpp +++ b/src/lib/rnp.cpp @@ -2096,11 +2096,12 @@ FFI_GUARD rnp_result_t rnp_input_from_memory(rnp_input_t *input, const uint8_t buf[], size_t buf_len, bool do_copy) try { - if (!input || !buf) { + if (!input || (!buf && buf_len > 0)) { return RNP_ERROR_NULL_POINTER; } - if (!buf_len) { - return RNP_ERROR_SHORT_BUFFER; + if (buf_len == 0) { + // prevent malloc(0) + do_copy = false; } *input = new rnp_input_st(); uint8_t *data = (uint8_t *) buf; diff --git a/src/tests/ffi-enc.cpp b/src/tests/ffi-enc.cpp index 0ee1b28517..fa16c860f8 100644 --- a/src/tests/ffi-enc.cpp +++ b/src/tests/ffi-enc.cpp @@ -370,20 +370,29 @@ TEST_F(rnp_tests, test_ffi_encrypt_pass_provider) rnp_ffi_destroy(ffi); } -TEST_F(rnp_tests, test_ffi_encrypt_set_cipher) +class ffi_encrypt_tests : public rnp_tests, public testing::WithParamInterface { +}; + +TEST_P(ffi_encrypt_tests, test_ffi_encrypt_set_cipher) { /* setup FFI */ rnp_ffi_t ffi = NULL; assert_rnp_success(rnp_ffi_create(&ffi, "GPG", "GPG")); /* create input + output */ - rnp_input_t input = NULL; - const char *plaintext = "Data encrypted with password using different CEK/KEK."; + rnp_input_t input = NULL; + const char * plaintext = GetParam(); + const size_t plaintext_size = plaintext ? strlen(plaintext) : 0; + const char * decrypted = + plaintext ? plaintext : ""; // NULL input gives us "" when decrypted assert_rnp_failure( - rnp_input_from_memory(NULL, (const uint8_t *) plaintext, strlen(plaintext), false)); - assert_rnp_failure(rnp_input_from_memory(&input, NULL, strlen(plaintext), false)); - assert_rnp_failure(rnp_input_from_memory(&input, (const uint8_t *) plaintext, 0, false)); + rnp_input_from_memory(NULL, (const uint8_t *) plaintext, plaintext_size, false)); + if (plaintext == NULL) { // Corner case + assert_rnp_failure(rnp_input_from_memory(&input, NULL, 5, false)); + } + assert_rnp_success(rnp_input_from_memory(&input, (const uint8_t *) plaintext, 0, false)); + assert_rnp_success(rnp_input_from_memory(&input, (const uint8_t *) plaintext, 0, true)); assert_rnp_success( - rnp_input_from_memory(&input, (const uint8_t *) plaintext, strlen(plaintext), false)); + rnp_input_from_memory(&input, (const uint8_t *) plaintext, plaintext_size, false)); rnp_output_t output = NULL; assert_rnp_success(rnp_output_to_path(&output, "encrypted")); /* create encrypt operation */ @@ -414,7 +423,7 @@ TEST_F(rnp_tests, test_ffi_encrypt_set_cipher) assert_rnp_success(rnp_op_verify_execute(verify)); rnp_input_destroy(input); rnp_output_destroy(output); - assert_string_equal(file_to_str("decrypted").c_str(), plaintext); + assert_string_equal(file_to_str("decrypted").c_str(), decrypted); /* Check protection info */ char *mode = NULL; char *cipher = NULL; @@ -453,7 +462,7 @@ TEST_F(rnp_tests, test_ffi_encrypt_set_cipher) /* Now use AEAD */ assert_rnp_success( - rnp_input_from_memory(&input, (const uint8_t *) plaintext, strlen(plaintext), false)); + rnp_input_from_memory(&input, (const uint8_t *) plaintext, plaintext_size, false)); assert_rnp_success(rnp_output_to_path(&output, "encrypted-aead")); /* create encrypt operation */ assert_rnp_success(rnp_op_encrypt_create(&op, ffi, input, output)); @@ -478,7 +487,7 @@ TEST_F(rnp_tests, test_ffi_encrypt_set_cipher) assert_rnp_success(rnp_op_verify_execute(verify)); rnp_input_destroy(input); rnp_output_destroy(output); - assert_string_equal(file_to_str("decrypted").c_str(), plaintext); + assert_string_equal(file_to_str("decrypted").c_str(), decrypted); /* Check protection info */ assert_rnp_success(rnp_op_verify_get_protection_info(verify, &mode, &cipher, &valid)); assert_string_equal(mode, "aead-ocb"); @@ -512,6 +521,13 @@ TEST_F(rnp_tests, test_ffi_encrypt_set_cipher) rnp_ffi_destroy(ffi); } +static const char *test_text_1 = "Data encrypted with password using different CEK/KEK."; +static const char *test_text_2 = ""; +INSTANTIATE_TEST_SUITE_P( + tsetsstr, + ffi_encrypt_tests, + testing::Values(test_text_1, test_text_2, nullptr)); + TEST_F(rnp_tests, test_ffi_encrypt_pk) { rnp_ffi_t ffi = NULL;