webrtc_dtls/handshake/
handshake_message_client_key_exchange.rs

1#[cfg(test)]
2mod handshake_message_client_key_exchange_test;
3
4use std::io::{Read, Write};
5
6use byteorder::{BigEndian, WriteBytesExt};
7
8use super::*;
9
10#[derive(Clone, Debug, PartialEq, Eq)]
11pub struct HandshakeMessageClientKeyExchange {
12    pub(crate) identity_hint: Vec<u8>,
13    pub(crate) public_key: Vec<u8>,
14}
15
16impl HandshakeMessageClientKeyExchange {
17    pub fn handshake_type(&self) -> HandshakeType {
18        HandshakeType::ClientKeyExchange
19    }
20
21    pub fn size(&self) -> usize {
22        if !self.public_key.is_empty() {
23            1 + self.public_key.len()
24        } else {
25            2 + self.identity_hint.len()
26        }
27    }
28
29    pub fn marshal<W: Write>(&self, writer: &mut W) -> Result<()> {
30        if (!self.identity_hint.is_empty() && !self.public_key.is_empty())
31            || (self.identity_hint.is_empty() && self.public_key.is_empty())
32        {
33            return Err(Error::ErrInvalidClientKeyExchange);
34        }
35
36        if !self.public_key.is_empty() {
37            writer.write_u8(self.public_key.len() as u8)?;
38            writer.write_all(&self.public_key)?;
39        } else {
40            writer.write_u16::<BigEndian>(self.identity_hint.len() as u16)?;
41            writer.write_all(&self.identity_hint)?;
42        }
43
44        Ok(writer.flush()?)
45    }
46
47    pub fn unmarshal<R: Read>(reader: &mut R) -> Result<Self> {
48        let mut data = vec![];
49        reader.read_to_end(&mut data)?;
50
51        // If parsed as PSK return early and only populate PSK Identity Hint
52        let psk_length = ((data[0] as u16) << 8) | data[1] as u16;
53        if data.len() == psk_length as usize + 2 {
54            return Ok(HandshakeMessageClientKeyExchange {
55                identity_hint: data[2..].to_vec(),
56                public_key: vec![],
57            });
58        }
59
60        let public_key_length = data[0] as usize;
61        if data.len() != public_key_length + 1 {
62            return Err(Error::ErrBufferTooSmall);
63        }
64
65        Ok(HandshakeMessageClientKeyExchange {
66            identity_hint: vec![],
67            public_key: data[1..].to_vec(),
68        })
69    }
70}