summaryrefslogtreecommitdiffstats
path: root/openpgp/examples/sign.rs
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2018-12-20 17:42:00 +0100
committerJustus Winter <justus@sequoia-pgp.org>2019-01-15 14:09:15 +0100
commit5bef3bde45f71126cdca3e8ad30b1047287c843a (patch)
treee3b45081b6fc33115ce199716824d418d088f26c /openpgp/examples/sign.rs
parentf8a502c6b18e097bf1082877f3b6b2f5c99f3a41 (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.rs36
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