diff options
author | Neal H. Walfield <neal@pep.foundation> | 2020-04-02 14:48:03 +0200 |
---|---|---|
committer | Neal H. Walfield <neal@pep.foundation> | 2020-04-02 16:42:54 +0200 |
commit | 789ae8615fda8e6dcbc1a39625e322255da90cef (patch) | |
tree | 97b8fec96ef1bfcd1d7c09a264d138803a6b85c0 /openpgp-ffi/src | |
parent | 6dd60b0b306e5d69b8770a5fa1f0bbfcead2270c (diff) |
openpgp-ffi: Use UserIDAmalgamations, not UserIDBundles.
- Add the `UserID`, `UserIDAmalgamation` and
`ValidUserIDAmalgamation` types, and some associated methods.
- Replace the use of `UserIDBundle` with `UserIDAmalgamation` and
`ValidUserIDAmalgamation`.
Diffstat (limited to 'openpgp-ffi/src')
-rw-r--r-- | openpgp-ffi/src/amalgamation.rs | 112 | ||||
-rw-r--r-- | openpgp-ffi/src/cert.rs | 129 | ||||
-rw-r--r-- | openpgp-ffi/src/common.rs | 1 | ||||
-rw-r--r-- | openpgp-ffi/src/packet/userid.rs | 13 |
4 files changed, 221 insertions, 34 deletions
diff --git a/openpgp-ffi/src/amalgamation.rs b/openpgp-ffi/src/amalgamation.rs new file mode 100644 index 00000000..248fe24f --- /dev/null +++ b/openpgp-ffi/src/amalgamation.rs @@ -0,0 +1,112 @@ +//! `KeyAmalgamation`s. +//! +//! +//! Wraps [`sequoia-openpgp::cert::key_amalgamation::KeyAmalgamation`]. +//! +//! [`sequoia-openpgp::cert::key_amalgamation::KeyAmalgamation`]: ../../../sequoia_openpgp/cert/key_amalgamation/struct.KeyAmalgamation.html + +use libc::time_t; + +extern crate sequoia_openpgp as openpgp; + +use self::openpgp::cert::amalgamation::ValidAmalgamation as _; +use self::openpgp::cert::amalgamation::ValidateAmalgamation as _; + +use super::packet::userid::UserID; +use super::packet::signature::Signature; +use super::policy::Policy; +use super::revocation_status::RevocationStatus; + +use crate::Maybe; +use crate::MoveIntoRaw; +use crate::MoveResultIntoRaw; +use crate::RefRaw; +use crate::MoveFromRaw; +use crate::maybe_time; + +/// A local alias to appease the proc macro transformation. +type UserIDAmalgamationType<'a> + = openpgp::cert::amalgamation::ComponentAmalgamation<'a, openpgp::packet::UserID>; + +/// A `UserIDAmalgamation` holds a `UserID` and associated data. +/// +/// Wraps [`sequoia-openpgp::cert::amalgamation::ComponentAmalgamation`]. +/// +/// [`sequoia-openpgp::cert::amalgamation::ComponentAmalgamation`]: ../../../sequoia_openpgp/cert/amalgamation/struct.ComponentAmalgamation.html +#[crate::ffi_wrapper_type(prefix = "pgp_", + derive = "Clone, Debug")] +pub struct UserIDAmalgamation<'a>(UserIDAmalgamationType<'a>); + +/// Returns a reference to the `UserID`. +#[::sequoia_ffi_macros::extern_fn] #[no_mangle] +pub extern "C" fn pgp_user_id_amalgamation_user_id<'a>(ua: *const UserIDAmalgamation<'a>) + -> *const UserID +{ + let ua = ua.ref_raw(); + + ua.userid().move_into_raw() +} + +/// A local alias to appease the proc macro transformation. +type ValidUserIDAmalgamationType<'a> + = openpgp::cert::amalgamation::ValidComponentAmalgamation<'a, openpgp::packet::UserID>; + +/// A `ValidUserIDAmalgamation` holds a `UserID` and associated data +/// including a policy and a reference time. +/// +/// Wraps [`sequoia-openpgp::cert::amalgamation::ValidComponentAmalgamation`]. +/// +/// [`sequoia-openpgp::cert::amalgamation::ValidComponentAmalgamation`]: ../../../sequoia_openpgp/cert/amalgamation/struct.ValidComponentAmalgamation.html +#[crate::ffi_wrapper_type(prefix = "pgp_", + derive = "Clone, Debug")] +pub struct ValidUserIDAmalgamation<'a>(ValidUserIDAmalgamationType<'a>); + +/// Returns a reference to the `UserID`. +#[::sequoia_ffi_macros::extern_fn] #[no_mangle] +pub extern "C" fn pgp_valid_user_id_amalgamation_user_id<'a>(ua: *const ValidUserIDAmalgamation<'a>) + -> *const UserID +{ + let ua = ua.ref_raw(); + + ua.userid().move_into_raw() +} + +/// Returns the UserID's revocation status. +#[::sequoia_ffi_macros::extern_fn] #[no_mangle] +pub extern "C" fn pgp_valid_user_id_amalgamation_revocation_status<'a>(ua: *const ValidUserIDAmalgamation<'a>) + -> *mut RevocationStatus<'a> +{ + ua.ref_raw() + .revoked() + .move_into_raw() +} + +/// Returns the User ID's binding signature. +#[::sequoia_ffi_macros::extern_fn] #[no_mangle] +pub extern "C" fn pgp_valid_user_id_amalgamation_binding_signature<'a>(ua: *const ValidUserIDAmalgamation<'a>) + -> *const Signature +{ + ua.ref_raw() + .binding_signature() + .move_into_raw() +} + +/// Changes the policy applied to the `ValidUserIDAmalgamation`. +/// +/// This consumes the User ID amalgamation. +#[::sequoia_ffi_macros::extern_fn] #[no_mangle] +pub extern "C" +fn pgp_valid_user_id_amalgamation_with_policy<'a>(errp: Option<&mut *mut crate::error::Error>, + ua: *mut ValidUserIDAmalgamation<'a>, + policy: *const Policy, + time: time_t) + -> Maybe<ValidUserIDAmalgamation<'a>> +{ + ffi_make_fry_from_errp!(errp); + + let ua = ua.move_from_raw(); + let policy = policy.ref_raw(); + let time = maybe_time(time); + + ua.with_policy(&**policy, time).move_into_raw(errp) +} diff --git a/openpgp-ffi/src/cert.rs b/openpgp-ffi/src/cert.rs index 9c3f43ad..eb32d5a0 100644 --- a/openpgp-ffi/src/cert.rs +++ b/openpgp-ffi/src/cert.rs @@ -29,6 +29,7 @@ use super::packet_pile::PacketPile; use super::tsk::TSK; use super::revocation_status::RevocationStatus; use super::policy::Policy; +use super::amalgamation::{UserIDAmalgamation, ValidUserIDAmalgamation}; use super::key_amalgamation::{KeyAmalgamation, ValidKeyAmalgamation}; use crate::Maybe; @@ -371,68 +372,128 @@ fn pgp_cert_primary_user_id(cert: *const Cert, policy: *const Policy, } } -/* UserIDBundle */ +/* UserIDIter */ -/// Returns the user id. -/// -/// This function may fail and return NULL if the user id contains an -/// interior NUL byte. We do this rather than complicate the API, as -/// there is no valid use for such user ids; they must be malicious. +/// Wraps a UserIDIter for export via the FFI. +pub struct UserIDIterWrapper<'a> { + pub(crate) // For serialize.rs. + iter: Option<ComponentIter<'a, openpgp::packet::UserID>>, + // Whether next has been called. + next_called: bool, +} + +/// Returns an iterator over the Cert's user ids. +#[::sequoia_ffi_macros::extern_fn] #[no_mangle] +pub extern "C" fn pgp_cert_user_id_iter(cert: *const Cert) + -> *mut UserIDIterWrapper<'static> +{ + let cert = cert.ref_raw(); + box_raw!(UserIDIterWrapper { + iter: Some(cert.userids()), + next_called: false, + }) +} + +/// Changes the iterator to only return keys that are valid at time +/// `t`. /// -/// The caller must free the returned value. +/// Note: you may not call this function after starting to iterate. #[::sequoia_ffi_macros::extern_fn] #[no_mangle] -pub extern "C" fn pgp_user_id_bundle_user_id( - binding: *const UserIDBundle) - -> *mut c_char +pub extern "C" fn pgp_cert_user_id_iter_policy<'a>( + iter_wrapper: *mut UserIDIterWrapper<'a>, + policy: *const Policy, + when: time_t) + -> *mut ValidUserIDIterWrapper<'static> { - let binding = ffi_param_ref!(binding); + let policy = policy.ref_raw(); + let iter_wrapper = ffi_param_ref_mut!(iter_wrapper); + if iter_wrapper.next_called { + panic!("Can't change UserIDIter filter after iterating."); + } - ffi_return_maybe_string!(binding.userid().value()) + use std::mem::transmute; + box_raw!(ValidUserIDIterWrapper { + iter: Some(unsafe { + transmute(iter_wrapper.iter.take().unwrap() + .with_policy(&**policy, maybe_time(when))) + }), + next_called: false, + }) } -/// Returns a reference to the self-signature, if any. + +/// Frees a pgp_user_id_iter_t. #[::sequoia_ffi_macros::extern_fn] #[no_mangle] -pub extern "C" fn pgp_user_id_bundle_selfsig( - errp: Option<&mut *mut crate::error::Error>, - binding: *const UserIDBundle, - policy: *const Policy) - -> Maybe<Signature> +pub extern "C" fn pgp_cert_user_id_iter_free( + iter: Option<&mut UserIDIterWrapper>) { - let binding = ffi_param_ref!(binding); - let policy = &**policy.ref_raw(); - binding.binding_signature(policy, None).move_into_raw(errp) + ffi_free!(iter) } +/// Returns the next `UserIDAmalgamation`. +#[::sequoia_ffi_macros::extern_fn] #[no_mangle] +pub extern "C" fn pgp_cert_user_id_iter_next<'a>( + iter_wrapper: *mut UserIDIterWrapper<'a>) + -> Maybe<UserIDAmalgamation<'a>> +{ + let iter_wrapper = ffi_param_ref_mut!(iter_wrapper); + iter_wrapper.next_called = true; + + if let Some(ua) = iter_wrapper.iter.as_mut().unwrap().next() { + Some(ua).move_into_raw() + } else { + None + } +} -/* UserIDBundleIter */ +/// Wraps a ValidKeyIter for export via the FFI. +pub struct ValidUserIDIterWrapper<'a> { + pub(crate) // For serialize.rs. + iter: Option<ValidComponentIter<'a, openpgp::packet::UserID>>, + // Whether next has been called. + next_called: bool, +} /// Returns an iterator over the Cert's user id bundles. #[::sequoia_ffi_macros::extern_fn] #[no_mangle] -pub extern "C" fn pgp_cert_user_id_bundle_iter(cert: *const Cert) - -> *mut UserIDBundleIter<'static> +pub extern "C" fn pgp_cert_valid_user_id_iter(cert: *const Cert, + policy: *const Policy, when: time_t) + -> *mut ValidUserIDIterWrapper<'static> { let cert = cert.ref_raw(); - box_raw!(cert.userids().bundles()) + let iter = box_raw!(UserIDIterWrapper { + iter: Some(cert.userids()), + next_called: false, + }); + + pgp_cert_user_id_iter_policy(iter, policy, when) } -/// Frees a pgp_user_id_bundle_iter_t. +/// Frees a pgp_user_id_iter_t. #[::sequoia_ffi_macros::extern_fn] #[no_mangle] -pub extern "C" fn pgp_user_id_bundle_iter_free( - iter: Option<&mut UserIDBundleIter>) +pub extern "C" fn pgp_cert_valid_user_id_iter_free( + iter: Option<&mut ValidUserIDIterWrapper>) { ffi_free!(iter) } -/// Returns the next `UserIDBundle`. +/// Returns the next `UserIDAmalgamation`. #[::sequoia_ffi_macros::extern_fn] #[no_mangle] -pub extern "C" fn pgp_user_id_bundle_iter_next<'a>( - iter: *mut UserIDBundleIter<'a>) - -> Option<&'a UserIDBundle> +pub extern "C" fn pgp_cert_valid_user_id_iter_next<'a>( + iter_wrapper: *mut ValidUserIDIterWrapper<'a>) + -> Maybe<ValidUserIDAmalgamation<'a>> { - let iter = ffi_param_ref_mut!(iter); - iter.next() + let iter_wrapper = ffi_param_ref_mut!(iter_wrapper); + iter_wrapper.next_called = true; + + if let Some(ua) = iter_wrapper.iter.as_mut().unwrap().next() { + Some(ua).move_into_raw() + } else { + None + } } + /* cert::KeyIter. */ /// Wraps a KeyIter for export via the FFI. diff --git a/openpgp-ffi/src/common.rs b/openpgp-ffi/src/common.rs index cc2deb5e..529a33e5 100644 --- a/openpgp-ffi/src/common.rs +++ b/openpgp-ffi/src/common.rs @@ -344,3 +344,4 @@ pub mod tsk; pub mod revocation_status; pub mod policy; pub mod key_amalgamation; +pub mod amalgamation; diff --git a/openpgp-ffi/src/packet/userid.rs b/openpgp-ffi/src/packet/userid.rs index 69e49b42..339f1486 100644 --- a/openpgp-ffi/src/packet/userid.rs +++ b/openpgp-ffi/src/packet/userid.rs @@ -12,6 +12,19 @@ use super::Packet; use crate::RefRaw; use crate::MoveIntoRaw; +/// Holds a UserID packet. +/// +/// See [Section 5.11 of RFC 4880] for details. +/// +/// [Section 5.11 of RFC 4880]: https://tools.ietf.org/html/rfc4880#section-5.11 +/// +/// Wraps [`sequoia-openpgp::packet::UserID`]. +/// +/// [`sequoia-openpgp::packet::UserID`]: ../../../sequoia_openpgp/packet/struct.UserID.html +#[crate::ffi_wrapper_type(prefix = "pgp_", + derive = "Clone, Debug, PartialEq")] +pub struct UserID(openpgp::packet::UserID); + /// Create a new User ID with the value `value`. /// /// `value` need not be valid UTF-8, but it must be NUL terminated. |