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

randombit / botan / 12929244692

23 Jan 2025 12:32PM UTC coverage: 91.213% (+0.01%) from 91.202%
12929244692

Pull #4586

github

web-flow
Merge faf49c0d6 into 525a35d62
Pull Request #4586: Update pubkey.rst

93560 of 102573 relevant lines covered (91.21%)

11666193.05 hits per line

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

86.02
/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,189✔
30
   }
31

32
   return decoded;
3,684✔
33
}
3,189✔
34

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

44
   uint8_t decrypt_valid = 0;
263✔
45
   secure_vector<uint8_t> decoded = do_decrypt(decrypt_valid, in, length);
263✔
46

47
   auto valid_mask = CT::Mask<uint8_t>::is_equal(decrypt_valid, 0xFF);
263✔
48
   valid_mask &= CT::Mask<uint8_t>(CT::Mask<size_t>::is_zero(decoded.size() ^ expected_pt_len));
263✔
49

50
   decoded.resize(expected_pt_len);
263✔
51

52
   for(size_t i = 0; i != required_contents_length; ++i) {
379✔
53
      /*
54
      These values are chosen by the application and for TLS are constants,
55
      so this early failure via assert is fine since we know 0,1 < 48
56

57
      If there is a protocol that has content checks on the key where
58
      the expected offsets are controllable by the attacker this could
59
      still leak.
60

61
      Alternately could always reduce the offset modulo the length?
62
      */
63

64
      const uint8_t exp = required_content_bytes[i];
116✔
65
      const uint8_t off = required_content_offsets[i];
116✔
66

67
      BOTAN_ASSERT(off < expected_pt_len, "Offset in range of plaintext");
116✔
68

69
      auto eq = CT::Mask<uint8_t>::is_equal(decoded[off], exp);
116✔
70

71
      valid_mask &= eq;
116✔
72
   }
73

74
   // If valid_mask is false, assign fake pre master instead
75
   valid_mask.select_n(decoded.data(), decoded.data(), fake_pms.data(), expected_pt_len);
263✔
76

77
   return decoded;
263✔
78
}
263✔
79

80
secure_vector<uint8_t> PK_Decryptor::decrypt_or_random(const uint8_t in[],
205✔
81
                                                       size_t length,
82
                                                       size_t expected_pt_len,
83
                                                       RandomNumberGenerator& rng) const {
84
   return decrypt_or_random(in, length, expected_pt_len, rng, nullptr, nullptr, 0);
205✔
85
}
86

87
PK_Encryptor_EME::PK_Encryptor_EME(const Public_Key& key,
882✔
88
                                   RandomNumberGenerator& rng,
89
                                   std::string_view padding,
90
                                   std::string_view provider) {
882✔
91
   m_op = key.create_encryption_op(rng, padding, provider);
882✔
92
   if(!m_op) {
285✔
93
      throw Invalid_Argument(fmt("Key type {} does not support encryption", key.algo_name()));
×
94
   }
95
}
882✔
96

97
PK_Encryptor_EME::~PK_Encryptor_EME() = default;
489✔
98

99
PK_Encryptor_EME::PK_Encryptor_EME(PK_Encryptor_EME&&) noexcept = default;
×
100
PK_Encryptor_EME& PK_Encryptor_EME::operator=(PK_Encryptor_EME&&) noexcept = default;
×
101

102
size_t PK_Encryptor_EME::ciphertext_length(size_t ptext_len) const {
204✔
103
   return m_op->ciphertext_length(ptext_len);
204✔
104
}
105

106
std::vector<uint8_t> PK_Encryptor_EME::enc(const uint8_t in[], size_t length, RandomNumberGenerator& rng) const {
353✔
107
   return m_op->encrypt(std::span{in, length}, rng);
353✔
108
}
109

110
size_t PK_Encryptor_EME::maximum_input_size() const {
209✔
111
   return m_op->max_input_bits() / 8;
209✔
112
}
113

114
PK_Decryptor_EME::PK_Decryptor_EME(const Private_Key& key,
1,050✔
115
                                   RandomNumberGenerator& rng,
116
                                   std::string_view padding,
117
                                   std::string_view provider) {
1,050✔
118
   m_op = key.create_decryption_op(rng, padding, provider);
1,050✔
119
   if(!m_op) {
327✔
120
      throw Invalid_Argument(fmt("Key type {} does not support decryption", key.algo_name()));
×
121
   }
122
}
1,050✔
123

124
PK_Decryptor_EME::~PK_Decryptor_EME() = default;
573✔
125

126
PK_Decryptor_EME::PK_Decryptor_EME(PK_Decryptor_EME&&) noexcept = default;
×
127
PK_Decryptor_EME& PK_Decryptor_EME::operator=(PK_Decryptor_EME&&) noexcept = default;
×
128

129
size_t PK_Decryptor_EME::plaintext_length(size_t ctext_len) const {
203✔
130
   return m_op->plaintext_length(ctext_len);
203✔
131
}
132

133
secure_vector<uint8_t> PK_Decryptor_EME::do_decrypt(uint8_t& valid_mask, const uint8_t in[], size_t in_len) const {
5,451✔
134
   return m_op->decrypt(valid_mask, {in, in_len});
5,451✔
135
}
136

137
PK_KEM_Encryptor::PK_KEM_Encryptor(const Public_Key& key, std::string_view param, std::string_view provider) {
862✔
138
   m_op = key.create_kem_encryption_op(param, provider);
862✔
139
   if(!m_op) {
862✔
140
      throw Invalid_Argument(fmt("Key type {} does not support KEM encryption", key.algo_name()));
×
141
   }
142
}
862✔
143

144
PK_KEM_Encryptor::~PK_KEM_Encryptor() = default;
862✔
145

146
PK_KEM_Encryptor::PK_KEM_Encryptor(PK_KEM_Encryptor&&) noexcept = default;
×
147
PK_KEM_Encryptor& PK_KEM_Encryptor::operator=(PK_KEM_Encryptor&&) noexcept = default;
×
148

149
size_t PK_KEM_Encryptor::shared_key_length(size_t desired_shared_key_len) const {
6,874✔
150
   return m_op->shared_key_length(desired_shared_key_len);
6,874✔
151
}
152

153
size_t PK_KEM_Encryptor::encapsulated_key_length() const {
6,874✔
154
   return m_op->encapsulated_key_length();
6,874✔
155
}
156

157
void PK_KEM_Encryptor::encrypt(std::span<uint8_t> out_encapsulated_key,
3,383✔
158
                               std::span<uint8_t> out_shared_key,
159
                               RandomNumberGenerator& rng,
160
                               size_t desired_shared_key_len,
161
                               std::span<const uint8_t> salt) {
162
   BOTAN_ARG_CHECK(out_encapsulated_key.size() == encapsulated_key_length(), "not enough space for encapsulated key");
3,383✔
163
   BOTAN_ARG_CHECK(out_shared_key.size() == shared_key_length(desired_shared_key_len),
3,383✔
164
                   "not enough space for shared key");
165
   m_op->kem_encrypt(out_encapsulated_key, out_shared_key, rng, desired_shared_key_len, salt);
3,383✔
166
}
3,380✔
167

168
size_t PK_KEM_Decryptor::shared_key_length(size_t desired_shared_key_len) const {
7,020✔
169
   return m_op->shared_key_length(desired_shared_key_len);
7,020✔
170
}
171

172
size_t PK_KEM_Decryptor::encapsulated_key_length() const {
132✔
173
   return m_op->encapsulated_key_length();
132✔
174
}
175

176
PK_KEM_Decryptor::PK_KEM_Decryptor(const Private_Key& key,
804✔
177
                                   RandomNumberGenerator& rng,
178
                                   std::string_view param,
179
                                   std::string_view provider) {
804✔
180
   m_op = key.create_kem_decryption_op(rng, param, provider);
804✔
181
   if(!m_op) {
804✔
182
      throw Invalid_Argument(fmt("Key type {} does not support KEM decryption", key.algo_name()));
×
183
   }
184
}
804✔
185

186
PK_KEM_Decryptor::~PK_KEM_Decryptor() = default;
804✔
187

188
PK_KEM_Decryptor::PK_KEM_Decryptor(PK_KEM_Decryptor&&) noexcept = default;
×
189
PK_KEM_Decryptor& PK_KEM_Decryptor::operator=(PK_KEM_Decryptor&&) noexcept = default;
×
190

191
void PK_KEM_Decryptor::decrypt(std::span<uint8_t> out_shared_key,
3,454✔
192
                               std::span<const uint8_t> encap_key,
193
                               size_t desired_shared_key_len,
194
                               std::span<const uint8_t> salt) {
195
   BOTAN_ARG_CHECK(out_shared_key.size() == shared_key_length(desired_shared_key_len),
3,454✔
196
                   "inconsistent size of shared key output buffer");
197
   m_op->kem_decrypt(out_shared_key, encap_key, desired_shared_key_len, salt);
3,454✔
198
}
3,431✔
199

200
PK_Key_Agreement::PK_Key_Agreement(const Private_Key& key,
11,179✔
201
                                   RandomNumberGenerator& rng,
202
                                   std::string_view kdf,
203
                                   std::string_view provider) {
11,179✔
204
   m_op = key.create_key_agreement_op(rng, kdf, provider);
11,179✔
205
   if(!m_op) {
8,827✔
206
      throw Invalid_Argument(fmt("Key type {} does not support key agreement", key.algo_name()));
×
207
   }
208
}
11,179✔
209

210
PK_Key_Agreement::~PK_Key_Agreement() = default;
8,827✔
211

212
PK_Key_Agreement::PK_Key_Agreement(PK_Key_Agreement&&) noexcept = default;
×
213
PK_Key_Agreement& PK_Key_Agreement::operator=(PK_Key_Agreement&&) noexcept = default;
×
214

215
size_t PK_Key_Agreement::agreed_value_size() const {
872✔
216
   return m_op->agreed_value_size();
872✔
217
}
218

219
SymmetricKey PK_Key_Agreement::derive_key(size_t key_len,
185✔
220
                                          const uint8_t peer_key[],
221
                                          size_t peer_key_len,
222
                                          std::string_view salt) const {
223
   return this->derive_key(key_len, peer_key, peer_key_len, cast_char_ptr_to_uint8(salt.data()), salt.length());
185✔
224
}
225

226
SymmetricKey PK_Key_Agreement::derive_key(size_t key_len,
10,208✔
227
                                          const std::span<const uint8_t> peer_key,
228
                                          std::string_view salt) const {
229
   return this->derive_key(
10,208✔
230
      key_len, peer_key.data(), peer_key.size(), cast_char_ptr_to_uint8(salt.data()), salt.length());
10,208✔
231
}
232

233
SymmetricKey PK_Key_Agreement::derive_key(
10,409✔
234
   size_t key_len, const uint8_t peer_key[], size_t peer_key_len, const uint8_t salt[], size_t salt_len) const {
235
   return SymmetricKey(m_op->agree(key_len, {peer_key, peer_key_len}, {salt, salt_len}));
10,409✔
236
}
237

238
namespace {
239

240
void check_der_format_supported(Signature_Format format, size_t parts) {
34,731✔
241
   if(format != Signature_Format::Standard && parts == 1) {
34,731✔
242
      throw Invalid_Argument("This algorithm does not support DER encoding");
×
243
   }
244
}
34,731✔
245

246
}  // namespace
247

248
PK_Signer::PK_Signer(const Private_Key& key,
8,312✔
249
                     RandomNumberGenerator& rng,
250
                     std::string_view emsa,
251
                     Signature_Format format,
252
                     std::string_view provider) {
8,312✔
253
   m_op = key.create_signature_op(rng, emsa, provider);
8,312✔
254
   if(!m_op) {
4,563✔
255
      throw Invalid_Argument(fmt("Key type {} does not support signature generation", key.algo_name()));
×
256
   }
257
   m_sig_format = format;
4,563✔
258
   m_parts = key.message_parts();
4,563✔
259
   m_part_size = key.message_part_size();
4,563✔
260
   check_der_format_supported(format, m_parts);
4,563✔
261
}
8,312✔
262

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

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

271
PK_Signer::~PK_Signer() = default;
4,563✔
272

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

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

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

284
namespace {
285

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

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

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

303
}  // namespace
304

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

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

320
   if(m_sig_format == Signature_Format::Standard) {
7,632✔
321
      return sig;
7,230✔
322
   } else if(m_sig_format == Signature_Format::DerSequence) {
402✔
323
      return der_encode_signature(sig, m_parts, m_part_size);
402✔
324
   } else {
325
      throw Internal_Error("PK_Signer: Invalid signature format enum");
×
326
   }
327
}
7,632✔
328

329
PK_Verifier::PK_Verifier(const Public_Key& key,
63,407✔
330
                         std::string_view emsa,
331
                         Signature_Format format,
332
                         std::string_view provider) {
63,407✔
333
   m_op = key.create_verification_op(emsa, provider);
63,407✔
334
   if(!m_op) {
14,064✔
335
      throw Invalid_Argument(fmt("Key type {} does not support signature verification", key.algo_name()));
×
336
   }
337
   m_sig_format = format;
14,064✔
338
   m_parts = key.message_parts();
14,064✔
339
   m_part_size = key.message_part_size();
14,064✔
340
   check_der_format_supported(format, m_parts);
14,064✔
341
}
63,407✔
342

343
PK_Verifier::PK_Verifier(const Public_Key& key,
16,149✔
344
                         const AlgorithmIdentifier& signature_algorithm,
345
                         std::string_view provider) {
16,149✔
346
   m_op = key.create_x509_verification_op(signature_algorithm, provider);
16,149✔
347

348
   if(!m_op) {
16,104✔
349
      throw Invalid_Argument(fmt("Key type {} does not support X.509 signature verification", key.algo_name()));
×
350
   }
351

352
   m_sig_format = key.default_x509_signature_format();
16,104✔
353
   m_parts = key.message_parts();
16,104✔
354
   m_part_size = key.message_part_size();
16,104✔
355
   check_der_format_supported(m_sig_format, m_parts);
16,104✔
356
}
16,149✔
357

358
PK_Verifier::~PK_Verifier() = default;
30,168✔
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,752✔
364
   return m_op->hash_function();
15,752✔
365
}
366

367
void PK_Verifier::set_input_format(Signature_Format format) {
×
368
   check_der_format_supported(format, m_parts);
×
369
   m_sig_format = format;
×
370
}
×
371

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

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

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

385
namespace {
386

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

392
   BOTAN_ASSERT_NOMSG(sig_parts != 0 && sig_part_size != 0);
10,466✔
393

394
   size_t count = 0;
395

396
   while(ber_sig.more_items()) {
28,954✔
397
      BigInt sig_part;
20,306✔
398
      ber_sig.decode(sig_part);
20,306✔
399
      real_sig += sig_part.serialize(sig_part_size);
20,306✔
400
      ++count;
18,488✔
401
   }
20,306✔
402

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

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

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

415
}  // namespace
416

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

425
         try {
10,794✔
426
            real_sig = decode_der_signature(sig, length, m_parts, m_part_size);
18,637✔
427
            decoding_success = true;
7,843✔
428
         } catch(Decoding_Error&) {}
2,951✔
429

430
         bool accept = m_op->is_valid_signature(real_sig);
10,794✔
431

432
         return accept && decoding_success;
10,571✔
433
      } else {
10,794✔
434
         throw Internal_Error("PK_Verifier: Invalid signature format enum");
×
435
      }
436
   } catch(Invalid_Argument&) {
326✔
437
      return false;
223✔
438
   } catch(Decoding_Error&) {
326✔
439
      return false;
103✔
440
   } catch(Encoding_Error&) {
103✔
441
      return false;
×
442
   }
×
443
}
444

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