pcap_parser/pcapng/
decryption_secrets.rs

1use nom::bytes::streaming::take;
2use nom::error::{ErrorKind, ParseError};
3use nom::{Err, IResult};
4use rusticata_macros::{align32, newtype_enum};
5
6use crate::endianness::{PcapBE, PcapEndianness, PcapLE};
7use crate::{opt_parse_options, PcapError, PcapNGOption, DSB_MAGIC};
8
9use super::*;
10
11#[derive(Clone, Copy, Eq, PartialEq)]
12pub struct SecretsType(pub u32);
13
14newtype_enum! {
15    impl debug SecretsType {
16        TlsKeyLog = 0x544c_534b, // TLSK
17        WireguardKeyLog = 0x5747_4b4c,
18    }
19}
20
21#[derive(Debug)]
22pub struct DecryptionSecretsBlock<'a> {
23    pub block_type: u32,
24    pub block_len1: u32,
25    pub secrets_type: SecretsType,
26    pub secrets_len: u32,
27    pub data: &'a [u8],
28    pub options: Vec<PcapNGOption<'a>>,
29    pub block_len2: u32,
30}
31
32impl<'a, En: PcapEndianness> PcapNGBlockParser<'a, En, DecryptionSecretsBlock<'a>>
33    for DecryptionSecretsBlock<'a>
34{
35    const HDR_SZ: usize = 20;
36    const MAGIC: u32 = DSB_MAGIC;
37
38    fn inner_parse<E: ParseError<&'a [u8]>>(
39        block_type: u32,
40        block_len1: u32,
41        i: &'a [u8],
42        block_len2: u32,
43    ) -> IResult<&'a [u8], DecryptionSecretsBlock<'a>, E> {
44        // caller function already tested header type(magic) and length
45        // read end of header
46        let (i, secrets_type) = En::parse_u32(i)?;
47        let (i, secrets_len) = En::parse_u32(i)?;
48        // read packet data
49        // align32 can overflow
50        if secrets_len >= u32::MAX - 4 {
51            return Err(Err::Error(E::from_error_kind(i, ErrorKind::Verify)));
52        }
53        let padded_length = align32!(secrets_len);
54        let (i, data) = take(padded_length)(i)?;
55        // read options
56        let current_offset = (20 + padded_length) as usize;
57        let (i, options) = opt_parse_options::<En, E>(i, block_len1 as usize, current_offset)?;
58        if block_len2 != block_len1 {
59            return Err(Err::Error(E::from_error_kind(i, ErrorKind::Verify)));
60        }
61        let block = DecryptionSecretsBlock {
62            block_type,
63            block_len1,
64            secrets_type: SecretsType(secrets_type),
65            secrets_len,
66            data,
67            options,
68            block_len2,
69        };
70        Ok((i, block))
71    }
72}
73
74/// Parse a DecryptionSecrets Block (little-endian)
75#[inline]
76pub fn parse_decryptionsecretsblock_le(
77    i: &[u8],
78) -> IResult<&[u8], DecryptionSecretsBlock<'_>, PcapError<&[u8]>> {
79    ng_block_parser::<DecryptionSecretsBlock, PcapLE, _, _>()(i)
80}
81
82/// Parse a DecryptionSecrets Block (big-endian)
83#[inline]
84pub fn parse_decryptionsecretsblock_be(
85    i: &[u8],
86) -> IResult<&[u8], DecryptionSecretsBlock<'_>, PcapError<&[u8]>> {
87    ng_block_parser::<DecryptionSecretsBlock, PcapBE, _, _>()(i)
88}