webrtc_dtls/handshake/
handshake_random.rs1use std::io::{self, Read, Write};
2use std::time::{Duration, SystemTime};
3
4use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
5use rand::Rng;
6
7pub const RANDOM_BYTES_LENGTH: usize = 28;
8pub const HANDSHAKE_RANDOM_LENGTH: usize = RANDOM_BYTES_LENGTH + 4;
9
10#[derive(Clone, Debug, PartialEq, Eq)]
16pub struct HandshakeRandom {
17 pub gmt_unix_time: SystemTime,
18 pub random_bytes: [u8; RANDOM_BYTES_LENGTH],
19}
20
21impl Default for HandshakeRandom {
22 fn default() -> Self {
23 HandshakeRandom {
24 gmt_unix_time: SystemTime::UNIX_EPOCH,
25 random_bytes: [0u8; RANDOM_BYTES_LENGTH],
26 }
27 }
28}
29
30impl HandshakeRandom {
31 pub fn size(&self) -> usize {
32 4 + RANDOM_BYTES_LENGTH
33 }
34
35 pub fn marshal<W: Write>(&self, writer: &mut W) -> io::Result<()> {
36 let secs = match self.gmt_unix_time.duration_since(SystemTime::UNIX_EPOCH) {
37 Ok(d) => d.as_secs() as u32,
38 Err(_) => 0,
39 };
40 writer.write_u32::<BigEndian>(secs)?;
41 writer.write_all(&self.random_bytes)?;
42
43 writer.flush()
44 }
45
46 pub fn unmarshal<R: Read>(reader: &mut R) -> io::Result<Self> {
47 let secs = reader.read_u32::<BigEndian>()?;
48 let gmt_unix_time = if let Some(unix_time) =
49 SystemTime::UNIX_EPOCH.checked_add(Duration::new(secs as u64, 0))
50 {
51 unix_time
52 } else {
53 SystemTime::UNIX_EPOCH
54 };
55
56 let mut random_bytes = [0u8; RANDOM_BYTES_LENGTH];
57 reader.read_exact(&mut random_bytes)?;
58
59 Ok(HandshakeRandom {
60 gmt_unix_time,
61 random_bytes,
62 })
63 }
64
65 pub fn populate(&mut self) {
68 self.gmt_unix_time = SystemTime::now();
69 rand::thread_rng().fill(&mut self.random_bytes);
70 }
71}