sequoia_openpgp/packet/
padding.rs

1use std::fmt;
2
3#[cfg(test)]
4use quickcheck::{Arbitrary, Gen};
5
6use crate::{
7    Packet,
8    Result,
9    packet,
10};
11
12/// Holds a Padding packet.
13///
14/// Padding packets are used to obscure the size of cryptographic
15/// artifacts.
16///
17/// See [Padding Packet] for details.
18///
19///   [Padding Packet]: https://www.rfc-editor.org/rfc/rfc9580.html#padding-packet
20// IMPORTANT: If you add fields to this struct, you need to explicitly
21// IMPORTANT: implement PartialEq, Eq, and Hash.
22#[derive(Clone, PartialEq, Eq, Hash)]
23pub struct Padding {
24    pub(crate) common: packet::Common,
25    value: Vec<u8>,
26}
27
28assert_send_and_sync!(Padding);
29
30impl From<Vec<u8>> for Padding {
31    fn from(u: Vec<u8>) -> Self {
32        Padding {
33            common: Default::default(),
34            value: u,
35        }
36    }
37}
38
39impl fmt::Display for Padding {
40    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
41        let padding = String::from_utf8_lossy(&self.value[..]);
42        write!(f, "{}", padding)
43    }
44}
45
46impl fmt::Debug for Padding {
47    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
48        write!(f, "Padding {{ {} bytes }}", self.value.len())
49    }
50}
51
52impl Padding {
53    /// Creates a new Padding packet of the given size.
54    ///
55    /// Note that this is the net size, packet framing (CTB and packet
56    /// length) will come on top.
57    pub fn new(size: usize) -> Result<Padding> {
58        let mut v = vec![0; size];
59        crate::crypto::random(&mut v)?;
60        Ok(v.into())
61    }
62
63    /// Gets the padding packet's value.
64    pub(crate) fn value(&self) -> &[u8] {
65        self.value.as_slice()
66    }
67}
68
69impl From<Padding> for Packet {
70    fn from(s: Padding) -> Self {
71        Packet::Padding(s)
72    }
73}
74
75#[cfg(test)]
76impl Arbitrary for Padding {
77    fn arbitrary(g: &mut Gen) -> Self {
78        Vec::<u8>::arbitrary(g).into()
79    }
80}
81
82#[cfg(test)]
83mod tests {
84    use super::*;
85    use crate::parse::Parse;
86    use crate::serialize::MarshalInto;
87
88    quickcheck! {
89        fn roundtrip(p: Padding) -> bool {
90            let q = Padding::from_bytes(&p.to_vec().unwrap()).unwrap();
91            assert_eq!(p, q);
92            true
93        }
94    }
95}