1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
use heapless::{consts::*, Vec};
use p256::ecdh::EphemeralSecret;
use p256::elliptic_curve::rand_core::{CryptoRng, RngCore};
use p256::EncodedPoint;
use crate::buffer::*;
use crate::config::{TlsCipherSuite, TlsConfig};
use crate::extensions::ClientExtension;
use crate::handshake::{Random, LEGACY_VERSION};
use crate::named_groups::NamedGroup;
use crate::signature_schemes::SignatureScheme;
use crate::supported_versions::{ProtocolVersion, TLS13};
use crate::TlsError;
pub struct ClientHello<'config, CipherSuite>
where
CipherSuite: TlsCipherSuite,
{
config: &'config TlsConfig<'config, CipherSuite>,
random: Random,
pub(crate) secret: EphemeralSecret,
}
impl<'config, CipherSuite> ClientHello<'config, CipherSuite>
where
CipherSuite: TlsCipherSuite,
{
pub fn new<RNG>(config: &'config TlsConfig<'config, CipherSuite>, rng: &mut RNG) -> Self
where
RNG: CryptoRng + RngCore,
{
let mut random = [0; 32];
rng.fill_bytes(&mut random);
Self {
config,
random,
secret: EphemeralSecret::random(rng),
}
}
pub(crate) fn encode(&self, buf: &mut CryptoBuffer<'_>) -> Result<(), TlsError> {
let public_key = EncodedPoint::from(&self.secret.public_key());
let public_key = public_key.as_ref();
buf.extend_from_slice(&LEGACY_VERSION.to_be_bytes())
.map_err(|_| TlsError::EncodeError)?;
buf.extend_from_slice(&self.random)
.map_err(|_| TlsError::EncodeError)?;
buf.push(0).map_err(|_| TlsError::EncodeError)?;
buf.extend_from_slice(&2u16.to_be_bytes())
.map_err(|_| TlsError::EncodeError)?;
buf.extend_from_slice(&CipherSuite::CODE_POINT.to_be_bytes())
.map_err(|_| TlsError::EncodeError)?;
buf.push(1).map_err(|_| TlsError::EncodeError)?;
buf.push(0).map_err(|_| TlsError::EncodeError)?;
let mut extensions = Vec::<ClientExtension, U16>::new();
let extension_length_marker = buf.len();
buf.push(0).map_err(|_| TlsError::EncodeError)?;
buf.push(0).map_err(|_| TlsError::EncodeError)?;
let mut versions = Vec::<ProtocolVersion, U16>::new();
versions.push(TLS13).map_err(|_| TlsError::EncodeError)?;
extensions
.push(ClientExtension::SupportedVersions { versions })
.map_err(|_| TlsError::EncodeError)?;
let mut supported_signature_algorithms = Vec::<SignatureScheme, U16>::new();
supported_signature_algorithms.extend(self.config.signature_schemes.iter());
extensions
.push(ClientExtension::SignatureAlgorithms {
supported_signature_algorithms,
})
.map_err(|_| TlsError::EncodeError)?;
let mut supported_groups = Vec::<NamedGroup, U16>::new();
supported_groups.extend(self.config.named_groups.iter());
extensions
.push(ClientExtension::SupportedGroups { supported_groups })
.map_err(|_| TlsError::EncodeError)?;
extensions
.push(ClientExtension::KeyShare {
group: NamedGroup::Secp256r1,
opaque: public_key,
})
.map_err(|_| TlsError::EncodeError)?;
if let Some(server_name) = self.config.server_name.as_ref() {
extensions
.push(ClientExtension::ServerName { server_name })
.map_err(|_| TlsError::EncodeError)?;
}
for e in extensions {
e.encode(buf)?;
}
let extensions_length = (buf.len() as u16 - extension_length_marker as u16) - 2;
buf.set(extension_length_marker, extensions_length.to_be_bytes()[0])
.map_err(|_| TlsError::EncodeError)?;
buf.set(
extension_length_marker + 1,
extensions_length.to_be_bytes()[1],
)
.map_err(|_| TlsError::EncodeError)?;
Ok(())
}
}