Skip to content

Commit

Permalink
Allow zero-length input in rnp_input_from_memory() (#2246)
Browse files Browse the repository at this point in the history
* Allow zero-length input in rnp_input_from_memory()

* Split empty buf and null buf checks into separate tests
  • Loading branch information
desvxx authored Sep 16, 2024
1 parent 3d45a6b commit abec6c7
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 3 deletions.
8 changes: 6 additions & 2 deletions src/lib/rnp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2053,11 +2053,15 @@ 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) {
return RNP_ERROR_NULL_POINTER;
}
if (!buf && buf_len) {
return RNP_ERROR_NULL_POINTER;
}
if (!buf_len) {
return RNP_ERROR_SHORT_BUFFER;
// prevent malloc(0)
do_copy = false;
}
*input = new rnp_input_st();
uint8_t *data = (uint8_t *) buf;
Expand Down
76 changes: 75 additions & 1 deletion src/tests/ffi-enc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,8 @@ TEST_F(rnp_tests, test_ffi_encrypt_set_cipher)
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));
assert_rnp_success(rnp_input_from_memory(&input, (const uint8_t *) plaintext, 0, false));
assert_rnp_success(rnp_input_destroy(input));
assert_rnp_success(
rnp_input_from_memory(&input, (const uint8_t *) plaintext, strlen(plaintext), false));
rnp_output_t output = NULL;
Expand Down Expand Up @@ -512,6 +513,79 @@ TEST_F(rnp_tests, test_ffi_encrypt_set_cipher)
rnp_ffi_destroy(ffi);
}

TEST_F(rnp_tests, test_ffi_encrypt_empty_buffer)
{
/* 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 = "";
assert_rnp_success(
rnp_input_from_memory(&input, (const uint8_t *) plaintext, strlen(plaintext), false));
rnp_output_t output = NULL;
assert_rnp_success(rnp_output_to_path(&output, "encrypted"));
/* create encrypt operation */
rnp_op_encrypt_t op = NULL;
assert_rnp_success(rnp_op_encrypt_create(&op, ffi, input, output));
assert_rnp_success(rnp_op_encrypt_add_password(op, "password1", NULL, 0, "AES192"));
/* execute the operation */
assert_rnp_success(rnp_op_encrypt_execute(op));
assert_true(rnp_file_exists("encrypted"));
/* cleanup */
assert_rnp_success(rnp_input_destroy(input));
assert_rnp_success(rnp_output_destroy(output));
assert_rnp_success(rnp_op_encrypt_destroy(op));
/* decrypt with password1 */
assert_rnp_success(rnp_input_from_path(&input, "encrypted"));
assert_rnp_success(rnp_output_to_path(&output, "decrypted"));
assert_rnp_success(
rnp_ffi_set_pass_provider(ffi, ffi_string_password_provider, (void *) "password1"));
rnp_input_destroy(input);
rnp_output_destroy(output);
assert_string_equal(file_to_str("decrypted").c_str(), plaintext);
unlink("decrypted");
unlink("encrypted");

rnp_ffi_destroy(ffi);
}

TEST_F(rnp_tests, test_ffi_encrypt_null_buffer)
{
/* setup FFI */
rnp_ffi_t ffi = NULL;
assert_rnp_success(rnp_ffi_create(&ffi, "GPG", "GPG"));
/* create input + output */
rnp_input_t input = NULL;
assert_rnp_failure(rnp_input_from_memory(&input, NULL, 10 /*not zero value*/, false));
assert_rnp_success(rnp_input_from_memory(&input, NULL, 0, false));
rnp_output_t output = NULL;
assert_rnp_success(rnp_output_to_path(&output, "encrypted"));
/* create encrypt operation */
rnp_op_encrypt_t op = NULL;
assert_rnp_success(rnp_op_encrypt_create(&op, ffi, input, output));
assert_rnp_success(rnp_op_encrypt_add_password(op, "password1", NULL, 0, "AES192"));
/* execute the operation */
assert_rnp_success(rnp_op_encrypt_execute(op));
assert_true(rnp_file_exists("encrypted"));
/* cleanup */
assert_rnp_success(rnp_input_destroy(input));
assert_rnp_success(rnp_output_destroy(output));
assert_rnp_success(rnp_op_encrypt_destroy(op));
/* decrypt with password1 */
assert_rnp_success(rnp_input_from_path(&input, "encrypted"));
assert_rnp_success(rnp_output_to_path(&output, "decrypted"));
assert_rnp_success(
rnp_ffi_set_pass_provider(ffi, ffi_string_password_provider, (void *) "password1"));
rnp_input_destroy(input);
rnp_output_destroy(output);
assert_string_equal(file_to_str("decrypted").c_str(), "");
unlink("decrypted");
unlink("encrypted");

rnp_ffi_destroy(ffi);
}

TEST_F(rnp_tests, test_ffi_encrypt_pk)
{
rnp_ffi_t ffi = NULL;
Expand Down

0 comments on commit abec6c7

Please sign in to comment.