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

randombit / botan / 21966968252

12 Feb 2026 10:36PM UTC coverage: 90.07% (+0.003%) from 90.067%
21966968252

Pull #5321

github

web-flow
Merge fd30428c7 into e7443105f
Pull Request #5321: Avoid various unneeded include files

102234 of 113505 relevant lines covered (90.07%)

11432801.46 hits per line

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

85.94
/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 {
6,909✔
22
   uint8_t valid_mask = 0;
6,909✔
23

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

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

30
   return decoded;
3,691✔
31
}
3,185✔
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,
910✔
93
                                   RandomNumberGenerator& rng,
94
                                   std::string_view padding,
95
                                   std::string_view provider) {
910✔
96
   m_op = key.create_encryption_op(rng, padding, provider);
910✔
97
   if(!m_op) {
313✔
98
      throw Invalid_Argument(fmt("Key type {} does not support encryption", key.algo_name()));
×
99
   }
100
}
910✔
101

102
PK_Encryptor_EME::~PK_Encryptor_EME() = default;
517✔
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 {
204✔
108
   return m_op->ciphertext_length(ptext_len);
204✔
109
}
110

111
std::vector<uint8_t> PK_Encryptor_EME::enc(const uint8_t ptext[], size_t len, RandomNumberGenerator& rng) const {
381✔
112
   return m_op->encrypt(std::span{ptext, len}, rng);
381✔
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,052✔
120
                                   RandomNumberGenerator& rng,
121
                                   std::string_view padding,
122
                                   std::string_view provider) {
1,052✔
123
   m_op = key.create_decryption_op(rng, padding, provider);
1,052✔
124
   if(!m_op) {
329✔
125
      throw Invalid_Argument(fmt("Key type {} does not support decryption", key.algo_name()));
×
126
   }
127
}
1,052✔
128

129
PK_Decryptor_EME::~PK_Decryptor_EME() = default;
575✔
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 {
203✔
135
   return m_op->plaintext_length(ctext_len);
203✔
136
}
137

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

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

149
PK_KEM_Encryptor::PK_KEM_Encryptor(const Public_Key& key,
×
150
                                   RandomNumberGenerator& rng,
151
                                   std::string_view kem_param,
152
                                   std::string_view provider) :
×
153
      PK_KEM_Encryptor(key, kem_param, provider) {
×
154
   BOTAN_UNUSED(rng);
×
155
}
×
156

157
PK_KEM_Encryptor::~PK_KEM_Encryptor() = default;
862✔
158

159
PK_KEM_Encryptor::PK_KEM_Encryptor(PK_KEM_Encryptor&&) noexcept = default;
×
160
PK_KEM_Encryptor& PK_KEM_Encryptor::operator=(PK_KEM_Encryptor&&) noexcept = default;
×
161

162
size_t PK_KEM_Encryptor::shared_key_length(size_t desired_shared_key_len) const {
6,976✔
163
   return m_op->shared_key_length(desired_shared_key_len);
6,976✔
164
}
165

166
size_t PK_KEM_Encryptor::encapsulated_key_length() const {
6,881✔
167
   return m_op->encapsulated_key_length();
6,881✔
168
}
169

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

181
size_t PK_KEM_Decryptor::shared_key_length(size_t desired_shared_key_len) const {
7,130✔
182
   return m_op->shared_key_length(desired_shared_key_len);
7,130✔
183
}
184

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

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

199
PK_KEM_Decryptor::~PK_KEM_Decryptor() = default;
804✔
200

201
PK_KEM_Decryptor::PK_KEM_Decryptor(PK_KEM_Decryptor&&) noexcept = default;
×
202
PK_KEM_Decryptor& PK_KEM_Decryptor::operator=(PK_KEM_Decryptor&&) noexcept = default;
×
203

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

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

223
PK_Key_Agreement::~PK_Key_Agreement() = default;
8,866✔
224

225
PK_Key_Agreement::PK_Key_Agreement(PK_Key_Agreement&&) noexcept = default;
×
226
PK_Key_Agreement& PK_Key_Agreement::operator=(PK_Key_Agreement&&) noexcept = default;
×
227

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

232
SymmetricKey PK_Key_Agreement::derive_key(size_t key_len,
182✔
233
                                          const uint8_t peer_key[],
234
                                          size_t peer_key_len,
235
                                          std::string_view salt) const {
236
   return this->derive_key(key_len, {peer_key, peer_key_len}, as_span_of_bytes(salt));
182✔
237
}
238

239
SymmetricKey PK_Key_Agreement::derive_key(size_t key_len,
10,248✔
240
                                          const std::span<const uint8_t> peer_key,
241
                                          std::string_view salt) const {
242
   return this->derive_key(key_len, peer_key, as_span_of_bytes(salt));
10,248✔
243
}
244

245
SymmetricKey PK_Key_Agreement::derive_key(size_t key_len,
10,449✔
246
                                          std::span<const uint8_t> peer_key,
247
                                          std::span<const uint8_t> salt) const {
248
   return SymmetricKey(m_op->agree(key_len, peer_key, salt));
10,449✔
249
}
250

251
PK_Signer::PK_Signer(const Private_Key& key,
9,919✔
252
                     RandomNumberGenerator& rng,
253
                     std::string_view padding,
254
                     Signature_Format format,
255
                     std::string_view provider) :
9,919✔
256
      m_sig_format(format), m_sig_element_size(key._signature_element_size_for_DER_encoding()) {
9,919✔
257
   if(m_sig_format == Signature_Format::DerSequence) {
9,919✔
258
      BOTAN_ARG_CHECK(m_sig_element_size.has_value(), "This key does not support DER signatures");
1,950✔
259
   }
260

261
   m_op = key.create_signature_op(rng, padding, provider);
9,919✔
262
   if(!m_op) {
6,145✔
263
      throw Invalid_Argument(fmt("Key type {} does not support signature generation", key.algo_name()));
×
264
   }
265
}
9,919✔
266

267
AlgorithmIdentifier PK_Signer::algorithm_identifier() const {
2,067✔
268
   return m_op->algorithm_identifier();
2,067✔
269
}
270

271
std::string PK_Signer::hash_function() const {
2,576✔
272
   return m_op->hash_function();
2,576✔
273
}
274

275
PK_Signer::~PK_Signer() = default;
6,145✔
276

277
PK_Signer::PK_Signer(PK_Signer&&) noexcept = default;
×
278
PK_Signer& PK_Signer::operator=(PK_Signer&&) noexcept = default;
×
279

280
void PK_Signer::update(std::string_view in) {
1✔
281
   this->update(as_span_of_bytes(in));
1✔
282
}
1✔
283

284
void PK_Signer::update(const uint8_t in[], size_t length) {
10,485✔
285
   m_op->update({in, length});
10,485✔
286
}
10,484✔
287

288
namespace {
289

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

295
   BufferSlicer bs_sig(sig);
13,471✔
296
   std::vector<BigInt> sig_parts;
13,471✔
297
   sig_parts.reserve(parts);
13,471✔
298
   for(size_t i = 0; i != parts; ++i) {
40,413✔
299
      sig_parts.emplace_back(BigInt::from_bytes(bs_sig.take(part_size)));
26,942✔
300
   }
301

302
   std::vector<uint8_t> output;
13,471✔
303
   DER_Encoder(output).start_sequence().encode_list(sig_parts).end_cons();
53,884✔
304
   return output;
13,471✔
305
}
13,471✔
306

307
}  // namespace
308

309
size_t PK_Signer::signature_length() const {
1,332✔
310
   if(m_sig_format == Signature_Format::Standard) {
1,332✔
311
      return m_op->signature_length();
1,330✔
312
   } else if(m_sig_format == Signature_Format::DerSequence) {
2✔
313
      const size_t sig_len = m_op->signature_length();
2✔
314

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

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

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

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

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

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

353
std::vector<uint8_t> PK_Signer::signature(RandomNumberGenerator& rng) {
10,439✔
354
   std::vector<uint8_t> sig = m_op->sign(rng);
10,439✔
355

356
   if(m_sig_format == Signature_Format::Standard) {
10,435✔
357
      return sig;
7,230✔
358
   } else if(m_sig_format == Signature_Format::DerSequence) {
3,205✔
359
      BOTAN_ASSERT_NOMSG(m_sig_element_size.has_value());
3,205✔
360
      return der_encode_signature(sig, 2, m_sig_element_size.value());
3,205✔
361
   } else {
362
      throw Internal_Error("PK_Signer: Invalid signature format enum");
×
363
   }
364
}
10,435✔
365

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

375
   m_sig_format = format;
14,215✔
376
   m_sig_element_size = key._signature_element_size_for_DER_encoding();
14,215✔
377

378
   if(m_sig_format == Signature_Format::DerSequence) {
14,215✔
379
      BOTAN_ARG_CHECK(m_sig_element_size.has_value(), "This key does not support DER signatures");
7,913✔
380
   }
381
}
63,600✔
382

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

391
   m_sig_format = key._default_x509_signature_format();
21,134✔
392
   m_sig_element_size = key._signature_element_size_for_DER_encoding();
21,134✔
393
}
21,179✔
394

395
PK_Verifier::~PK_Verifier() = default;
35,349✔
396

397
PK_Verifier::PK_Verifier(PK_Verifier&&) noexcept = default;
×
398
PK_Verifier& PK_Verifier::operator=(PK_Verifier&&) noexcept = default;
×
399

400
std::string PK_Verifier::hash_function() const {
20,705✔
401
   return m_op->hash_function();
20,705✔
402
}
403

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

411
bool PK_Verifier::verify_message(const uint8_t msg[], size_t msg_length, const uint8_t sig[], size_t sig_length) {
91,560✔
412
   update(msg, msg_length);
91,560✔
413
   return check_signature(sig, sig_length);
91,560✔
414
}
415

416
void PK_Verifier::update(std::string_view in) {
48✔
417
   this->update(as_span_of_bytes(in));
48✔
418
}
48✔
419

420
void PK_Verifier::update(const uint8_t in[], size_t length) {
96,325✔
421
   m_op->update({in, length});
96,325✔
422
}
96,325✔
423

424
namespace {
425

426
std::vector<uint8_t> decode_der_signature(const uint8_t sig[], size_t length, size_t sig_parts, size_t sig_part_size) {
12,530✔
427
   std::vector<uint8_t> real_sig;
12,530✔
428
   BER_Decoder decoder(sig, length);
12,530✔
429
   BER_Decoder ber_sig = decoder.start_sequence();
12,530✔
430

431
   BOTAN_ASSERT_NOMSG(sig_parts != 0 && sig_part_size != 0);
12,198✔
432

433
   size_t count = 0;
434

435
   while(ber_sig.more_items()) {
34,135✔
436
      BigInt sig_part;
23,767✔
437
      ber_sig.decode(sig_part);
23,767✔
438
      real_sig += sig_part.serialize(sig_part_size);
22,165✔
439
      ++count;
21,937✔
440
   }
23,767✔
441

442
   if(count != sig_parts) {
10,368✔
443
      throw Decoding_Error("PK_Verifier: signature size invalid");
102✔
444
   }
445

446
   const std::vector<uint8_t> reencoded = der_encode_signature(real_sig, sig_parts, sig_part_size);
10,266✔
447

448
   if(reencoded.size() != length || CT::is_equal(reencoded.data(), sig, reencoded.size()).as_bool() == false) {
10,266✔
449
      throw Decoding_Error("PK_Verifier: signature is not the canonical DER encoding");
707✔
450
   }
451
   return real_sig;
19,118✔
452
}
15,169✔
453

454
}  // namespace
455

456
bool PK_Verifier::check_signature(const uint8_t sig[], size_t length) {
97,650✔
457
   try {
97,650✔
458
      if(m_sig_format == Signature_Format::Standard) {
97,650✔
459
         return m_op->is_valid_signature({sig, length});
85,120✔
460
      } else if(m_sig_format == Signature_Format::DerSequence) {
12,530✔
461
         bool decoding_success = false;
12,530✔
462
         std::vector<uint8_t> real_sig;
12,530✔
463

464
         BOTAN_ASSERT_NOMSG(m_sig_element_size.has_value());
12,530✔
465

466
         try {
12,530✔
467
            real_sig = decode_der_signature(sig, length, 2, m_sig_element_size.value());
22,089✔
468
            decoding_success = true;
9,559✔
469
         } catch(Decoding_Error&) {}
2,971✔
470

471
         const bool accept = m_op->is_valid_signature(real_sig);
12,530✔
472

473
         return accept && decoding_success;
12,302✔
474
      } else {
12,530✔
475
         throw Internal_Error("PK_Verifier: Invalid signature format enum");
×
476
      }
477
   } catch(Invalid_Argument&) {
330✔
478
      return false;
228✔
479
   } catch(Decoding_Error&) {
330✔
480
      return false;
102✔
481
   } catch(Encoding_Error&) {
102✔
482
      return false;
×
483
   }
×
484
}
485

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