summaryrefslogtreecommitdiffstats
path: root/tool
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2018-05-28 15:13:10 +0200
committerJustus Winter <justus@sequoia-pgp.org>2018-05-28 18:24:51 +0200
commit412325c7f16c6dd621758799951f0ea95b0ecf60 (patch)
tree47a9329641184ea9f77878bcef4b7b33eae39cbe /tool
parent3e94748e0ee91f105a052c95e842d4eb9ee499b3 (diff)
openpgp: Encrypt with n passphrases.
- Also support decryption with any SKESK in sq.
Diffstat (limited to 'tool')
-rw-r--r--tool/src/commands.rs53
1 files changed, 30 insertions, 23 deletions
diff --git a/tool/src/commands.rs b/tool/src/commands.rs
index 53df3e2b..1dcbd877 100644
--- a/tool/src/commands.rs
+++ b/tool/src/commands.rs
@@ -14,12 +14,11 @@ pub fn decrypt(input: &mut io::Read, output: &mut io::Write,
-> Result<(), failure::Error> {
#[derive(PartialEq)]
enum State {
- Start,
- Decrypted(u8, Vec<u8>),
+ Start(Vec<()>, Vec<openpgp::SKESK>),
Deciphered,
Done,
}
- let mut state = State::Start;
+ let mut state = State::Start(vec![], vec![]);
let mut ppo
= openpgp::parse::PacketParserBuilder::from_reader(input)?
.map(map).finalize()?;
@@ -40,7 +39,7 @@ pub fn decrypt(input: &mut io::Read, output: &mut io::Write,
state = match state {
// Look for an PKESK or SKESK packet.
- State::Start =>
+ State::Start(pkesks, mut skesks) =>
match pp.packet {
Packet::Unknown(ref u) => {
match u.tag {
@@ -49,29 +48,37 @@ pub fn decrypt(input: &mut io::Read, output: &mut io::Write,
supported."),
_ => (),
}
- State::Start
+ State::Start(pkesks, skesks)
},
Packet::SKESK(ref skesk) => {
- let pass = rpassword::prompt_password_stderr(
- "Enter passphrase to decrypt message: ")?;
- match skesk.decrypt(pass.into_bytes().as_ref()) {
- Ok((algo, key)) => State::Decrypted(algo.into(), key),
- Err(e) => {
- eprintln!("Decryption failed: {}", e);
- State::Start
- },
+ // xxx do after recurse and avoid clone
+ skesks.push(skesk.clone());
+ State::Start(pkesks, skesks)
+ },
+ Packet::SEIP(_) => {
+ let mut state = None;
+ for _pkesk in pkesks.iter() {
+ // XXX try to decrypt those
+ }
+ if ! skesks.is_empty() {
+ let pass = rpassword::prompt_password_stderr(
+ "Enter passphrase to decrypt message: ")?
+ .into_bytes();
+
+ for skesk in skesks.iter() {
+ let (algo, key) =
+ skesk.decrypt(&pass)?;
+
+ let r = pp.decrypt(algo, &key[..]);
+ if r.is_ok() {
+ state = Some(State::Deciphered);
+ break;
+ }
+ }
}
+ state.unwrap_or(State::Start(pkesks, skesks))
},
- _ => State::Start,
- },
-
- // Look for an SEIP packet.
- State::Decrypted(algo, key) =>
- if let Packet::SEIP(_) = pp.packet {
- pp.decrypt(algo.into(), &key[..])?;
- State::Deciphered
- } else {
- State::Decrypted(algo, key)
+ _ => State::Start(pkesks, skesks),
},
// Look for the literal data packet.