Botan 3.0.0
Crypto and TLS for C&
msg_client_kex.cpp
Go to the documentation of this file.
1/*
2* Client Key Exchange Message
3* (C) 2004-2010,2016 Jack Lloyd
4* 2017 Harry Reimann, Rohde & Schwarz Cybersecurity
5*
6* Botan is released under the Simplified BSD License (see license.txt)
7*/
8
9#include <botan/tls_messages.h>
10#include <botan/tls_extensions.h>
11#include <botan/rng.h>
12
13#include <botan/internal/tls_reader.h>
14#include <botan/internal/tls_handshake_io.h>
15#include <botan/internal/tls_handshake_state.h>
16#include <botan/internal/tls_handshake_hash.h>
17#include <botan/credentials_manager.h>
18#include <botan/internal/ct_utils.h>
19
20#include <botan/rsa.h>
21#include <botan/ecdh.h>
22
23namespace Botan::TLS {
24
25/*
26* Create a new Client Key Exchange message
27*/
29 Handshake_State& state,
30 const Policy& policy,
33 std::string_view hostname,
35 {
36 const Kex_Algo kex_algo = state.ciphersuite().kex_method();
37
38 if(kex_algo == Kex_Algo::PSK)
39 {
40 std::string identity_hint;
41
42 if(state.server_kex())
43 {
44 TLS_Data_Reader reader("ClientKeyExchange", state.server_kex()->params());
45 identity_hint = reader.get_string(2, 0, 65535);
46 }
47
48 const std::string psk_identity =
49 creds.psk_identity("tls-client", std::string(hostname), identity_hint);
50
51 append_tls_length_value(m_key_material, psk_identity, 2);
52
53 SymmetricKey psk = creds.psk("tls-client", std::string(hostname), psk_identity);
54
55 std::vector<uint8_t> zeros(psk.length());
56
57 append_tls_length_value(m_pre_master, zeros, 2);
58 append_tls_length_value(m_pre_master, psk.bits_of(), 2);
59 }
60 else if(state.server_kex())
61 {
62 TLS_Data_Reader reader("ClientKeyExchange", state.server_kex()->params());
63
64 SymmetricKey psk;
65
66 if(kex_algo == Kex_Algo::ECDHE_PSK)
67 {
68 std::string identity_hint = reader.get_string(2, 0, 65535);
69
70 const std::string psk_identity =
71 creds.psk_identity("tls-client", std::string(hostname), identity_hint);
72
73 append_tls_length_value(m_key_material, psk_identity, 2);
74
75 psk = creds.psk("tls-client", std::string(hostname), psk_identity);
76 }
77
78 if(kex_algo == Kex_Algo::DH)
79 {
80 const auto modulus = BigInt::decode(reader.get_range<uint8_t>(2, 1, 65535));
81 const auto generator = BigInt::decode(reader.get_range<uint8_t>(2, 1, 65535));
82 const std::vector<uint8_t> peer_public_value = reader.get_range<uint8_t>(2, 1, 65535);
83
84 if(reader.remaining_bytes())
85 throw Decoding_Error("Bad params size for DH key exchange");
86
87 DL_Group group(modulus, generator);
88
89 if(!group.verify_group(rng, false))
90 { throw TLS_Exception(Alert::InsufficientSecurity, "DH group validation failed"); }
91
92 const auto private_key = state.callbacks().tls_generate_ephemeral_key(group, rng);
93 auto shared_secret =
96 *private_key,
97 peer_public_value,
98 rng,
99 policy));
100
101 if(kex_algo == Kex_Algo::DH)
102 m_pre_master = std::move(shared_secret);
103 else
104 {
105 append_tls_length_value(m_pre_master, shared_secret, 2);
106 append_tls_length_value(m_pre_master, psk.bits_of(), 2);
107 }
108
109 append_tls_length_value(m_key_material, private_key->public_value(), 2);
110 }
111 else if(kex_algo == Kex_Algo::ECDH ||
112 kex_algo == Kex_Algo::ECDHE_PSK)
113 {
114 const uint8_t curve_type = reader.get_byte();
115 if(curve_type != 3)
116 throw Decoding_Error("Server sent non-named ECC curve");
117
118 const Group_Params curve_id = static_cast<Group_Params>(reader.get_uint16_t());
119 const std::vector<uint8_t> peer_public_value = reader.get_range<uint8_t>(1, 1, 255);
120
121 if(policy.choose_key_exchange_group({curve_id}, {}) != curve_id)
122 {
123 throw TLS_Exception(Alert::HandshakeFailure,
124 "Server sent ECC curve prohibited by policy");
125 }
126
127 const auto private_key = state.callbacks().tls_generate_ephemeral_key(curve_id, rng);
128 auto shared_secret =
129 state.callbacks().tls_ephemeral_key_agreement(curve_id,
130 *private_key,
131 peer_public_value,
132 rng,
133 policy);
134
135 if(kex_algo == Kex_Algo::ECDH)
136 {
137 m_pre_master = std::move(shared_secret);
138 }
139 else
140 {
141 append_tls_length_value(m_pre_master, shared_secret, 2);
142 append_tls_length_value(m_pre_master, psk.bits_of(), 2);
143 }
144
145 if(is_ecdh(curve_id))
146 {
147 auto ecdh_key = dynamic_cast<ECDH_PublicKey*>(private_key.get());
148 if(!ecdh_key)
149 {
150 throw TLS_Exception(Alert::InternalError,
151 "Application did not provide a ECDH_PublicKey");
152 }
153 append_tls_length_value(m_key_material,
154 ecdh_key->public_value(
155 state.server_hello()->prefers_compressed_ec_points()
158 1);
159 }
160 else
161 {
162 append_tls_length_value(m_key_material, private_key->public_value(), 1);
163 }
164 }
165 else
166 {
167 throw Internal_Error("Client_Key_Exchange: Unknown key exchange method was negotiated");
168 }
169
170 reader.assert_done();
171 }
172 else
173 {
174 // No server key exchange msg better mean RSA kex + RSA key in cert
175
176 if(kex_algo != Kex_Algo::STATIC_RSA)
177 throw Unexpected_Message("No server kex message, but negotiated a key exchange that required it");
178
180 throw Internal_Error("No server public key for RSA exchange");
181
182 if(auto rsa_pub = dynamic_cast<const RSA_PublicKey*>(server_public_key))
183 {
184 const Protocol_Version offered_version = state.client_hello()->legacy_version();
185
186 rng.random_vec(m_pre_master, 48);
187 m_pre_master[0] = offered_version.major_version();
188 m_pre_master[1] = offered_version.minor_version();
189
190 PK_Encryptor_EME encryptor(*rsa_pub, rng, "PKCS1v15");
191
192 const std::vector<uint8_t> encrypted_key = encryptor.encrypt(m_pre_master, rng);
193
194 append_tls_length_value(m_key_material, encrypted_key, 2);
195 }
196 else
197 throw TLS_Exception(Alert::HandshakeFailure,
198 "Expected a RSA key in server cert but got " +
199 server_public_key->algo_name());
200 }
201
202 state.hash().update(io.send(*this));
203 }
204
205/*
206* Read a Client Key Exchange message
207*/
208Client_Key_Exchange::Client_Key_Exchange(const std::vector<uint8_t>& contents,
209 const Handshake_State& state,
210 const Private_Key* server_rsa_kex_key,
211 Credentials_Manager& creds,
212 const Policy& policy,
214 {
215 const Kex_Algo kex_algo = state.ciphersuite().kex_method();
216
217 if(kex_algo == Kex_Algo::STATIC_RSA)
218 {
219 BOTAN_ASSERT(state.server_certs() && !state.server_certs()->cert_chain().empty(),
220 "RSA key exchange negotiated so server sent a certificate");
221
222 if(!server_rsa_kex_key)
223 throw Internal_Error("Expected RSA kex but no server kex key set");
224
225 if(server_rsa_kex_key->algo_name() != "RSA")
226 throw Internal_Error("Expected RSA key but got " + server_rsa_kex_key->algo_name());
227
228 TLS_Data_Reader reader("ClientKeyExchange", contents);
229 const std::vector<uint8_t> encrypted_pre_master = reader.get_range<uint8_t>(2, 0, 65535);
230 reader.assert_done();
231
232 PK_Decryptor_EME decryptor(*server_rsa_kex_key, rng, "PKCS1v15");
233
234 const uint8_t client_major = state.client_hello()->legacy_version().major_version();
235 const uint8_t client_minor = state.client_hello()->legacy_version().minor_version();
236
237 /*
238 * PK_Decryptor::decrypt_or_random will return a random value if
239 * either the length does not match the expected value or if the
240 * version number embedded in the PMS does not match the one sent
241 * in the client hello.
242 */
243 const size_t expected_plaintext_size = 48;
244 const size_t expected_content_size = 2;
245 const uint8_t expected_content_bytes[expected_content_size] = { client_major, client_minor };
246 const uint8_t expected_content_pos[expected_content_size] = { 0, 1 };
247
248 m_pre_master =
249 decryptor.decrypt_or_random(encrypted_pre_master.data(),
250 encrypted_pre_master.size(),
251 expected_plaintext_size,
252 rng,
253 expected_content_bytes,
254 expected_content_pos,
255 expected_content_size);
256 }
257 else
258 {
259 TLS_Data_Reader reader("ClientKeyExchange", contents);
260
261 SymmetricKey psk;
262
263 if(key_exchange_is_psk(kex_algo))
264 {
265 const std::string psk_identity = reader.get_string(2, 0, 65535);
266
267 psk = creds.psk("tls-server",
268 state.client_hello()->sni_hostname(),
269 psk_identity);
270
271 if(psk.length() == 0)
272 {
273 if(policy.hide_unknown_users())
274 psk = SymmetricKey(rng, 16);
275 else
276 throw TLS_Exception(Alert::UnknownPSKIdentity,
277 "No PSK for identifier " + psk_identity);
278 }
279 }
280
281 if(kex_algo == Kex_Algo::PSK)
282 {
283 std::vector<uint8_t> zeros(psk.length());
284 append_tls_length_value(m_pre_master, zeros, 2);
285 append_tls_length_value(m_pre_master, psk.bits_of(), 2);
286 }
287 else if(kex_algo == Kex_Algo::DH ||
288 kex_algo == Kex_Algo::ECDH ||
289 kex_algo == Kex_Algo::ECDHE_PSK)
290 {
291 const Private_Key& private_key = state.server_kex()->server_kex_key();
292
293 const PK_Key_Agreement_Key* ka_key =
294 dynamic_cast<const PK_Key_Agreement_Key*>(&private_key);
295
296 if(!ka_key)
297 throw Internal_Error("Expected key agreement key type but got " +
298 private_key.algo_name());
299
300 std::vector<uint8_t> client_pubkey;
301
302 if(ka_key->algo_name() == "DH")
303 {
304 client_pubkey = reader.get_range<uint8_t>(2, 0, 65535);
305 }
306 else
307 {
308 client_pubkey = reader.get_range<uint8_t>(1, 1, 255);
309 }
310
311 try
312 {
313 PK_Key_Agreement ka(*ka_key, rng, "Raw");
314
315 secure_vector<uint8_t> shared_secret = ka.derive_key(0, client_pubkey).bits_of();
316
317 if(ka_key->algo_name() == "DH")
318 shared_secret = CT::strip_leading_zeros(shared_secret);
319
320 if(kex_algo == Kex_Algo::ECDHE_PSK)
321 {
322 append_tls_length_value(m_pre_master, shared_secret, 2);
323 append_tls_length_value(m_pre_master, psk.bits_of(), 2);
324 }
325 else
326 m_pre_master = shared_secret;
327 }
328 catch(Invalid_Argument& e)
329 {
330 throw TLS_Exception(Alert::IllegalParameter, e.what());
331 }
332 catch(std::exception&)
333 {
334 /*
335 * Something failed in the DH/ECDH computation. To avoid possible
336 * attacks which are based on triggering and detecting some edge
337 * failure condition, randomize the pre-master output and carry on,
338 * allowing the protocol to fail later in the finished checks.
339 */
340 rng.random_vec(m_pre_master, ka_key->public_value().size());
341 }
342
343 reader.assert_done();
344 }
345 else
346 throw Internal_Error("Client_Key_Exchange: Unknown key exchange negotiated");
347 }
348 }
349
350}
#define BOTAN_ASSERT(expr, assertion_made)
Definition: assert.h:54
virtual std::string algo_name() const =0
static BigInt decode(const uint8_t buf[], size_t length)
Definition: bigint.h:805
virtual std::string psk_identity(const std::string &type, const std::string &context, const std::string &identity_hint)
virtual SymmetricKey psk(const std::string &type, const std::string &context, const std::string &identity)
bool verify_group(RandomNumberGenerator &rng, bool strong=true) const
Definition: dl_group.cpp:417
const char * what() const noexcept override
Definition: exceptn.h:94
secure_vector< uint8_t > bits_of() const
Definition: symkey.h:35
size_t length() const
Definition: symkey.h:28
secure_vector< uint8_t > decrypt_or_random(const uint8_t in[], size_t length, size_t expected_pt_len, RandomNumberGenerator &rng) const
Definition: pubkey.cpp:81
virtual std::vector< uint8_t > public_value() const =0
SymmetricKey derive_key(size_t key_len, const uint8_t in[], size_t in_len, const uint8_t params[], size_t params_len) const
Definition: pubkey.cpp:234
void random_vec(std::span< uint8_t > v)
Definition: rng.h:178
virtual secure_vector< uint8_t > tls_ephemeral_key_agreement(const std::variant< TLS::Group_Params, DL_Group > &group, const PK_Key_Agreement_Key &private_key, const std::vector< uint8_t > &public_value, RandomNumberGenerator &rng, const Policy &policy)
virtual std::unique_ptr< PK_Key_Agreement_Key > tls_generate_ephemeral_key(const std::variant< TLS::Group_Params, DL_Group > &group, RandomNumberGenerator &rng)
Kex_Algo kex_method() const
Client_Key_Exchange(Handshake_IO &io, Handshake_State &state, const Policy &policy, Credentials_Manager &creds, const Public_Key *server_public_key, std::string_view hostname, RandomNumberGenerator &rng)
void server_certs(Certificate_12 *server_certs)
void server_hello(Server_Hello_12 *server_hello)
void server_kex(Server_Key_Exchange *server_kex)
const Ciphersuite & ciphersuite() const
void client_hello(Client_Hello_12 *client_hello)
virtual bool hide_unknown_users() const
Definition: tls_policy.cpp:370
virtual Group_Params choose_key_exchange_group(const std::vector< Group_Params > &supported_by_peer, const std::vector< Group_Params > &offered_by_peer) const
Definition: tls_policy.cpp:131
uint8_t major_version() const
Definition: tls_version.h:86
uint8_t minor_version() const
Definition: tls_version.h:91
std::string get_string(size_t len_bytes, size_t min_bytes, size_t max_bytes)
Definition: tls_reader.h:142
std::vector< T > get_range(size_t len_bytes, size_t min_elems, size_t max_elems)
Definition: tls_reader.h:121
size_t remaining_bytes() const
Definition: tls_reader.h:40
secure_vector< uint8_t > strip_leading_zeros(const uint8_t in[], size_t length)
Definition: ct_utils.cpp:87
void append_tls_length_value(std::vector< uint8_t, Alloc > &buf, const T *vals, size_t vals_size, size_t tag_size)
Definition: tls_reader.h:214
constexpr bool is_ecdh(const Group_Params group)
Definition: tls_algos.h:107
bool key_exchange_is_psk(Kex_Algo m)
Definition: tls_algos.h:147
OctetString SymmetricKey
Definition: symkey.h:145
std::vector< T, secure_allocator< T > > secure_vector
Definition: secmem.h:64
std::unique_ptr< Public_Key > server_public_key