1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
/// This program demonstrates how to decrypt a stream of data.
use std::env;
use std::io;
use std::collections::HashMap;
extern crate openpgp;
use openpgp::{
Packet,
KeyID,
Key,
TPK,
SecretKey,
};
use openpgp::parse::PacketParserResult;
pub fn main() {
let args: Vec<String> = env::args().collect();
if args.len() < 2 {
panic!("A simple decryption filter.\n\n\
Usage: {} <keyfile> [<keyfile>...] <input >output\n", args[0]);
}
// Read the transferable secret keys from the given files.
let mut keys: HashMap<KeyID, Key> = HashMap::new();
for f in args[1..].iter() {
let tsk = TPK::from_reader(
// Use an openpgp::Reader so that we accept both armored
// and plain PGP data.
openpgp::Reader::from_file(f)
.expect("Failed to open file"))
.expect("Failed to read key");
for key in tsk.keys() {
// XXX this is cheating, we just add all keys, even if
// they should not be used for encryption
keys.insert(key.fingerprint().to_keyid(), key.clone());
}
}
#[derive(PartialEq)]
enum State {
Start(Vec<openpgp::PKESK>, Vec<openpgp::SKESK>),
Deciphered,
Done,
}
let mut state = State::Start(vec![], vec![]);
let mut input = io::stdin();
let mut ppr
= openpgp::parse::PacketParser::from_reader(
openpgp::Reader::from_reader(&mut input)
.expect("Failed to build reader"))
.expect("Failed to build parser");
while let PacketParserResult::Some(mut pp) = ppr {
state = match state {
// Look for an PKESK or SKESK packet.
State::Start(mut pkesks, mut skesks) =>
match pp.packet {
Packet::SEIP(_) => {
let mut state = None;
for pkesk in pkesks.iter() {
if let Some(tsk) = keys.get(&pkesk.recipient()) {
if let Some(SecretKey::Unencrypted{ref mpis}) =
tsk.secret()
{
if let Ok((algo, key)) = pkesk.decrypt(tsk, mpis) {
let r = pp.decrypt(algo, &key[..]);
if r.is_ok() {
state = Some(State::Deciphered);
break;
}
}
}
}
}
state.unwrap_or(State::Start(pkesks, skesks))
},
_ => State::Start(pkesks, skesks),
},
// Look for the literal data packet.
State::Deciphered =>
if let Packet::Literal(_) = pp.packet {
io::copy(&mut pp, &mut io::stdout())
.expect("Failed to copy data");
State::Done
} else {
State::Deciphered
},
// We continue to parse, useful for dumping
// encrypted packets.
State::Done => State::Done,
};
let ((packet, _), (ppr_tmp, _)) = pp.recurse()
.expect("Failed to recurse");
ppr = ppr_tmp;
state = match state {
// Look for an PKESK or SKESK packet.
State::Start(mut pkesks, mut skesks) =>
match packet {
Packet::PKESK(pkesk) => {
pkesks.push(pkesk);
State::Start(pkesks, skesks)
},
Packet::SKESK(skesk) => {
skesks.push(skesk);
State::Start(pkesks, skesks)
},
_ => State::Start(pkesks, skesks),
},
// Do nothing in all other states.
s => s,
};
}
if state != State::Done {
panic!("decryption failed");
}
}
|