cmail_rpgp/packet/
padding.rs1use std::io;
2
3use rand::{CryptoRng, RngCore};
4
5use crate::errors::Result;
6use crate::packet::PacketTrait;
7use crate::ser::Serialize;
8use crate::types::{Tag, Version};
9
10#[derive(derive_more::Debug, Clone, PartialEq, Eq)]
14pub struct Padding {
15 packet_version: Version,
16 #[debug("{}", hex::encode(data))]
18 data: Vec<u8>,
19}
20
21impl Padding {
22 pub fn from_slice(packet_version: Version, input: &[u8]) -> Result<Self> {
24 Ok(Padding {
25 packet_version,
26 data: input.to_vec(),
27 })
28 }
29
30 pub fn new<R: CryptoRng + RngCore>(mut rng: R, packet_version: Version, size: usize) -> Self {
32 let mut data = vec![0u8; size];
33 rng.fill_bytes(&mut data);
34 Padding {
35 packet_version,
36 data,
37 }
38 }
39
40 pub fn packet_version(&self) -> Version {
41 self.packet_version
42 }
43}
44
45impl Serialize for Padding {
46 fn to_writer<W: io::Write>(&self, writer: &mut W) -> Result<()> {
47 writer.write_all(&self.data)?;
48
49 Ok(())
50 }
51}
52
53impl PacketTrait for Padding {
54 fn packet_version(&self) -> Version {
55 self.packet_version
56 }
57
58 fn tag(&self) -> Tag {
59 Tag::Padding
60 }
61}
62
63#[cfg(test)]
64mod tests {
65 use rand::SeedableRng;
66 use rand_chacha::ChaCha20Rng;
67
68 use super::super::single;
69 use super::*;
70 use crate::packet::Packet;
71 use crate::types::PacketLength;
72
73 #[test]
74 fn test_padding_roundtrip() {
75 let packet_raw = hex::decode("d50ec5a293072991628147d72c8f86b7").expect("valid hex");
76 let (rest, (version, tag, plen)) = single::parser(&packet_raw).expect("parse");
77
78 let PacketLength::Fixed(len) = plen else {
79 panic!("invalid parse result");
80 };
81 assert_eq!(rest.len(), len);
82
83 let full_packet = single::body_parser(version, tag, &rest[..len]).expect("body parse");
84
85 let Packet::Padding(ref packet) = full_packet else {
86 panic!("invalid packet: {:?}", full_packet);
87 };
88 assert_eq!(
89 packet.data,
90 hex::decode("c5a293072991628147d72c8f86b7").expect("valid hex")
91 );
92
93 let encoded = full_packet.to_bytes().expect("encode");
95 assert_eq!(encoded, packet_raw);
96 }
97
98 #[test]
99 fn test_padding_new() {
100 let mut rng = ChaCha20Rng::seed_from_u64(1);
101 let packet = Padding::new(&mut rng, Version::New, 20);
102 assert_eq!(packet.data.len(), 20);
103
104 let encoded = packet.to_bytes().expect("encode");
105 assert_eq!(encoded, packet.data);
106 }
107}