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

randombit / botan / 12950926957

24 Jan 2025 01:49PM UTC coverage: 91.215% (+0.005%) from 91.21%
12950926957

push

github

web-flow
Merge pull request #4586 from randombit/jack/update-pubkey-rst

Update pubkey.rst

93622 of 102639 relevant lines covered (91.21%)

11747617.43 hits per line

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

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

32
   return decoded;
3,692✔
33
}
3,190✔
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,872✔
157
   return m_op->shared_key_length(desired_shared_key_len);
6,872✔
158
}
159

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

164
void PK_KEM_Encryptor::encrypt(std::span<uint8_t> out_encapsulated_key,
3,382✔
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,382✔
170
   BOTAN_ARG_CHECK(out_shared_key.size() == shared_key_length(desired_shared_key_len),
3,382✔
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,382✔
173
}
3,379✔
174

175
size_t PK_KEM_Decryptor::shared_key_length(size_t desired_shared_key_len) const {
7,018✔
176
   return m_op->shared_key_length(desired_shared_key_len);
7,018✔
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,453✔
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,453✔
203
                   "inconsistent size of shared key output buffer");
204
   m_op->kem_decrypt(out_shared_key, encap_key, desired_shared_key_len, salt);
3,453✔
205
}
3,430✔
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 peer_key[],
228
                                          size_t peer_key_len,
229
                                          std::string_view salt) const {
230
   return this->derive_key(key_len, peer_key, peer_key_len, cast_char_ptr_to_uint8(salt.data()), salt.length());
185✔
231
}
232

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

240
SymmetricKey PK_Key_Agreement::derive_key(
10,413✔
241
   size_t key_len, const uint8_t peer_key[], size_t peer_key_len, const uint8_t salt[], size_t salt_len) const {
242
   return SymmetricKey(m_op->agree(key_len, {peer_key, peer_key_len}, {salt, salt_len}));
10,413✔
243
}
244

245
namespace {
246

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

253
}  // namespace
254

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

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

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

278
PK_Signer::~PK_Signer() = default;
4,562✔
279

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

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

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

291
namespace {
292

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

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

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

310
}  // namespace
311

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

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

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

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

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

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

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

365
PK_Verifier::~PK_Verifier() = default;
30,170✔
366

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

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

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

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

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

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

392
namespace {
393

394
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✔
395
   std::vector<uint8_t> real_sig;
10,794✔
396
   BER_Decoder decoder(sig, length);
10,794✔
397
   BER_Decoder ber_sig = decoder.start_sequence();
10,794✔
398

399
   BOTAN_ASSERT_NOMSG(sig_parts != 0 && sig_part_size != 0);
10,466✔
400

401
   size_t count = 0;
402

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

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

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

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

422
}  // namespace
423

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

432
         try {
10,794✔
433
            real_sig = decode_der_signature(sig, length, m_parts, m_part_size);
18,635✔
434
            decoding_success = true;
7,841✔
435
         } catch(Decoding_Error&) {}
2,953✔
436

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

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

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