summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2019-09-06 16:28:27 +0200
committerJustus Winter <justus@sequoia-pgp.org>2019-09-06 16:42:12 +0200
commit6aef02cd7e182587a488c952f6b9771ce50a10ec (patch)
tree27375090e73cb67ceb2b3303a290aa5164d43185
parentb5b37595a0393130239e23d0aeb342890a1ed67f (diff)
tool: Support decrypting messages with wildcard recipients.
-rw-r--r--tool/src/commands/decrypt.rs60
1 files changed, 60 insertions, 0 deletions
diff --git a/tool/src/commands/decrypt.rs b/tool/src/commands/decrypt.rs
index 20811618..444f1cbd 100644
--- a/tool/src/commands/decrypt.rs
+++ b/tool/src/commands/decrypt.rs
@@ -205,6 +205,66 @@ impl<'a> DecryptionHelper for Helper<'a> {
}
}
+ // Third, we try to decrypt PKESK packets with wildcard
+ // recipients using those keys that we can use without
+ // prompting for a password.
+ for pkesk in pkesks.iter().filter(|p| p.recipient().is_wildcard()) {
+ for key in self.secret_keys.values() {
+ if key.secret().map(|s| ! s.is_encrypted()).unwrap_or(false) {
+ if let Ok(fp) = key.clone().into_keypair()
+ .and_then(|mut k|
+ self.try_decrypt(pkesk, &mut k, &mut decrypt))
+ {
+ return Ok(fp);
+ }
+ }
+ }
+ }
+
+ // Fourth, we try to decrypt PKESK packets with wildcard
+ // recipients using those keys that are encrypted.
+ for pkesk in pkesks.iter().filter(|p| p.recipient().is_wildcard()) {
+ // Don't ask the user to decrypt a key if we don't support
+ // the algorithm.
+ if ! pkesk.pk_algo().is_supported() {
+ continue;
+ }
+
+ // To appease the borrow checker, iterate over the
+ // hashmap, awkwardly.
+ for keyid in self.secret_keys.keys().cloned().collect::<Vec<_>>()
+ {
+ let mut keypair = loop {
+ let key = self.secret_keys.get_mut(&keyid).unwrap(); // Yuck
+
+ if key.secret().map(|s| ! s.is_encrypted()).unwrap_or(false)
+ {
+ break key.clone().into_keypair().unwrap();
+ }
+
+ let p = rpassword::read_password_from_tty(Some(
+ &format!(
+ "Enter password to decrypt key {}: ",
+ self.key_hints.get(&keyid).unwrap())))?.into();
+
+ let algo = key.pk_algo();
+ if let Some(()) =
+ key.secret_mut()
+ .and_then(|s| s.decrypt_in_place(algo, &p).ok())
+ {
+ break key.clone().into_keypair().unwrap()
+ } else {
+ eprintln!("Bad password.");
+ }
+ };
+
+ if let Ok(fp) = self.try_decrypt(pkesk, &mut keypair,
+ &mut decrypt) {
+ return Ok(fp);
+ }
+ }
+ }
+
if skesks.is_empty() {
return
Err(failure::err_msg("No key to decrypt message"));