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

randombit / botan / 28994301380

09 Jul 2026 12:46AM UTC coverage: 89.396% (+1.7%) from 87.739%
28994301380

push

github

web-flow
Merge pull request #5712 from randombit/jack/cdp-aia-extn

Improve CDP, AIA and IDP extension decoding and handling

113303 of 126743 relevant lines covered (89.4%)

10806632.55 hits per line

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

85.43
/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/pk_ops.h>
13
#include <botan/rng.h>
14
#include <botan/internal/buffer_slicer.h>
15
#include <botan/internal/ct_utils.h>
16
#include <botan/internal/fmt.h>
17
#include <botan/internal/mem_utils.h>
18

19
namespace Botan {
20

21
secure_vector<uint8_t> PK_Decryptor::decrypt(const uint8_t in[], size_t length) const {
7,283✔
22
   uint8_t valid_mask = 0;
7,283✔
23

24
   secure_vector<uint8_t> decoded = do_decrypt(valid_mask, in, length);
7,283✔
25

26
   if(valid_mask == 0) {
7,193✔
27
      throw Decoding_Error("Invalid public key ciphertext, cannot decrypt");
3,200✔
28
   }
29

30
   return decoded;
3,993✔
31
}
3,200✔
32

33
secure_vector<uint8_t> PK_Decryptor::decrypt_or_random(const uint8_t in[],
587✔
34
                                                       size_t length,
35
                                                       size_t expected_pt_len,
36
                                                       RandomNumberGenerator& rng,
37
                                                       const uint8_t required_content_bytes[],
38
                                                       const uint8_t required_content_offsets[],
39
                                                       size_t required_contents_length) const {
40
   const secure_vector<uint8_t> fake_pms = [&]() {
1,761✔
41
      auto pms = rng.random_vec(expected_pt_len);
587✔
42

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

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

57
      return pms;
587✔
58
   }();
587✔
59

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

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

66
   decoded.resize(expected_pt_len);
587✔
67

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

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

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

76
      valid_mask &= eq;
2,100✔
77
   }
78

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

82
   return decoded;
587✔
83
}
587✔
84

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

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

102
PK_Encryptor_EME::~PK_Encryptor_EME() = default;
531✔
103

104
PK_Encryptor_EME::PK_Encryptor_EME(PK_Encryptor_EME&&) noexcept = default;
×
105
PK_Encryptor_EME& PK_Encryptor_EME::operator=(PK_Encryptor_EME&&) noexcept = default;
×
106

107
size_t PK_Encryptor_EME::ciphertext_length(size_t ptext_len) const {
211✔
108
   return m_op->ciphertext_length(ptext_len);
211✔
109
}
110

111
std::vector<uint8_t> PK_Encryptor_EME::enc(const uint8_t ptext[], size_t len, RandomNumberGenerator& rng) const {
395✔
112
   return m_op->encrypt(std::span{ptext, len}, rng);
395✔
113
}
114

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

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

129
PK_Decryptor_EME::~PK_Decryptor_EME() = default;
614✔
130

131
PK_Decryptor_EME::PK_Decryptor_EME(PK_Decryptor_EME&&) noexcept = default;
×
132
PK_Decryptor_EME& PK_Decryptor_EME::operator=(PK_Decryptor_EME&&) noexcept = default;
×
133

134
size_t PK_Decryptor_EME::plaintext_length(size_t ctext_len) const {
209✔
135
   return m_op->plaintext_length(ctext_len);
209✔
136
}
137

138
size_t PK_Decryptor_EME::ciphertext_length(size_t ptext_len) const {
246✔
139
   return m_op->ciphertext_length(ptext_len);
246✔
140
}
141

142
secure_vector<uint8_t> PK_Decryptor_EME::do_decrypt(uint8_t& valid_mask, const uint8_t in[], size_t in_len) const {
6,073✔
143
   return m_op->decrypt(valid_mask, {in, in_len});
6,073✔
144
}
145

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

153
PK_KEM_Encryptor::PK_KEM_Encryptor(const Public_Key& key,
×
154
                                   RandomNumberGenerator& rng,
155
                                   std::string_view kem_param,
156
                                   std::string_view provider) :
×
157
      PK_KEM_Encryptor(key, kem_param, provider) {
×
158
   BOTAN_UNUSED(rng);
×
159
}
×
160

161
PK_KEM_Encryptor::~PK_KEM_Encryptor() = default;
880✔
162

163
PK_KEM_Encryptor::PK_KEM_Encryptor(PK_KEM_Encryptor&&) noexcept = default;
×
164
PK_KEM_Encryptor& PK_KEM_Encryptor::operator=(PK_KEM_Encryptor&&) noexcept = default;
×
165

166
size_t PK_KEM_Encryptor::shared_key_length(size_t desired_shared_key_len) const {
2,430✔
167
   return m_op->shared_key_length(desired_shared_key_len);
2,430✔
168
}
169

170
size_t PK_KEM_Encryptor::encapsulated_key_length() const {
2,335✔
171
   return m_op->encapsulated_key_length();
2,335✔
172
}
173

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

185
size_t PK_KEM_Decryptor::shared_key_length(size_t desired_shared_key_len) const {
2,750✔
186
   return m_op->shared_key_length(desired_shared_key_len);
2,750✔
187
}
188

189
size_t PK_KEM_Decryptor::encapsulated_key_length() const {
144✔
190
   return m_op->encapsulated_key_length();
144✔
191
}
192

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

203
PK_KEM_Decryptor::~PK_KEM_Decryptor() = default;
831✔
204

205
PK_KEM_Decryptor::PK_KEM_Decryptor(PK_KEM_Decryptor&&) noexcept = default;
×
206
PK_KEM_Decryptor& PK_KEM_Decryptor::operator=(PK_KEM_Decryptor&&) noexcept = default;
×
207

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

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

227
PK_Key_Agreement::~PK_Key_Agreement() = default;
9,257✔
228

229
PK_Key_Agreement::PK_Key_Agreement(PK_Key_Agreement&&) noexcept = default;
×
230
PK_Key_Agreement& PK_Key_Agreement::operator=(PK_Key_Agreement&&) noexcept = default;
×
231

232
size_t PK_Key_Agreement::agreed_value_size() const {
953✔
233
   return m_op->agreed_value_size();
953✔
234
}
235

236
SymmetricKey PK_Key_Agreement::derive_key(size_t key_len,
182✔
237
                                          const uint8_t peer_key[],
238
                                          size_t peer_key_len,
239
                                          std::string_view salt) const {
240
   return this->derive_key(key_len, {peer_key, peer_key_len}, as_span_of_bytes(salt));
182✔
241
}
242

243
SymmetricKey PK_Key_Agreement::derive_key(size_t key_len,
10,717✔
244
                                          const std::span<const uint8_t> peer_key,
245
                                          std::string_view salt) const {
246
   return this->derive_key(key_len, peer_key, as_span_of_bytes(salt));
10,717✔
247
}
248

249
SymmetricKey PK_Key_Agreement::derive_key(size_t key_len,
10,918✔
250
                                          std::span<const uint8_t> peer_key,
251
                                          std::span<const uint8_t> salt) const {
252
   return SymmetricKey(m_op->agree(key_len, peer_key, salt));
10,918✔
253
}
254

255
PK_Signer::PK_Signer(const Private_Key& key,
10,299✔
256
                     RandomNumberGenerator& rng,
257
                     std::string_view padding,
258
                     Signature_Format format,
259
                     std::string_view provider) :
10,299✔
260
      m_sig_format(format), m_sig_element_size(key._signature_element_size_for_DER_encoding()) {
10,299✔
261
   if(m_sig_format == Signature_Format::DerSequence) {
10,299✔
262
      BOTAN_ARG_CHECK(m_sig_element_size.has_value(), "This key does not support DER signatures");
1,998✔
263
   }
264

265
   m_op = key.create_signature_op(rng, padding, provider);
10,299✔
266
   if(!m_op) {
6,525✔
267
      throw Invalid_Argument(fmt("Key type {} does not support signature generation", key.algo_name()));
×
268
   }
269
}
10,299✔
270

271
AlgorithmIdentifier PK_Signer::algorithm_identifier() const {
2,073✔
272
   return m_op->algorithm_identifier();
2,073✔
273
}
274

275
std::string PK_Signer::hash_function() const {
2,582✔
276
   return m_op->hash_function();
2,582✔
277
}
278

279
PK_Signer::~PK_Signer() = default;
6,525✔
280

281
PK_Signer::PK_Signer(PK_Signer&&) noexcept = default;
×
282
PK_Signer& PK_Signer::operator=(PK_Signer&&) noexcept = default;
×
283

284
void PK_Signer::update(std::string_view in) {
1✔
285
   this->update(as_span_of_bytes(in));
1✔
286
}
1✔
287

288
void PK_Signer::update(const uint8_t in[], size_t length) {
13,149✔
289
   m_op->update({in, length});
13,149✔
290
}
13,147✔
291

292
namespace {
293

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

299
   BufferSlicer bs_sig(sig);
3,249✔
300
   std::vector<BigInt> sig_parts;
3,249✔
301
   sig_parts.reserve(parts);
3,249✔
302
   for(size_t i = 0; i != parts; ++i) {
9,747✔
303
      sig_parts.emplace_back(BigInt::from_bytes(bs_sig.take(part_size)));
6,498✔
304
   }
305

306
   std::vector<uint8_t> output;
3,249✔
307
   DER_Encoder(output).start_sequence().encode_list(sig_parts).end_cons();
12,996✔
308
   return output;
3,249✔
309
}
3,249✔
310

311
}  // namespace
312

313
size_t PK_Signer::signature_length() const {
1,332✔
314
   if(m_sig_format == Signature_Format::Standard) {
1,332✔
315
      return m_op->signature_length();
1,330✔
316
   } else if(m_sig_format == Signature_Format::DerSequence) {
2✔
317
      const size_t sig_len = m_op->signature_length();
2✔
318

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

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

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

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

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

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

357
std::vector<uint8_t> PK_Signer::signature(RandomNumberGenerator& rng) {
13,102✔
358
   std::vector<uint8_t> sig = m_op->sign(rng);
13,102✔
359

360
   if(m_sig_format == Signature_Format::Standard) {
13,095✔
361
      return sig;
9,846✔
362
   } else if(m_sig_format == Signature_Format::DerSequence) {
3,249✔
363
      BOTAN_ASSERT_NOMSG(m_sig_element_size.has_value());
3,249✔
364
      return der_encode_signature(sig, 2, m_sig_element_size.value());
3,249✔
365
   } else {
366
      throw Internal_Error("PK_Signer: Invalid signature format enum");
×
367
   }
368
}
13,095✔
369

370
PK_Verifier::PK_Verifier(const Public_Key& key,
64,044✔
371
                         std::string_view padding,
372
                         Signature_Format format,
373
                         std::string_view provider) {
64,044✔
374
   m_op = key.create_verification_op(padding, provider);
64,044✔
375
   if(!m_op) {
14,605✔
376
      throw Invalid_Argument(fmt("Key type {} does not support signature verification", key.algo_name()));
×
377
   }
378

379
   m_sig_format = format;
14,605✔
380
   m_sig_element_size = key._signature_element_size_for_DER_encoding();
14,605✔
381

382
   if(m_sig_format == Signature_Format::DerSequence) {
14,605✔
383
      BOTAN_ARG_CHECK(m_sig_element_size.has_value(), "This key does not support DER signatures");
7,948✔
384
   }
385
}
64,044✔
386

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

395
   m_sig_format = key._default_x509_signature_format();
13,740✔
396
   m_sig_element_size = key._signature_element_size_for_DER_encoding();
13,740✔
397
}
13,742✔
398

399
PK_Verifier::~PK_Verifier() = default;
28,345✔
400

401
PK_Verifier::PK_Verifier(PK_Verifier&&) noexcept = default;
×
402
PK_Verifier& PK_Verifier::operator=(PK_Verifier&&) noexcept = default;
×
403

404
std::string PK_Verifier::hash_function() const {
13,305✔
405
   return m_op->hash_function();
13,305✔
406
}
407

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

415
bool PK_Verifier::verify_message(const uint8_t msg[], size_t msg_length, const uint8_t sig[], size_t sig_length) {
138,205✔
416
   update(msg, msg_length);
138,205✔
417
   return check_signature(sig, sig_length);
138,205✔
418
}
419

420
void PK_Verifier::update(std::string_view in) {
48✔
421
   this->update(as_span_of_bytes(in));
48✔
422
}
48✔
423

424
void PK_Verifier::update(const uint8_t in[], size_t length) {
170,405✔
425
   m_op->update({in, length});
170,405✔
426
}
170,405✔
427

428
namespace {
429

430
std::vector<uint8_t> decode_der_signature_pair(std::span<const uint8_t> der_sig, size_t sig_part_size) {
11,982✔
431
   BOTAN_ASSERT_NOMSG(sig_part_size > 0);
11,982✔
432

433
   BigInt r;
11,982✔
434
   BigInt s;
11,982✔
435

436
   // TODO should be able to just get the integer bytes directly from
437
   // BER_Decoder without using BigInt here
438
   BER_Decoder(der_sig, BER_Decoder::Limits::DER()).start_sequence().decode(r).decode(s).end_cons().verify_end();
25,776✔
439

440
   const bool invalid_r = r.is_negative() || r.bytes() > sig_part_size;
9,679✔
441
   const bool invalid_s = s.is_negative() || s.bytes() > sig_part_size;
9,679✔
442

443
   if(invalid_r || invalid_s) {
9,679✔
444
      throw Decoding_Error("Invalid DER encoding of signature");
598✔
445
   }
446

447
   std::vector<uint8_t> sig(2 * sig_part_size);
9,081✔
448
   r.serialize_to(std::span{sig}.first(sig_part_size));
9,081✔
449
   s.serialize_to(std::span{sig}.last(sig_part_size));
9,081✔
450
   return sig;
9,081✔
451
}
14,883✔
452

453
}  // namespace
454

455
bool PK_Verifier::check_signature(const uint8_t sig[], size_t length) {
158,018✔
456
   try {
158,018✔
457
      if(m_sig_format == Signature_Format::Standard) {
158,018✔
458
         return m_op->is_valid_signature({sig, length});
146,036✔
459
      } else if(m_sig_format == Signature_Format::DerSequence) {
11,982✔
460
         bool decoding_success = false;
11,982✔
461
         std::vector<uint8_t> real_sig;
11,982✔
462

463
         BOTAN_ASSERT_NOMSG(m_sig_element_size.has_value());
11,982✔
464

465
         try {
11,982✔
466
            real_sig = decode_der_signature_pair({sig, length}, m_sig_element_size.value());
21,063✔
467
            decoding_success = true;
9,081✔
468
         } catch(...) {}
2,901✔
469

470
         // It is critical that is_valid_signature is called even if DER decoding failed, since
471
         // that is what resets the internal state (message hashes, etc)
472
         const bool accept = m_op->is_valid_signature(real_sig);
11,982✔
473

474
         return accept && decoding_success;
11,982✔
475
      } else {
11,982✔
476
         throw Internal_Error("PK_Verifier: Invalid signature format enum");
×
477
      }
478
   } catch(Invalid_Argument&) {
2,268✔
479
      return false;
×
480
   } catch(Decoding_Error&) {
2,268✔
481
      return false;
2,268✔
482
   } catch(Encoding_Error&) {
2,268✔
483
      return false;
×
484
   }
×
485
}
486

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