Coverage Report

Created: 2020-06-30 13:58

/src/botan/src/lib/tls/msg_server_kex.cpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
* Server Key Exchange Message
3
* (C) 2004-2010,2012,2015,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/internal/tls_reader.h>
12
#include <botan/internal/tls_handshake_io.h>
13
#include <botan/internal/tls_handshake_state.h>
14
#include <botan/credentials_manager.h>
15
#include <botan/loadstor.h>
16
#include <botan/pubkey.h>
17
18
#include <botan/dh.h>
19
#include <botan/ecdh.h>
20
21
#if defined(BOTAN_HAS_CURVE_25519)
22
  #include <botan/curve25519.h>
23
#endif
24
25
#if defined(BOTAN_HAS_CECPQ1)
26
  #include <botan/cecpq1.h>
27
#endif
28
29
#if defined(BOTAN_HAS_SRP6)
30
  #include <botan/srp6.h>
31
#endif
32
33
namespace Botan {
34
35
namespace TLS {
36
37
/**
38
* Create a new Server Key Exchange message
39
*/
40
Server_Key_Exchange::Server_Key_Exchange(Handshake_IO& io,
41
                                         Handshake_State& state,
42
                                         const Policy& policy,
43
                                         Credentials_Manager& creds,
44
                                         RandomNumberGenerator& rng,
45
                                         const Private_Key* signing_key)
46
24.3k
   {
47
24.3k
   const std::string hostname = state.client_hello()->sni_hostname();
48
24.3k
   const Kex_Algo kex_algo = state.ciphersuite().kex_method();
49
24.3k
50
24.3k
   if(kex_algo == Kex_Algo::PSK || kex_algo == Kex_Algo::DHE_PSK || kex_algo == Kex_Algo::ECDHE_PSK)
51
21.2k
      {
52
21.2k
      std::string identity_hint =
53
21.2k
         creds.psk_identity_hint("tls-server", hostname);
54
21.2k
55
21.2k
      append_tls_length_value(m_params, identity_hint, 2);
56
21.2k
      }
57
24.3k
58
24.3k
   if(kex_algo == Kex_Algo::DH || kex_algo == Kex_Algo::DHE_PSK)
59
5.63k
      {
60
5.63k
      const std::vector<Group_Params> dh_groups = state.client_hello()->supported_dh_groups();
61
5.63k
62
5.63k
      Group_Params shared_group = Group_Params::NONE;
63
5.63k
64
5.63k
      /*
65
5.63k
      If the client does not send any DH groups in the supported groups
66
5.63k
      extension, but does offer DH ciphersuites, we select a group arbitrarily
67
5.63k
      */
68
5.63k
69
5.63k
      if(dh_groups.empty())
70
3.87k
         {
71
3.87k
         shared_group = policy.default_dh_group();
72
3.87k
         }
73
1.76k
      else
74
1.76k
         {
75
1.76k
         shared_group = policy.choose_key_exchange_group(dh_groups);
76
1.76k
         }
77
5.63k
78
5.63k
      if(shared_group == Group_Params::NONE)
79
10
         throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
80
10
               "Could not agree on a DH group with the client");
81
5.62k
82
5.62k
      BOTAN_ASSERT(group_param_is_dh(shared_group), "DH groups for the DH ciphersuites god");
83
5.62k
84
5.62k
      const std::string group_name = state.callbacks().tls_decode_group_param(shared_group);
85
5.62k
      std::unique_ptr<DH_PrivateKey> dh(new DH_PrivateKey(rng, DL_Group(group_name)));
86
5.62k
87
5.62k
      append_tls_length_value(m_params, BigInt::encode(dh->get_domain().get_p()), 2);
88
5.62k
      append_tls_length_value(m_params, BigInt::encode(dh->get_domain().get_g()), 2);
89
5.62k
      append_tls_length_value(m_params, dh->public_value(), 2);
90
5.62k
      m_kex_key.reset(dh.release());
91
5.62k
      }
92
18.6k
   else if(kex_algo == Kex_Algo::ECDH || kex_algo == Kex_Algo::ECDHE_PSK)
93
18.2k
      {
94
18.2k
      const std::vector<Group_Params> ec_groups = state.client_hello()->supported_ecc_curves();
95
18.2k
96
18.2k
      if(ec_groups.empty())
97
0
         throw Internal_Error("Client sent no ECC extension but we negotiated ECDH");
98
18.2k
99
18.2k
      Group_Params shared_group = policy.choose_key_exchange_group(ec_groups);
100
18.2k
101
18.2k
      if(shared_group == Group_Params::NONE)
102
0
         throw TLS_Exception(Alert::HANDSHAKE_FAILURE, "No shared ECC group with client");
103
18.2k
104
18.2k
      std::vector<uint8_t> ecdh_public_val;
105
18.2k
106
18.2k
      if(shared_group == Group_Params::X25519)
107
423
         {
108
423
#if defined(BOTAN_HAS_CURVE_25519)
109
423
         std::unique_ptr<Curve25519_PrivateKey> x25519(new Curve25519_PrivateKey(rng));
110
423
         ecdh_public_val = x25519->public_value();
111
423
         m_kex_key.reset(x25519.release());
112
#else
113
         throw Internal_Error("Negotiated X25519 somehow, but it is disabled");
114
#endif
115
         }
116
17.8k
      else
117
17.8k
         {
118
17.8k
         Group_Params curve = policy.choose_key_exchange_group(ec_groups);
119
17.8k
120
17.8k
         const std::string curve_name = state.callbacks().tls_decode_group_param(curve);
121
17.8k
122
17.8k
         EC_Group ec_group(curve_name);
123
17.8k
         std::unique_ptr<ECDH_PrivateKey> ecdh(new ECDH_PrivateKey(rng, ec_group));
124
17.8k
125
17.8k
         // follow client's preference for point compression
126
17.8k
         ecdh_public_val = ecdh->public_value(
127
17.8k
            state.client_hello()->prefers_compressed_ec_points() ?
128
17.5k
            PointGFp::COMPRESSED : PointGFp::UNCOMPRESSED);
129
17.8k
130
17.8k
         m_kex_key.reset(ecdh.release());
131
17.8k
         }
132
18.2k
133
18.2k
      const uint16_t named_curve_id = static_cast<uint16_t>(shared_group);
134
18.2k
      m_params.push_back(3); // named curve
135
18.2k
      m_params.push_back(get_byte(0, named_curve_id));
136
18.2k
      m_params.push_back(get_byte(1, named_curve_id));
137
18.2k
138
18.2k
      append_tls_length_value(m_params, ecdh_public_val, 1);
139
18.2k
      }
140
471
#if defined(BOTAN_HAS_SRP6)
141
471
   else if(kex_algo == Kex_Algo::SRP_SHA)
142
0
      {
143
0
      const std::string srp_identifier = state.client_hello()->srp_identifier();
144
0
145
0
      std::string group_id;
146
0
      BigInt v;
147
0
      std::vector<uint8_t> salt;
148
0
149
0
      const bool found = creds.srp_verifier("tls-server", hostname,
150
0
                                            srp_identifier,
151
0
                                            group_id, v, salt,
152
0
                                            policy.hide_unknown_users());
153
0
154
0
      if(!found)
155
0
         throw TLS_Exception(Alert::UNKNOWN_PSK_IDENTITY,
156
0
                             "Unknown SRP user " + srp_identifier);
157
0
158
0
      m_srp_params.reset(new SRP6_Server_Session);
159
0
160
0
      BigInt B = m_srp_params->step1(v, group_id,
161
0
                                     "SHA-1", rng);
162
0
163
0
      DL_Group group(group_id);
164
0
165
0
      append_tls_length_value(m_params, BigInt::encode(group.get_p()), 2);
166
0
      append_tls_length_value(m_params, BigInt::encode(group.get_g()), 2);
167
0
      append_tls_length_value(m_params, salt, 1);
168
0
      append_tls_length_value(m_params, BigInt::encode(B), 2);
169
0
      }
170
471
#endif
171
471
#if defined(BOTAN_HAS_CECPQ1)
172
471
   else if(kex_algo == Kex_Algo::CECPQ1)
173
0
      {
174
0
      std::vector<uint8_t> cecpq1_offer(CECPQ1_OFFER_BYTES);
175
0
      m_cecpq1_key.reset(new CECPQ1_key);
176
0
      CECPQ1_offer(cecpq1_offer.data(), m_cecpq1_key.get(), rng);
177
0
      append_tls_length_value(m_params, cecpq1_offer, 2);
178
0
      }
179
471
#endif
180
471
   else if(kex_algo != Kex_Algo::PSK)
181
0
      {
182
0
      throw Internal_Error("Server_Key_Exchange: Unknown kex type " +
183
0
                           kex_method_to_string(kex_algo));
184
0
      }
185
24.3k
186
24.3k
   if(state.ciphersuite().signature_used())
187
0
      {
188
0
      BOTAN_ASSERT(signing_key, "Signing key was set");
189
0
190
0
      std::pair<std::string, Signature_Format> format =
191
0
         state.choose_sig_format(*signing_key, m_scheme, false, policy);
192
0
193
0
      std::vector<uint8_t> buf = state.client_hello()->random();
194
0
195
0
      buf += state.server_hello()->random();
196
0
      buf += params();
197
0
198
0
      m_signature =
199
0
         state.callbacks().tls_sign_message(*signing_key, rng,
200
0
                                            format.first, format.second, buf);
201
0
      }
202
24.3k
203
24.3k
   state.hash().update(io.send(*this));
204
24.3k
   }
205
206
/**
207
* Deserialize a Server Key Exchange message
208
*/
209
Server_Key_Exchange::Server_Key_Exchange(const std::vector<uint8_t>& buf,
210
                                         const Kex_Algo kex_algo,
211
                                         const Auth_Method auth_method,
212
                                         Protocol_Version version)
213
737
   {
214
737
   TLS_Data_Reader reader("ServerKeyExchange", buf);
215
737
216
737
   /*
217
737
   * Here we are deserializing enough to find out what offset the
218
737
   * signature is at. All processing is done when the Client Key Exchange
219
737
   * is prepared.
220
737
   */
221
737
222
737
   if(kex_algo == Kex_Algo::PSK || kex_algo == Kex_Algo::DHE_PSK || kex_algo == Kex_Algo::ECDHE_PSK)
223
31
      {
224
31
      reader.get_string(2, 0, 65535); // identity hint
225
31
      }
226
737
227
737
   if(kex_algo == Kex_Algo::DH || kex_algo == Kex_Algo::DHE_PSK)
228
218
      {
229
218
      // 3 bigints, DH p, g, Y
230
218
231
866
      for(size_t i = 0; i != 3; ++i)
232
648
         {
233
648
         reader.get_range<uint8_t>(2, 1, 65535);
234
648
         }
235
218
      }
236
519
   else if(kex_algo == Kex_Algo::ECDH || kex_algo == Kex_Algo::ECDHE_PSK)
237
503
      {
238
503
      reader.get_byte(); // curve type
239
503
      reader.get_uint16_t(); // curve id
240
503
      reader.get_range<uint8_t>(1, 1, 255); // public key
241
503
      }
242
16
   else if(kex_algo == Kex_Algo::SRP_SHA)
243
0
      {
244
0
      // 2 bigints (N,g) then salt, then server B
245
0
246
0
      reader.get_range<uint8_t>(2, 1, 65535);
247
0
      reader.get_range<uint8_t>(2, 1, 65535);
248
0
      reader.get_range<uint8_t>(1, 1, 255);
249
0
      reader.get_range<uint8_t>(2, 1, 65535);
250
0
      }
251
16
   else if(kex_algo == Kex_Algo::CECPQ1)
252
1
      {
253
1
      // u16 blob
254
1
      reader.get_range<uint8_t>(2, 1, 65535);
255
1
      }
256
15
   else if(kex_algo != Kex_Algo::PSK)
257
0
      throw Decoding_Error("Server_Key_Exchange: Unsupported kex type " +
258
0
                           kex_method_to_string(kex_algo));
259
737
260
737
   m_params.assign(buf.data(), buf.data() + reader.read_so_far());
261
737
262
737
   if(auth_method != Auth_Method::ANONYMOUS && auth_method != Auth_Method::IMPLICIT)
263
372
      {
264
372
      if(version.supports_negotiable_signature_algorithms())
265
372
         {
266
372
         m_scheme = static_cast<Signature_Scheme>(reader.get_uint16_t());
267
372
         }
268
372
269
372
      m_signature = reader.get_range<uint8_t>(2, 0, 65535);
270
372
      }
271
737
272
737
   reader.assert_done();
273
737
   }
274
275
/**
276
* Serialize a Server Key Exchange message
277
*/
278
std::vector<uint8_t> Server_Key_Exchange::serialize() const
279
24.3k
   {
280
24.3k
   std::vector<uint8_t> buf = params();
281
24.3k
282
24.3k
   if(m_signature.size())
283
0
      {
284
0
      if(m_scheme != Signature_Scheme::NONE)
285
0
         {
286
0
         const uint16_t scheme_code = static_cast<uint16_t>(m_scheme);
287
0
         buf.push_back(get_byte(0, scheme_code));
288
0
         buf.push_back(get_byte(1, scheme_code));
289
0
         }
290
0
291
0
      append_tls_length_value(buf, m_signature, 2);
292
0
      }
293
24.3k
294
24.3k
   return buf;
295
24.3k
   }
296
297
/**
298
* Verify a Server Key Exchange message
299
*/
300
bool Server_Key_Exchange::verify(const Public_Key& server_key,
301
                                 const Handshake_State& state,
302
                                 const Policy& policy) const
303
369
   {
304
369
   policy.check_peer_key_acceptable(server_key);
305
369
306
369
   std::pair<std::string, Signature_Format> format =
307
369
      state.parse_sig_format(server_key, m_scheme, false, policy);
308
369
309
369
   std::vector<uint8_t> buf = state.client_hello()->random();
310
369
311
369
   buf += state.server_hello()->random();
312
369
   buf += params();
313
369
314
369
   const bool signature_valid =
315
369
      state.callbacks().tls_verify_message(server_key, format.first, format.second,
316
369
                                           buf, m_signature);
317
369
318
369
#if defined(BOTAN_UNSAFE_FUZZER_MODE)
319
369
   BOTAN_UNUSED(signature_valid);
320
369
   return true;
321
#else
322
   return signature_valid;
323
#endif
324
   }
325
326
const Private_Key& Server_Key_Exchange::server_kex_key() const
327
14.0k
   {
328
14.0k
   BOTAN_ASSERT_NONNULL(m_kex_key);
329
14.0k
   return *m_kex_key;
330
14.0k
   }
331
332
}
333
334
}