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

randombit / botan / 13394769715

18 Feb 2025 03:11PM UTC coverage: 91.645% (+0.008%) from 91.637%
13394769715

push

github

web-flow
Merge pull request #4698 from Rohde-Schwarz/fix/assertion_in_signature

FIX: setting 'DER' format explicitly on `PK_Signer` trips assertion

94996 of 103656 relevant lines covered (91.65%)

11192395.07 hits per line

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

86.0
/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,909✔
24
   uint8_t valid_mask = 0;
6,909✔
25

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

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

32
   return decoded;
3,692✔
33
}
3,187✔
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(const Public_Key& key,
×
152
                                   RandomNumberGenerator& rng,
153
                                   std::string_view kem_param,
154
                                   std::string_view provider) :
×
155
      PK_KEM_Encryptor(key, kem_param, provider) {
×
156
   BOTAN_UNUSED(rng);
×
157
}
×
158

159
PK_KEM_Encryptor::~PK_KEM_Encryptor() = default;
862✔
160

161
PK_KEM_Encryptor::PK_KEM_Encryptor(PK_KEM_Encryptor&&) noexcept = default;
×
162
PK_KEM_Encryptor& PK_KEM_Encryptor::operator=(PK_KEM_Encryptor&&) noexcept = default;
×
163

164
size_t PK_KEM_Encryptor::shared_key_length(size_t desired_shared_key_len) const {
7,002✔
165
   return m_op->shared_key_length(desired_shared_key_len);
7,002✔
166
}
167

168
size_t PK_KEM_Encryptor::encapsulated_key_length() const {
6,907✔
169
   return m_op->encapsulated_key_length();
6,907✔
170
}
171

172
void PK_KEM_Encryptor::encrypt(std::span<uint8_t> out_encapsulated_key,
3,379✔
173
                               std::span<uint8_t> out_shared_key,
174
                               RandomNumberGenerator& rng,
175
                               size_t desired_shared_key_len,
176
                               std::span<const uint8_t> salt) {
177
   BOTAN_ARG_CHECK(out_encapsulated_key.size() == encapsulated_key_length(), "not enough space for encapsulated key");
3,379✔
178
   BOTAN_ARG_CHECK(out_shared_key.size() == shared_key_length(desired_shared_key_len),
3,379✔
179
                   "not enough space for shared key");
180
   m_op->kem_encrypt(out_encapsulated_key, out_shared_key, rng, desired_shared_key_len, salt);
3,379✔
181
}
3,376✔
182

183
size_t PK_KEM_Decryptor::shared_key_length(size_t desired_shared_key_len) const {
7,156✔
184
   return m_op->shared_key_length(desired_shared_key_len);
7,156✔
185
}
186

187
size_t PK_KEM_Decryptor::encapsulated_key_length() const {
132✔
188
   return m_op->encapsulated_key_length();
132✔
189
}
190

191
PK_KEM_Decryptor::PK_KEM_Decryptor(const Private_Key& key,
804✔
192
                                   RandomNumberGenerator& rng,
193
                                   std::string_view param,
194
                                   std::string_view provider) {
804✔
195
   m_op = key.create_kem_decryption_op(rng, param, provider);
804✔
196
   if(!m_op) {
804✔
197
      throw Invalid_Argument(fmt("Key type {} does not support KEM decryption", key.algo_name()));
×
198
   }
199
}
804✔
200

201
PK_KEM_Decryptor::~PK_KEM_Decryptor() = default;
804✔
202

203
PK_KEM_Decryptor::PK_KEM_Decryptor(PK_KEM_Decryptor&&) noexcept = default;
×
204
PK_KEM_Decryptor& PK_KEM_Decryptor::operator=(PK_KEM_Decryptor&&) noexcept = default;
×
205

206
void PK_KEM_Decryptor::decrypt(std::span<uint8_t> out_shared_key,
3,450✔
207
                               std::span<const uint8_t> encap_key,
208
                               size_t desired_shared_key_len,
209
                               std::span<const uint8_t> salt) {
210
   BOTAN_ARG_CHECK(out_shared_key.size() == shared_key_length(desired_shared_key_len),
3,450✔
211
                   "inconsistent size of shared key output buffer");
212
   m_op->kem_decrypt(out_shared_key, encap_key, desired_shared_key_len, salt);
3,450✔
213
}
3,427✔
214

215
PK_Key_Agreement::PK_Key_Agreement(const Private_Key& key,
11,183✔
216
                                   RandomNumberGenerator& rng,
217
                                   std::string_view kdf,
218
                                   std::string_view provider) {
11,183✔
219
   m_op = key.create_key_agreement_op(rng, kdf, provider);
11,183✔
220
   if(!m_op) {
8,831✔
221
      throw Invalid_Argument(fmt("Key type {} does not support key agreement", key.algo_name()));
×
222
   }
223
}
11,183✔
224

225
PK_Key_Agreement::~PK_Key_Agreement() = default;
8,831✔
226

227
PK_Key_Agreement::PK_Key_Agreement(PK_Key_Agreement&&) noexcept = default;
×
228
PK_Key_Agreement& PK_Key_Agreement::operator=(PK_Key_Agreement&&) noexcept = default;
×
229

230
size_t PK_Key_Agreement::agreed_value_size() const {
946✔
231
   return m_op->agreed_value_size();
946✔
232
}
233

234
SymmetricKey PK_Key_Agreement::derive_key(size_t key_len,
182✔
235
                                          const uint8_t peer_key[],
236
                                          size_t peer_key_len,
237
                                          std::string_view salt) const {
238
   return this->derive_key(key_len, peer_key, peer_key_len, cast_char_ptr_to_uint8(salt.data()), salt.length());
182✔
239
}
240

241
SymmetricKey PK_Key_Agreement::derive_key(size_t key_len,
10,216✔
242
                                          const std::span<const uint8_t> peer_key,
243
                                          std::string_view salt) const {
244
   return this->derive_key(
10,216✔
245
      key_len, peer_key.data(), peer_key.size(), cast_char_ptr_to_uint8(salt.data()), salt.length());
10,216✔
246
}
247

248
SymmetricKey PK_Key_Agreement::derive_key(
10,414✔
249
   size_t key_len, const uint8_t peer_key[], size_t peer_key_len, const uint8_t salt[], size_t salt_len) const {
250
   return SymmetricKey(m_op->agree(key_len, {peer_key, peer_key_len}, {salt, salt_len}));
10,414✔
251
}
252

253
PK_Signer::PK_Signer(const Private_Key& key,
8,346✔
254
                     RandomNumberGenerator& rng,
255
                     std::string_view emsa,
256
                     Signature_Format format,
257
                     std::string_view provider) :
8,346✔
258
      m_sig_format(format), m_sig_element_size(key._signature_element_size_for_DER_encoding()) {
8,346✔
259
   if(m_sig_format == Signature_Format::DerSequence) {
8,346✔
260
      BOTAN_ARG_CHECK(m_sig_element_size.has_value(), "This key does not support DER signatures");
369✔
261
   }
262

263
   m_op = key.create_signature_op(rng, emsa, provider);
8,346✔
264
   if(!m_op) {
4,572✔
265
      throw Invalid_Argument(fmt("Key type {} does not support signature generation", key.algo_name()));
×
266
   }
267
}
8,346✔
268

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

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

277
PK_Signer::~PK_Signer() = default;
4,572✔
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,680✔
287
   m_op->update({in, length});
7,680✔
288
}
7,679✔
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,970✔
293
   if(sig.size() % parts != 0 || sig.size() != parts * part_size) {
8,970✔
294
      throw Encoding_Error("Unexpected size for DER signature");
×
295
   }
296

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

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

309
}  // namespace
310

311
size_t PK_Signer::signature_length() const {
1,286✔
312
   if(m_sig_format == Signature_Format::Standard) {
1,286✔
313
      return m_op->signature_length();
1,283✔
314
   } else if(m_sig_format == Signature_Format::DerSequence) {
3✔
315
      size_t sig_len = m_op->signature_length();
3✔
316

317
      size_t der_overhead = [sig_len]() {
9✔
318
         /*
319
         This was computed by DER encoding of some maximal value signatures
320
         (since DER is variable length)
321

322
         The first two cases covers all EC schemes since groups are at most 521
323
         bits.
324

325
         The other cases are only for finite field DSA which practically is only
326
         used up to 3072 bit groups but the calculation is correct up to a
327
         262096 (!) bit group so allow it. There are some intermediate sizes but
328
         this function is allowed to (and indeed must) return an over-estimate
329
         rather than an exact value since the actual length will change based on
330
         the computed signature.
331
         */
332

333
         if(sig_len <= 120) {
3✔
334
            // EC signatures <= 480 bits
335
            return 8;
336
         } else if(sig_len <= 248) {
×
337
            // EC signatures > 480 bits (or very small DSA groups...)
338
            return 9;
339
         } else {
340
            // Everything else. This is an over-estimate for groups under
341
            // 2040 bits but exact otherwise
342

343
            // This requires 15 bytes DER overhead and should never happen
344
            BOTAN_ASSERT_NOMSG(sig_len < 65524);
×
345
            return 14;
346
         }
347
      }();
3✔
348

349
      return sig_len + der_overhead;
3✔
350
   } else {
351
      throw Internal_Error("PK_Signer: Invalid signature format enum");
×
352
   }
353
}
354

355
std::vector<uint8_t> PK_Signer::signature(RandomNumberGenerator& rng) {
7,648✔
356
   std::vector<uint8_t> sig = m_op->sign(rng);
7,648✔
357

358
   if(m_sig_format == Signature_Format::Standard) {
7,644✔
359
      return sig;
7,240✔
360
   } else if(m_sig_format == Signature_Format::DerSequence) {
404✔
361
      BOTAN_ASSERT_NOMSG(m_sig_element_size.has_value());
404✔
362
      return der_encode_signature(sig, 2, m_sig_element_size.value());
404✔
363
   } else {
364
      throw Internal_Error("PK_Signer: Invalid signature format enum");
×
365
   }
366
}
7,644✔
367

368
PK_Verifier::PK_Verifier(const Public_Key& key,
63,455✔
369
                         std::string_view emsa,
370
                         Signature_Format format,
371
                         std::string_view provider) {
63,455✔
372
   m_op = key.create_verification_op(emsa, provider);
63,455✔
373
   if(!m_op) {
14,076✔
374
      throw Invalid_Argument(fmt("Key type {} does not support signature verification", key.algo_name()));
×
375
   }
376

377
   m_sig_format = format;
14,076✔
378
   m_sig_element_size = key._signature_element_size_for_DER_encoding();
14,076✔
379

380
   if(m_sig_format == Signature_Format::DerSequence) {
14,076✔
381
      BOTAN_ARG_CHECK(m_sig_element_size.has_value(), "This key does not support DER signatures");
7,824✔
382
   }
383
}
63,455✔
384

385
PK_Verifier::PK_Verifier(const Public_Key& key,
16,154✔
386
                         const AlgorithmIdentifier& signature_algorithm,
387
                         std::string_view provider) {
16,154✔
388
   m_op = key.create_x509_verification_op(signature_algorithm, provider);
16,154✔
389
   if(!m_op) {
16,109✔
390
      throw Invalid_Argument(fmt("Key type {} does not support X.509 signature verification", key.algo_name()));
×
391
   }
392

393
   m_sig_format = key._default_x509_signature_format();
16,109✔
394
   m_sig_element_size = key._signature_element_size_for_DER_encoding();
16,109✔
395
}
16,154✔
396

397
PK_Verifier::~PK_Verifier() = default;
30,185✔
398

399
PK_Verifier::PK_Verifier(PK_Verifier&&) noexcept = default;
×
400
PK_Verifier& PK_Verifier::operator=(PK_Verifier&&) noexcept = default;
×
401

402
std::string PK_Verifier::hash_function() const {
15,757✔
403
   return m_op->hash_function();
15,757✔
404
}
405

406
void PK_Verifier::set_input_format(Signature_Format format) {
1✔
407
   if(format == Signature_Format::DerSequence) {
1✔
408
      BOTAN_ARG_CHECK(m_sig_element_size.has_value(), "This key does not support DER signatures");
1✔
409
   }
410
   m_sig_format = format;
1✔
411
}
1✔
412

413
bool PK_Verifier::verify_message(const uint8_t msg[], size_t msg_length, const uint8_t sig[], size_t sig_length) {
86,518✔
414
   update(msg, msg_length);
86,518✔
415
   return check_signature(sig, sig_length);
86,518✔
416
}
417

418
void PK_Verifier::update(std::string_view in) {
1✔
419
   this->update(cast_char_ptr_to_uint8(in.data()), in.size());
1✔
420
}
1✔
421

422
void PK_Verifier::update(const uint8_t in[], size_t length) {
91,252✔
423
   m_op->update({in, length});
91,252✔
424
}
91,252✔
425

426
namespace {
427

428
std::vector<uint8_t> decode_der_signature(const uint8_t sig[], size_t length, size_t sig_parts, size_t sig_part_size) {
10,822✔
429
   std::vector<uint8_t> real_sig;
10,822✔
430
   BER_Decoder decoder(sig, length);
10,822✔
431
   BER_Decoder ber_sig = decoder.start_sequence();
10,822✔
432

433
   BOTAN_ASSERT_NOMSG(sig_parts != 0 && sig_part_size != 0);
10,493✔
434

435
   size_t count = 0;
436

437
   while(ber_sig.more_items()) {
29,025✔
438
      BigInt sig_part;
20,357✔
439
      ber_sig.decode(sig_part);
20,357✔
440
      real_sig += sig_part.serialize(sig_part_size);
18,757✔
441
      ++count;
18,532✔
442
   }
20,357✔
443

444
   if(count != sig_parts) {
8,668✔
445
      throw Decoding_Error("PK_Verifier: signature size invalid");
102✔
446
   }
447

448
   const std::vector<uint8_t> reencoded = der_encode_signature(real_sig, sig_parts, sig_part_size);
8,566✔
449

450
   if(reencoded.size() != length || CT::is_equal(reencoded.data(), sig, reencoded.size()).as_bool() == false) {
16,830✔
451
      throw Decoding_Error("PK_Verifier: signature is not the canonical DER encoding");
703✔
452
   }
453
   return real_sig;
15,726✔
454
}
13,452✔
455

456
}  // namespace
457

458
bool PK_Verifier::check_signature(const uint8_t sig[], size_t length) {
92,538✔
459
   try {
92,538✔
460
      if(m_sig_format == Signature_Format::Standard) {
92,538✔
461
         return m_op->is_valid_signature({sig, length});
81,716✔
462
      } else if(m_sig_format == Signature_Format::DerSequence) {
10,822✔
463
         bool decoding_success = false;
10,822✔
464
         std::vector<uint8_t> real_sig;
10,822✔
465

466
         BOTAN_ASSERT_NOMSG(m_sig_element_size.has_value());
10,822✔
467

468
         try {
10,822✔
469
            real_sig = decode_der_signature(sig, length, 2, m_sig_element_size.value());
18,685✔
470
            decoding_success = true;
7,863✔
471
         } catch(Decoding_Error&) {}
2,959✔
472

473
         bool accept = m_op->is_valid_signature(real_sig);
10,822✔
474

475
         return accept && decoding_success;
10,597✔
476
      } else {
10,822✔
477
         throw Internal_Error("PK_Verifier: Invalid signature format enum");
×
478
      }
479
   } catch(Invalid_Argument&) {
336✔
480
      return false;
225✔
481
   } catch(Decoding_Error&) {
336✔
482
      return false;
111✔
483
   } catch(Encoding_Error&) {
111✔
484
      return false;
×
485
   }
×
486
}
487

488
}  // 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