summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeal H. Walfield <neal@pep.foundation>2018-12-17 12:48:07 +0100
committerNeal H. Walfield <neal@pep.foundation>2018-12-17 15:45:59 +0100
commit3366d09c94c88bb8366ed470e49ff841f336b894 (patch)
tree57e4e6dc28cc9457cf57555e941753812d03c34f
parent05e1b5dc9d189e3129f8da2c6beacb014f3fd698 (diff)
openpgp: Change KeyIter to also return the RevocationStatus.
- A Key's revocation status is a property of its binding, but the binding is not exposed by KeyIter. Expose it.
-rw-r--r--ffi/include/sequoia/openpgp.h17
-rw-r--r--ffi/src/openpgp.rs43
-rw-r--r--openpgp/examples/decrypt-with.rs2
-rw-r--r--openpgp/src/parse/stream.rs4
-rw-r--r--openpgp/src/tpk/mod.rs9
-rw-r--r--sqv/src/sqv.rs2
-rw-r--r--store/src/backend/mod.rs2
-rw-r--r--tool/src/commands/mod.rs2
8 files changed, 56 insertions, 25 deletions
diff --git a/ffi/include/sequoia/openpgp.h b/ffi/include/sequoia/openpgp.h
index 0e0439f8..765ff1a6 100644
--- a/ffi/include/sequoia/openpgp.h
+++ b/ffi/include/sequoia/openpgp.h
@@ -610,16 +610,19 @@ void sq_user_id_binding_iter_free (sq_user_id_binding_iter_t iter);
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.
+/// Returns the next key. 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.)
+/// If sigo is not NULL, stores the current self-signature (if any) in
+/// *sigo. (Note: subkeys always have signatures, but a primary key
+/// may not have a direct signature, and there might not be any user
+/// ids.)
+///
+/// If rso is not NULL, this stores the key's revocation status in
+/// *rso.
/*/
sq_p_key_t sq_tpk_key_iter_next (sq_tpk_key_iter_t iter,
- sq_packet_t *signature);
+ sq_signature_t *signature,
+ sq_revocation_status_t *rev);
/// Frees an sq_tpk_key_iter_t.
void sq_tpk_key_iter_free (sq_tpk_key_iter_t iter);
diff --git a/ffi/src/openpgp.rs b/ffi/src/openpgp.rs
index d98aa50c..fd77c5b3 100644
--- a/ffi/src/openpgp.rs
+++ b/ffi/src/openpgp.rs
@@ -1099,21 +1099,30 @@ pub extern "system" fn sq_user_id_binding_iter_next<'a>(
/* tpk::KeyIter. */
+/// Wrapers a KeyIter for export via the FFI.
+pub struct KeyIterWrapper<'a> {
+ iter: KeyIter<'a>,
+ rso: Option<RevocationStatus<'a>>,
+}
+
/// 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
+ -> *mut KeyIterWrapper
{
let tpk = tpk.expect("TPK is NULL");
- box_raw!(tpk.keys())
+ box_raw!(KeyIterWrapper {
+ iter: tpk.keys(),
+ rso: None,
+ })
}
/// Frees a sq_tpk_key_iter_t.
#[no_mangle]
pub extern "system" fn sq_tpk_key_iter_free(
- iter: *mut KeyIter)
+ iter: *mut KeyIterWrapper)
{
if iter.is_null() { return };
unsafe {
@@ -1121,17 +1130,33 @@ pub extern "system" fn sq_tpk_key_iter_free(
};
}
-/// Returns the next key.
+/// Returns the next key. Returns NULL if there are no more elements.
+///
+/// If sigo is not NULL, stores the current self-signature (if any) in
+/// *sigo. (Note: subkeys always have signatures, but a primary key
+/// may not have a direct signature, and there might not be any user
+/// ids.)
+///
+/// If rso is not NULL, this stores the key's revocation status in
+/// *rso.
#[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>>)
+ iter_wrapper: Option<&'a mut KeyIterWrapper<'a>>,
+ sigo: Option<&mut Option<&'a packet::Signature>>,
+ rso: Option<&mut &'a RevocationStatus<'a>>)
-> Option<&'a packet::Key>
{
- let iter = iter.expect("Iterator is NULL");
- if let Some((sig, key)) = iter.next() {
+ let iter_wrapper = iter_wrapper.expect("Iterator is NULL");
+ iter_wrapper.rso = None;
+
+ if let Some((sig, rs, key)) = iter_wrapper.iter.next() {
if let Some(ptr) = sigo {
- *ptr = box_raw!(sig);
+ *ptr = sig;
+ }
+
+ if let Some(ptr) = rso {
+ iter_wrapper.rso = Some(rs);
+ *ptr = iter_wrapper.rso.as_ref().unwrap();
}
Some(key)
diff --git a/openpgp/examples/decrypt-with.rs b/openpgp/examples/decrypt-with.rs
index c273a202..176e03de 100644
--- a/openpgp/examples/decrypt-with.rs
+++ b/openpgp/examples/decrypt-with.rs
@@ -57,7 +57,7 @@ impl Helper {
// Map (sub)KeyIDs to secrets.
let mut keys = HashMap::new();
for tpk in tpks {
- for (sig, key) in tpk.keys() {
+ for (sig, _, key) in tpk.keys() {
if sig.map(|s| (s.key_flags().can_encrypt_at_rest()
|| s.key_flags().can_encrypt_for_transport()))
.unwrap_or(false)
diff --git a/openpgp/src/parse/stream.rs b/openpgp/src/parse/stream.rs
index dacf38e6..1d2fe4eb 100644
--- a/openpgp/src/parse/stream.rs
+++ b/openpgp/src/parse/stream.rs
@@ -353,7 +353,7 @@ impl<'a, H: VerificationHelper> Verifier<'a, H> {
if let Some(issuer) = sig.get_issuer() {
if let Some((i, j)) = self.keys.get(&issuer) {
- let (_, key) = self.tpks[*i].keys().nth(*j).unwrap();
+ let (_, _, key) = self.tpks[*i].keys().nth(*j).unwrap();
if sig.verify(key).unwrap_or(false) {
self.sigs.iter_mut().last()
.expect("sigs is never empty").push(
@@ -1170,7 +1170,7 @@ impl<'a, H: VerificationHelper + DecryptionHelper> Decryptor<'a, H> {
if let Some(issuer) = sig.get_issuer() {
if let Some((i, j)) = self.keys.get(&issuer) {
- let (_, key) = self.tpks[*i].keys().nth(*j).unwrap();
+ let (_, _, key) = self.tpks[*i].keys().nth(*j).unwrap();
if sig.verify(key).unwrap_or(false) {
self.sigs.iter_mut().last()
.expect("sigs is never empty").push(
diff --git a/openpgp/src/tpk/mod.rs b/openpgp/src/tpk/mod.rs
index 2b61131e..5bd6f74b 100644
--- a/openpgp/src/tpk/mod.rs
+++ b/openpgp/src/tpk/mod.rs
@@ -694,16 +694,19 @@ pub struct KeyIter<'a> {
}
impl<'a> Iterator for KeyIter<'a> {
- type Item = (Option<&'a Signature>, &'a Key);
+ type Item = (Option<&'a Signature>, RevocationStatus<'a>, &'a Key);
fn next(&mut self) -> Option<Self::Item> {
if ! self.primary {
self.primary = true;
- Some((self.tpk.primary_key_signature(), self.tpk.primary()))
+ Some((self.tpk.primary_key_signature(),
+ self.tpk.revoked(),
+ self.tpk.primary()))
} else {
self.subkey_iter.next()
.map(|sk_binding| (sk_binding.binding_signature(),
- &sk_binding.subkey))
+ sk_binding.revoked(),
+ &sk_binding.subkey,))
}
}
}
diff --git a/sqv/src/sqv.rs b/sqv/src/sqv.rs
index 495ec5dc..a1f0c523 100644
--- a/sqv/src/sqv.rs
+++ b/sqv/src/sqv.rs
@@ -214,7 +214,7 @@ fn real_main() -> Result<(), failure::Error> {
if let Some(ref tpk) = tpko {
// Find the right key.
- for (_, key) in tpk.keys() {
+ for (_, _, key) in tpk.keys() {
if issuer == key.keyid() {
let mut hash = match hashes.get(&sig.hash_algo()) {
Some(h) => h.clone(),
diff --git a/store/src/backend/mod.rs b/store/src/backend/mod.rs
index 98e05fa4..39db1279 100644
--- a/store/src/backend/mod.rs
+++ b/store/src/backend/mod.rs
@@ -794,7 +794,7 @@ impl KeyServer {
/// Keeps the mapping of (sub)KeyIDs to keys up-to-date.
fn reindex_subkeys(c: &Connection, key_id: ID, tpk: &TPK) -> Result<()> {
- for (_, key) in tpk.keys() {
+ for (_, _, key) in tpk.keys() {
let keyid = key.fingerprint().to_keyid().as_u64()
.expect("computed keyid is valid");
diff --git a/tool/src/commands/mod.rs b/tool/src/commands/mod.rs
index 7255381e..f3a6d044 100644
--- a/tool/src/commands/mod.rs
+++ b/tool/src/commands/mod.rs
@@ -447,7 +447,7 @@ impl<'a> VerificationHelper for VHelper<'a> {
let mut tpks = self.tpks.take().unwrap();
let seen: HashSet<_> = tpks.iter()
.flat_map(|tpk| {
- tpk.keys().map(|(_, key)| key.fingerprint().to_keyid())
+ tpk.keys().map(|(_, _, key)| key.fingerprint().to_keyid())
}).collect();
// Explicitly provided keys are trusted.