1pub mod compressed_data;
18pub mod fingerprint;
20pub mod literal_data;
22pub mod mdc;
24pub mod misc;
26pub mod one_pass_signature;
28pub mod pkesk;
30pub mod public_key;
32pub mod secret_key;
34pub mod seipd;
36pub mod signature;
38pub mod skesk;
40pub mod subpackets;
42pub mod tags;
44pub mod user_attribute;
46pub mod user_id;
48
49use std::sync::Arc;
50
51use crate::error::{Error, Result};
52use crate::stream::ByteStream;
53use tags::PacketTag;
54
55#[derive(Debug, Clone)]
68pub struct Field {
69 pub name: Arc<str>,
71 pub value: Arc<str>,
73 pub indent: u8,
75 pub span: (usize, usize),
77}
78
79impl Field {
80 pub fn new(
82 name: impl Into<Arc<str>>,
83 value: impl Into<Arc<str>>,
84 indent: u8,
85 span: (usize, usize),
86 ) -> Self {
87 Self {
88 name: name.into(),
89 value: value.into(),
90 indent,
91 span,
92 }
93 }
94
95 pub fn packet(
99 name: impl Into<Arc<str>>,
100 value: impl Into<Arc<str>>,
101 span: (usize, usize),
102 ) -> Self {
103 Self::new(name, value, 0, span)
104 }
105
106 #[allow(clippy::self_named_constructors)]
110 pub fn field(
111 name: impl Into<Arc<str>>,
112 value: impl Into<Arc<str>>,
113 span: (usize, usize),
114 ) -> Self {
115 Self::new(name, value, 1, span)
116 }
117
118 pub fn subfield(
122 name: impl Into<Arc<str>>,
123 value: impl Into<Arc<str>>,
124 span: (usize, usize),
125 ) -> Self {
126 Self::new(name, value, 2, span)
127 }
128}
129
130#[derive(Debug, Clone)]
135pub struct Packet {
136 pub start: usize,
138 pub end: usize,
140 pub tag: PacketTag,
142 pub body: PacketBody,
144 pub fields: Vec<Field>,
146 pub children: Vec<Packet>,
150 pub child_buffer: Option<Arc<[u8]>>,
152}
153
154impl Packet {
155 pub fn new(
157 start: usize,
158 end: usize,
159 tag: PacketTag,
160 body: PacketBody,
161 fields: Vec<Field>,
162 ) -> Self {
163 Self {
164 start,
165 end,
166 tag,
167 body,
168 fields,
169 children: Vec::new(),
170 child_buffer: None,
171 }
172 }
173}
174
175#[derive(Debug, Clone)]
180pub enum PacketBody {
181 Pkesk(pkesk::PkeskPacket),
183 Signature(signature::SignaturePacket),
185 Skesk(skesk::SkeskPacket),
187 OnePassSignature(one_pass_signature::OnePassSignaturePacket),
189 SecretKey(secret_key::SecretKeyPacket),
191 PublicKey(public_key::PublicKeyPacket),
193 SecretSubkey(secret_key::SecretKeyPacket),
195 CompressedData(compressed_data::CompressedDataPacket),
197 SymmetricallyEncryptedData(misc::SymmetricallyEncryptedDataPacket),
199 Marker(misc::MarkerPacket),
201 LiteralData(literal_data::LiteralDataPacket),
203 UserId(user_id::UserIdPacket),
205 PublicSubkey(public_key::PublicKeyPacket),
207 UserAttribute(user_attribute::UserAttributePacket),
209 Seipd(seipd::SeipdPacket),
211 Mdc(mdc::MdcPacket),
213 AeadEncryptedData(misc::AeadEncryptedDataPacket),
215 Padding(misc::PaddingPacket),
217 Unknown(Vec<u8>),
219}
220
221pub fn parse_packets(bytes: Arc<[u8]>) -> Result<Vec<Packet>> {
230 parse_packets_at_depth(bytes, 0)
231}
232
233#[cfg(feature = "decompress")]
235const MAX_DEPTH: usize = 4;
236
237fn parse_packets_at_depth(bytes: Arc<[u8]>, depth: usize) -> Result<Vec<Packet>> {
238 let mut stream = ByteStream::from_arc(bytes);
239 let mut packets = Vec::new();
240
241 while !stream.is_empty() {
242 let packet = parse_packet(&mut stream, depth)?;
243 packets.push(packet);
244 }
245
246 Ok(packets)
247}
248
249fn parse_packet(stream: &mut ByteStream, depth: usize) -> Result<Packet> {
250 let packet_start = stream.abs_pos();
251 let mut fields = Vec::new();
252
253 let header_start = stream.abs_pos();
254 let header_byte = stream.octet()?;
255
256 if header_byte & 0x80 == 0 {
257 return Err(Error::InvalidPacketHeader(packet_start));
258 }
259
260 let new_format = header_byte & 0x40 != 0;
261 let (tag, body_length) = if new_format {
262 let tag = PacketTag::from_u8(header_byte & 0x3F);
263 let len = parse_new_length(stream)?;
264 (tag, len)
265 } else {
266 let tag = PacketTag::from_u8((header_byte >> 2) & 0x0F);
267 let len_type = header_byte & 0x03;
268 let len = parse_old_length(stream, len_type)?;
269 (tag, len)
270 };
271
272 let header_end = stream.abs_pos();
273 let packet_name: Arc<str> = format!("Packet: {}", tag).into();
274 fields.push(Field::packet(
275 packet_name,
276 format!("{} bytes", body_length),
277 (header_start, header_end),
278 ));
279
280 let body_start = stream.abs_pos();
281 let mut body_stream = stream.slice(stream.pos(), stream.pos() + body_length);
282 stream.skip(body_length)?;
283 let packet_end = stream.abs_pos();
284
285 let body = parse_packet_body(tag, &mut body_stream, &mut fields, body_start)?;
286
287 let mut children = Vec::new();
288 let mut child_buffer = None;
289 if let PacketBody::CompressedData(ref cd) = body {
290 expand_compressed(
291 cd,
292 depth,
293 &mut fields,
294 &mut children,
295 &mut child_buffer,
296 (body_start, packet_end),
297 );
298 }
299
300 Ok(Packet {
301 start: packet_start,
302 end: packet_end,
303 tag,
304 body,
305 fields,
306 children,
307 child_buffer,
308 })
309}
310
311#[cfg(feature = "decompress")]
316fn expand_compressed(
317 cd: &compressed_data::CompressedDataPacket,
318 depth: usize,
319 fields: &mut Vec<Field>,
320 children: &mut Vec<Packet>,
321 child_buffer: &mut Option<Arc<[u8]>>,
322 span: (usize, usize),
323) {
324 if depth >= MAX_DEPTH {
325 fields.push(Field::field(
326 "Decompressed",
327 "max nesting depth reached; not expanded",
328 span,
329 ));
330 return;
331 }
332
333 match compressed_data::decompress(cd.algorithm, &cd.compressed_data) {
334 Ok(buf) => {
335 let buf: Arc<[u8]> = buf.into();
336 match parse_packets_at_depth(Arc::clone(&buf), depth + 1) {
337 Ok(packets) => {
338 fields.push(Field::field(
339 "Decompressed",
340 format!("{} bytes, {} packets", buf.len(), packets.len()),
341 span,
342 ));
343 *children = packets;
344 *child_buffer = Some(buf);
345 }
346 Err(e) => {
347 fields.push(Field::field("Decompressed", format!("error: {}", e), span));
348 }
349 }
350 }
351 Err(msg) => {
352 fields.push(Field::field(
353 "Decompressed",
354 format!("error: {}", msg),
355 span,
356 ));
357 }
358 }
359}
360
361#[cfg(not(feature = "decompress"))]
362fn expand_compressed(
363 _cd: &compressed_data::CompressedDataPacket,
364 _depth: usize,
365 _fields: &mut Vec<Field>,
366 _children: &mut Vec<Packet>,
367 _child_buffer: &mut Option<Arc<[u8]>>,
368 _span: (usize, usize),
369) {
370}
371
372fn parse_new_length(stream: &mut ByteStream) -> Result<usize> {
373 let first = stream.octet()? as usize;
374 if first < 192 {
375 Ok(first)
376 } else if first < 224 {
377 let second = stream.octet()? as usize;
378 Ok(((first - 192) << 8) + second + 192)
379 } else if first == 255 {
380 Ok(stream.uint32()? as usize)
381 } else {
382 Ok(1 << (first & 0x1F))
383 }
384}
385
386fn parse_old_length(stream: &mut ByteStream, len_type: u8) -> Result<usize> {
387 match len_type {
388 0 => Ok(stream.octet()? as usize),
389 1 => Ok(stream.uint16()? as usize),
390 2 => Ok(stream.uint32()? as usize),
391 3 => Ok(stream.remaining()),
392 _ => unreachable!(),
393 }
394}
395
396fn parse_packet_body(
397 tag: PacketTag,
398 stream: &mut ByteStream,
399 fields: &mut Vec<Field>,
400 body_offset: usize,
401) -> Result<PacketBody> {
402 match tag {
403 PacketTag::PublicKeyEncryptedSessionKey => {
404 let pkesk = pkesk::parse_pkesk(stream, fields, body_offset)?;
405 Ok(PacketBody::Pkesk(pkesk))
406 }
407 PacketTag::Signature => {
408 let sig = signature::parse_signature(stream, fields, body_offset)?;
409 Ok(PacketBody::Signature(sig))
410 }
411 PacketTag::SymmetricKeyEncryptedSessionKey => {
412 let skesk = skesk::parse_skesk(stream, fields, body_offset)?;
413 Ok(PacketBody::Skesk(skesk))
414 }
415 PacketTag::OnePassSignature => {
416 let ops = one_pass_signature::parse_one_pass_signature(stream, fields, body_offset)?;
417 Ok(PacketBody::OnePassSignature(ops))
418 }
419 PacketTag::SecretKey => {
420 let sk = secret_key::parse_secret_key(stream, fields, body_offset)?;
421 Ok(PacketBody::SecretKey(sk))
422 }
423 PacketTag::PublicKey => {
424 let pk = public_key::parse_public_key(stream, fields, body_offset)?;
425 Ok(PacketBody::PublicKey(pk))
426 }
427 PacketTag::SecretSubkey => {
428 let sk = secret_key::parse_secret_key(stream, fields, body_offset)?;
429 Ok(PacketBody::SecretSubkey(sk))
430 }
431 PacketTag::CompressedData => {
432 let cd = compressed_data::parse_compressed_data(stream, fields, body_offset)?;
433 Ok(PacketBody::CompressedData(cd))
434 }
435 PacketTag::SymmetricallyEncryptedData => {
436 let sed = misc::parse_symmetrically_encrypted_data(stream, fields, body_offset)?;
437 Ok(PacketBody::SymmetricallyEncryptedData(sed))
438 }
439 PacketTag::Marker => {
440 let marker = misc::parse_marker(stream, fields, body_offset)?;
441 Ok(PacketBody::Marker(marker))
442 }
443 PacketTag::LiteralData => {
444 let ld = literal_data::parse_literal_data(stream, fields, body_offset)?;
445 Ok(PacketBody::LiteralData(ld))
446 }
447 PacketTag::UserId => {
448 let uid = user_id::parse_user_id(stream, fields, body_offset)?;
449 Ok(PacketBody::UserId(uid))
450 }
451 PacketTag::PublicSubkey => {
452 let pk = public_key::parse_public_key(stream, fields, body_offset)?;
453 Ok(PacketBody::PublicSubkey(pk))
454 }
455 PacketTag::UserAttribute => {
456 let ua = user_attribute::parse_user_attribute(stream, fields, body_offset)?;
457 Ok(PacketBody::UserAttribute(ua))
458 }
459 PacketTag::SymmetricallyEncryptedIntegrityProtectedData => {
460 let seipd = seipd::parse_seipd(stream, fields, body_offset)?;
461 Ok(PacketBody::Seipd(seipd))
462 }
463 PacketTag::ModificationDetectionCode => {
464 let mdc = mdc::parse_mdc(stream, fields, body_offset)?;
465 Ok(PacketBody::Mdc(mdc))
466 }
467 PacketTag::AeadEncryptedData => {
468 let aead = misc::parse_aead_encrypted_data(stream, fields, body_offset)?;
469 Ok(PacketBody::AeadEncryptedData(aead))
470 }
471 PacketTag::Padding => {
472 let padding = misc::parse_padding(stream, fields, body_offset)?;
473 Ok(PacketBody::Padding(padding))
474 }
475 _ => {
479 let data = stream.rest();
480 if !data.is_empty() {
481 let data_start = body_offset + stream.pos() - data.len();
482 let data_end = body_offset + stream.pos();
483 fields.push(Field::field(
484 "Data",
485 format!("{} bytes", data.len()),
486 (data_start, data_end),
487 ));
488 }
489 Ok(PacketBody::Unknown(data))
490 }
491 }
492}