diff options
author | Nora Widdecke <nora@sequoia-pgp.org> | 2022-06-29 19:11:00 +0200 |
---|---|---|
committer | Nora Widdecke <nora@sequoia-pgp.org> | 2022-06-29 19:19:28 +0200 |
commit | fbfb792c0a6d41397daf5475d25db7785f689b03 (patch) | |
tree | de02aa4fbf0ef82e2f30625e10f354fb0f84537d | |
parent | 56ad63f1b12f41ec38eddf2a2e8131a66a2e22fa (diff) |
sq: Add packet decrypt --session-key.
- Allow giving multiple session keys, try them all until one decrypts
the packet.
-rw-r--r-- | sq/src/commands/decrypt.rs | 6 | ||||
-rw-r--r-- | sq/src/sq-usage.rs | 3 | ||||
-rw-r--r-- | sq/src/sq.rs | 2 | ||||
-rw-r--r-- | sq/src/sq_cli.rs | 6 | ||||
-rw-r--r-- | sq/tests/sq-packet-decrypt.rs | 75 |
5 files changed, 90 insertions, 2 deletions
diff --git a/sq/src/commands/decrypt.rs b/sq/src/commands/decrypt.rs index 312b4a40..8e362621 100644 --- a/sq/src/commands/decrypt.rs +++ b/sq/src/commands/decrypt.rs @@ -393,11 +393,13 @@ pub fn decrypt(config: Config, pub fn decrypt_unwrap(config: Config, input: &mut (dyn io::Read + Sync + Send), output: &mut dyn io::Write, - secrets: Vec<Cert>, dump_session_key: bool) + secrets: Vec<Cert>, + session_keys: Vec<CliSessionKey>, + dump_session_key: bool) -> Result<()> { let mut helper = Helper::new(&config, None, 0, Vec::new(), secrets, - Vec::new(), + session_keys, dump_session_key, false); let mut ppr = PacketParser::from_reader(input)?; diff --git a/sq/src/sq-usage.rs b/sq/src/sq-usage.rs index 7b2bc0df..05f2c7fa 100644 --- a/sq/src/sq-usage.rs +++ b/sq/src/sq-usage.rs @@ -1557,6 +1557,9 @@ //! --recipient-key <KEY> //! Decrypts the message with KEY //! +//! --session-key <SESSION-KEY> +//! Decrypts an encrypted message using SESSION-KEY +//! //! EXAMPLES: //! //! # Unwraps the encryption revealing the signed message diff --git a/sq/src/sq.rs b/sq/src/sq.rs index 108a47f6..1ad1f500 100644 --- a/sq/src/sq.rs +++ b/sq/src/sq.rs @@ -695,10 +695,12 @@ fn main() -> Result<()> { let secrets = load_keys(command.secret_key_file.iter().map(|s| s.as_ref()))?; + let session_keys = command.session_key; commands::decrypt::decrypt_unwrap( config, &mut input, &mut output, secrets, + session_keys, command.dump_session_key)?; output.finalize()?; }, diff --git a/sq/src/sq_cli.rs b/sq/src/sq_cli.rs index 9d6dfb86..076ce430 100644 --- a/sq/src/sq_cli.rs +++ b/sq/src/sq_cli.rs @@ -519,6 +519,12 @@ pub struct PacketDecryptCommand { )] pub private_key_store: Option<String>, #[clap( + long = "session-key", + value_name = "SESSION-KEY", + help = "Decrypts an encrypted message using SESSION-KEY", + )] + pub session_key: Vec<CliSessionKey>, + #[clap( long = "dump-session-key", help = "Prints the session key to stderr", )] diff --git a/sq/tests/sq-packet-decrypt.rs b/sq/tests/sq-packet-decrypt.rs new file mode 100644 index 00000000..5a466ac7 --- /dev/null +++ b/sq/tests/sq-packet-decrypt.rs @@ -0,0 +1,75 @@ +#[cfg(test)] +mod sq_packet_decrypt { + use assert_cmd::Command; + use predicates::prelude::*; + + use openpgp::Result; + use sequoia_openpgp as openpgp; + + fn artifact(filename: &str) -> String { + format!("tests/data/{}", filename) + } + + // Integration tests should be done with subplot. + // However, at this time, subplot does not support static binary files in tests. + // Generating the test files would mean encrypting some static text symmetrically + // and then extracting the session key, which means parsing of human readabe cli output. + // So, for now, the tests go here. + #[test] + fn session_key() -> Result<()> { + Command::cargo_bin("sq") + .unwrap() + .arg("packet") + .arg("decrypt") + .args(["--session-key", "1FE820EC21FB5D7E33D83367106D1D3747DCD48E6320C1AEC57EE7D18FC437D4"]) + .arg(artifact("messages/rsa.msg.pgp")) + .assert() + .success() + .stderr(predicate::str::contains("Encrypted with Session Key")); + Ok(()) + } + + #[test] + fn session_key_with_prefix() -> Result<()> { + Command::cargo_bin("sq") + .unwrap() + .arg("packet") + .arg("decrypt") + .args(["--session-key", "9:1FE820EC21FB5D7E33D83367106D1D3747DCD48E6320C1AEC57EE7D18FC437D4"]) + .arg(artifact("messages/rsa.msg.pgp")) + .assert() + .success() + .stderr(predicate::str::contains("Decryption failed").not()); + Ok(()) + } + + #[test] + fn session_key_multiple() -> Result<()> { + Command::cargo_bin("sq") + .unwrap() + .arg("packet") + .arg("decrypt") + .args(["--session-key", "2FE820EC21FB5D7E33D83367106D1D3747DCD48E6320C1AEC57EE7D18FC437D4"]) + .args(["--session-key", "9:1FE820EC21FB5D7E33D83367106D1D3747DCD48E6320C1AEC57EE7D18FC437D4"]) + .args(["--session-key", "3FE820EC21FB5D7E33D83367106D1D3747DCD48E6320C1AEC57EE7D18FC437D4"]) + .arg(artifact("messages/rsa.msg.pgp")) + .assert() + .success() + .stderr(predicate::str::contains("Decryption failed").not()); + Ok(()) + } + + #[test] + fn session_key_wrong_key() -> Result<()> { + Command::cargo_bin("sq") + .unwrap() + .arg("packet") + .arg("decrypt") + .args(["--session-key", "BB9CCB8EDE22DC222C83BD1C63AEB97335DDC7B696DB171BD16EAA5784CC0478"]) + .arg(artifact("messages/rsa.msg.pgp")) + .assert() + .failure() + .stderr(predicate::str::contains("No key to decrypt message")); + Ok(()) + } +} |