diff options
author | Justus Winter <justus@sequoia-pgp.org> | 2019-03-21 12:58:33 +0100 |
---|---|---|
committer | Justus Winter <justus@sequoia-pgp.org> | 2019-03-21 14:59:26 +0100 |
commit | e3cb52fede1872f93371677224201228a62ae6ce (patch) | |
tree | 8da0c8d89a69e3d8ae6d165ee7505ed5647d2b0f /openpgp-ffi | |
parent | c04b985e0fe6f6b92b799702b290a521a8f5a912 (diff) |
openpgp-ffi: Reify the decryption wrapper.
- See #154.
Diffstat (limited to 'openpgp-ffi')
-rw-r--r-- | openpgp-ffi/examples/decrypt-with.c | 25 | ||||
-rw-r--r-- | openpgp-ffi/include/sequoia/openpgp.h | 24 | ||||
-rw-r--r-- | openpgp-ffi/src/parse/stream.rs | 81 |
3 files changed, 59 insertions, 71 deletions
diff --git a/openpgp-ffi/examples/decrypt-with.c b/openpgp-ffi/examples/decrypt-with.c index b54de0fc..ae5e871d 100644 --- a/openpgp-ffi/examples/decrypt-with.c +++ b/openpgp-ffi/examples/decrypt-with.c @@ -89,11 +89,12 @@ get_secret_keys_cb (void *cookie_opaque, int main (int argc, char **argv) { - pgp_status_t rc; pgp_error_t err; pgp_tpk_t tpk; pgp_reader_t source; - pgp_writer_t sink; + pgp_reader_t plaintext; + uint8_t buf[1024]; + ssize_t nread; if (argc != 2) error (1, 0, "Usage: %s <keyfile> <cipher >plain", argv[0]); @@ -104,20 +105,24 @@ main (int argc, char **argv) source = pgp_reader_from_fd (STDIN_FILENO); assert (source); - sink = pgp_writer_from_fd (STDOUT_FILENO); - assert (sink); struct decrypt_cookie cookie = { .key = tpk, .get_secret_keys_called = 0, }; - rc = pgp_decrypt (&err, source, sink, - get_public_keys_cb, get_secret_keys_cb, - check_signatures_cb, &cookie); - if (rc) - error (1, 0, "pgp_decrypt: %s", pgp_error_to_string (err)); + plaintext = pgp_decryptor_new (&err, source, + get_public_keys_cb, get_secret_keys_cb, + check_signatures_cb, &cookie); + if (! plaintext) + error (1, 0, "pgp_decryptor_new: %s", pgp_error_to_string (err)); + + while ((nread = pgp_reader_read (&err, plaintext, buf, sizeof buf)) > 0) { + write (STDOUT_FILENO, buf, nread); + } + if (nread < 0) + error (1, 0, "pgp_reader_read: %s", pgp_error_to_string (err)); - pgp_writer_free (sink); + pgp_reader_free (plaintext); pgp_reader_free (source); pgp_tpk_free (tpk); return 0; diff --git a/openpgp-ffi/include/sequoia/openpgp.h b/openpgp-ffi/include/sequoia/openpgp.h index 7063d214..3ffc7225 100644 --- a/openpgp-ffi/include/sequoia/openpgp.h +++ b/openpgp-ffi/include/sequoia/openpgp.h @@ -1422,11 +1422,25 @@ pgp_signature_t pgp_verification_result_signature( /*/ int pgp_verification_result_level(pgp_verification_result_t r); -pgp_status_t pgp_decrypt (pgp_error_t *errp, pgp_reader_t input, pgp_writer_t output, - pgp_sequoia_decrypt_get_public_keys_cb_t get_public_keys, - pgp_sequoia_decrypt_get_secret_keys_cb_t get_secret_keys, - pgp_sequoia_decrypt_check_signatures_cb_t check_signatures, - void *cookie); +/*/ +/// Decrypts an OpenPGP message. +/// +/// The message is read from `input` and the content of the +/// `LiteralData` packet is written to output. Note: the content is +/// written even if the message is not encrypted. You can determine +/// whether the message was actually decrypted by recording whether +/// the get_secret_keys callback was called in the cookie. +/// +/// The function takes three callbacks. The `cookie` is passed as the +/// first parameter to each of them. +/// +/// Note: all of the parameters are required; none may be NULL. +/*/ +pgp_reader_t pgp_decryptor_new (pgp_error_t *errp, pgp_reader_t input, + pgp_sequoia_decrypt_get_public_keys_cb_t get_public_keys, + pgp_sequoia_decrypt_get_secret_keys_cb_t get_secret_keys, + pgp_sequoia_decrypt_check_signatures_cb_t check_signatures, + void *cookie); pgp_status_t pgp_verify (pgp_error_t *errp, pgp_reader_t input, pgp_reader_t dsig, pgp_writer_t output, diff --git a/openpgp-ffi/src/parse/stream.rs b/openpgp-ffi/src/parse/stream.rs index 643c0a30..79682f38 100644 --- a/openpgp-ffi/src/parse/stream.rs +++ b/openpgp-ffi/src/parse/stream.rs @@ -40,6 +40,7 @@ use self::openpgp::parse::stream::{ use Maybe; use MoveFromRaw; use MoveIntoRaw; +use MoveResultIntoRaw; use RefMutRaw; use super::super::{ @@ -439,34 +440,6 @@ impl DecryptionHelper for DHelper { } } -// A helper function that returns a Result so that we can use ? to -// propagate errors. -fn decrypt_real<'a>(input: &'a mut io::ReaderKind, - output: &'a mut ::std::io::Write, - get_public_keys: GetPublicKeysCallback, - get_secret_keys: GetSecretKeysCallback, - check_signatures: CheckSignaturesCallback, - cookie: *mut HelperCookie) - -> Result<(), failure::Error> -{ - let helper = DHelper::new( - get_public_keys, get_secret_keys, check_signatures, cookie); - - let mut decryptor = Decryptor::from_reader(input, helper) - .context("Decryption failed")?; - - std_io::copy(&mut decryptor, output) - .map_err(|e| if e.get_ref().is_some() { - // Wrapped failure::Error. Recover it. - failure::Error::from_boxed_compat(e.into_inner().unwrap()) - } else { - // Plain io::Error. - ::failure::Error::from(e) - }).context("Decryption failed")?; - - Ok(()) -} - /// Decrypts an OpenPGP message. /// /// The message is read from `input` and the content of the @@ -572,13 +545,11 @@ fn decrypt_real<'a>(input: &'a mut io::ReaderKind, /// int /// main (int argc, char **argv) /// { -/// pgp_status_t rc; -/// pgp_error_t err; /// pgp_tpk_t tpk; /// pgp_reader_t source; -/// pgp_writer_t sink; -/// uint8_t *buf = NULL; -/// size_t buf_len = 0; +/// pgp_reader_t plaintext; +/// uint8_t buf[128]; +/// ssize_t nread; /// /// tpk = pgp_tpk_from_file ( /// NULL, "../openpgp/tests/data/keys/testy-private.pgp"); @@ -587,42 +558,40 @@ fn decrypt_real<'a>(input: &'a mut io::ReaderKind, /// source = pgp_reader_from_file ( /// NULL, "../openpgp/tests/data/messages/encrypted-to-testy.gpg"); /// assert (source); -/// sink = pgp_writer_alloc ((void **) &buf, &buf_len); -/// assert (sink); /// /// struct decrypt_cookie cookie = { /// .key = tpk, /// .get_secret_keys_called = 0, /// }; -/// rc = pgp_decrypt (&err, source, sink, -/// get_public_keys_cb, get_secret_keys_cb, -/// check_signatures_cb, &cookie); -/// assert (rc == PGP_STATUS_SUCCESS); +/// plaintext = pgp_decryptor_new (NULL, source, +/// get_public_keys_cb, get_secret_keys_cb, +/// check_signatures_cb, &cookie); +/// assert (plaintext); +/// +/// nread = pgp_reader_read (NULL, plaintext, buf, sizeof buf); +/// assert (nread == 13); +/// assert (memcmp (buf, "Test, 1-2-3.\n", nread) == 0); /// assert (cookie.get_secret_keys_called); -/// pgp_writer_free (sink); -/// assert (memcmp (buf, "Test, 1-2-3.\n", buf_len) == 0); -/// free (buf); +/// +/// pgp_reader_free (plaintext); /// pgp_reader_free (source); /// pgp_tpk_free (tpk); /// return 0; /// } /// ``` #[::sequoia_ffi_macros::extern_fn] #[no_mangle] pub extern "system" -fn pgp_decrypt<'a>(errp: Option<&mut *mut ::error::Error>, - input: *mut io::Reader, - output: *mut io::Writer, - get_public_keys: GetPublicKeysCallback, - get_secret_keys: GetSecretKeysCallback, - check_signatures: CheckSignaturesCallback, - cookie: *mut HelperCookie) - -> Status +fn pgp_decryptor_new<'a>(errp: Option<&mut *mut ::error::Error>, + input: *mut io::Reader, + get_public_keys: GetPublicKeysCallback, + get_secret_keys: GetSecretKeysCallback, + check_signatures: CheckSignaturesCallback, + cookie: *mut HelperCookie) + -> Maybe<io::Reader> { - ffi_make_fry_from_errp!(errp); - let input = input.ref_mut_raw(); - let output = output.ref_mut_raw(); - - let r = decrypt_real(input, output, + let helper = DHelper::new( get_public_keys, get_secret_keys, check_signatures, cookie); - ffi_try_status!(r) + Decryptor::from_reader(input.ref_mut_raw(), helper) + .map(|r| io::ReaderKind::Generic(Box::new(r))) + .move_into_raw(errp) } |