Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for mimemode in literal data packet. #2203

Merged
merged 2 commits into from
Mar 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions include/rnp/rnp.h
Original file line number Diff line number Diff line change
Expand Up @@ -2707,6 +2707,17 @@ RNP_API rnp_result_t rnp_op_verify_get_file_info(rnp_op_verify_t op,
char ** filename,
uint32_t * mtime);

/**
* @brief Get format of the data stored in the message, if available.
*
* @param op opaque verification context. Must be initialized and have execute() called on it.
* @param format character describing format would be stored here, see RFC 4880 section 5.9 and
* further standard extensions for possible values. If information is not
* available then '\0' value will be stored here. Cannot be NULL.
* @return RNP_SUCCESS if call succeeded.
*/
RNP_API rnp_result_t rnp_op_verify_get_format(rnp_op_verify_t op, char *format);

/**
* @brief Get data protection (encryption) mode, used in processed message.
*
Expand Down
3 changes: 1 addition & 2 deletions src/lib/ffi-priv-types.h
Original file line number Diff line number Diff line change
Expand Up @@ -187,8 +187,7 @@ struct rnp_op_verify_st {
rnp_ctx_t rnpctx{};
/* these fields are filled after operation execution */
std::vector<rnp_op_verify_signature_st> signatures_;
std::string filename;
uint32_t file_mtime{};
pgp_literal_hdr_t lithdr{};
/* encryption information */
bool encrypted{};
bool mdc{};
Expand Down
31 changes: 22 additions & 9 deletions src/lib/rnp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3110,20 +3110,18 @@ rnp_verify_src_provider(pgp_parse_handler_t *handler, pgp_source_t *src)
};

static bool
rnp_verify_dest_provider(pgp_parse_handler_t *handler,
pgp_dest_t ** dst,
bool * closedst,
const char * filename,
uint32_t mtime)
rnp_verify_dest_provider(pgp_parse_handler_t * handler,
pgp_dest_t ** dst,
bool * closedst,
const pgp_literal_hdr_t *lithdr)
{
rnp_op_verify_t op = (rnp_op_verify_t) handler->param;
if (!op->output) {
return false;
}
*dst = &(op->output->dst);
*closedst = false;
op->filename = filename ? std::string(filename) : "";
op->file_mtime = mtime;
op->lithdr = lithdr ? *lithdr : pgp_literal_hdr_t();
return true;
}

Expand Down Expand Up @@ -3396,9 +3394,24 @@ try {
return RNP_ERROR_NULL_POINTER;
}
if (mtime) {
*mtime = op->file_mtime;
*mtime = op->lithdr.timestamp;
}
return filename ? ret_str_value(op->filename.c_str(), filename) : RNP_SUCCESS;
if (!filename) {
return RNP_SUCCESS;
}
const std::string fname(op->lithdr.fname, op->lithdr.fname_len);
return ret_str_value(fname.c_str(), filename);
}
FFI_GUARD

rnp_result_t
rnp_op_verify_get_format(rnp_op_verify_t op, char *format)
try {
if (!op || !format) {
return RNP_ERROR_NULL_POINTER;
}
*format = (char) op->lithdr.format;
return RNP_SUCCESS;
}
FFI_GUARD

Expand Down
8 changes: 4 additions & 4 deletions src/lib/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -365,10 +365,10 @@ typedef enum {
} pgp_key_server_prefs_t;

typedef struct pgp_literal_hdr_t {
uint8_t format;
char fname[256];
uint8_t fname_len;
uint32_t timestamp;
uint8_t format{};
char fname[256]{};
uint8_t fname_len{};
uint32_t timestamp{};
} pgp_literal_hdr_t;

typedef struct pgp_aead_hdr_t {
Expand Down
17 changes: 7 additions & 10 deletions src/librepgp/stream-parse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1968,11 +1968,11 @@ init_literal_src(pgp_source_t *src, pgp_source_t *readsrc)
case 'u':
case 'l':
case '1':
case 'm':
break;
default:
RNP_LOG("unknown data format %" PRIu8, format);
ret = RNP_ERROR_BAD_FORMAT;
goto finish;
RNP_LOG("Warning: unknown data format %" PRIu8 ", ignoring.", format);
break;
}
param->hdr.format = format;
/* file name */
Expand Down Expand Up @@ -2913,20 +2913,17 @@ process_pgp_source(pgp_parse_handler_t *handler, pgp_source_t &src)
}
/* file processing case */
decsrc = &ctx.sources.back();
const char *filename = NULL;
uint32_t mtime = 0;
const pgp_literal_hdr_t *lithdr = nullptr;

if (ctx.literal_src) {
auto &hdr = get_literal_src_hdr(*ctx.literal_src);
filename = hdr.fname;
mtime = hdr.timestamp;
lithdr = &get_literal_src_hdr(*ctx.literal_src);
if (ctx.signed_src) {
signed_src_set_literal_hdr(*ctx.signed_src, hdr);
signed_src_set_literal_hdr(*ctx.signed_src, *lithdr);
}
}

if (!handler->dest_provider ||
!handler->dest_provider(handler, &outdest, &closeout, filename, mtime)) {
!handler->dest_provider(handler, &outdest, &closeout, lithdr)) {
res = RNP_ERROR_WRITE;
goto finish;
}
Expand Down
9 changes: 4 additions & 5 deletions src/librepgp/stream-parse.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,10 @@

typedef struct pgp_parse_handler_t pgp_parse_handler_t;
typedef struct pgp_signature_info_t pgp_signature_info_t;
typedef bool pgp_destination_func_t(pgp_parse_handler_t *handler,
pgp_dest_t ** dst,
bool * closedst,
const char * filename,
uint32_t mtime);
typedef bool pgp_destination_func_t(pgp_parse_handler_t * handler,
pgp_dest_t ** dst,
bool * closedst,
const pgp_literal_hdr_t *lithdr);
typedef bool pgp_source_func_t(pgp_parse_handler_t *handler, pgp_source_t *src);
typedef void pgp_signatures_func_t(const std::vector<pgp_signature_info_t> &sigs, void *param);

Expand Down
Binary file not shown.
29 changes: 29 additions & 0 deletions src/tests/ffi-enc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1519,3 +1519,32 @@ TEST_F(rnp_tests, test_ffi_v5_signatures)

rnp_ffi_destroy(ffi);
}

TEST_F(rnp_tests, test_ffi_mimemode_signature)
{
rnp_ffi_t ffi = NULL;
assert_rnp_success(rnp_ffi_create(&ffi, "GPG", "GPG"));
assert_true(import_pub_keys(ffi, "data/test_stream_key_load/ecc-25519-pub.asc"));

rnp_input_t input = NULL;
assert_rnp_success(
rnp_input_from_path(&input, "data/test_messages/message.txt.signed-mimemode"));
rnp_output_t output = NULL;
assert_rnp_success(rnp_output_to_null(&output));
rnp_op_verify_t verify = NULL;
assert_rnp_success(rnp_op_verify_create(&verify, ffi, input, output));
assert_rnp_success(rnp_op_verify_execute(verify));
size_t sigcount = 255;
assert_rnp_success(rnp_op_verify_get_signature_count(verify, &sigcount));
assert_int_equal(sigcount, 1);
rnp_op_verify_signature_t sig = NULL;
assert_rnp_success(rnp_op_verify_get_signature_at(verify, 0, &sig));
assert_rnp_success(rnp_op_verify_signature_get_status(sig));
char format = 0;
assert_rnp_success(rnp_op_verify_get_format(verify, &format));
assert_int_equal(format, 'm');
rnp_op_verify_destroy(verify);
rnp_input_destroy(input);
rnp_output_destroy(output);
rnp_ffi_destroy(ffi);
}
10 changes: 10 additions & 0 deletions src/tests/ffi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3833,6 +3833,11 @@ TEST_F(rnp_tests, test_ffi_op_verify_sig_count)
assert_rnp_success(rnp_op_verify_get_signature_count(verify, &sigcount));
assert_int_equal(sigcount, 1);
assert_true(check_signature(verify, 0, RNP_SUCCESS));
char format = 'b';
assert_rnp_failure(rnp_op_verify_get_format(NULL, &format));
assert_rnp_failure(rnp_op_verify_get_format(verify, NULL));
assert_rnp_success(rnp_op_verify_get_format(verify, &format));
assert_int_equal(format, '\0');
rnp_op_verify_destroy(verify);
rnp_input_destroy(source);
rnp_input_destroy(input);
Expand Down Expand Up @@ -3879,6 +3884,11 @@ TEST_F(rnp_tests, test_ffi_op_verify_sig_count)
assert_rnp_success(rnp_op_verify_get_signature_count(verify, &sigcount));
assert_int_equal(sigcount, 1);
assert_true(check_signature(verify, 0, RNP_SUCCESS));
format = '\0';
assert_rnp_failure(rnp_op_verify_get_format(NULL, &format));
assert_rnp_failure(rnp_op_verify_get_format(verify, NULL));
assert_rnp_success(rnp_op_verify_get_format(verify, &format));
assert_int_equal(format, 't');
rnp_op_verify_destroy(verify);
rnp_input_destroy(input);
rnp_output_destroy(output);
Expand Down