reqtls/message/
key_exchange.rs1use 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 hellman_param: ServerHellmanParam,
133}
134
135impl Default for ServerKeyExchange {
136 fn default() -> Self {
137 ServerKeyExchange {
138 handshake_type: HandshakeType::ServerKeyExchange,
139 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 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