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

randombit / botan / 12965174500

25 Jan 2025 01:02PM UTC coverage: 91.219% (-0.008%) from 91.227%
12965174500

Pull #4592

github

web-flow
Merge 2e35a9bd1 into 79027d241
Pull Request #4592: Some initial refactoring for splitting public and private keys

93633 of 102646 relevant lines covered (91.22%)

11545786.96 hits per line

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

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

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

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

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

175
size_t PK_KEM_Decryptor::shared_key_length(size_t desired_shared_key_len) const {
7,030✔
176
   return m_op->shared_key_length(desired_shared_key_len);
7,030✔
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,459✔
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,459✔
203
                   "inconsistent size of shared key output buffer");
204
   m_op->kem_decrypt(out_shared_key, encap_key, desired_shared_key_len, salt);
3,459✔
205
}
3,436✔
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
PK_Signer::PK_Signer(const Private_Key& key,
8,313✔
246
                     RandomNumberGenerator& rng,
247
                     std::string_view emsa,
248
                     Signature_Format format,
249
                     std::string_view provider) :
8,313✔
250
      m_sig_format(format) {
8,313✔
251
   if(m_sig_format == Signature_Format::DerSequence) {
8,313✔
252
      m_sig_element_size = key._signature_element_size();
368✔
253
      BOTAN_ARG_CHECK(m_sig_element_size.has_value(), "This key does not support DER signatures");
368✔
254
   }
255

256
   m_op = key.create_signature_op(rng, emsa, provider);
8,313✔
257
   if(!m_op) {
4,564✔
258
      throw Invalid_Argument(fmt("Key type {} does not support signature generation", key.algo_name()));
×
259
   }
260
}
8,313✔
261

262
AlgorithmIdentifier PK_Signer::algorithm_identifier() const {
505✔
263
   return m_op->algorithm_identifier();
505✔
264
}
265

266
std::string PK_Signer::hash_function() const {
806✔
267
   return m_op->hash_function();
806✔
268
}
269

270
PK_Signer::~PK_Signer() = default;
4,564✔
271

272
PK_Signer::PK_Signer(PK_Signer&&) noexcept = default;
×
273
PK_Signer& PK_Signer::operator=(PK_Signer&&) noexcept = default;
×
274

275
void PK_Signer::update(std::string_view in) {
1✔
276
   this->update(cast_char_ptr_to_uint8(in.data()), in.size());
1✔
277
}
1✔
278

279
void PK_Signer::update(const uint8_t in[], size_t length) {
7,666✔
280
   m_op->update({in, length});
7,666✔
281
}
7,665✔
282

283
namespace {
284

285
std::vector<uint8_t> der_encode_signature(std::span<const uint8_t> sig, size_t parts, size_t part_size) {
8,946✔
286
   if(sig.size() % parts != 0 || sig.size() != parts * part_size) {
8,946✔
287
      throw Encoding_Error("Unexpected size for DER signature");
×
288
   }
289

290
   BufferSlicer bs_sig(sig);
8,946✔
291
   std::vector<BigInt> sig_parts;
8,946✔
292
   sig_parts.reserve(parts);
8,946✔
293
   for(size_t i = 0; i != parts; ++i) {
26,838✔
294
      sig_parts.emplace_back(BigInt::from_bytes(bs_sig.take(part_size)));
35,784✔
295
   }
296

297
   std::vector<uint8_t> output;
8,946✔
298
   DER_Encoder(output).start_sequence().encode_list(sig_parts).end_cons();
35,784✔
299
   return output;
8,946✔
300
}
8,946✔
301

302
}  // namespace
303

304
size_t PK_Signer::signature_length() const {
1,278✔
305
   if(m_sig_format == Signature_Format::Standard) {
1,278✔
306
      return m_op->signature_length();
1,275✔
307
   } else if(m_sig_format == Signature_Format::DerSequence) {
3✔
308
      // This is a large over-estimate but its easier than computing
309
      // the exact value
310
      return m_op->signature_length() + (8 + 4 * 2);
3✔
311
   } else {
312
      throw Internal_Error("PK_Signer: Invalid signature format enum");
×
313
   }
314
}
315

316
std::vector<uint8_t> PK_Signer::signature(RandomNumberGenerator& rng) {
7,634✔
317
   std::vector<uint8_t> sig = m_op->sign(rng);
7,634✔
318

319
   if(m_sig_format == Signature_Format::Standard) {
7,630✔
320
      return sig;
7,228✔
321
   } else if(m_sig_format == Signature_Format::DerSequence) {
402✔
322
      BOTAN_ASSERT_NOMSG(m_sig_element_size.has_value());
402✔
323
      return der_encode_signature(sig, 2, m_sig_element_size.value());
402✔
324
   } else {
325
      throw Internal_Error("PK_Signer: Invalid signature format enum");
×
326
   }
327
}
7,630✔
328

329
PK_Verifier::PK_Verifier(const Public_Key& key,
63,408✔
330
                         std::string_view emsa,
331
                         Signature_Format format,
332
                         std::string_view provider) {
63,408✔
333
   m_op = key.create_verification_op(emsa, provider);
63,408✔
334
   if(!m_op) {
14,065✔
335
      throw Invalid_Argument(fmt("Key type {} does not support signature verification", key.algo_name()));
×
336
   }
337

338
   m_sig_format = format;
14,065✔
339
   m_sig_element_size = key._signature_element_size();
14,065✔
340

341
   if(m_sig_format == Signature_Format::DerSequence) {
14,065✔
342
      BOTAN_ARG_CHECK(m_sig_element_size.has_value(), "This key does not support DER signatures");
7,823✔
343
   }
344
}
63,408✔
345

346
PK_Verifier::PK_Verifier(const Public_Key& key,
16,152✔
347
                         const AlgorithmIdentifier& signature_algorithm,
348
                         std::string_view provider) {
16,152✔
349
   m_op = key.create_x509_verification_op(signature_algorithm, provider);
16,152✔
350
   if(!m_op) {
16,107✔
351
      throw Invalid_Argument(fmt("Key type {} does not support X.509 signature verification", key.algo_name()));
×
352
   }
353

354
   m_sig_format = key._default_x509_signature_format();
16,107✔
355
   m_sig_element_size = key._signature_element_size();
16,107✔
356
}
16,152✔
357

358
PK_Verifier::~PK_Verifier() = default;
30,172✔
359

360
PK_Verifier::PK_Verifier(PK_Verifier&&) noexcept = default;
×
361
PK_Verifier& PK_Verifier::operator=(PK_Verifier&&) noexcept = default;
×
362

363
std::string PK_Verifier::hash_function() const {
15,755✔
364
   return m_op->hash_function();
15,755✔
365
}
366

367
void PK_Verifier::set_input_format(Signature_Format format) {
×
368
   if(format == Signature_Format::DerSequence) {
×
369
      BOTAN_ARG_CHECK(m_sig_element_size.has_value(), "This key does not support DER signatures");
×
370
   }
371
   m_sig_format = format;
×
372
}
×
373

374
bool PK_Verifier::verify_message(const uint8_t msg[], size_t msg_length, const uint8_t sig[], size_t sig_length) {
86,235✔
375
   update(msg, msg_length);
86,235✔
376
   return check_signature(sig, sig_length);
86,235✔
377
}
378

379
void PK_Verifier::update(std::string_view in) {
1✔
380
   this->update(cast_char_ptr_to_uint8(in.data()), in.size());
1✔
381
}
1✔
382

383
void PK_Verifier::update(const uint8_t in[], size_t length) {
90,970✔
384
   m_op->update({in, length});
90,970✔
385
}
90,970✔
386

387
namespace {
388

389
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✔
390
   std::vector<uint8_t> real_sig;
10,794✔
391
   BER_Decoder decoder(sig, length);
10,794✔
392
   BER_Decoder ber_sig = decoder.start_sequence();
10,794✔
393

394
   BOTAN_ASSERT_NOMSG(sig_parts != 0 && sig_part_size != 0);
10,465✔
395

396
   size_t count = 0;
397

398
   while(ber_sig.more_items()) {
28,951✔
399
      BigInt sig_part;
20,305✔
400
      ber_sig.decode(sig_part);
20,305✔
401
      real_sig += sig_part.serialize(sig_part_size);
20,305✔
402
      ++count;
18,486✔
403
   }
20,305✔
404

405
   if(count != sig_parts) {
8,646✔
406
      throw Decoding_Error("PK_Verifier: signature size invalid");
102✔
407
   }
408

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

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

417
}  // namespace
418

419
bool PK_Verifier::check_signature(const uint8_t sig[], size_t length) {
92,256✔
420
   try {
92,256✔
421
      if(m_sig_format == Signature_Format::Standard) {
92,256✔
422
         return m_op->is_valid_signature({sig, length});
81,462✔
423
      } else if(m_sig_format == Signature_Format::DerSequence) {
10,794✔
424
         bool decoding_success = false;
10,794✔
425
         std::vector<uint8_t> real_sig;
10,794✔
426

427
         BOTAN_ASSERT_NOMSG(m_sig_element_size.has_value());
10,794✔
428

429
         try {
10,794✔
430
            real_sig = decode_der_signature(sig, length, 2, m_sig_element_size.value());
18,635✔
431
            decoding_success = true;
7,841✔
432
         } catch(Decoding_Error&) {}
2,953✔
433

434
         bool accept = m_op->is_valid_signature(real_sig);
10,794✔
435

436
         return accept && decoding_success;
10,571✔
437
      } else {
10,794✔
438
         throw Internal_Error("PK_Verifier: Invalid signature format enum");
×
439
      }
440
   } catch(Invalid_Argument&) {
342✔
441
      return false;
223✔
442
   } catch(Decoding_Error&) {
342✔
443
      return false;
119✔
444
   } catch(Encoding_Error&) {
119✔
445
      return false;
×
446
   }
×
447
}
448

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