diff options
author | Justus Winter <justus@sequoia-pgp.org> | 2019-10-04 15:31:28 +0200 |
---|---|---|
committer | Justus Winter <justus@sequoia-pgp.org> | 2019-12-06 15:11:54 +0100 |
commit | 30b37711392468161817653211754601f4f52057 (patch) | |
tree | 4060e00c6a3a9d18ec759e95d954a77f389f7a57 /tool/src/commands/decrypt.rs | |
parent | 149f252e5d1f6e30869f7981622322ab345cd2fc (diff) |
tool: Add packet decrypt that unwraps encryption containers.
Diffstat (limited to 'tool/src/commands/decrypt.rs')
-rw-r--r-- | tool/src/commands/decrypt.rs | 54 |
1 files changed, 53 insertions, 1 deletions
diff --git a/tool/src/commands/decrypt.rs b/tool/src/commands/decrypt.rs index f04b6ac1..2e2753f6 100644 --- a/tool/src/commands/decrypt.rs +++ b/tool/src/commands/decrypt.rs @@ -10,8 +10,13 @@ use crate::openpgp::types::SymmetricAlgorithm; use crate::openpgp::fmt::hex; use crate::openpgp::crypto::{self, SessionKey}; use crate::openpgp::{Fingerprint, Cert, KeyID, Result}; +use crate::openpgp::packet; use crate::openpgp::packet::prelude::*; -use crate::openpgp::parse::PacketParser; +use crate::openpgp::parse::{ + Parse, + PacketParser, + PacketParserResult, +}; use crate::openpgp::parse::stream::{ VerificationHelper, DecryptionHelper, Decryptor, MessageStructure, }; @@ -319,3 +324,50 @@ pub fn decrypt(ctx: &Context, mapping: &mut store::Mapping, helper.vhelper.print_status(); return Ok(()); } + +pub fn decrypt_unwrap(ctx: &Context, mapping: &mut store::Mapping, + input: &mut dyn io::Read, output: &mut dyn io::Write, + secrets: Vec<Cert>, dump_session_key: bool) + -> Result<()> { + let mut helper = Helper::new(ctx, mapping, 0, Vec::new(), secrets, + dump_session_key, false, false); + + let mut ppr = PacketParser::from_reader(input)?; + + let mut pkesks: Vec<packet::PKESK> = Vec::new(); + let mut skesks: Vec<packet::SKESK> = Vec::new(); + while let PacketParserResult::Some(mut pp) = ppr { + match pp.packet { + Packet::SEIP(_) | Packet::AED(_) => { + { + let decrypt = + |algo, secret: &SessionKey| pp.decrypt(algo, secret); + helper.decrypt(&pkesks[..], &skesks[..], decrypt)?; + } + if ! pp.decrypted() { + // XXX: That is not quite the right error to return. + return Err( + openpgp::Error::InvalidSessionKey( + "No session key".into()).into()); + } + + io::copy(&mut pp, output)?; + return Ok(()); + }, + Packet::MDC(ref mdc) => if ! mdc.valid() { + return Err(openpgp::Error::ManipulatedMessage.into()); + }, + _ => (), + } + + let (p, ppr_tmp) = pp.recurse()?; + match p { + Packet::PKESK(pkesk) => pkesks.push(pkesk), + Packet::SKESK(skesk) => skesks.push(skesk), + _ => (), + } + ppr = ppr_tmp; + } + + Ok(()) +} |