• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

randombit / botan / 12939727421

23 Jan 2025 11:05PM UTC coverage: 91.212% (+0.01%) from 91.202%
12939727421

push

github

web-flow
Merge pull request #4582 from randombit/jack/fake-pms-match-expected

In PK_Decryptor::decrypt_or_random return a fake PMS matching expected content bytes

93618 of 102638 relevant lines covered (91.21%)

11596786.31 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

86.36
/src/lib/pubkey/pubkey.cpp
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/pss_params.h>
15
#include <botan/rng.h>
16
#include <botan/internal/ct_utils.h>
17
#include <botan/internal/fmt.h>
18
#include <botan/internal/parsing.h>
19
#include <botan/internal/stl_util.h>
20

21
namespace Botan {
22

23
secure_vector<uint8_t> PK_Decryptor::decrypt(const uint8_t in[], size_t length) const {
6,911✔
24
   uint8_t valid_mask = 0;
6,911✔
25

26
   secure_vector<uint8_t> decoded = do_decrypt(valid_mask, in, length);
6,911✔
27

28
   if(valid_mask == 0) {
6,883✔
29
      throw Decoding_Error("Invalid public key ciphertext, cannot decrypt");
3,193✔
30
   }
31

32
   return decoded;
3,690✔
33
}
3,193✔
34

35
secure_vector<uint8_t> PK_Decryptor::decrypt_or_random(const uint8_t in[],
587✔
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
                                                       size_t required_contents_length) const {
42
   const secure_vector<uint8_t> fake_pms = [&]() {
1,761✔
43
      auto pms = rng.random_vec(expected_pt_len);
587✔
44

45
      for(size_t i = 0; i != required_contents_length; ++i) {
2,687✔
46
         const uint8_t exp = required_content_bytes[i];
2,100✔
47

48
         /*
49
         If an offset repeats we don't detect this and just return a PMS that satisfies
50
         the last requested index. If the requested (idx,value) tuple is the same, that's
51
         fine and just redundant. If they disagree, decryption will always fail, since the
52
         same byte cannot possibly have two distinct values.
53
         */
54
         const uint8_t off = required_content_offsets[i];
2,100✔
55
         BOTAN_ASSERT(off < expected_pt_len, "Offset in range of plaintext");
2,100✔
56
         pms[off] = exp;
2,100✔
57
      }
58

59
      return pms;
587✔
60
   }();
587✔
61

62
   uint8_t decrypt_valid = 0;
587✔
63
   secure_vector<uint8_t> decoded = do_decrypt(decrypt_valid, in, length);
587✔
64

65
   auto valid_mask = CT::Mask<uint8_t>::is_equal(decrypt_valid, 0xFF);
587✔
66
   valid_mask &= CT::Mask<uint8_t>(CT::Mask<size_t>::is_equal(decoded.size(), expected_pt_len));
587✔
67

68
   decoded.resize(expected_pt_len);
587✔
69

70
   for(size_t i = 0; i != required_contents_length; ++i) {
2,687✔
71
      const uint8_t exp = required_content_bytes[i];
2,100✔
72

73
      // We know off is in range because we already checked it when creating the fake premaster above
74
      const uint8_t off = required_content_offsets[i];
2,100✔
75

76
      auto eq = CT::Mask<uint8_t>::is_equal(decoded[off], exp);
2,100✔
77

78
      valid_mask &= eq;
2,100✔
79
   }
80

81
   // If valid_mask is false, assign fake pre master instead
82
   valid_mask.select_n(decoded.data(), decoded.data(), fake_pms.data(), expected_pt_len);
587✔
83

84
   return decoded;
587✔
85
}
587✔
86

87
secure_vector<uint8_t> PK_Decryptor::decrypt_or_random(const uint8_t in[],
405✔
88
                                                       size_t length,
89
                                                       size_t expected_pt_len,
90
                                                       RandomNumberGenerator& rng) const {
91
   return decrypt_or_random(in, length, expected_pt_len, rng, nullptr, nullptr, 0);
405✔
92
}
93

94
PK_Encryptor_EME::PK_Encryptor_EME(const Public_Key& key,
884✔
95
                                   RandomNumberGenerator& rng,
96
                                   std::string_view padding,
97
                                   std::string_view provider) {
884✔
98
   m_op = key.create_encryption_op(rng, padding, provider);
884✔
99
   if(!m_op) {
287✔
100
      throw Invalid_Argument(fmt("Key type {} does not support encryption", key.algo_name()));
×
101
   }
102
}
884✔
103

104
PK_Encryptor_EME::~PK_Encryptor_EME() = default;
491✔
105

106
PK_Encryptor_EME::PK_Encryptor_EME(PK_Encryptor_EME&&) noexcept = default;
×
107
PK_Encryptor_EME& PK_Encryptor_EME::operator=(PK_Encryptor_EME&&) noexcept = default;
×
108

109
size_t PK_Encryptor_EME::ciphertext_length(size_t ptext_len) const {
204✔
110
   return m_op->ciphertext_length(ptext_len);
204✔
111
}
112

113
std::vector<uint8_t> PK_Encryptor_EME::enc(const uint8_t in[], size_t length, RandomNumberGenerator& rng) const {
355✔
114
   return m_op->encrypt(std::span{in, length}, rng);
355✔
115
}
116

117
size_t PK_Encryptor_EME::maximum_input_size() const {
209✔
118
   return m_op->max_input_bits() / 8;
209✔
119
}
120

121
PK_Decryptor_EME::PK_Decryptor_EME(const Private_Key& key,
1,052✔
122
                                   RandomNumberGenerator& rng,
123
                                   std::string_view padding,
124
                                   std::string_view provider) {
1,052✔
125
   m_op = key.create_decryption_op(rng, padding, provider);
1,052✔
126
   if(!m_op) {
329✔
127
      throw Invalid_Argument(fmt("Key type {} does not support decryption", key.algo_name()));
×
128
   }
129
}
1,052✔
130

131
PK_Decryptor_EME::~PK_Decryptor_EME() = default;
575✔
132

133
PK_Decryptor_EME::PK_Decryptor_EME(PK_Decryptor_EME&&) noexcept = default;
×
134
PK_Decryptor_EME& PK_Decryptor_EME::operator=(PK_Decryptor_EME&&) noexcept = default;
×
135

136
size_t PK_Decryptor_EME::plaintext_length(size_t ctext_len) const {
203✔
137
   return m_op->plaintext_length(ctext_len);
203✔
138
}
139

140
secure_vector<uint8_t> PK_Decryptor_EME::do_decrypt(uint8_t& valid_mask, const uint8_t in[], size_t in_len) const {
5,775✔
141
   return m_op->decrypt(valid_mask, {in, in_len});
5,775✔
142
}
143

144
PK_KEM_Encryptor::PK_KEM_Encryptor(const Public_Key& key, std::string_view param, std::string_view provider) {
862✔
145
   m_op = key.create_kem_encryption_op(param, provider);
862✔
146
   if(!m_op) {
862✔
147
      throw Invalid_Argument(fmt("Key type {} does not support KEM encryption", key.algo_name()));
×
148
   }
149
}
862✔
150

151
PK_KEM_Encryptor::~PK_KEM_Encryptor() = default;
862✔
152

153
PK_KEM_Encryptor::PK_KEM_Encryptor(PK_KEM_Encryptor&&) noexcept = default;
×
154
PK_KEM_Encryptor& PK_KEM_Encryptor::operator=(PK_KEM_Encryptor&&) noexcept = default;
×
155

156
size_t PK_KEM_Encryptor::shared_key_length(size_t desired_shared_key_len) const {
6,870✔
157
   return m_op->shared_key_length(desired_shared_key_len);
6,870✔
158
}
159

160
size_t PK_KEM_Encryptor::encapsulated_key_length() const {
6,870✔
161
   return m_op->encapsulated_key_length();
6,870✔
162
}
163

164
void PK_KEM_Encryptor::encrypt(std::span<uint8_t> out_encapsulated_key,
3,381✔
165
                               std::span<uint8_t> out_shared_key,
166
                               RandomNumberGenerator& rng,
167
                               size_t desired_shared_key_len,
168
                               std::span<const uint8_t> salt) {
169
   BOTAN_ARG_CHECK(out_encapsulated_key.size() == encapsulated_key_length(), "not enough space for encapsulated key");
3,381✔
170
   BOTAN_ARG_CHECK(out_shared_key.size() == shared_key_length(desired_shared_key_len),
3,381✔
171
                   "not enough space for shared key");
172
   m_op->kem_encrypt(out_encapsulated_key, out_shared_key, rng, desired_shared_key_len, salt);
3,381✔
173
}
3,378✔
174

175
size_t PK_KEM_Decryptor::shared_key_length(size_t desired_shared_key_len) const {
7,016✔
176
   return m_op->shared_key_length(desired_shared_key_len);
7,016✔
177
}
178

179
size_t PK_KEM_Decryptor::encapsulated_key_length() const {
132✔
180
   return m_op->encapsulated_key_length();
132✔
181
}
182

183
PK_KEM_Decryptor::PK_KEM_Decryptor(const Private_Key& key,
804✔
184
                                   RandomNumberGenerator& rng,
185
                                   std::string_view param,
186
                                   std::string_view provider) {
804✔
187
   m_op = key.create_kem_decryption_op(rng, param, provider);
804✔
188
   if(!m_op) {
804✔
189
      throw Invalid_Argument(fmt("Key type {} does not support KEM decryption", key.algo_name()));
×
190
   }
191
}
804✔
192

193
PK_KEM_Decryptor::~PK_KEM_Decryptor() = default;
804✔
194

195
PK_KEM_Decryptor::PK_KEM_Decryptor(PK_KEM_Decryptor&&) noexcept = default;
×
196
PK_KEM_Decryptor& PK_KEM_Decryptor::operator=(PK_KEM_Decryptor&&) noexcept = default;
×
197

198
void PK_KEM_Decryptor::decrypt(std::span<uint8_t> out_shared_key,
3,452✔
199
                               std::span<const uint8_t> encap_key,
200
                               size_t desired_shared_key_len,
201
                               std::span<const uint8_t> salt) {
202
   BOTAN_ARG_CHECK(out_shared_key.size() == shared_key_length(desired_shared_key_len),
3,452✔
203
                   "inconsistent size of shared key output buffer");
204
   m_op->kem_decrypt(out_shared_key, encap_key, desired_shared_key_len, salt);
3,452✔
205
}
3,429✔
206

207
PK_Key_Agreement::PK_Key_Agreement(const Private_Key& key,
11,185✔
208
                                   RandomNumberGenerator& rng,
209
                                   std::string_view kdf,
210
                                   std::string_view provider) {
11,185✔
211
   m_op = key.create_key_agreement_op(rng, kdf, provider);
11,185✔
212
   if(!m_op) {
8,833✔
213
      throw Invalid_Argument(fmt("Key type {} does not support key agreement", key.algo_name()));
×
214
   }
215
}
11,185✔
216

217
PK_Key_Agreement::~PK_Key_Agreement() = default;
8,833✔
218

219
PK_Key_Agreement::PK_Key_Agreement(PK_Key_Agreement&&) noexcept = default;
×
220
PK_Key_Agreement& PK_Key_Agreement::operator=(PK_Key_Agreement&&) noexcept = default;
×
221

222
size_t PK_Key_Agreement::agreed_value_size() const {
872✔
223
   return m_op->agreed_value_size();
872✔
224
}
225

226
SymmetricKey PK_Key_Agreement::derive_key(size_t key_len,
185✔
227
                                          const uint8_t in[],
228
                                          size_t in_len,
229
                                          std::string_view params) const {
230
   return this->derive_key(key_len, in, in_len, cast_char_ptr_to_uint8(params.data()), params.length());
185✔
231
}
232

233
SymmetricKey PK_Key_Agreement::derive_key(size_t key_len,
10,214✔
234
                                          const std::span<const uint8_t> in,
235
                                          std::string_view params) const {
236
   return this->derive_key(key_len, in.data(), in.size(), cast_char_ptr_to_uint8(params.data()), params.length());
10,214✔
237
}
238

239
SymmetricKey PK_Key_Agreement::derive_key(
10,415✔
240
   size_t key_len, const uint8_t in[], size_t in_len, const uint8_t salt[], size_t salt_len) const {
241
   return SymmetricKey(m_op->agree(key_len, {in, in_len}, {salt, salt_len}));
10,415✔
242
}
243

244
namespace {
245

246
void check_der_format_supported(Signature_Format format, size_t parts) {
34,736✔
247
   if(format != Signature_Format::Standard && parts == 1) {
34,736✔
248
      throw Invalid_Argument("This algorithm does not support DER encoding");
×
249
   }
250
}
34,736✔
251

252
}  // namespace
253

254
PK_Signer::PK_Signer(const Private_Key& key,
8,313✔
255
                     RandomNumberGenerator& rng,
256
                     std::string_view emsa,
257
                     Signature_Format format,
258
                     std::string_view provider) {
8,313✔
259
   m_op = key.create_signature_op(rng, emsa, provider);
8,313✔
260
   if(!m_op) {
4,564✔
261
      throw Invalid_Argument(fmt("Key type {} does not support signature generation", key.algo_name()));
×
262
   }
263
   m_sig_format = format;
4,564✔
264
   m_parts = key.message_parts();
4,564✔
265
   m_part_size = key.message_part_size();
4,564✔
266
   check_der_format_supported(format, m_parts);
4,564✔
267
}
8,313✔
268

269
AlgorithmIdentifier PK_Signer::algorithm_identifier() const {
505✔
270
   return m_op->algorithm_identifier();
505✔
271
}
272

273
std::string PK_Signer::hash_function() const {
806✔
274
   return m_op->hash_function();
806✔
275
}
276

277
PK_Signer::~PK_Signer() = default;
4,564✔
278

279
PK_Signer::PK_Signer(PK_Signer&&) noexcept = default;
×
280
PK_Signer& PK_Signer::operator=(PK_Signer&&) noexcept = default;
×
281

282
void PK_Signer::update(std::string_view in) {
1✔
283
   this->update(cast_char_ptr_to_uint8(in.data()), in.size());
1✔
284
}
1✔
285

286
void PK_Signer::update(const uint8_t in[], size_t length) {
7,667✔
287
   m_op->update({in, length});
7,667✔
288
}
7,666✔
289

290
namespace {
291

292
std::vector<uint8_t> der_encode_signature(std::span<const uint8_t> sig, size_t parts, size_t part_size) {
8,948✔
293
   if(sig.size() % parts != 0 || sig.size() != parts * part_size) {
8,948✔
294
      throw Encoding_Error("Unexpected size for DER signature");
×
295
   }
296

297
   BufferSlicer bs_sig(sig);
8,948✔
298
   std::vector<BigInt> sig_parts;
8,948✔
299
   sig_parts.reserve(parts);
8,948✔
300
   for(size_t i = 0; i != parts; ++i) {
26,844✔
301
      sig_parts.emplace_back(BigInt::from_bytes(bs_sig.take(part_size)));
35,792✔
302
   }
303

304
   std::vector<uint8_t> output;
8,948✔
305
   DER_Encoder(output).start_sequence().encode_list(sig_parts).end_cons();
35,792✔
306
   return output;
8,948✔
307
}
8,948✔
308

309
}  // namespace
310

311
size_t PK_Signer::signature_length() const {
1,278✔
312
   if(m_sig_format == Signature_Format::Standard) {
1,278✔
313
      return m_op->signature_length();
1,275✔
314
   } else if(m_sig_format == Signature_Format::DerSequence) {
3✔
315
      // This is a large over-estimate but its easier than computing
316
      // the exact value
317
      return m_op->signature_length() + (8 + 4 * m_parts);
3✔
318
   } else {
319
      throw Internal_Error("PK_Signer: Invalid signature format enum");
×
320
   }
321
}
322

323
std::vector<uint8_t> PK_Signer::signature(RandomNumberGenerator& rng) {
7,635✔
324
   std::vector<uint8_t> sig = m_op->sign(rng);
7,635✔
325

326
   if(m_sig_format == Signature_Format::Standard) {
7,631✔
327
      return sig;
7,229✔
328
   } else if(m_sig_format == Signature_Format::DerSequence) {
402✔
329
      return der_encode_signature(sig, m_parts, m_part_size);
402✔
330
   } else {
331
      throw Internal_Error("PK_Signer: Invalid signature format enum");
×
332
   }
333
}
7,631✔
334

335
PK_Verifier::PK_Verifier(const Public_Key& key,
63,408✔
336
                         std::string_view emsa,
337
                         Signature_Format format,
338
                         std::string_view provider) {
63,408✔
339
   m_op = key.create_verification_op(emsa, provider);
63,408✔
340
   if(!m_op) {
14,065✔
341
      throw Invalid_Argument(fmt("Key type {} does not support signature verification", key.algo_name()));
×
342
   }
343
   m_sig_format = format;
14,065✔
344
   m_parts = key.message_parts();
14,065✔
345
   m_part_size = key.message_part_size();
14,065✔
346
   check_der_format_supported(format, m_parts);
14,065✔
347
}
63,408✔
348

349
PK_Verifier::PK_Verifier(const Public_Key& key,
16,152✔
350
                         const AlgorithmIdentifier& signature_algorithm,
351
                         std::string_view provider) {
16,152✔
352
   m_op = key.create_x509_verification_op(signature_algorithm, provider);
16,152✔
353

354
   if(!m_op) {
16,107✔
355
      throw Invalid_Argument(fmt("Key type {} does not support X.509 signature verification", key.algo_name()));
×
356
   }
357

358
   m_sig_format = key.default_x509_signature_format();
16,107✔
359
   m_parts = key.message_parts();
16,107✔
360
   m_part_size = key.message_part_size();
16,107✔
361
   check_der_format_supported(m_sig_format, m_parts);
16,107✔
362
}
16,152✔
363

364
PK_Verifier::~PK_Verifier() = default;
30,172✔
365

366
PK_Verifier::PK_Verifier(PK_Verifier&&) noexcept = default;
×
367
PK_Verifier& PK_Verifier::operator=(PK_Verifier&&) noexcept = default;
×
368

369
std::string PK_Verifier::hash_function() const {
15,755✔
370
   return m_op->hash_function();
15,755✔
371
}
372

373
void PK_Verifier::set_input_format(Signature_Format format) {
×
374
   check_der_format_supported(format, m_parts);
×
375
   m_sig_format = format;
×
376
}
×
377

378
bool PK_Verifier::verify_message(const uint8_t msg[], size_t msg_length, const uint8_t sig[], size_t sig_length) {
86,217✔
379
   update(msg, msg_length);
86,217✔
380
   return check_signature(sig, sig_length);
86,217✔
381
}
382

383
void PK_Verifier::update(std::string_view in) {
1✔
384
   this->update(cast_char_ptr_to_uint8(in.data()), in.size());
1✔
385
}
1✔
386

387
void PK_Verifier::update(const uint8_t in[], size_t length) {
90,952✔
388
   m_op->update({in, length});
90,952✔
389
}
90,952✔
390

391
namespace {
392

393
std::vector<uint8_t> decode_der_signature(const uint8_t sig[], size_t length, size_t sig_parts, size_t sig_part_size) {
10,794✔
394
   std::vector<uint8_t> real_sig;
10,794✔
395
   BER_Decoder decoder(sig, length);
10,794✔
396
   BER_Decoder ber_sig = decoder.start_sequence();
10,794✔
397

398
   BOTAN_ASSERT_NOMSG(sig_parts != 0 && sig_part_size != 0);
10,465✔
399

400
   size_t count = 0;
401

402
   while(ber_sig.more_items()) {
28,952✔
403
      BigInt sig_part;
20,304✔
404
      ber_sig.decode(sig_part);
20,304✔
405
      real_sig += sig_part.serialize(sig_part_size);
20,304✔
406
      ++count;
18,487✔
407
   }
20,304✔
408

409
   if(count != sig_parts) {
8,648✔
410
      throw Decoding_Error("PK_Verifier: signature size invalid");
102✔
411
   }
412

413
   const std::vector<uint8_t> reencoded = der_encode_signature(real_sig, sig_parts, sig_part_size);
8,546✔
414

415
   if(reencoded.size() != length || CT::is_equal(reencoded.data(), sig, reencoded.size()).as_bool() == false) {
16,790✔
416
      throw Decoding_Error("PK_Verifier: signature is not the canonical DER encoding");
703✔
417
   }
418
   return real_sig;
15,686✔
419
}
13,416✔
420

421
}  // namespace
422

423
bool PK_Verifier::check_signature(const uint8_t sig[], size_t length) {
92,238✔
424
   try {
92,238✔
425
      if(m_sig_format == Signature_Format::Standard) {
92,238✔
426
         return m_op->is_valid_signature({sig, length});
81,444✔
427
      } else if(m_sig_format == Signature_Format::DerSequence) {
10,794✔
428
         bool decoding_success = false;
10,794✔
429
         std::vector<uint8_t> real_sig;
10,794✔
430

431
         try {
10,794✔
432
            real_sig = decode_der_signature(sig, length, m_parts, m_part_size);
18,637✔
433
            decoding_success = true;
7,843✔
434
         } catch(Decoding_Error&) {}
2,951✔
435

436
         bool accept = m_op->is_valid_signature(real_sig);
10,794✔
437

438
         return accept && decoding_success;
10,571✔
439
      } else {
10,794✔
440
         throw Internal_Error("PK_Verifier: Invalid signature format enum");
×
441
      }
442
   } catch(Invalid_Argument&) {
340✔
443
      return false;
223✔
444
   } catch(Decoding_Error&) {
340✔
445
      return false;
117✔
446
   } catch(Encoding_Error&) {
117✔
447
      return false;
×
448
   }
×
449
}
450

451
}  // namespace Botan
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc