summaryrefslogtreecommitdiffstats
path: root/openpgp-ffi/src/parse/stream.rs
diff options
context:
space:
mode:
Diffstat (limited to 'openpgp-ffi/src/parse/stream.rs')
-rw-r--r--openpgp-ffi/src/parse/stream.rs49
1 files changed, 38 insertions, 11 deletions
diff --git a/openpgp-ffi/src/parse/stream.rs b/openpgp-ffi/src/parse/stream.rs
index 747452a0..16fb1829 100644
--- a/openpgp-ffi/src/parse/stream.rs
+++ b/openpgp-ffi/src/parse/stream.rs
@@ -11,6 +11,7 @@
//! [`sequoia-openpgp::parse::stream`]: ../../../../sequoia_openpgp/parse/stream/index.html
use std::ptr;
+use std::sync::Mutex;
use libc::{c_int, c_void, time_t};
use sequoia_openpgp as openpgp;
@@ -430,13 +431,16 @@ type CheckCallback = extern fn(*mut HelperCookie,
-> Status;
// This fetches keys and computes the validity of the verification.
-struct VHelper {
+struct VHelper(Mutex<VHelperClosure>);
+struct VHelperClosure {
inspect_cb: Option<InspectCallback>,
get_certs_cb: GetPublicKeysCallback,
check_signatures_cb: CheckCallback,
cookie: *mut HelperCookie,
}
+unsafe impl Send for VHelperClosure {}
+
impl VHelper {
fn new(inspect_cb: Option<InspectCallback>,
get_certs: GetPublicKeysCallback,
@@ -444,19 +448,20 @@ impl VHelper {
cookie: *mut HelperCookie)
-> Self
{
- VHelper {
+ VHelper(Mutex::new(VHelperClosure {
inspect_cb,
get_certs_cb: get_certs,
check_signatures_cb: check_signatures,
- cookie,
- }
+ cookie: cookie,
+ }))
}
}
impl VerificationHelper for VHelper {
fn inspect(&mut self, pp: &PacketParser) -> openpgp::Result<()> {
- if let Some(cb) = self.inspect_cb {
- match cb(self.cookie, pp) {
+ let closure = self.0.get_mut().expect("Mutex not to be poisoned");
+ if let Some(cb) = closure.inspect_cb {
+ match cb(closure.cookie, pp) {
Status::Success => Ok(()),
// XXX: Convert the status to an error better.
status => Err(anyhow::anyhow!(
@@ -481,8 +486,9 @@ impl VerificationHelper for VHelper {
let mut free : FreeCallback = |_| {};
- let result = (self.get_certs_cb)(
- self.cookie,
+ let closure = self.0.get_mut().expect("Mutex not to be poisoned");
+ let result = (closure.get_certs_cb)(
+ closure.cookie,
ids.as_ptr(), ids.len(),
&mut cert_refs_raw, &mut cert_refs_raw_len as *mut usize,
&mut free);
@@ -515,8 +521,9 @@ impl VerificationHelper for VHelper {
fn check(&mut self, structure: stream::MessageStructure)
-> Result<(), anyhow::Error>
{
- let result = (self.check_signatures_cb)(self.cookie,
- structure.move_into_raw());
+ let closure = self.0.get_mut().expect("Mutex not to be poisoned");
+ let result = (closure.check_signatures_cb)(closure.cookie,
+ structure.move_into_raw());
if result != Status::Success {
// XXX: We need to convert the status to an error. A
// status contains less information, but we should do the
@@ -535,6 +542,12 @@ impl VerificationHelper for VHelper {
/// No attempt is made to decrypt any encryption packets. These are
/// treated as opaque containers.
///
+/// # Sending objects across thread boundaries
+///
+/// If you send a Sequoia object (like a pgp_verifier_t) that reads
+/// from an callback across thread boundaries, you must make sure that
+/// the callbacks and cookie support that as well.
+///
/// # Examples
///
/// ```c
@@ -663,6 +676,12 @@ pub struct DetachedVerifier(openpgp::parse::stream::DetachedVerifier<'static, VH
/// Verifies a detached OpenPGP signature.
///
+/// # Sending objects across thread boundaries
+///
+/// If you send a Sequoia object (like a pgp_verifier_t) that reads
+/// from an callback across thread boundaries, you must make sure that
+/// the callbacks and cookie support that as well.
+///
/// # Examples
///
/// ```c
@@ -871,8 +890,10 @@ impl DecryptionHelper for DHelper {
(*closure)(algo.into(), sk.ref_raw())
}
+ let closure =
+ self.vhelper.0.get_mut().expect("Mutex not to be poisoned");
let result = (self.decrypt_cb)(
- self.vhelper.cookie,
+ closure.cookie,
pkesks.as_ptr(), pkesks.len(), skesks.as_ptr(), skesks.len(),
sym_algo.map(|s| u8::from(s)).unwrap_or(0),
trampoline::<D>,
@@ -904,6 +925,12 @@ impl DecryptionHelper for DHelper {
///
/// Note: all of the parameters are required; none may be NULL.
///
+/// # Sending objects across thread boundaries
+///
+/// If you send a Sequoia object (like a pgp_verifier_t) that reads
+/// from an callback across thread boundaries, you must make sure that
+/// the callbacks and cookie support that as well.
+///
/// # Examples
///
/// ```c