summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2019-11-26 17:54:04 +0100
committerJustus Winter <justus@sequoia-pgp.org>2019-11-27 14:09:26 +0100
commit6fa1c0c42d21c7876c594f9c658742f6639f86b9 (patch)
treee38d797dbbf38c7ce5a1c8ca45a04a7ecbe316b6
parenta52f66d26bdef3ce9c8948aa058dff39048e16c3 (diff)
openpgp: Fix Signature::get_issuer to return set of issuers.
- A signature can contain multiple hints as to who created the signature. Return all those hints to the caller. - Adapt all callers accordingly. - Fixes #264.
-rw-r--r--openpgp/examples/web-of-trust.rs7
-rw-r--r--openpgp/src/packet/signature/mod.rs28
-rw-r--r--openpgp/src/parse/stream.rs16
-rw-r--r--tool/src/commands/mod.rs5
4 files changed, 34 insertions, 22 deletions
diff --git a/openpgp/examples/web-of-trust.rs b/openpgp/examples/web-of-trust.rs
index 754a7b13..34cbe289 100644
--- a/openpgp/examples/web-of-trust.rs
+++ b/openpgp/examples/web-of-trust.rs
@@ -10,6 +10,7 @@
use std::env;
extern crate sequoia_openpgp as openpgp;
+use crate::openpgp::KeyID;
use crate::openpgp::tpk::TPKParser;
use crate::openpgp::parse::Parse;
@@ -39,14 +40,12 @@ fn main() {
let keyid = tpk.keyid();
for uidb in tpk.userids() {
for tps in uidb.certifications() {
- if let Some(issuer) = tps.get_issuer() {
+ for issuer in tps.get_issuers() {
println!("{}, {:?}, {}",
- issuer.as_u64().unwrap(),
+ KeyID::from(issuer).as_u64().unwrap(),
String::from_utf8_lossy(
uidb.userid().value()),
keyid.as_u64().unwrap());
- } else {
- eprintln!("No issuer!?");
}
}
}
diff --git a/openpgp/src/packet/signature/mod.rs b/openpgp/src/packet/signature/mod.rs
index 4fb15d18..a754bec7 100644
--- a/openpgp/src/packet/signature/mod.rs
+++ b/openpgp/src/packet/signature/mod.rs
@@ -19,7 +19,6 @@ use crate::packet::{
key,
Key,
};
-use crate::KeyID;
use crate::packet::UserID;
use crate::packet::UserAttribute;
use crate::Packet;
@@ -476,13 +475,25 @@ impl Signature4 {
::std::mem::replace(&mut self.level, level)
}
- /// Gets the issuer.
- pub fn get_issuer(&self) -> Option<KeyID> {
- if let Some(id) = self.issuer() {
- Some(id)
- } else {
- None
- }
+ /// Collects all the issuers.
+ ///
+ /// A signature can contain multiple hints as to who issued the
+ /// signature.
+ pub fn get_issuers(&self) -> std::collections::HashSet<crate::KeyHandle> {
+ use crate::packet::signature::subpacket:: SubpacketValue;
+
+ self.hashed_area().iter()
+ .chain(self.unhashed_area().iter())
+ .filter_map(|(_, _, subpacket)| {
+ match subpacket.value() {
+ SubpacketValue::Issuer(i) =>
+ Some(crate::KeyHandle::KeyID(i.clone())),
+ SubpacketValue::IssuerFingerprint(i) =>
+ Some(crate::KeyHandle::Fingerprint(i.clone())),
+ _ => None,
+ }
+ })
+ .collect()
}
/// Normalizes the signature.
@@ -1098,6 +1109,7 @@ impl From<Signature4> for super::Signature {
#[cfg(test)]
mod test {
use super::*;
+ use crate::KeyID;
use crate::conversions::Time;
use crate::crypto;
use crate::crypto::mpis::MPI;
diff --git a/openpgp/src/parse/stream.rs b/openpgp/src/parse/stream.rs
index cca238dc..43120f87 100644
--- a/openpgp/src/parse/stream.rs
+++ b/openpgp/src/parse/stream.rs
@@ -606,8 +606,8 @@ impl<'a, H: VerificationHelper> Verifier<'a, H> {
//
// In this case, we get the issuer from the
// signature itself.
- if let Some(issuer) = sig.get_issuer() {
- issuers.push(issuer);
+ if let Some(issuer) = sig.get_issuers().iter().next() {
+ issuers.push(issuer.clone().into());
} else {
issuers.push(KeyID::wildcard());
}
@@ -656,9 +656,9 @@ impl<'a, H: VerificationHelper> Verifier<'a, H> {
IMessageLayer::SignatureGroup { sigs, .. } => {
results.new_signature_group();
for sig in sigs.into_iter() {
- if let Some(issuer) = sig.get_issuer() {
+ if let Some(issuer) = sig.get_issuers().iter().next() {
let r = if let Some((i, j)) =
- self.keys.get(&issuer)
+ self.keys.get(&issuer.clone().into())
{
let tpk = &self.tpks[*i];
let (binding, revoked, key)
@@ -1421,8 +1421,8 @@ impl<'a, H: VerificationHelper + DecryptionHelper> Decryptor<'a, H> {
//
// In this case, we get the issuer from the
// signature itself.
- if let Some(issuer) = sig.get_issuer() {
- issuers.push(issuer);
+ if let Some(issuer) = sig.get_issuers().iter().next() {
+ issuers.push(issuer.clone().into());
} else {
issuers.push(KeyID::wildcard());
}
@@ -1518,9 +1518,9 @@ impl<'a, H: VerificationHelper + DecryptionHelper> Decryptor<'a, H> {
IMessageLayer::SignatureGroup { sigs, .. } => {
results.new_signature_group();
for sig in sigs.into_iter() {
- if let Some(issuer) = sig.get_issuer() {
+ if let Some(issuer) = sig.get_issuers().iter().next() {
results.push_verification_result(
- if let Some((i, j)) = self.keys.get(&issuer) {
+ if let Some((i, j)) = self.keys.get(&issuer.clone().into()) {
let tpk = &self.tpks[*i];
let (binding, revoked, key)
= tpk.keys_all().nth(*j).unwrap();
diff --git a/tool/src/commands/mod.rs b/tool/src/commands/mod.rs
index 6da5f56b..a7b76038 100644
--- a/tool/src/commands/mod.rs
+++ b/tool/src/commands/mod.rs
@@ -238,8 +238,9 @@ impl<'a> VHelper<'a> {
use self::VerificationResult::*;
for result in results {
if let MissingKey { sig } = result {
- let issuer = sig.get_issuer()
- .expect("missing key checksum has an issuer");
+ let issuer = sig.get_issuers().iter().nth(0)
+ .expect("missing key checksum has an issuer")
+ .to_string();
let what = match sig.level() {
0 => "checksum".into(),
n => format!("level {} notarizing checksum", n),