diff options
author | Justus Winter <justus@sequoia-pgp.org> | 2019-11-27 14:07:58 +0100 |
---|---|---|
committer | Justus Winter <justus@sequoia-pgp.org> | 2019-11-27 14:09:26 +0100 |
commit | 5eb6ad9f545291f05f5f2455684da68594c8a4dd (patch) | |
tree | 4e7aaae032f0aef7c8606a5ddc3c0ff51095fae3 | |
parent | 6fa1c0c42d21c7876c594f9c658742f6639f86b9 (diff) |
openpgp: Fix issuer handling in the streaming verifier.
- To that end, make VerificationHelper::get_public_keys take
KeyHandles for all the issuers.
-rw-r--r-- | guide/src/chapter_01.md | 8 | ||||
-rw-r--r-- | guide/src/chapter_02.md | 8 | ||||
-rw-r--r-- | ipc/examples/gpg-agent-decrypt.rs | 2 | ||||
-rw-r--r-- | ipc/tests/gpg-agent.rs | 4 | ||||
-rw-r--r-- | openpgp-ffi/src/parse/stream.rs | 11 | ||||
-rw-r--r-- | openpgp/examples/decrypt-with.rs | 2 | ||||
-rw-r--r-- | openpgp/examples/generate-encrypt-decrypt.rs | 2 | ||||
-rw-r--r-- | openpgp/examples/generate-sign-verify.rs | 2 | ||||
-rw-r--r-- | openpgp/src/parse/stream.rs | 163 | ||||
-rw-r--r-- | openpgp/src/serialize/stream.rs | 7 | ||||
-rw-r--r-- | tool/src/commands/decrypt.rs | 2 | ||||
-rw-r--r-- | tool/src/commands/mod.rs | 14 |
12 files changed, 130 insertions, 95 deletions
diff --git a/guide/src/chapter_01.md b/guide/src/chapter_01.md index 889e82f1..cc31f3a2 100644 --- a/guide/src/chapter_01.md +++ b/guide/src/chapter_01.md @@ -97,7 +97,7 @@ fn main() { # } # # impl<'a> VerificationHelper for Helper<'a> { -# fn get_public_keys(&mut self, _ids: &[openpgp::KeyID]) +# fn get_public_keys(&mut self, _ids: &[openpgp::KeyHandle]) # -> openpgp::Result<Vec<openpgp::TPK>> { # // Return public keys for signature verification here. # Ok(vec![self.tpk.clone()]) @@ -243,7 +243,7 @@ fn generate() -> openpgp::Result<openpgp::TPK> { # } # # impl<'a> VerificationHelper for Helper<'a> { -# fn get_public_keys(&mut self, _ids: &[openpgp::KeyID]) +# fn get_public_keys(&mut self, _ids: &[openpgp::KeyHandle]) # -> openpgp::Result<Vec<openpgp::TPK>> { # // Return public keys for signature verification here. # Ok(vec![self.tpk.clone()]) @@ -389,7 +389,7 @@ fn sign(sink: &mut Write, plaintext: &str, tsk: &openpgp::TPK) # } # # impl<'a> VerificationHelper for Helper<'a> { -# fn get_public_keys(&mut self, _ids: &[openpgp::KeyID]) +# fn get_public_keys(&mut self, _ids: &[openpgp::KeyHandle]) # -> openpgp::Result<Vec<openpgp::TPK>> { # // Return public keys for signature verification here. # Ok(vec![self.tpk.clone()]) @@ -546,7 +546,7 @@ struct Helper<'a> { } impl<'a> VerificationHelper for Helper<'a> { - fn get_public_keys(&mut self, _ids: &[openpgp::KeyID]) + fn get_public_keys(&mut self, _ids: &[openpgp::KeyHandle]) -> openpgp::Result<Vec<openpgp::TPK>> { // Return public keys for signature verification here. Ok(vec![self.tpk.clone()]) diff --git a/guide/src/chapter_02.md b/guide/src/chapter_02.md index 80ae2fa2..7ebf4461 100644 --- a/guide/src/chapter_02.md +++ b/guide/src/chapter_02.md @@ -105,7 +105,7 @@ fn main() { # } # # impl<'a> VerificationHelper for Helper<'a> { -# fn get_public_keys(&mut self, _ids: &[openpgp::KeyID]) +# fn get_public_keys(&mut self, _ids: &[openpgp::KeyHandle]) # -> openpgp::Result<Vec<openpgp::TPK>> { # // Return public keys for signature verification here. # Ok(Vec::new()) @@ -248,7 +248,7 @@ fn generate() -> openpgp::Result<openpgp::TPK> { # } # # impl<'a> VerificationHelper for Helper<'a> { -# fn get_public_keys(&mut self, _ids: &[openpgp::KeyID]) +# fn get_public_keys(&mut self, _ids: &[openpgp::KeyHandle]) # -> openpgp::Result<Vec<openpgp::TPK>> { # // Return public keys for signature verification here. # Ok(Vec::new()) @@ -391,7 +391,7 @@ fn encrypt(sink: &mut Write, plaintext: &str, recipient: &openpgp::TPK) # } # # impl<'a> VerificationHelper for Helper<'a> { -# fn get_public_keys(&mut self, _ids: &[openpgp::KeyID]) +# fn get_public_keys(&mut self, _ids: &[openpgp::KeyHandle]) # -> openpgp::Result<Vec<openpgp::TPK>> { # // Return public keys for signature verification here. # Ok(Vec::new()) @@ -548,7 +548,7 @@ struct Helper<'a> { } impl<'a> VerificationHelper for Helper<'a> { - fn get_public_keys(&mut self, _ids: &[openpgp::KeyID]) + fn get_public_keys(&mut self, _ids: &[openpgp::KeyHandle]) -> openpgp::Result<Vec<openpgp::TPK>> { // Return public keys for signature verification here. Ok(Vec::new()) diff --git a/ipc/examples/gpg-agent-decrypt.rs b/ipc/examples/gpg-agent-decrypt.rs index 3eeb140d..345cdd74 100644 --- a/ipc/examples/gpg-agent-decrypt.rs +++ b/ipc/examples/gpg-agent-decrypt.rs @@ -112,7 +112,7 @@ impl<'a> DecryptionHelper for Helper<'a> { } impl<'a> VerificationHelper for Helper<'a> { - fn get_public_keys(&mut self, _ids: &[openpgp::KeyID]) + fn get_public_keys(&mut self, _ids: &[openpgp::KeyHandle]) -> failure::Fallible<Vec<openpgp::TPK>> { Ok(Vec::new()) // Feed the TPKs to the verifier here. } diff --git a/ipc/tests/gpg-agent.rs b/ipc/tests/gpg-agent.rs index 5ebdd281..26887f42 100644 --- a/ipc/tests/gpg-agent.rs +++ b/ipc/tests/gpg-agent.rs @@ -140,7 +140,7 @@ fn sign() { } impl<'a> VerificationHelper for Helper<'a> { - fn get_public_keys(&mut self, _ids: &[openpgp::KeyID]) + fn get_public_keys(&mut self, _ids: &[openpgp::KeyHandle]) -> openpgp::Result<Vec<openpgp::TPK>> { // Return public keys for signature verification here. Ok(vec![self.tpk.clone()]) @@ -251,7 +251,7 @@ fn decrypt() { } impl<'a> VerificationHelper for Helper<'a> { - fn get_public_keys(&mut self, _ids: &[openpgp::KeyID]) + fn get_public_keys(&mut self, _ids: &[openpgp::KeyHandle]) -> openpgp::Result<Vec<openpgp::TPK>> { // Return public keys for signature verification here. Ok(Vec::new()) diff --git a/openpgp-ffi/src/parse/stream.rs b/openpgp-ffi/src/parse/stream.rs index 608c7b85..6e38739b 100644 --- a/openpgp-ffi/src/parse/stream.rs +++ b/openpgp-ffi/src/parse/stream.rs @@ -334,13 +334,14 @@ impl VHelper { } impl VerificationHelper for VHelper { - fn get_public_keys(&mut self, ids: &[openpgp::KeyID]) + fn get_public_keys(&mut self, ids: &[openpgp::KeyHandle]) -> Result<Vec<openpgp::TPK>, failure::Error> { - // The size of KeyID is not known in C. Convert from an array - // of KeyIDs to an array of KeyID refs. + // The size of ID is not known in C. Convert to KeyID, and + // move it to C. let ids : Vec<*mut keyid::KeyID> = - ids.iter().map(|k| k.move_into_raw()).collect(); + ids.iter().map(|k| openpgp::KeyID::from(k.clone()).move_into_raw()) + .collect(); let mut tpk_refs_raw : *mut *mut TPK = ptr::null_mut(); let mut tpk_refs_raw_len = 0usize; @@ -657,7 +658,7 @@ impl DHelper { } impl VerificationHelper for DHelper { - fn get_public_keys(&mut self, ids: &[openpgp::KeyID]) + fn get_public_keys(&mut self, ids: &[openpgp::KeyHandle]) -> Result<Vec<openpgp::TPK>, failure::Error> { self.vhelper.get_public_keys(ids) diff --git a/openpgp/examples/decrypt-with.rs b/openpgp/examples/decrypt-with.rs index 050f54d0..d630a3e6 100644 --- a/openpgp/examples/decrypt-with.rs +++ b/openpgp/examples/decrypt-with.rs @@ -105,7 +105,7 @@ impl DecryptionHelper for Helper { } impl VerificationHelper for Helper { - fn get_public_keys(&mut self, _ids: &[openpgp::KeyID]) + fn get_public_keys(&mut self, _ids: &[openpgp::KeyHandle]) -> failure::Fallible<Vec<openpgp::TPK>> { Ok(Vec::new()) // Feed the TPKs to the verifier here. } diff --git a/openpgp/examples/generate-encrypt-decrypt.rs b/openpgp/examples/generate-encrypt-decrypt.rs index 995ecabd..ddba52e5 100644 --- a/openpgp/examples/generate-encrypt-decrypt.rs +++ b/openpgp/examples/generate-encrypt-decrypt.rs @@ -96,7 +96,7 @@ struct Helper<'a> { } impl<'a> VerificationHelper for Helper<'a> { - fn get_public_keys(&mut self, _ids: &[openpgp::KeyID]) + fn get_public_keys(&mut self, _ids: &[openpgp::KeyHandle]) -> openpgp::Result<Vec<openpgp::TPK>> { // Return public keys for signature verification here. Ok(Vec::new()) diff --git a/openpgp/examples/generate-sign-verify.rs b/openpgp/examples/generate-sign-verify.rs index 6c43f25c..f937dd84 100644 --- a/openpgp/examples/generate-sign-verify.rs +++ b/openpgp/examples/generate-sign-verify.rs @@ -85,7 +85,7 @@ struct Helper<'a> { } impl<'a> VerificationHelper for Helper<'a> { - fn get_public_keys(&mut self, _ids: &[openpgp::KeyID]) + fn get_public_keys(&mut self, _ids: &[openpgp::KeyHandle]) -> openpgp::Result<Vec<openpgp::TPK>> { // Return public keys for signature verification here. Ok(vec![self.tpk.clone()]) diff --git a/openpgp/src/parse/stream.rs b/openpgp/src/parse/stream.rs index 43120f87..7a6d2917 100644 --- a/openpgp/src/parse/stream.rs +++ b/openpgp/src/parse/stream.rs @@ -87,7 +87,7 @@ const BUFFER_SIZE: usize = 25 * 1024 * 1024; /// // This fetches keys and computes the validity of the verification. /// struct Helper {}; /// impl VerificationHelper for Helper { -/// fn get_public_keys(&mut self, _ids: &[KeyID]) -> Result<Vec<TPK>> { +/// fn get_public_keys(&mut self, _ids: &[openpgp::KeyHandle]) -> Result<Vec<TPK>> { /// Ok(Vec::new()) // Feed the TPKs to the verifier here... /// } /// fn check(&mut self, structure: &MessageStructure) -> Result<()> { @@ -125,7 +125,7 @@ pub struct Verifier<'a, H: VerificationHelper> { helper: H, tpks: Vec<TPK>, /// Maps KeyID to tpks[i].keys_all().nth(j). - keys: HashMap<KeyID, (usize, usize)>, + keys: HashMap<crate::KeyHandle, (usize, usize)>, oppr: Option<PacketParserResult<'a>>, structure: IMessageStructure, @@ -429,7 +429,7 @@ enum IMessageLayer { /// Helper for signature verification. pub trait VerificationHelper { /// Retrieves the TPKs containing the specified keys. - fn get_public_keys(&mut self, _: &[KeyID]) -> Result<Vec<TPK>>; + fn get_public_keys(&mut self, _: &[crate::KeyHandle]) -> Result<Vec<TPK>>; /// Conveys the message structure. /// @@ -569,7 +569,7 @@ impl<'a, H: VerificationHelper> Verifier<'a, H> { v.structure.new_compression_layer(p.algorithm()), Packet::OnePassSig(ref ops) => { v.structure.push_ops(ops); - issuers.push(ops.issuer().clone()); + issuers.push(ops.issuer().clone().into()); }, Packet::Literal(_) => { v.structure.insert_missing_signature_group(); @@ -579,13 +579,16 @@ impl<'a, H: VerificationHelper> Verifier<'a, H> { for (i, tpk) in v.tpks.iter().enumerate() { if can_sign(tpk.primary(), tpk.primary_key_signature(None), t) { - v.keys.insert(tpk.keyid(), (i, 0)); + v.keys.insert(tpk.fingerprint().into(), (i, 0)); + v.keys.insert(tpk.keyid().into(), (i, 0)); } for (j, skb) in tpk.subkeys().enumerate() { let key = skb.key(); if can_sign(key, skb.binding_signature(None), t) { - v.keys.insert(key.keyid(), + v.keys.insert(key.fingerprint().into(), + (i, j + 1)); + v.keys.insert(key.keyid().into(), (i, j + 1)); } } @@ -606,10 +609,13 @@ impl<'a, H: VerificationHelper> Verifier<'a, H> { // // In this case, we get the issuer from the // signature itself. - if let Some(issuer) = sig.get_issuers().iter().next() { - issuers.push(issuer.clone().into()); + let sig_issuers = sig.get_issuers(); + if sig_issuers.is_empty() { + issuers.push(KeyID::wildcard().into()); } else { - issuers.push(KeyID::wildcard()); + for issuer in sig_issuers { + issuers.push(issuer); + } } v.structure.push_bare_signature(sig); @@ -655,38 +661,44 @@ impl<'a, H: VerificationHelper> Verifier<'a, H> { unreachable!("not decrypting messages"), IMessageLayer::SignatureGroup { sigs, .. } => { results.new_signature_group(); - for sig in sigs.into_iter() { - if let Some(issuer) = sig.get_issuers().iter().next() { - let r = if let Some((i, j)) = - self.keys.get(&issuer.clone().into()) - { + 'sigs: for sig in sigs.into_iter() { + for issuer in sig.get_issuers() { + if let Some((i, j)) = self.keys.get(&issuer) { let tpk = &self.tpks[*i]; let (binding, revoked, key) = tpk.keys_all().nth(*j).unwrap(); - if sig.verify(key).unwrap_or(false) { - if sig.signature_alive(self.time, None) { - VerificationResult::GoodChecksum { - sig, tpk, key, binding, revoked, + results.push_verification_result( + if sig.verify(key).unwrap_or(false) { + if sig.signature_alive(self.time, None) + { + VerificationResult::GoodChecksum { + sig: sig.clone(), + tpk, key, binding, revoked, + } + } else { + VerificationResult::NotAlive { + sig: sig.clone(), + tpk, key, binding, revoked, + } } } else { - VerificationResult::NotAlive { - sig, tpk, key, binding, revoked, + VerificationResult::BadChecksum { + sig: sig.clone(), + tpk, key, binding, revoked, } } - } else { - VerificationResult::BadChecksum { - sig, tpk, key, binding, revoked, - } - } - } else { - VerificationResult::MissingKey { - sig, - } - }; - results.push_verification_result(r); - } else { - // No issuer, ignore malformed signature. + ); + + // We found a key, continue to next sig. + continue 'sigs; + } } + + results.push_verification_result( + VerificationResult::MissingKey { + sig, + } + ); } }, } @@ -988,7 +1000,7 @@ impl<'a> io::Read for Transformer<'a> { /// // This fetches keys and computes the validity of the verification. /// struct Helper {}; /// impl VerificationHelper for Helper { -/// fn get_public_keys(&mut self, _ids: &[KeyID]) -> Result<Vec<TPK>> { +/// fn get_public_keys(&mut self, _ids: &[openpgp::KeyHandle]) -> Result<Vec<TPK>> { /// Ok(Vec::new()) // Feed the TPKs to the verifier here... /// } /// fn check(&mut self, structure: &MessageStructure) -> Result<()> { @@ -1128,7 +1140,7 @@ impl DetachedVerifier { /// // This fetches keys and computes the validity of the verification. /// struct Helper {}; /// impl VerificationHelper for Helper { -/// fn get_public_keys(&mut self, _ids: &[KeyID]) -> Result<Vec<TPK>> { +/// fn get_public_keys(&mut self, _ids: &[openpgp::KeyHandle]) -> Result<Vec<TPK>> { /// Ok(Vec::new()) // Feed the TPKs to the verifier here... /// } /// fn check(&mut self, structure: &MessageStructure) -> Result<()> { @@ -1175,7 +1187,7 @@ pub struct Decryptor<'a, H: VerificationHelper + DecryptionHelper> { helper: H, tpks: Vec<TPK>, /// Maps KeyID to tpks[i].keys_all().nth(j). - keys: HashMap<KeyID, (usize, usize)>, + keys: HashMap<crate::KeyHandle, (usize, usize)>, oppr: Option<PacketParserResult<'a>>, identity: Option<Fingerprint>, structure: IMessageStructure, @@ -1364,7 +1376,7 @@ impl<'a, H: VerificationHelper + DecryptionHelper> Decryptor<'a, H> { }, Packet::OnePassSig(ref ops) => { v.structure.push_ops(ops); - issuers.push(ops.issuer().clone()); + issuers.push(ops.issuer().clone().into()); }, Packet::Literal(_) => { v.structure.insert_missing_signature_group(); @@ -1387,13 +1399,17 @@ impl<'a, H: VerificationHelper + DecryptionHelper> Decryptor<'a, H> { if can_sign(tpk.primary().into(), tpk.primary_key_signature(None)) { - v.keys.insert(tpk.keyid(), (i, 0)); + v.keys.insert(tpk.fingerprint().into(), (i, 0)); + v.keys.insert(tpk.keyid().into(), (i, 0)); } for (j, skb) in tpk.subkeys().enumerate() { let key = skb.key(); if can_sign(key.into(), skb.binding_signature(None)) { - v.keys.insert(key.keyid(), (i, j + 1)); + v.keys.insert(key.fingerprint().into(), + (i, j + 1)); + v.keys.insert(key.keyid().into(), + (i, j + 1)); } } } @@ -1421,10 +1437,13 @@ 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_issuers().iter().next() { - issuers.push(issuer.clone().into()); + let sig_issuers = sig.get_issuers(); + if sig_issuers.is_empty() { + issuers.push(KeyID::wildcard().into()); } else { - issuers.push(KeyID::wildcard()); + for issuer in sig_issuers { + issuers.push(issuer); + } } } v.structure.push_bare_signature(sig); @@ -1517,13 +1536,13 @@ impl<'a, H: VerificationHelper + DecryptionHelper> Decryptor<'a, H> { results.new_encryption_layer(sym_algo, aead_algo), IMessageLayer::SignatureGroup { sigs, .. } => { results.new_signature_group(); - for sig in sigs.into_iter() { - if let Some(issuer) = sig.get_issuers().iter().next() { - results.push_verification_result( - 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(); + 'sigs: for sig in sigs.into_iter() { + for issuer in sig.get_issuers() { + if let Some((i, j)) = self.keys.get(&issuer) { + let tpk = &self.tpks[*i]; + let (binding, revoked, key) + = tpk.keys_all().nth(*j).unwrap(); + results.push_verification_result( if sig.verify(key).unwrap_or(false) && sig.signature_alive(self.time, None) { @@ -1542,33 +1561,42 @@ impl<'a, H: VerificationHelper + DecryptionHelper> Decryptor<'a, H> { // the signature as // bad. VerificationResult::BadChecksum - { sig, tpk, key, binding, - revoked, } + { + sig: sig.clone(), + tpk, key, binding, revoked, + } } else { VerificationResult::GoodChecksum - { sig, tpk, key, binding, - revoked, } + { + sig: sig.clone(), + tpk, key, binding, revoked, + } } } else { // No identity information. - VerificationResult::GoodChecksum - { sig, tpk, key, binding, - revoked, } + VerificationResult::GoodChecksum { + sig: sig.clone(), + tpk, key, binding, revoked, + } } } else { VerificationResult::BadChecksum { - sig, tpk, key, binding, revoked, + sig: sig.clone(), + tpk, key, binding, revoked, } } - } else { - VerificationResult::MissingKey { - sig, - } - } - ); - } else { - // No issuer, ignore malformed signature. + ); + + // We found a key, continue to next sig. + continue 'sigs; + } } + + results.push_verification_result( + VerificationResult::MissingKey { + sig, + } + ); } }, } @@ -1682,7 +1710,7 @@ mod test { } impl VerificationHelper for VHelper { - fn get_public_keys(&mut self, _ids: &[KeyID]) -> Result<Vec<TPK>> { + fn get_public_keys(&mut self, _ids: &[crate::KeyHandle]) -> Result<Vec<TPK>> { Ok(self.keys.clone()) } @@ -1803,7 +1831,8 @@ mod test { fn verifier_levels() { struct VHelper(()); impl VerificationHelper for VHelper { - fn get_public_keys(&mut self, _ids: &[KeyID]) -> Result<Vec<TPK>> { + fn get_public_keys(&mut self, _ids: &[crate::KeyHandle]) + -> Result<Vec<TPK>> { Ok(Vec::new()) } diff --git a/openpgp/src/serialize/stream.rs b/openpgp/src/serialize/stream.rs index c533124b..c0c8424d 100644 --- a/openpgp/src/serialize/stream.rs +++ b/openpgp/src/serialize/stream.rs @@ -247,7 +247,7 @@ impl<'a> Signer<'a> { /// // Now check the signature. /// struct Helper<'a>(&'a openpgp::TPK); /// impl<'a> VerificationHelper for Helper<'a> { - /// fn get_public_keys(&mut self, _: &[openpgp::KeyID]) + /// fn get_public_keys(&mut self, _: &[openpgp::KeyHandle]) /// -> openpgp::Result<Vec<openpgp::TPK>> { /// Ok(vec![self.0.clone()]) /// } @@ -351,7 +351,7 @@ impl<'a> Signer<'a> { /// // Now check the signature. /// struct Helper<'a>(&'a openpgp::TPK); /// impl<'a> VerificationHelper for Helper<'a> { - /// fn get_public_keys(&mut self, _: &[openpgp::KeyID]) + /// fn get_public_keys(&mut self, _: &[openpgp::KeyHandle]) /// -> openpgp::Result<Vec<openpgp::TPK>> { /// Ok(vec![self.0.clone()]) /// } @@ -1661,7 +1661,8 @@ mod test { tsk: &'a TPK, }; impl<'a> VerificationHelper for Helper<'a> { - fn get_public_keys(&mut self, _ids: &[KeyID]) -> Result<Vec<TPK>> { + fn get_public_keys(&mut self, _ids: &[crate::KeyHandle]) + -> Result<Vec<TPK>> { Ok(Vec::new()) } fn check(&mut self, _structure: &MessageStructure) -> Result<()> { diff --git a/tool/src/commands/decrypt.rs b/tool/src/commands/decrypt.rs index b85e6797..33725290 100644 --- a/tool/src/commands/decrypt.rs +++ b/tool/src/commands/decrypt.rs @@ -123,7 +123,7 @@ impl<'a> Helper<'a> { } impl<'a> VerificationHelper for Helper<'a> { |