From f3d87851bcc4e82f22f49c6ceb9a385fc97eca86 Mon Sep 17 00:00:00 2001 From: Kai Michaelis Date: Fri, 18 Jan 2019 15:08:40 +0100 Subject: sqv: ensure keys are signing capable before verifying sigs Closes #164 --- sqv/src/sqv.rs | 13 ++++++- sqv/tests/data/no-signing-caps.key | Bin 0 -> 1718 bytes sqv/tests/data/no-signing-caps.sig | Bin 0 -> 438 bytes sqv/tests/wrong-key-flags.rs | 71 +++++++++++++++++++++++++++++++++++++ 4 files changed, 83 insertions(+), 1 deletion(-) create mode 100644 sqv/tests/data/no-signing-caps.key create mode 100644 sqv/tests/data/no-signing-caps.sig create mode 100644 sqv/tests/wrong-key-flags.rs (limited to 'sqv') diff --git a/sqv/src/sqv.rs b/sqv/src/sqv.rs index ca11d035..fc8a98a3 100644 --- a/sqv/src/sqv.rs +++ b/sqv/src/sqv.rs @@ -214,8 +214,19 @@ fn real_main() -> Result<(), failure::Error> { if let Some(ref tpk) = tpko { // Find the right key. - for (_, _, key) in tpk.keys() { + for (maybe_binding, _, key) in tpk.keys() { + let binding = match maybe_binding { + Some(b) => b, + None => continue, + }; + if issuer == key.keyid() { + if !binding.key_flags().can_sign() { + eprintln!("Cannot check signature, key has no siginig \ + capability"); + continue 'sig_loop; + } + let mut hash = match hashes.get(&sig.hash_algo()) { Some(h) => h.clone(), None => { diff --git a/sqv/tests/data/no-signing-caps.key b/sqv/tests/data/no-signing-caps.key new file mode 100644 index 00000000..7aabd532 Binary files /dev/null and b/sqv/tests/data/no-signing-caps.key differ diff --git a/sqv/tests/data/no-signing-caps.sig b/sqv/tests/data/no-signing-caps.sig new file mode 100644 index 00000000..c32210d4 Binary files /dev/null and b/sqv/tests/data/no-signing-caps.sig differ diff --git a/sqv/tests/wrong-key-flags.rs b/sqv/tests/wrong-key-flags.rs new file mode 100644 index 00000000..e7e73cf7 --- /dev/null +++ b/sqv/tests/wrong-key-flags.rs @@ -0,0 +1,71 @@ +extern crate assert_cli; + +#[cfg(test)] +mod integration { + use assert_cli::Assert; + use std::path; + + #[test] + fn not_signing_capable_subkey() { + Assert::cargo_binary("sqv") + .current_dir(path::Path::new("tests").join("data")) + .with_args( + &["--keyring", + &"no-signing-caps.key", + &"no-signing-caps.sig", + &"msg.txt"]) + .fails() + .unwrap(); + } +} + +// Code to create the data for the test cases above +// extern crate sequoia_openpgp; +// +// #[test] +// fn create_key() { +// use std::fs::File; +// use sequoia_openpgp::{ +// tpk::TPKBuilder, +// packet::{ +// signature, +// key::SecretKey, +// }, +// crypto::KeyPair, +// serialize::Serialize, +// constants::{ +// SignatureType, +// HashAlgorithm, +// } +// }; +// +// let (tpk, _) = TPKBuilder::default() +// .add_userid("Testy Mc Test") +// .add_encryption_subkey() +// .generate().unwrap(); +// let subkey = tpk.subkeys().next().unwrap(); +// let key = subkey.subkey(); +// let sig = { +// let mpis = match key.secret() { +// Some(SecretKey::Unencrypted{ ref mpis }) => mpis, +// _ => unreachable!(), +// }; +// let mut b = signature::Builder::new(SignatureType::Binary); +// b.set_signature_creation_time(time::now()).unwrap(); +// b.set_issuer_fingerprint(key.fingerprint()).unwrap(); +// b.set_issuer(key.fingerprint().to_keyid()).unwrap(); +// b.sign_message( +// &mut KeyPair::new(key.clone(), mpis.clone()).unwrap(), +// HashAlgorithm::SHA512, b"Hello, World").unwrap() +// }; +// +// { +// let mut fd = File::create("key").unwrap(); +// tpk.serialize(&mut fd).unwrap(); +// } +// +// { +// let mut fd = File::create("sig").unwrap(); +// sig.serialize(&mut fd).unwrap(); +// } +// } -- cgit v1.2.3