1 use crate::content::*;
2 
3 use crate::error::*;
4 
5 use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
6 use std::io::{Read, Write};
7 
8 pub const RECORD_LAYER_HEADER_SIZE: usize = 13;
9 pub const MAX_SEQUENCE_NUMBER: u64 = 0x0000FFFFFFFFFFFF;
10 
11 pub const DTLS1_2MAJOR: u8 = 0xfe;
12 pub const DTLS1_2MINOR: u8 = 0xfd;
13 
14 pub const DTLS1_0MAJOR: u8 = 0xfe;
15 pub const DTLS1_0MINOR: u8 = 0xff;
16 
17 // VERSION_DTLS12 is the DTLS version in the same style as
18 // VersionTLSXX from crypto/tls
19 pub const VERSION_DTLS12: u16 = 0xfefd;
20 
21 pub const PROTOCOL_VERSION1_0: ProtocolVersion = ProtocolVersion {
22     major: DTLS1_0MAJOR,
23     minor: DTLS1_0MINOR,
24 };
25 pub const PROTOCOL_VERSION1_2: ProtocolVersion = ProtocolVersion {
26     major: DTLS1_2MAJOR,
27     minor: DTLS1_2MINOR,
28 };
29 
30 // https://tools.ietf.org/html/rfc4346#section-6.2.1
31 #[derive(Copy, Clone, PartialEq, Eq, Debug, Default)]
32 pub struct ProtocolVersion {
33     pub major: u8,
34     pub minor: u8,
35 }
36 
37 #[derive(Copy, Clone, PartialEq, Eq, Debug, Default)]
38 pub struct RecordLayerHeader {
39     pub content_type: ContentType,
40     pub protocol_version: ProtocolVersion,
41     pub epoch: u16,
42     pub sequence_number: u64, // uint48 in spec
43     pub content_len: u16,
44 }
45 
46 impl RecordLayerHeader {
marshal<W: Write>(&self, writer: &mut W) -> Result<()>47     pub fn marshal<W: Write>(&self, writer: &mut W) -> Result<()> {
48         if self.sequence_number > MAX_SEQUENCE_NUMBER {
49             return Err(Error::ErrSequenceNumberOverflow);
50         }
51 
52         writer.write_u8(self.content_type as u8)?;
53         writer.write_u8(self.protocol_version.major)?;
54         writer.write_u8(self.protocol_version.minor)?;
55         writer.write_u16::<BigEndian>(self.epoch)?;
56 
57         let be: [u8; 8] = self.sequence_number.to_be_bytes();
58         writer.write_all(&be[2..])?; // uint48 in spec
59 
60         writer.write_u16::<BigEndian>(self.content_len)?;
61 
62         Ok(writer.flush()?)
63     }
64 
unmarshal<R: Read>(reader: &mut R) -> Result<Self>65     pub fn unmarshal<R: Read>(reader: &mut R) -> Result<Self> {
66         let content_type = reader.read_u8()?.into();
67         let major = reader.read_u8()?;
68         let minor = reader.read_u8()?;
69         let epoch = reader.read_u16::<BigEndian>()?;
70 
71         // SequenceNumber is stored as uint48, make into uint64
72         let mut be: [u8; 8] = [0u8; 8];
73         reader.read_exact(&mut be[2..])?;
74         let sequence_number = u64::from_be_bytes(be);
75 
76         let protocol_version = ProtocolVersion { major, minor };
77         if protocol_version != PROTOCOL_VERSION1_0 && protocol_version != PROTOCOL_VERSION1_2 {
78             return Err(Error::ErrUnsupportedProtocolVersion);
79         }
80         let content_len = reader.read_u16::<BigEndian>()?;
81 
82         Ok(RecordLayerHeader {
83             content_type,
84             protocol_version,
85             epoch,
86             sequence_number,
87             content_len,
88         })
89     }
90 }
91