Skip to main content

wireforge_app/tls/
record.rs

1//! TLS Record layer parser (RFC 8446 ยง5.1).
2
3pub struct TlsRecord<'a> { buf: &'a [u8] }
4
5impl<'a> TlsRecord<'a> {
6    pub fn parse(buf: &'a [u8]) -> Option<Self> {
7        if buf.len() < 5 { return None; }
8        Some(Self { buf })
9    }
10
11    pub fn content_type(&self) -> u8 { self.buf[0] }
12    pub fn version(&self) -> u16 { u16::from_be_bytes([self.buf[1], self.buf[2]]) }
13    pub fn length(&self) -> u16 { u16::from_be_bytes([self.buf[3], self.buf[4]]) }
14    pub fn fragment(&self) -> &'a [u8] {
15        let end = (5 + self.length() as usize).min(self.buf.len());
16        &self.buf[5..end]
17    }
18}
19
20#[cfg(test)]
21mod tests {
22    use super::*;
23
24    #[test]
25    fn parse_valid_record() {
26        let data = &[0x16u8, 0x03, 0x03, 0x00, 0x04, 0x01, 0x02, 0x03, 0x04];
27        let rec = TlsRecord::parse(data).unwrap();
28        assert_eq!(rec.content_type(), 0x16);
29        assert_eq!(rec.version(), 0x0303);
30        assert_eq!(rec.length(), 4);
31        assert_eq!(rec.fragment(), &[0x01, 0x02, 0x03, 0x04]);
32    }
33
34    #[test]
35    fn parse_too_short() {
36        assert!(TlsRecord::parse(&[]).is_none());
37        assert!(TlsRecord::parse(&[0x16, 0x03, 0x03, 0x00]).is_none());
38    }
39}