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

randombit / botan / 12976993364

26 Jan 2025 05:51PM UTC coverage: 91.251% (-0.005%) from 91.256%
12976993364

push

github

web-flow
Merge pull request #4599 from randombit/jack/split-api-and-compiler-headers

Split compiler.h into two headers

93963 of 102972 relevant lines covered (91.25%)

11437005.01 hits per line

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

84.68
/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,874✔
29
      throw Decoding_Error("Invalid public key ciphertext, cannot decrypt");
3,185✔
30
   }
31

32
   return decoded;
3,689✔
33
}
3,185✔
34

35
secure_vector<uint8_t> PK_Decryptor::decrypt_or_random(const uint8_t in[],
586✔
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,758✔
43
      auto pms = rng.random_vec(expected_pt_len);
586✔
44

45
      for(size_t i = 0; i != required_contents_length; ++i) {
2,684✔
46
         const uint8_t exp = required_content_bytes[i];
2,098✔
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,098✔
55
         BOTAN_ASSERT(off < expected_pt_len, "Offset in range of plaintext");
2,098✔
56
         pms[off] = exp;
2,098✔
57
      }
58

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

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

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

68
   decoded.resize(expected_pt_len);
586✔
69

70
   for(size_t i = 0; i != required_contents_length; ++i) {
2,684✔
71
      const uint8_t exp = required_content_bytes[i];
2,098✔
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,098✔
75

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

78
      valid_mask &= eq;
2,098✔
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);
586✔
83

84
   return decoded;
586✔
85
}
586✔
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,
883✔
95
                                   RandomNumberGenerator& rng,
96
                                   std::string_view padding,
97
                                   std::string_view provider) {
883✔
98
   m_op = key.create_encryption_op(rng, padding, provider);
883✔
99
   if(!m_op) {
286✔
100
      throw Invalid_Argument(fmt("Key type {} does not support encryption", key.algo_name()));
×
101
   }
102
}
883✔
103

104
PK_Encryptor_EME::~PK_Encryptor_EME() = default;
490✔
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 {
354✔
114
   return m_op->encrypt(std::span{in, length}, rng);
354✔
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,051✔
122
                                   RandomNumberGenerator& rng,
123
                                   std::string_view padding,
124
                                   std::string_view provider) {
1,051✔
125
   m_op = key.create_decryption_op(rng, padding, provider);
1,051✔
126
   if(!m_op) {
328✔
127
      throw Invalid_Argument(fmt("Key type {} does not support decryption", key.algo_name()));
×
128
   }
129
}
1,051✔
130

131
PK_Decryptor_EME::~PK_Decryptor_EME() = default;
574✔
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,774✔
141
   return m_op->decrypt(valid_mask, {in, in_len});
5,774✔
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 {
6,884✔
165
   return m_op->shared_key_length(desired_shared_key_len);
6,884✔
166
}
167

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

172
void PK_KEM_Encryptor::encrypt(std::span<uint8_t> out_encapsulated_key,
3,388✔
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,388✔
178
   BOTAN_ARG_CHECK(out_shared_key.size() == shared_key_length(desired_shared_key_len),
3,388✔
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,388✔
181
}
3,385✔
182

183
size_t PK_KEM_Decryptor::shared_key_length(size_t desired_shared_key_len) const {
7,030✔
184
   return m_op->shared_key_length(desired_shared_key_len);
7,030✔
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,459✔
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,459✔
211
                   "inconsistent size of shared key output buffer");
212
   m_op->kem_decrypt(out_shared_key, encap_key, desired_shared_key_len, salt);
3,459✔
213
}
3,436✔
214

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

225
PK_Key_Agreement::~PK_Key_Agreement() = default;
8,833✔
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 {
872✔
231
   return m_op->agreed_value_size();
872✔
232
}
233

234
SymmetricKey PK_Key_Agreement::derive_key(size_t key_len,
185✔
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());
185✔
239
}
240

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

248
SymmetricKey PK_Key_Agreement::derive_key(
10,415✔
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,415✔
251
}
252

253
namespace {
254

255
void check_der_format_supported(Signature_Format format, size_t parts) {
34,733✔
256
   if(format != Signature_Format::Standard && parts == 1) {
34,733✔
257
      throw Invalid_Argument("This algorithm does not support DER encoding");
×
258
   }
259
}
34,733✔
260

261
}  // namespace
262

263
PK_Signer::PK_Signer(const Private_Key& key,
8,313✔
264
                     RandomNumberGenerator& rng,
265
                     std::string_view emsa,
266
                     Signature_Format format,
267
                     std::string_view provider) {
8,313✔
268
   m_op = key.create_signature_op(rng, emsa, provider);
8,313✔
269
   if(!m_op) {
4,564✔
270
      throw Invalid_Argument(fmt("Key type {} does not support signature generation", key.algo_name()));
×
271
   }
272
   m_sig_format = format;
4,564✔
273
   m_parts = key.message_parts();
4,564✔
274
   m_part_size = key.message_part_size();
4,564✔
275
   check_der_format_supported(format, m_parts);
4,564✔
276
}
8,313✔
277

278
AlgorithmIdentifier PK_Signer::algorithm_identifier() const {
505✔
279
   return m_op->algorithm_identifier();
505✔
280
}
281

282
std::string PK_Signer::hash_function() const {
806✔
283
   return m_op->hash_function();
806✔
284
}
285

286
PK_Signer::~PK_Signer() = default;
4,564✔
287

288
PK_Signer::PK_Signer(PK_Signer&&) noexcept = default;
×
289
PK_Signer& PK_Signer::operator=(PK_Signer&&) noexcept = default;
×
290

291
void PK_Signer::update(std::string_view in) {
1✔
292
   this->update(cast_char_ptr_to_uint8(in.data()), in.size());
1✔
293
}
1✔
294

295
void PK_Signer::update(const uint8_t in[], size_t length) {
7,667✔
296
   m_op->update({in, length});
7,667✔
297
}
7,666✔
298

299
namespace {
300

301
std::vector<uint8_t> der_encode_signature(std::span<const uint8_t> sig, size_t parts, size_t part_size) {
8,949✔
302
   if(sig.size() % parts != 0 || sig.size() != parts * part_size) {
8,949✔
303
      throw Encoding_Error("Unexpected size for DER signature");
×
304
   }
305

306
   BufferSlicer bs_sig(sig);
8,949✔
307
   std::vector<BigInt> sig_parts;
8,949✔
308
   sig_parts.reserve(parts);
8,949✔
309
   for(size_t i = 0; i != parts; ++i) {
26,847✔
310
      sig_parts.emplace_back(BigInt::from_bytes(bs_sig.take(part_size)));
35,796✔
311
   }
312

313
   std::vector<uint8_t> output;
8,949✔
314
   DER_Encoder(output).start_sequence().encode_list(sig_parts).end_cons();
35,796✔
315
   return output;
8,949✔
316
}
8,949✔
317

318
}  // namespace
319

320
size_t PK_Signer::signature_length() const {
1,278✔
321
   if(m_sig_format == Signature_Format::Standard) {
1,278✔
322
      return m_op->signature_length();
1,275✔
323
   } else if(m_sig_format == Signature_Format::DerSequence) {
3✔
324
      // This is a large over-estimate but its easier than computing
325
      // the exact value
326
      return m_op->signature_length() + (8 + 4 * m_parts);
3✔
327
   } else {
328
      throw Internal_Error("PK_Signer: Invalid signature format enum");
×
329
   }
330
}
331

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

335
   if(m_sig_format == Signature_Format::Standard) {
7,631✔
336
      return sig;
7,228✔
337
   } else if(m_sig_format == Signature_Format::DerSequence) {
403✔
338
      return der_encode_signature(sig, m_parts, m_part_size);
403✔
339
   } else {
340
      throw Internal_Error("PK_Signer: Invalid signature format enum");
×
341
   }
342
}
7,631✔
343

344
PK_Verifier::PK_Verifier(const Public_Key& key,
63,408✔
345
                         std::string_view emsa,
346
                         Signature_Format format,
347
                         std::string_view provider) {
63,408✔
348
   m_op = key.create_verification_op(emsa, provider);
63,408✔
349
   if(!m_op) {
14,065✔
350
      throw Invalid_Argument(fmt("Key type {} does not support signature verification", key.algo_name()));
×
351
   }
352
   m_sig_format = format;
14,065✔
353
   m_parts = key.message_parts();
14,065✔
354
   m_part_size = key.message_part_size();
14,065✔
355
   check_der_format_supported(format, m_parts);
14,065✔
356
}
63,408✔
357

358
PK_Verifier::PK_Verifier(const Public_Key& key,
16,149✔
359
                         const AlgorithmIdentifier& signature_algorithm,
360
                         std::string_view provider) {
16,149✔
361
   m_op = key.create_x509_verification_op(signature_algorithm, provider);
16,149✔
362

363
   if(!m_op) {
16,104✔
364
      throw Invalid_Argument(fmt("Key type {} does not support X.509 signature verification", key.algo_name()));
×
365
   }
366

367
   m_sig_format = key.default_x509_signature_format();
16,104✔
368
   m_parts = key.message_parts();
16,104✔
369
   m_part_size = key.message_part_size();
16,104✔
370
   check_der_format_supported(m_sig_format, m_parts);
16,104✔
371
}
16,149✔
372

373
PK_Verifier::~PK_Verifier() = default;
30,169✔
374

375
PK_Verifier::PK_Verifier(PK_Verifier&&) noexcept = default;
×
376
PK_Verifier& PK_Verifier::operator=(PK_Verifier&&) noexcept = default;
×
377

378
std::string PK_Verifier::hash_function() const {
15,752✔
379
   return m_op->hash_function();
15,752✔
380
}
381

382
void PK_Verifier::set_input_format(Signature_Format format) {
×
383
   check_der_format_supported(format, m_parts);
×
384
   m_sig_format = format;
×
385
}
×
386

387
bool PK_Verifier::verify_message(const uint8_t msg[], size_t msg_length, const uint8_t sig[], size_t sig_length) {
86,240✔
388
   update(msg, msg_length);
86,240✔
389
   return check_signature(sig, sig_length);
86,240✔
390
}
391

392
void PK_Verifier::update(std::string_view in) {
1✔
393
   this->update(cast_char_ptr_to_uint8(in.data()), in.size());
1✔
394
}
1✔
395

396
void PK_Verifier::update(const uint8_t in[], size_t length) {
90,975✔
397
   m_op->update({in, length});
90,975✔
398
}
90,975✔
399

400
namespace {
401

402
std::vector<uint8_t> decode_der_signature(const uint8_t sig[], size_t length, size_t sig_parts, size_t sig_part_size) {
10,798✔
403
   std::vector<uint8_t> real_sig;
10,798✔
404
   BER_Decoder decoder(sig, length);
10,798✔
405
   BER_Decoder ber_sig = decoder.start_sequence();
10,798✔
406

407
   BOTAN_ASSERT_NOMSG(sig_parts != 0 && sig_part_size != 0);
10,469✔
408

409
   size_t count = 0;
410

411
   while(ber_sig.more_items()) {
28,958✔
412
      BigInt sig_part;
20,310✔
413
      ber_sig.decode(sig_part);
20,310✔
414
      real_sig += sig_part.serialize(sig_part_size);
20,310✔
415
      ++count;
18,489✔
416
   }
20,310✔
417

418
   if(count != sig_parts) {
8,648✔
419
      throw Decoding_Error("PK_Verifier: signature size invalid");
102✔
420
   }
421

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

424
   if(reencoded.size() != length || CT::is_equal(reencoded.data(), sig, reencoded.size()).as_bool() == false) {
16,790✔
425
      throw Decoding_Error("PK_Verifier: signature is not the canonical DER encoding");
703✔
426
   }
427
   return real_sig;
15,686✔
428
}
13,424✔
429

430
}  // namespace
431

432
bool PK_Verifier::check_signature(const uint8_t sig[], size_t length) {
92,261✔
433
   try {
92,261✔
434
      if(m_sig_format == Signature_Format::Standard) {
92,261✔
435
         return m_op->is_valid_signature({sig, length});
81,463✔
436
      } else if(m_sig_format == Signature_Format::DerSequence) {
10,798✔
437
         bool decoding_success = false;
10,798✔
438
         std::vector<uint8_t> real_sig;
10,798✔
439

440
         try {
10,798✔
441
            real_sig = decode_der_signature(sig, length, m_parts, m_part_size);
18,641✔
442
            decoding_success = true;
7,843✔
443
         } catch(Decoding_Error&) {}
2,955✔
444

445
         bool accept = m_op->is_valid_signature(real_sig);
10,798✔
446

447
         return accept && decoding_success;
10,575✔
448
      } else {
10,798✔
449
         throw Internal_Error("PK_Verifier: Invalid signature format enum");
×
450
      }
451
   } catch(Invalid_Argument&) {
341✔
452
      return false;
223✔
453
   } catch(Decoding_Error&) {
341✔
454
      return false;
118✔
455
   } catch(Encoding_Error&) {
118✔
456
      return false;
×
457
   }
×
458
}
459

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