1 //! Packet container support.
2 //!
3 //! Some packets contain other packets.  This creates a tree
4 //! structure.
5 
6 use std::fmt;
7 use std::hash::{Hash, Hasher};
8 use std::slice;
9 use std::vec;
10 
11 use crate::{
12     Packet,
13     crypto::hash,
14     packet::Iter,
15     types::HashAlgorithm,
16 };
17 
18 /// A packet's body holds either unprocessed bytes, processed bytes,
19 /// or packets.
20 ///
21 /// We conceptually divide packets into two parts: the header and the
22 /// body.  Whereas the header is read eagerly when the packet is
23 /// deserialized, the body is only read on demand.
24 ///
25 /// A packet's body is stored here either when configured via
26 /// [`PacketParserBuilder::buffer_unread_content`], when one of the
27 /// [`PacketPile`] deserialization routines is used, or on demand for
28 /// a particular packet using the
29 /// [`PacketParser::buffer_unread_content`] method.
30 ///
31 ///   [`PacketParserBuilder::buffer_unread_content`]: ../parse/struct.PacketParserBuilder.html#method.buffer_unread_content
32 ///   [`PacketPile`]: ../struct.PacketPile.html
33 ///   [`PacketParser::buffer_unread_content`]: ../parse/struct.PacketParser.html#method.buffer_unread_content
34 ///
35 /// There are three different types of packets:
36 ///
37 ///   - Packets like the [`UserID`] and [`Signature`] packets, don't
38 ///     actually have a body.
39 ///
40 ///   [`UserID`]: ../packet/struct.UserID.html
41 ///   [`Signature`]: ../packet/signature/struct.Signature.html
42 ///
43 ///   - One packet, the literal data packet, includes unstructured
44 ///     data.  That data is stored in [`Literal`].
45 ///
46 ///   [`Literal`]: ../packet/struct.Literal.html
47 ///
48 ///   - Some packets are containers.  If the parser does not parse the
49 ///     packet's child, either because the caller used
50 ///     [`PacketParser::next`] to get the next packet, or the maximum
51 ///     recursion depth was reached, then the packets can be stored here
52 ///     as a byte stream.  (If the caller so chooses, the content can be
53 ///     parsed later using the regular deserialization routines, since
54 ///     the content is just an OpenPGP message.)
55 ///
56 ///   [`PacketParser::next`]: ../parse/struct.PacketParser.html#method.next
57 #[derive(Clone, Debug)]
58 pub enum Body {
59     /// Unprocessed packet body.
60     ///
61     /// The body has not been processed, i.e. it is still encrypted.
62     ///
63     /// Note: if some of a packet's data is streamed, and the
64     /// `PacketParser` is configured to buffer unread content, then
65     /// this is not the packet's entire content; it is just the unread
66     /// content.
67     Unprocessed(Vec<u8>),
68 
69     /// Processed packed body.
70     ///
71     /// The body has been processed, i.e. decompressed or decrypted,
72     /// but not parsed into packets.
73     ///
74     /// Note: if some of a packet's data is streamed, and the
75     /// `PacketParser` is configured to buffer unread content, then
76     /// this is not the packet's entire content; it is just the unread
77     /// content.
78     Processed(Vec<u8>),
79 
80     /// Parsed packet body.
81     ///
82     /// Used by container packets (such as the encryption and
83     /// compression packets) to reference their immediate children.
84     /// This results in a tree structure.
85     ///
86     /// This is automatically populated when using the [`PacketPile`]
87     /// deserialization routines, e.g., [`PacketPile::from_file`].  By
88     /// default, it is *not* automatically filled in by the
89     /// [`PacketParser`] deserialization routines; this needs to be
90     /// done manually.
91     ///
92     ///   [`PacketPile`]: ../struct.PacketPile.html
93     ///   [`PacketPile::from_file`]: ../struct.PacketPile.html#method.from_file
94     ///   [`PacketParser`]: ../parse/struct.PacketParser.html
95     Structured(Vec<Packet>),
96 }
97 
98 /// Holds packet bodies.
99 ///
100 /// This is used by OpenPGP container packets, like the compressed
101 /// data packet, to store the containing packets.
102 #[derive(Clone)]
103 pub struct Container {
104     /// Holds a packet's body.
105     body: Body,
106 
107     /// We compute a digest over the body to implement comparison.
108     body_digest: Vec<u8>,
109 }
110 
111 impl std::ops::Deref for Container {
112     type Target = Body;
deref(&self) -> &Self::Target113     fn deref(&self) -> &Self::Target {
114         &self.body
115     }
116 }
117 
118 // Pick the fastest hash function from the SHA2 family for the
119 // architectures word size.  On 64-bit architectures, SHA512 is almost
120 // twice as fast, but on 32-bit ones, SHA256 is faster.
121 #[cfg(target_pointer_width = "64")]
122 const CONTAINER_BODY_HASH: HashAlgorithm = HashAlgorithm::SHA512;
123 #[cfg(not(target_pointer_width = "64"))]
124 const CONTAINER_BODY_HASH: HashAlgorithm = HashAlgorithm::SHA256;
125 
126 impl PartialEq for Container {
eq(&self, other: &Container) -> bool127     fn eq(&self, other: &Container) -> bool {
128         use Body::*;
129         match (&self.body, &other.body) {
130             (Unprocessed(_), Unprocessed(_)) =>
131                 self.body_digest == other.body_digest,
132             (Processed(_), Processed(_)) =>
133                 self.body_digest == other.body_digest,
134             (Structured(a), Structured(b)) =>
135                 a == b,
136             _ => false,
137         }
138     }
139 }
140 
141 impl Eq for Container {}
142 
143 impl Hash for Container {
hash<H: Hasher>(&self, state: &mut H)144     fn hash<H: Hasher>(&self, state: &mut H) {
145         if let Body::Structured(packets) = &self.body {
146             packets.hash(state);
147         } else {
148             self.body_digest.hash(state);
149         }
150     }
151 }
152 
153 impl Default for Container {
default() -> Self154     fn default() -> Self {
155         Self {
156             body: Body::Structured(Vec::with_capacity(0)),
157             body_digest: Vec::with_capacity(0),
158         }
159     }
160 }
161 
162 impl From<Vec<Packet>> for Container {
from(packets: Vec<Packet>) -> Self163     fn from(packets: Vec<Packet>) -> Self {
164         Self {
165             body: Body::Structured(packets),
166             body_digest: Vec::with_capacity(0),
167         }
168     }
169 }
170 
171 impl fmt::Debug for Container {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result172     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
173         fn fmt_bytes(f: &mut fmt::Formatter, tag: &str, bytes: &[u8],
174                      digest: String)
175                      -> fmt::Result
176         {
177             let threshold = 16;
178             let prefix = &bytes[..std::cmp::min(threshold, bytes.len())];
179             let mut prefix_fmt = crate::fmt::hex::encode(prefix);
180             if bytes.len() > threshold {
181                 prefix_fmt.push_str("...");
182             }
183             prefix_fmt.push_str(&format!(" ({} bytes)", bytes.len())[..]);
184 
185             f.debug_struct("Container")
186                 .field(tag, &prefix_fmt)
187                 .field("digest", &digest)
188                 .finish()
189         }
190 
191         use Body::*;
192         match &self.body {
193             Unprocessed(bytes) =>
194                 fmt_bytes(f, "unprocessed", bytes, self.body_digest()),
195             Processed(bytes) =>
196                 fmt_bytes(f, "processed", bytes, self.body_digest()),
197             Structured(packets) =>
198                 f.debug_struct("Container").field("packets", packets).finish(),
199         }
200     }
201 }
202 
203 impl Container {
default_unprocessed() -> Self204     pub(crate) fn default_unprocessed() -> Self {
205         Self {
206             body: Body::Unprocessed(Vec::with_capacity(0)),
207             body_digest: Self::empty_body_digest(),
208         }
209     }
210 
211     /// Returns a reference to this Packet's children.
212     ///
213     /// Returns `None` if the body is not structured.
children_ref(&self) -> Option<&[Packet]>214     pub fn children_ref(&self) -> Option<&[Packet]> {
215         if let Body::Structured(packets) = &self.body {
216             Some(&packets[..])
217         } else {
218             None
219         }
220     }
221 
222     /// Returns a mutable reference to this Packet's children.
223     ///
224     /// Returns `None` if the body is not structured.
children_mut(&mut self) -> Option<&mut Vec<Packet>>225     pub fn children_mut(&mut self) -> Option<&mut Vec<Packet>> {
226         if let Body::Structured(packets) = &mut self.body {
227             Some(packets)
228         } else {
229            None
230         }
231     }
232 
233     /// Returns an iterator over the packet's descendants.  The
234     /// descendants are visited in depth-first order.
235     ///
236     /// Returns `None` if the body is not structured.
descendants(&self) -> Option<Iter>237     pub fn descendants(&self) -> Option<Iter> {
238         Some(Iter {
239             // Iterate over each packet in the message.
240             children: self.children()?,
241             child: None,
242             grandchildren: None,
243             depth: 0,
244         })
245     }
246 
247     /// Returns an iterator over the packet's immediate children.
248     ///
249     /// Returns `None` if the body is not structured.
children<'a>(&'a self) -> Option<slice::Iter<'a, Packet>>250     pub fn children<'a>(&'a self) -> Option<slice::Iter<'a, Packet>> {
251         Some(self.children_ref()?.iter())
252     }
253 
254     /// Returns an `IntoIter` over the packet's immediate children.
255     ///
256     /// Returns `None` if the body is not structured.
into_children(self) -> Option<vec::IntoIter<Packet>>257     pub fn into_children(self) -> Option<vec::IntoIter<Packet>> {
258         if let Body::Structured(packets) = self.body {
259             Some(packets.into_iter())
260         } else {
261             None
262         }
263     }
264 
265     /// Gets the packet's body.
body(&self) -> &Body266     pub fn body(&self) -> &Body {
267         &self.body
268     }
269 
270     /// Sets the packet's body.
set_body(&mut self, body: Body) -> Body271     pub fn set_body(&mut self, body: Body) -> Body {
272         use Body::*;
273         let mut h = Self::make_body_hash();
274         match &body {
275             Unprocessed(bytes) => h.update(bytes),
276             Processed(bytes) => h.update(bytes),
277             Structured(_) => (),
278         }
279         self.set_body_hash(h);
280         std::mem::replace(&mut self.body, body)
281     }
282 
283     /// Returns the hash for the empty body.
empty_body_digest() -> Vec<u8>284     fn empty_body_digest() -> Vec<u8> {
285         lazy_static!{
286             static ref DIGEST: Vec<u8> = {
287                 let mut h = Container::make_body_hash();
288                 let mut d = vec![0; h.digest_size()];
289                 h.digest(&mut d);
290                 d
291             };
292         }
293 
294         DIGEST.clone()
295     }
296 
297     /// Creates a hash context for hashing the body.
298     pub(crate) // For parse.rs
make_body_hash() -> hash::Context299     fn make_body_hash() -> hash::Context {
300         CONTAINER_BODY_HASH.context()
301             .expect("CONTAINER_BODY_HASH must be implemented")
302     }
303 
304     /// Hashes content that has been streamed.
305     pub(crate) // For parse.rs
set_body_hash(&mut self, mut h: hash::Context)306     fn set_body_hash(&mut self, mut h: hash::Context) {
307         self.body_digest.resize(h.digest_size(), 0);
308         h.digest(&mut self.body_digest);
309     }
310 
311     pub(crate)
body_digest(&self) -> String312     fn body_digest(&self) -> String {
313         crate::fmt::hex::encode(&self.body_digest)
314     }
315 
316     // Converts an indentation level to whitespace.
indent(depth: usize) -> &'static str317     fn indent(depth: usize) -> &'static str {
318         use std::cmp;
319 
320         let s = "                                                  ";
321         return &s[0..cmp::min(depth, s.len())];
322     }
323 
324     // Pretty prints the container to stderr.
325     //
326     // This function is primarily intended for debugging purposes.
327     //
328     // `indent` is the number of spaces to indent the output.
pretty_print(&self, indent: usize)329     pub(crate) fn pretty_print(&self, indent: usize) {
330         for (i, p) in self.children_ref().iter().enumerate() {
331             eprintln!("{}{}: {:?}",
332                       Self::indent(indent), i + 1, p);
333             if let Some(ref children) = self.children_ref()
334                 .and_then(|c| c.get(i)).and_then(|p| p.container_ref())
335             {
336                 children.pretty_print(indent + 1);
337             }
338         }
339     }
340 }
341 
342 macro_rules! impl_body_forwards {
343     ($typ:ident) => {
344         /// This packet implements the unprocessed container
345         /// interface.
346         ///
347         /// Container packets like this one can contain unprocessed
348         /// data.
349         impl $typ {
350         /// Returns a reference to the container.
351             pub(crate) fn container_ref(&self) -> &packet::Container {
352                 &self.container
353             }
354 
355             /// Returns a mutable reference to the container.
356             pub(crate) fn container_mut(&mut self) -> &mut packet::Container {
357                 &mut self.container
358             }
359 
360             /// Gets a reference to the this packet's body.
361             pub fn body(&self) -> &[u8] {
362                 use crate::packet::Body::*;
363                 match self.container.body() {
364                     Unprocessed(bytes) => bytes,
365                     Processed(_) => unreachable!(
366                         "Unprocessed container has processed body"),
367                     Structured(_) => unreachable!(
368                         "Unprocessed container has structured body"),
369                 }
370             }
371 
372             /// Sets the this packet's body.
373             pub fn set_body(&mut self, data: Vec<u8>) -> Vec<u8> {
374                 use crate::packet::{Body, Body::*};
375                 match self.container.set_body(Body::Unprocessed(data)) {
376                     Unprocessed(bytes) => bytes,
377                     Processed(_) => unreachable!(
378                         "Unprocessed container has processed body"),
379                     Structured(_) => unreachable!(
380                         "Unprocessed container has structured body"),
381                 }
382             }
383         }
384     };
385 }
386 
387 impl Packet {
388     pub(crate) // for packet_pile.rs
container_ref(&self) -> Option<&Container>389     fn container_ref(&self) -> Option<&Container> {
390         use std::ops::Deref;
391         match self {
392             Packet::CompressedData(p) => Some(p.deref()),
393             Packet::SEIP(p) => Some(p.deref()),
394             Packet::AED(p) => Some(p.deref()),
395             Packet::Literal(p) => Some(p.container_ref()),
396             Packet::Unknown(p) => Some(p.container_ref()),
397             _ => None,
398         }
399     }
400 
401     pub(crate) // for packet_pile.rs, packet_pile_parser.rs, parse.rs
container_mut(&mut self) -> Option<&mut Container>402     fn container_mut(&mut self) -> Option<&mut Container> {
403         use std::ops::DerefMut;
404         match self {
405             Packet::CompressedData(p) => Some(p.deref_mut()),
406             Packet::SEIP(p) => Some(p.deref_mut()),
407             Packet::AED(p) => Some(p.deref_mut()),
408             Packet::Literal(p) => Some(p.container_mut()),
409             Packet::Unknown(p) => Some(p.container_mut()),
410             _ => None,
411         }
412     }
413 
414     /// Returns an iterator over the packet's immediate children.
children<'a>(&'a self) -> Option<impl Iterator<Item = &'a Packet>>415     pub(crate) fn children<'a>(&'a self)
416                                -> Option<impl Iterator<Item = &'a Packet>> {
417         self.container_ref().and_then(|c| c.children())
418     }
419 
420     /// Returns an iterator over all of the packet's descendants, in
421     /// depth-first order.
descendants(&self) -> Option<Iter>422     pub(crate) fn descendants(&self) -> Option<Iter> {
423         self.container_ref().and_then(|c| c.descendants())
424     }
425 
426     /// Retrieves the packet's unprocessed body.
427     #[cfg(test)]
unprocessed_body(&self) -> Option<&[u8]>428     pub(crate) fn unprocessed_body(&self) -> Option<&[u8]> {
429         self.container_ref().and_then(|c| match c.body() {
430             Body::Unprocessed(bytes) => Some(&bytes[..]),
431             _ => None,
432         })
433     }
434 
435     /// Retrieves the packet's processed body.
436     #[cfg(test)]
processed_body(&self) -> Option<&[u8]>437     pub(crate) fn processed_body(&self) -> Option<&[u8]> {
438         self.container_ref().and_then(|c| match c.body() {
439             Body::Processed(bytes) => Some(&bytes[..]),
440             _ => None,
441         })
442     }
443 }
444