summaryrefslogtreecommitdiffstats
path: root/openpgp-ffi
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2019-03-21 12:58:33 +0100
committerJustus Winter <justus@sequoia-pgp.org>2019-03-21 14:59:26 +0100
commite3cb52fede1872f93371677224201228a62ae6ce (patch)
tree8da0c8d89a69e3d8ae6d165ee7505ed5647d2b0f /openpgp-ffi
parentc04b985e0fe6f6b92b799702b290a521a8f5a912 (diff)
openpgp-ffi: Reify the decryption wrapper.
- See #154.
Diffstat (limited to 'openpgp-ffi')
-rw-r--r--openpgp-ffi/examples/decrypt-with.c25
-rw-r--r--openpgp-ffi/include/sequoia/openpgp.h24
-rw-r--r--openpgp-ffi/src/parse/stream.rs81
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)
}