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