Coverage Report

Created: 2024-11-21 06:38

/src/botan/src/lib/pubkey/pubkey.cpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
* (C) 1999-2010,2015,2018 Jack Lloyd
3
*
4
* Botan is released under the Simplified BSD License (see license.txt)
5
*/
6
7
#include <botan/pubkey.h>
8
9
#include <botan/ber_dec.h>
10
#include <botan/bigint.h>
11
#include <botan/der_enc.h>
12
#include <botan/mem_ops.h>
13
#include <botan/pk_ops.h>
14
#include <botan/rng.h>
15
#include <botan/internal/ct_utils.h>
16
#include <botan/internal/fmt.h>
17
#include <botan/internal/parsing.h>
18
#include <botan/internal/pss_params.h>
19
#include <botan/internal/stl_util.h>
20
21
namespace Botan {
22
23
0
secure_vector<uint8_t> PK_Decryptor::decrypt(const uint8_t in[], size_t length) const {
24
0
   uint8_t valid_mask = 0;
25
26
0
   secure_vector<uint8_t> decoded = do_decrypt(valid_mask, in, length);
27
28
0
   if(valid_mask == 0) {
29
0
      throw Decoding_Error("Invalid public key ciphertext, cannot decrypt");
30
0
   }
31
32
0
   return decoded;
33
0
}
34
35
secure_vector<uint8_t> PK_Decryptor::decrypt_or_random(const uint8_t in[],
36
                                                       size_t length,
37
                                                       size_t expected_pt_len,
38
                                                       RandomNumberGenerator& rng,
39
                                                       const uint8_t required_content_bytes[],
40
                                                       const uint8_t required_content_offsets[],
41
0
                                                       size_t required_contents_length) const {
42
0
   const secure_vector<uint8_t> fake_pms = rng.random_vec(expected_pt_len);
43
44
0
   uint8_t decrypt_valid = 0;
45
0
   secure_vector<uint8_t> decoded = do_decrypt(decrypt_valid, in, length);
46
47
0
   auto valid_mask = CT::Mask<uint8_t>::is_equal(decrypt_valid, 0xFF);
48
0
   valid_mask &= CT::Mask<uint8_t>(CT::Mask<size_t>::is_zero(decoded.size() ^ expected_pt_len));
49
50
0
   decoded.resize(expected_pt_len);
51
52
0
   for(size_t i = 0; i != required_contents_length; ++i) {
53
      /*
54
      These values are chosen by the application and for TLS are constants,
55
      so this early failure via assert is fine since we know 0,1 < 48
56
57
      If there is a protocol that has content checks on the key where
58
      the expected offsets are controllable by the attacker this could
59
      still leak.
60
61
      Alternately could always reduce the offset modulo the length?
62
      */
63
64
0
      const uint8_t exp = required_content_bytes[i];
65
0
      const uint8_t off = required_content_offsets[i];
66
67
0
      BOTAN_ASSERT(off < expected_pt_len, "Offset in range of plaintext");
68
69
0
      auto eq = CT::Mask<uint8_t>::is_equal(decoded[off], exp);
70
71
0
      valid_mask &= eq;
72
0
   }
73
74
   // If valid_mask is false, assign fake pre master instead
75
0
   valid_mask.select_n(decoded.data(), decoded.data(), fake_pms.data(), expected_pt_len);
76
77
0
   return decoded;
78
0
}
79
80
secure_vector<uint8_t> PK_Decryptor::decrypt_or_random(const uint8_t in[],
81
                                                       size_t length,
82
                                                       size_t expected_pt_len,
83
0
                                                       RandomNumberGenerator& rng) const {
84
0
   return decrypt_or_random(in, length, expected_pt_len, rng, nullptr, nullptr, 0);
85
0
}
86
87
PK_Encryptor_EME::PK_Encryptor_EME(const Public_Key& key,
88
                                   RandomNumberGenerator& rng,
89
                                   std::string_view padding,
90
0
                                   std::string_view provider) {
91
0
   m_op = key.create_encryption_op(rng, padding, provider);
92
0
   if(!m_op) {
93
0
      throw Invalid_Argument(fmt("Key type {} does not support encryption", key.algo_name()));
94
0
   }
95
0
}
96
97
0
PK_Encryptor_EME::~PK_Encryptor_EME() = default;
98
99
0
PK_Encryptor_EME::PK_Encryptor_EME(PK_Encryptor_EME&&) noexcept = default;
100
0
PK_Encryptor_EME& PK_Encryptor_EME::operator=(PK_Encryptor_EME&&) noexcept = default;
101
102
0
size_t PK_Encryptor_EME::ciphertext_length(size_t ptext_len) const {
103
0
   return m_op->ciphertext_length(ptext_len);
104
0
}
105
106
0
std::vector<uint8_t> PK_Encryptor_EME::enc(const uint8_t in[], size_t length, RandomNumberGenerator& rng) const {
107
0
   return m_op->encrypt(std::span{in, length}, rng);
108
0
}
109
110
0
size_t PK_Encryptor_EME::maximum_input_size() const {
111
0
   return m_op->max_input_bits() / 8;
112
0
}
113
114
PK_Decryptor_EME::PK_Decryptor_EME(const Private_Key& key,
115
                                   RandomNumberGenerator& rng,
116
                                   std::string_view padding,
117
0
                                   std::string_view provider) {
118
0
   m_op = key.create_decryption_op(rng, padding, provider);
119
0
   if(!m_op) {
120
0
      throw Invalid_Argument(fmt("Key type {} does not support decryption", key.algo_name()));
121
0
   }
122
0
}
123
124
0
PK_Decryptor_EME::~PK_Decryptor_EME() = default;
125
126
0
PK_Decryptor_EME::PK_Decryptor_EME(PK_Decryptor_EME&&) noexcept = default;
127
0
PK_Decryptor_EME& PK_Decryptor_EME::operator=(PK_Decryptor_EME&&) noexcept = default;
128
129
0
size_t PK_Decryptor_EME::plaintext_length(size_t ctext_len) const {
130
0
   return m_op->plaintext_length(ctext_len);
131
0
}
132
133
0
secure_vector<uint8_t> PK_Decryptor_EME::do_decrypt(uint8_t& valid_mask, const uint8_t in[], size_t in_len) const {
134
0
   return m_op->decrypt(valid_mask, {in, in_len});
135
0
}
136
137
0
PK_KEM_Encryptor::PK_KEM_Encryptor(const Public_Key& key, std::string_view param, std::string_view provider) {
138
0
   m_op = key.create_kem_encryption_op(param, provider);
139
0
   if(!m_op) {
140
0
      throw Invalid_Argument(fmt("Key type {} does not support KEM encryption", key.algo_name()));
141
0
   }
142
0
}
143
144
0
PK_KEM_Encryptor::~PK_KEM_Encryptor() = default;
145
146
0
PK_KEM_Encryptor::PK_KEM_Encryptor(PK_KEM_Encryptor&&) noexcept = default;
147
0
PK_KEM_Encryptor& PK_KEM_Encryptor::operator=(PK_KEM_Encryptor&&) noexcept = default;
148
149
0
size_t PK_KEM_Encryptor::shared_key_length(size_t desired_shared_key_len) const {
150
0
   return m_op->shared_key_length(desired_shared_key_len);
151
0
}
152
153
0
size_t PK_KEM_Encryptor::encapsulated_key_length() const {
154
0
   return m_op->encapsulated_key_length();
155
0
}
156
157
void PK_KEM_Encryptor::encrypt(std::span<uint8_t> out_encapsulated_key,
158
                               std::span<uint8_t> out_shared_key,
159
                               RandomNumberGenerator& rng,
160
                               size_t desired_shared_key_len,
161
0
                               std::span<const uint8_t> salt) {
162
0
   BOTAN_ARG_CHECK(out_encapsulated_key.size() == encapsulated_key_length(), "not enough space for encapsulated key");
163
0
   BOTAN_ARG_CHECK(out_shared_key.size() == shared_key_length(desired_shared_key_len),
164
0
                   "not enough space for shared key");
165
0
   m_op->kem_encrypt(out_encapsulated_key, out_shared_key, rng, desired_shared_key_len, salt);
166
0
}
167
168
0
size_t PK_KEM_Decryptor::shared_key_length(size_t desired_shared_key_len) const {
169
0
   return m_op->shared_key_length(desired_shared_key_len);
170
0
}
171
172
0
size_t PK_KEM_Decryptor::encapsulated_key_length() const {
173
0
   return m_op->encapsulated_key_length();
174
0
}
175
176
PK_KEM_Decryptor::PK_KEM_Decryptor(const Private_Key& key,
177
                                   RandomNumberGenerator& rng,
178
                                   std::string_view param,
179
0
                                   std::string_view provider) {
180
0
   m_op = key.create_kem_decryption_op(rng, param, provider);
181
0
   if(!m_op) {
182
0
      throw Invalid_Argument(fmt("Key type {} does not support KEM decryption", key.algo_name()));
183
0
   }
184
0
}
185
186
0
PK_KEM_Decryptor::~PK_KEM_Decryptor() = default;
187
188
0
PK_KEM_Decryptor::PK_KEM_Decryptor(PK_KEM_Decryptor&&) noexcept = default;
189
0
PK_KEM_Decryptor& PK_KEM_Decryptor::operator=(PK_KEM_Decryptor&&) noexcept = default;
190
191
void PK_KEM_Decryptor::decrypt(std::span<uint8_t> out_shared_key,
192
                               std::span<const uint8_t> encap_key,
193
                               size_t desired_shared_key_len,
194
0
                               std::span<const uint8_t> salt) {
195
0
   BOTAN_ARG_CHECK(out_shared_key.size() == shared_key_length(desired_shared_key_len),
196
0
                   "inconsistent size of shared key output buffer");
197
0
   m_op->kem_decrypt(out_shared_key, encap_key, desired_shared_key_len, salt);
198
0
}
199
200
PK_Key_Agreement::PK_Key_Agreement(const Private_Key& key,
201
                                   RandomNumberGenerator& rng,
202
                                   std::string_view kdf,
203
0
                                   std::string_view provider) {
204
0
   m_op = key.create_key_agreement_op(rng, kdf, provider);
205
0
   if(!m_op) {
206
0
      throw Invalid_Argument(fmt("Key type {} does not support key agreement", key.algo_name()));
207
0
   }
208
0
}
209
210
0
PK_Key_Agreement::~PK_Key_Agreement() = default;
211
212
0
PK_Key_Agreement::PK_Key_Agreement(PK_Key_Agreement&&) noexcept = default;
213
0
PK_Key_Agreement& PK_Key_Agreement::operator=(PK_Key_Agreement&&) noexcept = default;
214
215
0
size_t PK_Key_Agreement::agreed_value_size() const {
216
0
   return m_op->agreed_value_size();
217
0
}
218
219
SymmetricKey PK_Key_Agreement::derive_key(size_t key_len,
220
                                          const uint8_t in[],
221
                                          size_t in_len,
222
0
                                          std::string_view params) const {
223
0
   return this->derive_key(key_len, in, in_len, cast_char_ptr_to_uint8(params.data()), params.length());
224
0
}
225
226
SymmetricKey PK_Key_Agreement::derive_key(size_t key_len,
227
                                          const std::span<const uint8_t> in,
228
0
                                          std::string_view params) const {
229
0
   return this->derive_key(key_len, in.data(), in.size(), cast_char_ptr_to_uint8(params.data()), params.length());
230
0
}
231
232
SymmetricKey PK_Key_Agreement::derive_key(
233
0
   size_t key_len, const uint8_t in[], size_t in_len, const uint8_t salt[], size_t salt_len) const {
234
0
   return SymmetricKey(m_op->agree(key_len, {in, in_len}, {salt, salt_len}));
235
0
}
236
237
namespace {
238
239
1.18k
void check_der_format_supported(Signature_Format format, size_t parts) {
240
1.18k
   if(format != Signature_Format::Standard && parts == 1) {
241
0
      throw Invalid_Argument("This algorithm does not support DER encoding");
242
0
   }
243
1.18k
}
244
245
}  // namespace
246
247
PK_Signer::PK_Signer(const Private_Key& key,
248
                     RandomNumberGenerator& rng,
249
                     std::string_view emsa,
250
                     Signature_Format format,
251
417
                     std::string_view provider) {
252
417
   m_op = key.create_signature_op(rng, emsa, provider);
253
417
   if(!m_op) {
254
0
      throw Invalid_Argument(fmt("Key type {} does not support signature generation", key.algo_name()));
255
0
   }
256
417
   m_sig_format = format;
257
417
   m_parts = key.message_parts();
258
417
   m_part_size = key.message_part_size();
259
417
   check_der_format_supported(format, m_parts);
260
417
}
261
262
0
AlgorithmIdentifier PK_Signer::algorithm_identifier() const {
263
0
   return m_op->algorithm_identifier();
264
0
}
265
266
0
std::string PK_Signer::hash_function() const {
267
0
   return m_op->hash_function();
268
0
}
269
270
407
PK_Signer::~PK_Signer() = default;
271
272
0
PK_Signer::PK_Signer(PK_Signer&&) noexcept = default;
273
0
PK_Signer& PK_Signer::operator=(PK_Signer&&) noexcept = default;
274
275
0
void PK_Signer::update(std::string_view in) {
276
0
   this->update(cast_char_ptr_to_uint8(in.data()), in.size());
277
0
}
278
279
407
void PK_Signer::update(const uint8_t in[], size_t length) {
280
407
   m_op->update({in, length});
281
407
}
282
283
namespace {
284
285
251
std::vector<uint8_t> der_encode_signature(std::span<const uint8_t> sig, size_t parts, size_t part_size) {
286
251
   if(sig.size() % parts != 0 || sig.size() != parts * part_size) {
287
0
      throw Encoding_Error("Unexpected size for DER signature");
288
0
   }
289
290
251
   BufferSlicer bs_sig(sig);
291
251
   std::vector<BigInt> sig_parts;
292
251
   sig_parts.reserve(parts);
293
753
   for(size_t i = 0; i != parts; ++i) {
294
502
      sig_parts.emplace_back(BigInt::from_bytes(bs_sig.take(part_size)));
295
502
   }
296
297
251
   std::vector<uint8_t> output;
298
251
   DER_Encoder(output).start_sequence().encode_list(sig_parts).end_cons();
299
251
   return output;
300
251
}
301
302
}  // namespace
303
304
0
size_t PK_Signer::signature_length() const {
305
0
   if(m_sig_format == Signature_Format::Standard) {
306
0
      return m_op->signature_length();
307
0
   } else if(m_sig_format == Signature_Format::DerSequence) {
308
      // This is a large over-estimate but its easier than computing
309
      // the exact value
310
0
      return m_op->signature_length() + (8 + 4 * m_parts);
311
0
   } else {
312
0
      throw Internal_Error("PK_Signer: Invalid signature format enum");
313
0
   }
314
0
}
315
316
407
std::vector<uint8_t> PK_Signer::signature(RandomNumberGenerator& rng) {
317
407
   std::vector<uint8_t> sig = m_op->sign(rng);
318
319
407
   if(m_sig_format == Signature_Format::Standard) {
320
50
      return sig;
321
357
   } else if(m_sig_format == Signature_Format::DerSequence) {
322
251
      return der_encode_signature(sig, m_parts, m_part_size);
323
251
   } else {
324
106
      throw Internal_Error("PK_Signer: Invalid signature format enum");
325
106
   }
326
407
}
327
328
PK_Verifier::PK_Verifier(const Public_Key& key,
329
                         std::string_view emsa,
330
                         Signature_Format format,
331
775
                         std::string_view provider) {
332
775
   m_op = key.create_verification_op(emsa, provider);
333
775
   if(!m_op) {
334
0
      throw Invalid_Argument(fmt("Key type {} does not support signature verification", key.algo_name()));
335
0
   }
336
775
   m_sig_format = format;
337
775
   m_parts = key.message_parts();
338
775
   m_part_size = key.message_part_size();
339
775
   check_der_format_supported(format, m_parts);
340
775
}
341
342
PK_Verifier::PK_Verifier(const Public_Key& key,
343
                         const AlgorithmIdentifier& signature_algorithm,
344
0
                         std::string_view provider) {
345
0
   m_op = key.create_x509_verification_op(signature_algorithm, provider);
346
347
0
   if(!m_op) {
348
0
      throw Invalid_Argument(fmt("Key type {} does not support X.509 signature verification", key.algo_name()));
349
0
   }
350
351
0
   m_sig_format = key.default_x509_signature_format();
352
0
   m_parts = key.message_parts();
353
0
   m_part_size = key.message_part_size();
354
0
   check_der_format_supported(m_sig_format, m_parts);
355
0
}
356
357
775
PK_Verifier::~PK_Verifier() = default;
358
359
0
PK_Verifier::PK_Verifier(PK_Verifier&&) noexcept = default;
360
0
PK_Verifier& PK_Verifier::operator=(PK_Verifier&&) noexcept = default;
361
362
0
std::string PK_Verifier::hash_function() const {
363
0
   return m_op->hash_function();
364
0
}
365
366
0
void PK_Verifier::set_input_format(Signature_Format format) {
367
0
   check_der_format_supported(format, m_parts);
368
0
   m_sig_format = format;
369
0
}
370
371
775
bool PK_Verifier::verify_message(const uint8_t msg[], size_t msg_length, const uint8_t sig[], size_t sig_length) {
372
775
   update(msg, msg_length);
373
775
   return check_signature(sig, sig_length);
374
775
}
375
376
0
void PK_Verifier::update(std::string_view in) {
377
0
   this->update(cast_char_ptr_to_uint8(in.data()), in.size());
378
0
}
379
380
775
void PK_Verifier::update(const uint8_t in[], size_t length) {
381
775
   m_op->update({in, length});
382
775
}
383
384
namespace {
385
386
0
std::vector<uint8_t> decode_der_signature(const uint8_t sig[], size_t length, size_t sig_parts, size_t sig_part_size) {
387
0
   std::vector<uint8_t> real_sig;
388
0
   BER_Decoder decoder(sig, length);
389
0
   BER_Decoder ber_sig = decoder.start_sequence();
390
391
0
   BOTAN_ASSERT_NOMSG(sig_parts != 0 && sig_part_size != 0);
392
393
0
   size_t count = 0;
394
395
0
   while(ber_sig.more_items()) {
396
0
      BigInt sig_part;
397
0
      ber_sig.decode(sig_part);
398
0
      real_sig += sig_part.serialize(sig_part_size);
399
0
      ++count;
400
0
   }
401
402
0
   if(count != sig_parts) {
403
0
      throw Decoding_Error("PK_Verifier: signature size invalid");
404
0
   }
405
406
0
   const std::vector<uint8_t> reencoded = der_encode_signature(real_sig, sig_parts, sig_part_size);
407
408
0
   if(reencoded.size() != length || CT::is_equal(reencoded.data(), sig, reencoded.size()).as_bool() == false) {
409
0
      throw Decoding_Error("PK_Verifier: signature is not the canonical DER encoding");
410
0
   }
411
0
   return real_sig;
412
0
}
413
414
}  // namespace
415
416
775
bool PK_Verifier::check_signature(const uint8_t sig[], size_t length) {
417
775
   try {
418
775
      if(m_sig_format == Signature_Format::Standard) {
419
775
         return m_op->is_valid_signature({sig, length});
420
775
      } else if(m_sig_format == Signature_Format::DerSequence) {
421
0
         bool decoding_success = false;
422
0
         std::vector<uint8_t> real_sig;
423
424
0
         try {
425
0
            real_sig = decode_der_signature(sig, length, m_parts, m_part_size);
426
0
            decoding_success = true;
427
0
         } catch(Decoding_Error&) {}
428
429
0
         bool accept = m_op->is_valid_signature(real_sig);
430
431
0
         return accept && decoding_success;
432
0
      } else {
433
0
         throw Internal_Error("PK_Verifier: Invalid signature format enum");
434
0
      }
435
775
   } catch(Invalid_Argument&) {
436
0
      return false;
437
0
   } catch(Decoding_Error&) {
438
0
      return false;
439
0
   } catch(Encoding_Error&) {
440
0
      return false;
441
0
   }
442
775
}
443
444
}  // namespace Botan