rtc_dtls/handshake/
handshake_random.rs1use rand::RngExt;
2
3use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
4use std::io::{self, Read, Write};
5use std::time::{Duration, SystemTime};
6
7pub const RANDOM_BYTES_LENGTH: usize = 28;
9pub const HANDSHAKE_RANDOM_LENGTH: usize = RANDOM_BYTES_LENGTH + 4;
11
12#[derive(Clone, Debug, PartialEq, Eq)]
18pub struct HandshakeRandom {
19 pub gmt_unix_time: SystemTime,
21 pub random_bytes: [u8; RANDOM_BYTES_LENGTH],
23}
24
25impl Default for HandshakeRandom {
26 fn default() -> Self {
27 HandshakeRandom {
28 gmt_unix_time: SystemTime::UNIX_EPOCH,
29 random_bytes: [0u8; RANDOM_BYTES_LENGTH],
30 }
31 }
32}
33
34impl HandshakeRandom {
35 pub fn size(&self) -> usize {
37 4 + RANDOM_BYTES_LENGTH
38 }
39
40 pub fn marshal<W: Write>(&self, writer: &mut W) -> io::Result<()> {
46 let secs = match self.gmt_unix_time.duration_since(SystemTime::UNIX_EPOCH) {
47 Ok(d) => d.as_secs() as u32,
48 Err(_) => 0,
49 };
50 writer.write_u32::<BigEndian>(secs)?;
51 writer.write_all(&self.random_bytes)?;
52
53 writer.flush()
54 }
55
56 pub fn unmarshal<R: Read>(reader: &mut R) -> io::Result<Self> {
62 let secs = reader.read_u32::<BigEndian>()?;
63 let gmt_unix_time = if let Some(unix_time) =
64 SystemTime::UNIX_EPOCH.checked_add(Duration::new(secs as u64, 0))
65 {
66 unix_time
67 } else {
68 SystemTime::UNIX_EPOCH
69 };
70
71 let mut random_bytes = [0u8; RANDOM_BYTES_LENGTH];
72 reader.read_exact(&mut random_bytes)?;
73
74 Ok(HandshakeRandom {
75 gmt_unix_time,
76 random_bytes,
77 })
78 }
79
80 pub fn populate(&mut self) {
84 self.gmt_unix_time = SystemTime::now();
85 rand::rng().fill(&mut self.random_bytes);
86 }
87}