summaryrefslogtreecommitdiffstats
path: root/openpgp-ffi/src
diff options
context:
space:
mode:
authorNeal H. Walfield <neal@pep.foundation>2020-04-02 14:48:03 +0200
committerNeal H. Walfield <neal@pep.foundation>2020-04-02 16:42:54 +0200
commit789ae8615fda8e6dcbc1a39625e322255da90cef (patch)
tree97b8fec96ef1bfcd1d7c09a264d138803a6b85c0 /openpgp-ffi/src
parent6dd60b0b306e5d69b8770a5fa1f0bbfcead2270c (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.rs112
-rw-r--r--openpgp-ffi/src/cert.rs129
-rw-r--r--openpgp-ffi/src/common.rs1
-rw-r--r--openpgp-ffi/src/packet/userid.rs13
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.