summaryrefslogtreecommitdiffstats
path: root/tool
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2018-04-12 17:49:00 +0200
committerJustus Winter <justus@sequoia-pgp.org>2018-05-03 17:31:40 +0200
commitfb73ab393c1235d57e6e72514e89f50b24fd14ee (patch)
treed6291d2479413eed8281200f48e3a29f193310f7 /tool
parentc4ee712d84e03164cd77d6e63c7a0cae4496cab8 (diff)
tool: Move the decryption command to a new file.
Diffstat (limited to 'tool')
-rw-r--r--tool/src/commands.rs88
-rw-r--r--tool/src/main.rs83
2 files changed, 91 insertions, 80 deletions
diff --git a/tool/src/commands.rs b/tool/src/commands.rs
new file mode 100644
index 00000000..2f3f3422
--- /dev/null
+++ b/tool/src/commands.rs
@@ -0,0 +1,88 @@
+use failure;
+use std::io;
+use rpassword;
+
+extern crate openpgp;
+use openpgp::{Packet, Tag};
+
+// Indent packets according to their recursion level.
+const INDENT: &'static str
+ = " ";
+
+pub fn decrypt(input: &mut io::Read, output: &mut io::Write, dump: bool)
+ -> Result<(), failure::Error> {
+ #[derive(PartialEq)]
+ enum State {
+ Start,
+ Decrypted(u8, Vec<u8>),
+ Deciphered,
+ Done,
+ }
+ let mut state = State::Start;
+ let mut ppo = openpgp::parse::PacketParser::from_reader(input)?;
+
+ while let Some(mut pp) = ppo {
+ state = match state {
+ // Look for an PKESK or SKESK packet.
+ State::Start =>
+ match pp.packet {
+ Packet::Unknown(ref u) => {
+ match u.tag {
+ Tag::PKESK =>
+ eprintln!("Decryption using PKESK not yet \
+ supported."),
+ _ => (),
+ }
+ State::Start
+ },
+ 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
+ },
+ }
+ },
+ _ => 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)
+ },
+
+ // Look for the literal data packet.
+ State::Deciphered =>
+ if let Packet::Literal(_) = pp.packet {
+ io::copy(&mut pp, output)?;
+ State::Done
+ } else {
+ State::Deciphered
+ },
+
+ // We continue to parse, useful for dumping
+ // encrypted packets.
+ State::Done => State::Done,
+ };
+
+ if dump {
+ eprintln!("{}{:?}",
+ &INDENT[0..pp.recursion_depth as usize], pp.packet);
+ }
+
+ let (_, _, ppo_tmp, _) = pp.recurse()?;
+ ppo = ppo_tmp;
+ }
+
+ if state != State::Done {
+ return Err(failure::err_msg("Decryption failed."));
+ }
+ Ok(())
+}
diff --git a/tool/src/main.rs b/tool/src/main.rs
index 6c7f725e..670e2398 100644
--- a/tool/src/main.rs
+++ b/tool/src/main.rs
@@ -20,12 +20,13 @@ extern crate sequoia_core;
extern crate sequoia_net;
extern crate sequoia_store;
-use openpgp::{armor, Fingerprint, TPK, Packet, Tag};
+use openpgp::{armor, Fingerprint, TPK};
use sequoia_core::{Context, NetworkPolicy};
use sequoia_net::KeyServer;
use sequoia_store::{Store, LogIter};
mod cli;
+mod commands;
fn open_or_stdin(f: Option<&str>) -> Result<Box<io::Read>, failure::Error> {
match f {
@@ -45,84 +46,6 @@ fn create_or_stdout(f: Option<&str>) -> Result<Box<io::Write>, failure::Error> {
const INDENT: &'static str
= " ";
-fn decrypt(input: &mut io::Read, output: &mut io::Write, dump: bool)
- -> Result<(), failure::Error> {
- #[derive(PartialEq)]
- enum State {
- Start,
- Decrypted(u8, Vec<u8>),
- Deciphered,
- Done,
- }
- let mut state = State::Start;
- let mut ppo = openpgp::parse::PacketParser::from_reader(input)?;
-
- while let Some(mut pp) = ppo {
- state = match state {
- // Look for an PKESK or SKESK packet.
- State::Start =>
- match pp.packet {
- Packet::Unknown(ref u) => {
- match u.tag {
- Tag::PKESK =>
- eprintln!("Decryption using PKESK not yet \
- supported."),
- _ => (),
- }
- State::Start
- },
- 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
- },
- }
- },
- _ => 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)
- },
-
- // Look for the literal data packet.
- State::Deciphered =>
- if let Packet::Literal(_) = pp.packet {
- io::copy(&mut pp, output)?;
- State::Done
- } else {
- State::Deciphered
- },
-
- // We continue to parse, useful for dumping
- // encrypted packets.
- State::Done => State::Done,
- };
-
- if dump {
- eprintln!("{}{:?}",
- &INDENT[0..pp.recursion_depth as usize], pp.packet);
- }
-
- let (_, _, ppo_tmp, _) = pp.recurse()?;
- ppo = ppo_tmp;
- }
-
- if state != State::Done {
- return Err(failure::err_msg("Decryption failed."));
- }
- Ok(())
-}
-
fn real_main() -> Result<(), failure::Error> {
let matches = cli::build().get_matches();
@@ -150,7 +73,7 @@ fn real_main() -> Result<(), failure::Error> {
} else {
input
};
- return decrypt(&mut input, &mut output, dump);
+ commands::decrypt(&mut input, &mut output, dump)?;
},
("enarmor", Some(m)) => {
let mut input = open_or_stdin(m.value_of("input"))?;