From 89c7f7d72f041cc739cde563558acd381164a965 Mon Sep 17 00:00:00 2001 From: "Neal H. Walfield" Date: Thu, 22 Nov 2018 10:47:39 +0100 Subject: ffi: Provide an interface to iterate over Keys in a TPK. - Add sq_tpk_key_iter, sq_tpk_key_iter_free, and sq_tpk_key_iter_next. --- ffi/include/sequoia/openpgp.h | 28 +++++++++++++++++++++++++++ ffi/src/openpgp.rs | 44 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+) (limited to 'ffi') diff --git a/ffi/include/sequoia/openpgp.h b/ffi/include/sequoia/openpgp.h index c39581c7..a46aa275 100644 --- a/ffi/include/sequoia/openpgp.h +++ b/ffi/include/sequoia/openpgp.h @@ -578,6 +578,28 @@ sq_user_id_binding_t sq_user_id_binding_iter_next (sq_user_id_binding_iter_t ite /// Frees an sq_user_id_binding_iter_t. void sq_user_id_binding_iter_free (sq_user_id_binding_iter_t iter); +/* openpgp::tpk::KeyIter. */ + +/*/ +/// An iterator over keys in a TPK. +/*/ +typedef struct sq_tpk_key_iter *sq_tpk_key_iter_t; + +/*/ +/// Returns a reference to the next element in the iterator. Returns +/// NULL if there are no more elements. +/// +/// If signature is not NULL, stores a reference to the key's most +/// recent self-signature, if any. (Note: subkeys always have +/// signatures, but a primary key may not have a direct signature, and +/// there might not be any user ids.) +/*/ +sq_p_key_t sq_tpk_key_iter_next (sq_tpk_key_iter_t iter, + sq_packet_t *signature); + +/// Frees an sq_tpk_key_iter_t. +void sq_tpk_key_iter_free (sq_tpk_key_iter_t iter); + /* openpgp::tpk. */ /*/ @@ -745,6 +767,12 @@ int sq_tpk_is_tsk(sq_tpk_t tpk); /*/ sq_user_id_binding_iter_t sq_tpk_user_id_binding_iter (sq_tpk_t tpk); +/*/ +/// Returns an iterator over all `Key`s (both the primary key and any +/// subkeys) in a TPK. +/*/ +sq_tpk_key_iter_t sq_tpk_key_iter (sq_tpk_t tpk); + /* TPKBuilder */ typedef struct sq_tpk_builder *sq_tpk_builder_t; diff --git a/ffi/src/openpgp.rs b/ffi/src/openpgp.rs index 34c96806..a531fec0 100644 --- a/ffi/src/openpgp.rs +++ b/ffi/src/openpgp.rs @@ -30,6 +30,7 @@ use self::openpgp::tpk::{ TPKBuilder, UserIDBinding, UserIDBindingIter, + KeyIter }; use self::openpgp::packet; use self::openpgp::parse::{PacketParserResult, PacketParser, PacketParserEOF}; @@ -1042,6 +1043,49 @@ pub extern "system" fn sq_user_id_binding_iter_next<'a>( iter.next() } +/* tpk::KeyIter. */ + +/// Returns an iterator over the TPK's keys. +/// +/// This iterates over both the primary key and any subkeys. +#[no_mangle] +pub extern "system" fn sq_tpk_key_iter(tpk: Option<&TPK>) + -> *mut KeyIter +{ + let tpk = tpk.expect("TPK is NULL"); + box_raw!(tpk.keys()) +} + +/// Frees a sq_tpk_key_iter_t. +#[no_mangle] +pub extern "system" fn sq_tpk_key_iter_free( + iter: *mut KeyIter) +{ + if iter.is_null() { return }; + unsafe { + drop(Box::from_raw(iter)) + }; +} + +/// Returns the next key. +#[no_mangle] +pub extern "system" fn sq_tpk_key_iter_next<'a>( + iter: Option<&mut KeyIter<'a>>, + sigo: Option<&mut *mut Option<&'a packet::Signature>>) + -> Option<&'a packet::Key> +{ + let iter = iter.expect("Iterator is NULL"); + if let Some((sig, key)) = iter.next() { + if let Some(ptr) = sigo { + *ptr = box_raw!(sig); + } + + Some(key) + } else { + None + } +} + /* TPKBuilder */ /// Creates a default `sq_tpk_builder_t`. -- cgit v1.2.3