summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--guide/src/chapter_01.md204
-rw-r--r--guide/src/chapter_02.md8
-rw-r--r--openpgp-ffi/examples/decrypt-with.c87
-rw-r--r--openpgp-ffi/include/sequoia/openpgp.h96
-rw-r--r--openpgp-ffi/include/sequoia/openpgp/types.h37
-rw-r--r--openpgp-ffi/src/parse/stream.rs379
-rw-r--r--openpgp/examples/decrypt-with.rs44
-rw-r--r--openpgp/examples/generate-encrypt-decrypt.rs2
-rw-r--r--openpgp/examples/generate-sign-verify.rs51
-rw-r--r--openpgp/src/parse/stream.rs574
-rw-r--r--openpgp/src/serialize/stream.rs30
-rw-r--r--tool/src/commands/decrypt.rs6
-rw-r--r--tool/src/commands/mod.rs131
13 files changed, 1150 insertions, 499 deletions
diff --git a/guide/src/chapter_01.md b/guide/src/chapter_01.md
index f5663bc9..8d973e07 100644
--- a/guide/src/chapter_01.md
+++ b/guide/src/chapter_01.md
@@ -101,30 +101,41 @@ fn main() {
# Ok(vec![self.tpk.clone()])
# }
#
-# fn check(&mut self, sigs: Vec<Vec<VerificationResult>>)
+# fn check(&mut self, structure: &MessageStructure)
# -> openpgp::Result<()> {
# // In this function, we implement our signature verification
# // policy.
#
-# // First, we are interested in signatures over the data,
-# // i.e. level 0 signatures.
-# let sigs_over_data = sigs.get(0)
-# .ok_or_else(|| failure::err_msg("No level 0 signatures found"))?;
-#
-# // Now, let's see if there is a signature on that level.
-# let sig_result = sigs_over_data.get(0)
-# .ok_or_else(|| failure::err_msg("No signature found"))?;
-#
-# // Finally, given a VerificationResult, which only says
-# // whether the signature checks out mathematically, we apply
-# // our policy.
-# match sig_result {
-# VerificationResult::GoodChecksum(..) =>
-# Ok(()), // Good signature
-# VerificationResult::MissingKey(_) =>
-# Err(failure::err_msg("Missing key to verify signature")),
-# VerificationResult::BadChecksum(_) =>
-# Err(failure::err_msg("Bad signature")),
+# let mut good = false;
+# for (i, layer) in structure.iter().enumerate() {
+# match (i, layer) {
+# // First, we are interested in signatures over the
+# // data, i.e. level 0 signatures.
+# (0, MessageLayer::SignatureGroup { ref results }) => {
+# // Finally, given a VerificationResult, which only says
+# // whether the signature checks out mathematically, we apply
+# // our policy.
+# match results.get(0) {
+# Some(VerificationResult::GoodChecksum(..)) =>
+# good = true,
+# Some(VerificationResult::MissingKey(_)) =>
+# return Err(failure::err_msg(
+# "Missing key to verify signature")),
+# Some(VerificationResult::BadChecksum(_)) =>
+# return Err(failure::err_msg("Bad signature")),
+# None =>
+# return Err(failure::err_msg("No signature")),
+# }
+# },
+# _ => return Err(failure::err_msg(
+# "Unexpected message structure")),
+# }
+# }
+#
+# if good {
+# Ok(()) // Good signature.
+# } else {
+# Err(failure::err_msg("Signature verification failed"))
# }
# }
# }
@@ -231,30 +242,41 @@ fn generate() -> openpgp::Result<openpgp::TPK> {
# Ok(vec![self.tpk.clone()])
# }
#
-# fn check(&mut self, sigs: Vec<Vec<VerificationResult>>)
+# fn check(&mut self, structure: &MessageStructure)
# -> openpgp::Result<()> {
# // In this function, we implement our signature verification
# // policy.
#
-# // First, we are interested in signatures over the data,
-# // i.e. level 0 signatures.
-# let sigs_over_data = sigs.get(0)
-# .ok_or_else(|| failure::err_msg("No level 0 signatures found"))?;
-#
-# // Now, let's see if there is a signature on that level.
-# let sig_result = sigs_over_data.get(0)
-# .ok_or_else(|| failure::err_msg("No signature found"))?;
-#
-# // Finally, given a VerificationResult, which only says
-# // whether the signature checks out mathematically, we apply
-# // our policy.
-# match sig_result {
-# VerificationResult::GoodChecksum(..) =>
-# Ok(()), // Good signature
-# VerificationResult::MissingKey(_) =>
-# Err(failure::err_msg("Missing key to verify signature")),
-# VerificationResult::BadChecksum(_) =>
-# Err(failure::err_msg("Bad signature")),
+# let mut good = false;
+# for (i, layer) in structure.iter().enumerate() {
+# match (i, layer) {
+# // First, we are interested in signatures over the
+# // data, i.e. level 0 signatures.
+# (0, MessageLayer::SignatureGroup { ref results }) => {
+# // Finally, given a VerificationResult, which only says
+# // whether the signature checks out mathematically, we apply
+# // our policy.
+# match results.get(0) {
+# Some(VerificationResult::GoodChecksum(..)) =>
+# good = true,
+# Some(VerificationResult::MissingKey(_)) =>
+# return Err(failure::err_msg(
+# "Missing key to verify signature")),
+# Some(VerificationResult::BadChecksum(_)) =>
+# return Err(failure::err_msg("Bad signature")),
+# None =>
+# return Err(failure::err_msg("No signature")),
+# }
+# },
+# _ => return Err(failure::err_msg(
+# "Unexpected message structure")),
+# }
+# }
+#
+# if good {
+# Ok(()) // Good signature.
+# } else {
+# Err(failure::err_msg("Signature verification failed"))
# }
# }
# }
@@ -361,30 +383,41 @@ fn sign(sink: &mut Write, plaintext: &str, tsk: &openpgp::TPK)
# Ok(vec![self.tpk.clone()])
# }
#
-# fn check(&mut self, sigs: Vec<Vec<VerificationResult>>)
+# fn check(&mut self, structure: &MessageStructure)
# -> openpgp::Result<()> {
# // In this function, we implement our signature verification
# // policy.
#
-# // First, we are interested in signatures over the data,
-# // i.e. level 0 signatures.
-# let sigs_over_data = sigs.get(0)
-# .ok_or_else(|| failure::err_msg("No level 0 signatures found"))?;
-#
-# // Now, let's see if there is a signature on that level.
-# let sig_result = sigs_over_data.get(0)
-# .ok_or_else(|| failure::err_msg("No signature found"))?;
-#
-# // Finally, given a VerificationResult, which only says
-# // whether the signature checks out mathematically, we apply
-# // our policy.
-# match sig_result {
-# VerificationResult::GoodChecksum(..) =>
-# Ok(()), // Good signature
-# VerificationResult::MissingKey(_) =>
-# Err(failure::err_msg("Missing key to verify signature")),
-# VerificationResult::BadChecksum(_) =>
-# Err(failure::err_msg("Bad signature")),
+# let mut good = false;
+# for (i, layer) in structure.iter().enumerate() {
+# match (i, layer) {
+# // First, we are interested in signatures over the
+# // data, i.e. level 0 signatures.
+# (0, MessageLayer::SignatureGroup { ref results }) => {
+# // Finally, given a VerificationResult, which only says
+# // whether the signature checks out mathematically, we apply
+# // our policy.
+# match results.get(0) {
+# Some(VerificationResult::GoodChecksum(..)) =>
+# good = true,
+# Some(VerificationResult::MissingKey(_)) =>
+# return Err(failure::err_msg(
+# "Missing key to verify signature")),
+# Some(VerificationResult::BadChecksum(_)) =>
+# return Err(failure::err_msg("Bad signature")),
+# None =>
+# return Err(failure::err_msg("No signature")),
+# }
+# },
+# _ => return Err(failure::err_msg(
+# "Unexpected message structure")),
+# }
+# }
+#
+# if good {
+# Ok(()) // Good signature.
+# } else {
+# Err(failure::err_msg("Signature verification failed"))
# }
# }
# }
@@ -502,30 +535,41 @@ impl<'a> VerificationHelper for Helper<'a> {
Ok(vec![self.tpk.clone()])
}
- fn check(&mut self, sigs: Vec<Vec<VerificationResult>>)
+ fn check(&mut self, structure: &MessageStructure)
-> openpgp::Result<()> {
// In this function, we implement our signature verification
// policy.
- // First, we are interested in signatures over the data,
- // i.e. level 0 signatures.
- let sigs_over_data = sigs.get(0)
- .ok_or_else(|| failure::err_msg("No level 0 signatures found"))?;
-
- // Now, let's see if there is a signature on that level.
- let sig_result = sigs_over_data.get(0)
- .ok_or_else(|| failure::err_msg("No signature found"))?;
-
- // Finally, given a VerificationResult, which only says
- // whether the signature checks out mathematically, we apply
- // our policy.
- match sig_result {
- VerificationResult::GoodChecksum(..) =>
- Ok(()), // Good signature
- VerificationResult::MissingKey(_) =>
- Err(failure::err_msg("Missing key to verify signature")),
- VerificationResult::BadChecksum(_) =>
- Err(failure::err_msg("Bad signature")),
+ let mut good = false;
+ for (i, layer) in structure.iter().enumerate() {
+ match (i, layer) {
+ // First, we are interested in signatures over the
+ // data, i.e. level 0 signatures.
+ (0, MessageLayer::SignatureGroup { ref results }) => {
+ // Finally, given a VerificationResult, which only says
+ // whether the signature checks out mathematically, we apply
+ // our policy.
+ match results.get(0) {
+ Some(VerificationResult::GoodChecksum(..)) =>
+ good = true,
+ Some(VerificationResult::MissingKey(_)) =>
+ return Err(failure::err_msg(
+ "Missing key to verify signature")),
+ Some(VerificationResult::BadChecksum(_)) =>
+ return Err(failure::err_msg("Bad signature")),
+ None =>
+ return Err(failure::err_msg("No signature")),
+ }
+ },
+ _ => return Err(failure::err_msg(
+ "Unexpected message structure")),
+ }
+ }
+
+ if good {
+ Ok(()) // Good signature.
+ } else {
+ Err(failure::err_msg("Signature verification failed"))
}
}
}
diff --git a/guide/src/chapter_02.md b/guide/src/chapter_02.md
index 751a04a1..f66e15b3 100644
--- a/guide/src/chapter_02.md
+++ b/guide/src/chapter_02.md
@@ -102,7 +102,7 @@ fn main() {
# Ok(Vec::new())
# }
#
-# fn check(&mut self, _sigs: Vec<Vec<VerificationResult>>)
+# fn check(&mut self, _structure: &MessageStructure)
# -> openpgp::Result<()> {
# // Implement your signature verification policy here.
# Ok(())
@@ -236,7 +236,7 @@ fn generate() -> openpgp::Result<openpgp::TPK> {
# Ok(Vec::new())
# }
#
-# fn check(&mut self, _sigs: Vec<Vec<VerificationResult>>)
+# fn check(&mut self, _structure: &MessageStructure)
# -> openpgp::Result<()> {
# // Implement your signature verification policy here.
# Ok(())
@@ -370,7 +370,7 @@ fn encrypt(sink: &mut Write, plaintext: &str, recipient: &openpgp::TPK)
# Ok(Vec::new())
# }
#
-# fn check(&mut self, _sigs: Vec<Vec<VerificationResult>>)
+# fn check(&mut self, _structure: &MessageStructure)
# -> openpgp::Result<()> {
# // Implement your signature verification policy here.
# Ok(())
@@ -518,7 +518,7 @@ impl<'a> VerificationHelper for Helper<'a> {
Ok(Vec::new())
}
- fn check(&mut self, _sigs: Vec<Vec<VerificationResult>>)
+ fn check(&mut self, _structure: &MessageStructure)
-> openpgp::Result<()> {
// Implement your signature verification policy here.
Ok(())
diff --git a/openpgp-ffi/examples/decrypt-with.c b/openpgp-ffi/examples/decrypt-with.c
index 969b7e28..68ef0606 100644
--- a/openpgp-ffi/examples/decrypt-with.c
+++ b/openpgp-ffi/examples/decrypt-with.c
@@ -38,9 +38,90 @@ get_public_keys_cb (void *cookie_raw,
}
static pgp_status_t
-check_signatures_cb(void *cookie_opaque,
- pgp_verification_results_t results, size_t levels)
+check_cb (void *cookie_opaque, pgp_message_structure_t structure)
{
+ pgp_message_structure_iter_t iter = pgp_message_structure_iter (structure);
+
+ for (pgp_message_layer_t layer = pgp_message_structure_iter_next (iter);
+ layer;
+ layer = pgp_message_structure_iter_next (iter)) {
+ uint8_t algo;
+ uint8_t aead_algo;
+ pgp_verification_result_iter_t results;
+
+ switch (pgp_message_layer_variant (layer)) {
+ case PGP_MESSAGE_LAYER_COMPRESSION:
+ pgp_message_layer_compression (layer, &algo);
+ fprintf (stderr, "Compressed using %d\n", algo);
+ break;
+
+ case PGP_MESSAGE_LAYER_ENCRYPTION:
+ pgp_message_layer_encryption (layer, &algo, &aead_algo);
+ if (aead_algo) {
+ fprintf (stderr, "Encrypted and protected using %d/%d\n",
+ algo, aead_algo);
+ } else {
+ fprintf (stderr, "Encrypted using %d\n", algo);
+ }
+ break;
+
+ case PGP_MESSAGE_LAYER_SIGNATURE_GROUP:
+ pgp_message_layer_signature_group (layer, &results);
+ for (pgp_verification_result_t result =
+ pgp_verification_result_iter_next (results);
+ result;
+ result = pgp_verification_result_iter_next (results)) {
+ pgp_signature_t sig;
+ pgp_keyid_t keyid;
+ char *keyid_str = NULL;
+
+ switch (pgp_verification_result_variant (result)) {
+ case PGP_VERIFICATION_RESULT_GOOD_CHECKSUM:
+ pgp_verification_result_good_checksum (result, &sig, NULL,
+ NULL, NULL, NULL);
+ keyid = pgp_signature_issuer (sig);
+ keyid_str = pgp_keyid_to_string (keyid);
+ fprintf (stderr, "Good signature from %s\n", keyid_str);
+ break;
+
+ case PGP_VERIFICATION_RESULT_MISSING_KEY:
+ pgp_verification_result_missing_key (result, &sig);
+ keyid = pgp_signature_issuer (sig);
+ keyid_str = pgp_keyid_to_string (keyid);
+ fprintf (stderr, "No key to check signature from %s\n", keyid_str);
+ break;
+
+ case PGP_VERIFICATION_RESULT_BAD_CHECKSUM:
+ pgp_verification_result_bad_checksum (result, &sig);
+ keyid = pgp_signature_issuer (sig);
+ if (keyid) {
+ keyid_str = pgp_keyid_to_string (keyid);
+ fprintf (stderr, "Bad signature from %s\n", keyid_str);
+ } else {
+ fprintf (stderr, "Bad signature without issuer information\n");
+ }
+ break;
+
+ default:
+ assert (! "reachable");
+ }
+ free (keyid_str);
+ pgp_signature_free (sig);
+ pgp_verification_result_free (result);
+ }
+ pgp_verification_result_iter_free (results);
+ break;
+
+ default:
+ assert (! "reachable");
+ }
+
+ pgp_message_layer_free (layer);
+ }
+
+ pgp_message_structure_iter_free (iter);
+ pgp_message_structure_free (structure);
+
/* Implement your verification policy here. */
return PGP_STATUS_SUCCESS;
}
@@ -128,7 +209,7 @@ main (int argc, char **argv)
};
plaintext = pgp_decryptor_new (&err, source,
get_public_keys_cb, decrypt_cb,
- check_signatures_cb, &cookie, 0);
+ check_cb, &cookie, 0);
if (! plaintext)
error (1, 0, "pgp_decryptor_new: %s", pgp_error_to_string (err));
diff --git a/openpgp-ffi/include/sequoia/openpgp.h b/openpgp-ffi/include/sequoia/openpgp.h
index db3c82aa..3b001a15 100644
--- a/openpgp-ffi/include/sequoia/openpgp.h
+++ b/openpgp-ffi/include/sequoia/openpgp.h
@@ -1447,33 +1447,91 @@ pgp_writer_stack_t pgp_encryptor_new (pgp_error_t *errp,
pgp_encryption_mode_t mode,
uint8_t cipher_algo);
-void pgp_verification_results_at_level(pgp_verification_results_t results,
- size_t level,
- pgp_verification_result_t **r,
- size_t *r_count);
+/*/
+/// Frees this object.
+/*/
+void pgp_message_structure_free (pgp_message_structure_t);
+
+/*/
+/// Returns a human readable description of this object suitable for
+/// debugging.
+/*/
+char *pgp_message_structure_debug (const pgp_message_structure_t);
+pgp_message_structure_iter_t
+pgp_message_structure_iter (pgp_message_structure_t);
/*/
-/// Returns the verification result code.
+/// Frees this object.
/*/
-pgp_verification_result_code_t pgp_verification_result_code(
- pgp_verification_result_t r);
+void pgp_message_structure_iter_free (pgp_message_structure_iter_t);
+
+pgp_message_layer_t
+pgp_message_structure_iter_next (pgp_message_structure_iter_t);
/*/
-/// Returns a reference to the signature.
-///
-/// Do not modify the signature nor free it.
+/// Frees this object.
/*/
-pgp_signature_t pgp_verification_result_signature(
+void pgp_message_layer_free (pgp_message_layer_t);
+
+/*/
+/// Returns a human readable description of this object suitable for
+/// debugging.
+/*/
+char *pgp_message_layer_debug (const pgp_message_layer_t);
+
+/*/
+/// Returns the message layer variant.
+/*/
+pgp_message_layer_variant_t
+pgp_message_layer_variant (pgp_message_layer_t);
+
+/*/
+/// Return the fields of the variants.
+/*/
+bool pgp_message_layer_compression (pgp_message_layer_t, uint8_t *);
+bool pgp_message_layer_encryption (pgp_message_layer_t, uint8_t *, uint8_t *);
+bool pgp_message_layer_signature_group (pgp_message_layer_t,
+ pgp_verification_result_iter_t *);
+
+/*/
+/// Frees this object.
+/*/
+void pgp_verification_result_iter_free (pgp_verification_result_iter_t);
+
+pgp_verification_result_t
+pgp_verification_result_iter_next (pgp_verification_result_iter_t);
+
+/*/
+/// Frees this object.
+/*/
+void pgp_verification_result_free (pgp_verification_result_t);
+
+/*/
+/// Returns a human readable description of this object suitable for
+/// debugging.
+/*/
+char *pgp_verification_result_debug (const pgp_verification_result_t);
+
+/*/
+/// Returns the verification result variant.
+/*/
+pgp_verification_result_variant_t pgp_verification_result_variant (
pgp_verification_result_t r);
/*/
-/// Returns the signature's level.
-///
-/// A level of zero means that the data was signed, a level of one
-/// means that one or more signatures were notarized, etc.
+/// Return the fields of the variants.
/*/
-int pgp_verification_result_level(pgp_verification_result_t r);
+bool pgp_verification_result_good_checksum (pgp_verification_result_t,
+ pgp_signature_t *,
+ pgp_tpk_t *,
+ pgp_key_t *,
+ pgp_signature_t *,
+ pgp_revocation_status_t *);
+bool pgp_verification_result_missing_key (pgp_verification_result_t,
+ pgp_signature_t *);
+bool pgp_verification_result_bad_checksum (pgp_verification_result_t,
+ pgp_signature_t *);
/*/
/// Decrypts an OpenPGP message.
@@ -1492,7 +1550,7 @@ int pgp_verification_result_level(pgp_verification_result_t r);
pgp_reader_t pgp_decryptor_new (pgp_error_t *errp, pgp_reader_t input,
pgp_decryptor_get_public_keys_cb_t get_public_keys,
pgp_decryptor_decrypt_cb_t decrypt,
- pgp_decryptor_check_signatures_cb_t check_signatures,
+ pgp_decryptor_check_cb_t check,
void *cookie, time_t time);
/*/
@@ -1503,7 +1561,7 @@ pgp_reader_t pgp_decryptor_new (pgp_error_t *errp, pgp_reader_t input,
/*/
pgp_reader_t pgp_verifier_new (pgp_error_t *errp, pgp_reader_t input,
pgp_decryptor_get_public_keys_cb_t get_public_keys,
- pgp_decryptor_check_signatures_cb_t check_signatures,
+ pgp_decryptor_check_cb_t check,
void *cookie, time_t time);
/*/
@@ -1512,7 +1570,7 @@ pgp_reader_t pgp_verifier_new (pgp_error_t *errp, pgp_reader_t input,
pgp_reader_t pgp_detached_verifier_new (pgp_error_t *errp,
pgp_reader_t signature_input, pgp_reader_t input,
pgp_decryptor_get_public_keys_cb_t get_public_keys,
- pgp_decryptor_check_signatures_cb_t check_signatures,
+ pgp_decryptor_check_cb_t check,
void *cookie, time_t time);
#endif
diff --git a/openpgp-ffi/include/sequoia/openpgp/types.h b/openpgp-ffi/include/sequoia/openpgp/types.h
index c6572346..40c926d0 100644
--- a/openpgp-ffi/include/sequoia/openpgp/types.h
+++ b/openpgp-ffi/include/sequoia/openpgp/types.h
@@ -464,18 +464,38 @@ typedef enum pgp_encryption_mode {
PGP_ENCRYPTION_MODE_FOR_TRANSPORT = 1,
} pgp_encryption_mode_t;
-typedef struct pgp_verification_results *pgp_verification_results_t;
+/// Communicates the message structure to the VerificationHelper.
+typedef struct pgp_message_structure *pgp_message_structure_t;
+
+/// Iterates over the message structure.
+typedef struct pgp_message_structure_iter *pgp_message_structure_iter_t;
+
+/// Represents a layer of the message structure.
+typedef struct pgp_message_layer *pgp_message_layer_t;
+
+typedef enum pgp_message_layer_variant {
+ PGP_MESSAGE_LAYER_COMPRESSION = 1,
+ PGP_MESSAGE_LAYER_ENCRYPTION = 2,
+ PGP_MESSAGE_LAYER_SIGNATURE_GROUP = 3,
+
+ /* Dummy value to make sure the enumeration has a defined size. Do
+ not use this value. */
+ PGP_MESSAGE_LAYER_CODE_FORCE_WIDTH = INT_MAX,
+} pgp_message_layer_variant_t;
+
typedef struct pgp_verification_result *pgp_verification_result_t;
-typedef enum pgp_verification_result_code {
- PGP_VERIFICATION_RESULT_CODE_GOOD_CHECKSUM = 1,
- PGP_VERIFICATION_RESULT_CODE_MISSING_KEY = 2,
- PGP_VERIFICATION_RESULT_CODE_BAD_CHECKSUM = 3,
+typedef struct pgp_verification_result_iter *pgp_verification_result_iter_t;
+
+typedef enum pgp_verification_result_variant {
+ PGP_VERIFICATION_RESULT_GOOD_CHECKSUM = 1,
+ PGP_VERIFICATION_RESULT_MISSING_KEY = 2,
+ PGP_VERIFICATION_RESULT_BAD_CHECKSUM = 3,
/* Dummy value to make sure the enumeration has a defined size. Do
not use this value. */
PGP_VERIFICATION_RESULT_CODE_FORCE_WIDTH = INT_MAX,
-} pgp_verification_result_code_t;
+} pgp_verification_result_variant_t;
typedef pgp_status_t (*pgp_decryptor_get_public_keys_cb_t) (void *,
pgp_keyid_t *, size_t,
@@ -494,8 +514,7 @@ typedef pgp_status_t (*pgp_decryptor_decrypt_cb_t) (void *,
void *,
pgp_fingerprint_t *);
-typedef pgp_status_t (*pgp_decryptor_check_signatures_cb_t) (void *,
- pgp_verification_results_t,
- size_t);
+typedef pgp_status_t (*pgp_decryptor_check_cb_t) (void *,
+ pgp_message_structure_t);
#endif
diff --git a/openpgp-ffi/src/parse/stream.rs b/openpgp-ffi/src/parse/stream.rs
index ebd4bc50..8dcaf101 100644
--- a/openpgp-ffi/src/parse/stream.rs
+++ b/openpgp-ffi/src/parse/stream.rs
@@ -11,7 +11,7 @@
//! [`sequoia-openpgp::parse::stream`]: ../../../sequoia_openpgp/parse/stream/index.html
use std::ptr;
-use libc::{c_int, size_t, c_void, uint8_t, time_t};
+use libc::{c_int, c_void, uint8_t, time_t};
extern crate sequoia_openpgp as openpgp;
extern crate time;
@@ -25,10 +25,10 @@ use self::openpgp::{
},
};
use self::openpgp::parse::stream::{
+ self,
DecryptionHelper,
Decryptor,
VerificationHelper,
- VerificationResult,
Verifier,
DetachedVerifier,
};
@@ -45,93 +45,221 @@ use super::super::{
crypto,
io,
keyid,
- packet,
tpk::TPK,
+ packet::signature::Signature,
+ packet::key::Key,
+ revocation_status::RevocationStatus,
};
-// Decryptor.
+/// Communicates the message structure to the VerificationHelper.
+#[::ffi_wrapper_type(prefix = "pgp_", derive = "Debug")]
+pub struct MessageStructure<'a>(stream::MessageStructure<'a>);
-/// A message's verification results.
-///
-/// Conceptually, the verification results are an array of an array of
-/// VerificationResult. The outer array is for the verification level
-/// and is indexed by the verification level. A verification level of
-/// zero corresponds to direct signatures; A verification level of 1
-/// corresponds to notarizations (i.e., signatures of signatures);
-/// etc.
+/// Iterates over the message structure.
+#[::sequoia_ffi_macros::extern_fn] #[no_mangle] pub extern "system"
+fn pgp_message_structure_iter(structure: *const MessageStructure)
+ -> *mut MessageStructureIter {
+ structure.ref_raw().iter().move_into_raw()
+}
+
+/// Iterates over the message structure.
+#[::ffi_wrapper_type(prefix = "pgp_", derive = "Iterator(MessageLayer)")]
+pub struct MessageStructureIter<'a>(stream::MessageStructureIter<'a>);
+
+/// Represents a layer of the message structure.
+#[::ffi_wrapper_type(prefix = "pgp_", derive = "Debug")]
+pub struct MessageLayer<'a>(stream::MessageLayer<'a>);
+
+/// Returns the message layer variant.
+#[::sequoia_ffi_macros::extern_fn] #[no_mangle] pub extern "C"
+fn pgp_message_layer_variant(result: *const MessageLayer)
+ -> c_int
+{
+ use self::stream::MessageLayer::*;
+ match result.ref_raw() {
+ Compression { .. } => 1,
+ Encryption { .. } => 2,
+ SignatureGroup { .. } => 3,
+ }
+}
+
+/// Decomposes a `MessageLayer::Compression`.
///
-/// Within each level, there can be one or more signatures.
-pub struct VerificationResults<'a> {
- results: Vec<Vec<&'a VerificationResult<'a>>>,
+/// Returns `true` iff the given value is a
+/// `MessageLayer::Compression`, and returns each of the variants
+/// members if the corresponding parameter is not `NULL`.