diff options
author | Justus Winter <justus@sequoia-pgp.org> | 2018-12-20 17:42:00 +0100 |
---|---|---|
committer | Justus Winter <justus@sequoia-pgp.org> | 2019-01-15 14:09:15 +0100 |
commit | 5bef3bde45f71126cdca3e8ad30b1047287c843a (patch) | |
tree | e3b45081b6fc33115ce199716824d418d088f26c /openpgp/examples/sign.rs | |
parent | f8a502c6b18e097bf1082877f3b6b2f5c99f3a41 (diff) |
openpgp: Hand a Vec<crypto::Signer> to stream::Signer.
- Using `crypto::Signer`s has several benefits. First, it shifts
the decision which key to use to the caller, moving policy out of
the caller. Second, it forces the caller to deal with encrypted
keys. Finally, it allows us to use remote keys like smart cards
in the future.
- Fixes #142.
Diffstat (limited to 'openpgp/examples/sign.rs')
-rw-r--r-- | openpgp/examples/sign.rs | 36 |
1 files changed, 31 insertions, 5 deletions
diff --git a/openpgp/examples/sign.rs b/openpgp/examples/sign.rs index 961c9597..c3ee0728 100644 --- a/openpgp/examples/sign.rs +++ b/openpgp/examples/sign.rs @@ -5,7 +5,9 @@ use std::io; extern crate sequoia_openpgp as openpgp; use openpgp::armor; +use openpgp::crypto; use openpgp::constants::DataFormat; +use openpgp::packet::key::SecretKey; use openpgp::parse::Parse; use openpgp::serialize::stream::{Message, LiteralWriter, Signer}; @@ -18,10 +20,33 @@ fn main() { } // Read the transferable secret keys from the given files. - let tsks: Vec<openpgp::TPK> = args[1..].iter().map(|f| { - openpgp::TPK::from_file(f) - .expect("Failed to read key") - }).collect(); + let mut keys = Vec::new(); + 'nextfile: for filename in &args[1..] { + let tsk = openpgp::TPK::from_file(filename) + .expect("Failed to read key"); + + for key in tsk.select_signing_keys(None) { + if let Some(mut secret) = key.secret() { + let secret_mpis = match secret { + SecretKey::Encrypted { .. } => { + let password = rpassword::prompt_password_stderr( + &format!("Please enter password to decrypt {}/{}: ", + tsk, key)).unwrap(); + secret.decrypt(key.pk_algo(), &password.into()) + .expect("decryption failed") + }, + SecretKey::Unencrypted { ref mpis } => + mpis.clone(), + }; + + keys.push(crypto::KeyPair::new(key.clone(), secret_mpis) + .unwrap()); + break 'nextfile; + } + } + + panic!("Found no suitable signing key on {}", tsk); + } // Compose a writer stack corresponding to the output format and // packet structure we want. First, we want the output to be @@ -34,7 +59,8 @@ fn main() { // Now, create a signer that emits a signature. let signer = Signer::new( - message, &tsks.iter().collect::<Vec<&openpgp::TPK>>()) + message, + keys.iter_mut().map(|s| -> &mut dyn crypto::Signer { s }).collect()) .expect("Failed to create signer"); // Then, create a literal writer to wrap the data in a literal |