summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKai Michaelis <kai@sequoia-pgp.org>2019-01-18 15:08:40 +0100
committerKai Michaelis <kai@sequoia-pgp.org>2019-01-18 15:10:15 +0100
commitf3d87851bcc4e82f22f49c6ceb9a385fc97eca86 (patch)
treedb415b2b38c8c240216a3338fee421f65c5cf713
parent37b79c2cca645cac52a5c2ca9cbcd083b78dc40a (diff)
sqv: ensure keys are signing capable before verifying sigs
Closes #164
-rw-r--r--sqv/src/sqv.rs13
-rw-r--r--sqv/tests/data/no-signing-caps.keybin0 -> 1718 bytes
-rw-r--r--sqv/tests/data/no-signing-caps.sigbin0 -> 438 bytes
-rw-r--r--sqv/tests/wrong-key-flags.rs71
4 files changed, 83 insertions, 1 deletions
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
--- /dev/null
+++ b/sqv/tests/data/no-signing-caps.key
Binary files 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
--- /dev/null
+++ b/sqv/tests/data/no-signing-caps.sig
Binary files 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();
+// }
+// }