Skip to main content

reqtls/message/
key_exchange.rs

1use crate::bytes::ByteRef;
2use crate::{CipherSuite, WriteExt};
3use crate::error::RlsResult;
4use super::super::boring::SignatureAlgorithm;
5use super::super::message::HandshakeType;
6use super::super::bytes::Bytes;
7
8#[derive(Debug, Copy, Clone)]
9pub enum CurveType {
10    NamedCurve = 0x3
11}
12
13impl CurveType {
14    pub fn from_u8(v: u8) -> Option<Self> {
15        match v {
16            0x3 => Some(Self::NamedCurve),
17            _ => None
18        }
19    }
20
21    pub fn as_u8(&self) -> u8 {
22        *self as u8
23    }
24}
25
26#[allow(non_camel_case_types)]
27#[derive(Debug, Copy, Clone)]
28pub enum NamedCurve {
29    x25519 = 0x1d,
30    Secp256r1 = 0x17,
31    Secp384r1 = 0x18,
32    Secp521r1 = 0x19,
33}
34
35impl NamedCurve {
36    pub fn from_u16(v: u16) -> Option<Self> {
37        match v {
38            0x1d => Some(Self::x25519),
39            0x17 => Some(Self::Secp256r1),
40            0x18 => Some(Self::Secp384r1),
41            0x19 => Some(Self::Secp521r1),
42            _ => None
43        }
44    }
45
46    pub fn as_u16(&self) -> u16 { self.clone() as u16 }
47}
48
49#[derive(Debug)]
50pub struct ServerHellmanParam {
51    curve_type: CurveType,
52    named_curve: NamedCurve,
53    pub_key_len: u8,
54    pub_key: Bytes,
55    signature_algorithm: SignatureAlgorithm,
56    signature_len: u16,
57    signature: Bytes,
58}
59
60impl ServerHellmanParam {
61    pub fn new() -> ServerHellmanParam {
62        ServerHellmanParam {
63            curve_type: CurveType::NamedCurve,
64            named_curve: NamedCurve::Secp384r1,
65            pub_key_len: 0,
66            pub_key: Bytes::none(),
67            signature_algorithm: SignatureAlgorithm::RSA_PSS_RSAE_SHA256,
68            signature_len: 0,
69            signature: Bytes::none(),
70        }
71    }
72    pub fn from_bytes(bytes: &[u8]) -> RlsResult<ServerHellmanParam> {
73        let mut res = ServerHellmanParam::new();
74        res.curve_type = CurveType::from_u8(bytes[0]).ok_or("CurveType Unknown")?;
75        let v = u16::from_be_bytes([bytes[1], bytes[2]]);
76        res.named_curve = NamedCurve::from_u16(v).ok_or(format!("NamedCurve Unknown-{}", v))?;
77        res.pub_key_len = bytes[3];
78        res.pub_key = Bytes::new(bytes[4..res.pub_key_len as usize + 4].to_vec());
79        let index = res.pub_key_len as usize + 4;
80        let v = u16::from_be_bytes([bytes[index], bytes[index + 1]]);
81        res.signature_algorithm = SignatureAlgorithm::new(v);
82        res.signature_len = u16::from_be_bytes([bytes[index + 2], bytes[index + 3]]);
83        res.signature = Bytes::new(bytes[index + 4..index + 4 + res.signature_len as usize].to_vec());
84        Ok(res)
85    }
86
87    pub fn len(&self) -> usize {
88        8 + self.pub_key.len() + self.signature.len()
89    }
90
91    pub fn write_to<W: WriteExt>(self, writer: &mut W) {
92        writer.write_u8(self.curve_type as u8);
93        writer.write_u16(self.named_curve as u16);
94        writer.write_u8(self.pub_key.len() as u8);
95        writer.write_slice(self.pub_key.as_ref());
96        writer.write_u16(self.signature_algorithm.into_inner());
97        writer.write_u16(self.signature.len() as u16);
98        writer.write_slice(self.signature.as_ref());
99    }
100
101    pub fn curve_type(&self) -> &CurveType { &self.curve_type }
102
103    pub fn pub_key(&self) -> &Bytes {
104        &self.pub_key
105    }
106
107    pub fn named_curve(&self) -> &NamedCurve {
108        &self.named_curve
109    }
110
111    pub fn signature(&self) -> &Bytes {
112        &self.signature
113    }
114
115    pub fn signature_algorithm(&self) -> &SignatureAlgorithm {
116        &self.signature_algorithm
117    }
118
119    pub fn set_pub_key(&mut self, pub_key: impl Into<Vec<u8>>) {
120        self.pub_key = Bytes::new(pub_key.into());
121    }
122
123    pub fn set_signature(&mut self, signature: Bytes) {
124        self.signature = signature;
125    }
126}
127
128#[derive(Debug)]
129pub struct ServerKeyExchange {
130    handshake_type: HandshakeType,
131    // len: u32,
132    hellman_param: ServerHellmanParam,
133}
134
135impl Default for ServerKeyExchange {
136    fn default() -> Self {
137        ServerKeyExchange {
138            handshake_type: HandshakeType::ServerKeyExchange,
139            // len: 0,
140            hellman_param: ServerHellmanParam::new(),
141        }
142    }
143}
144
145impl ServerKeyExchange {
146    pub fn from_bytes(ht: HandshakeType, bytes: &[u8]) -> RlsResult<ServerKeyExchange> {
147        let len = u32::from_be_bytes([0, bytes[1], bytes[2], bytes[3]].try_into()?) as usize;
148        // let mut res =
149        // let mut res = ServerKeyExchange::default();
150        // res.handshake_type = ht;
151        // res.len = u32::from_be_bytes([0, bytes[1], bytes[2], bytes[3]].try_into()?);
152        // res.hellman_param = ServerHellmanParam::from_bytes(&bytes[4..])?;
153        Ok(ServerKeyExchange {
154            handshake_type: ht,
155            hellman_param: ServerHellmanParam::from_bytes(&bytes[4..4 + len])?,
156        })
157    }
158
159    pub fn is_empty(&self) -> bool { self.len() == 0 }
160
161    pub fn len(&self) -> usize {
162        4 + self.hellman_param.len()
163    }
164
165    pub fn write_to<W: WriteExt>(self, writer: &mut W) {
166        writer.write_u8(self.handshake_type as u8);
167        writer.write_u32(self.hellman_param.len() as u32, true);
168        self.hellman_param.write_to(writer);
169    }
170
171    pub fn hellman_param(&self) -> &ServerHellmanParam {
172        &self.hellman_param
173    }
174
175    pub fn hellman_param_mut(&mut self) -> &mut ServerHellmanParam { &mut self.hellman_param }
176}
177
178#[derive(Debug)]
179pub struct ClientHellmanParam<'a> {
180    pub_key_len: u16,
181    pub_key: ByteRef<'a>,
182}
183
184impl<'a> ClientHellmanParam<'a> {
185    pub fn new() -> ClientHellmanParam<'a> {
186        ClientHellmanParam {
187            pub_key_len: 0,
188            pub_key: ByteRef::default(),
189        }
190    }
191
192    pub fn from_bytes(bytes: &'a [u8], suite: Option<&CipherSuite>) -> RlsResult<ClientHellmanParam<'a>> {
193        let mut res = ClientHellmanParam::new();
194        let key_size = suite.map(|x| x.key_size()).unwrap_or(1);
195        res.pub_key_len = if key_size == 2 { u16::from_be_bytes([bytes[0], bytes[1]]) } else { bytes[0] as u16 };
196        res.pub_key = ByteRef::new(&bytes[key_size as usize..res.pub_key_len as usize + key_size as usize]);
197        Ok(res)
198    }
199    pub fn len(&self, key_size: u8) -> usize {
200        key_size as usize + self.pub_key.len()
201    }
202
203    pub fn write_to<W: WriteExt>(self, writer: &mut W, key_size: u8) {
204        match key_size {
205            2 => writer.write_u16(self.pub_key.len() as u16),
206            _ => writer.write_u8(self.pub_key.len() as u8),
207        }
208        writer.write_slice(self.pub_key.as_ref());
209    }
210
211    pub fn pub_key(&self) -> &ByteRef<'a> {
212        &self.pub_key
213    }
214}
215
216#[derive(Debug)]
217pub struct ClientKeyExchange<'a> {
218    handshake_type: HandshakeType,
219    hellman_param: ClientHellmanParam<'a>,
220}
221
222impl<'a> Default for ClientKeyExchange<'a> {
223    fn default() -> Self {
224        ClientKeyExchange {
225            handshake_type: HandshakeType::ClientHello,
226            hellman_param: ClientHellmanParam::new(),
227        }
228    }
229}
230
231impl<'a> ClientKeyExchange<'a> {
232    pub fn from_bytes(ht: HandshakeType, bytes: &'a [u8], suite: Option<&CipherSuite>) -> RlsResult<ClientKeyExchange<'a>> {
233        let len = u32::from_be_bytes([0, bytes[1], bytes[2], bytes[3]]) as usize;
234        Ok(ClientKeyExchange {
235            handshake_type: ht,
236            hellman_param: ClientHellmanParam::from_bytes(&bytes[4..4 + len], suite)?,
237        })
238    }
239
240    pub fn len(&self, key_size: u8) -> usize {
241        4 + self.hellman_param.len(key_size)
242    }
243
244    pub fn write_to<W: WriteExt>(self, writer: &mut W, key_size: u8) {
245        writer.write_u8(self.handshake_type as u8);
246        writer.write_u32(self.hellman_param.len(key_size) as u32, true);
247        self.hellman_param.write_to(writer, key_size);
248    }
249
250    pub fn set_pub_key(&mut self, pub_key: &'a [u8]) {
251        self.hellman_param.pub_key = ByteRef::new(pub_key);
252        self.hellman_param.pub_key_len = self.hellman_param.pub_key.len() as u16;
253    }
254
255    pub fn hellman_param(&self) -> &ClientHellmanParam<'a> {
256        &self.hellman_param
257    }
258}
259