summaryrefslogtreecommitdiffstats
path: root/tool/src/commands/decrypt.rs
diff options
context:
space:
mode:
Diffstat (limited to 'tool/src/commands/decrypt.rs')
-rw-r--r--tool/src/commands/decrypt.rs54
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(())
+}