Coverage Report

Created: 2026-07-25 06:49

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/botan/src/lib/pubkey/pubkey.cpp
Line
Count
Source
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
0
secure_vector<uint8_t> PK_Decryptor::decrypt(const uint8_t in[], size_t length) const {
24
0
   uint8_t valid_mask = 0;
25
26
0
   secure_vector<uint8_t> decoded = do_decrypt(valid_mask, in, length);
27
28
0
   if(valid_mask == 0) {
29
0
      throw Decoding_Error("Invalid public key ciphertext, cannot decrypt");
30
0
   }
31
32
0
   return decoded;
33
0
}
34
35
secure_vector<uint8_t> PK_Decryptor::decrypt_or_random(const uint8_t in[],
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
0
                                                       size_t required_contents_length) const {
42
0
   const secure_vector<uint8_t> fake_pms = [&]() {
43
0
      auto pms = rng.random_vec(expected_pt_len);
44
45
0
      for(size_t i = 0; i != required_contents_length; ++i) {
46
0
         const uint8_t exp = required_content_bytes[i];
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
0
         const uint8_t off = required_content_offsets[i];
55
0
         BOTAN_ASSERT(off < expected_pt_len, "Offset in range of plaintext");
56
0
         pms[off] = exp;
57
0
      }
58
59
0
      return pms;
60
0
   }();
61
62
0
   uint8_t decrypt_valid = 0;
63
0
   secure_vector<uint8_t> decoded = do_decrypt(decrypt_valid, in, length);
64
65
0
   auto valid_mask = CT::Mask<uint8_t>::is_equal(decrypt_valid, 0xFF);
66
0
   valid_mask &= CT::Mask<uint8_t>(CT::Mask<size_t>::is_equal(decoded.size(), expected_pt_len));
67
68
0
   decoded.resize(expected_pt_len);
69
70
0
   for(size_t i = 0; i != required_contents_length; ++i) {
71
0
      const uint8_t exp = required_content_bytes[i];
72
73
      // We know off is in range because we already checked it when creating the fake premaster above
74
0
      const uint8_t off = required_content_offsets[i];
75
76
0
      auto eq = CT::Mask<uint8_t>::is_equal(decoded[off], exp);
77
78
0
      valid_mask &= eq;
79
0
   }
80
81
   // If valid_mask is false, assign fake pre master instead
82
0
   valid_mask.select_n(decoded.data(), decoded.data(), fake_pms.data(), expected_pt_len);
83
84
0
   return decoded;
85
0
}
86
87
secure_vector<uint8_t> PK_Decryptor::decrypt_or_random(const uint8_t in[],
88
                                                       size_t length,
89
                                                       size_t expected_pt_len,
90
0
                                                       RandomNumberGenerator& rng) const {
91
0
   return decrypt_or_random(in, length, expected_pt_len, rng, nullptr, nullptr, 0);
92
0
}
93
94
PK_Encryptor_EME::PK_Encryptor_EME(const Public_Key& key,
95
                                   RandomNumberGenerator& rng,
96
                                   std::string_view padding,
97
0
                                   std::string_view provider) {
98
0
   m_op = key.create_encryption_op(rng, padding, provider);
99
0
   if(!m_op) {
100
0
      throw Invalid_Argument(fmt("Key type {} does not support encryption", key.algo_name()));
101
0
   }
102
0
}
103
104
0
PK_Encryptor_EME::~PK_Encryptor_EME() = default;
105
106
0
PK_Encryptor_EME::PK_Encryptor_EME(PK_Encryptor_EME&&) noexcept = default;
107
0
PK_Encryptor_EME& PK_Encryptor_EME::operator=(PK_Encryptor_EME&&) noexcept = default;
108
109
0
size_t PK_Encryptor_EME::ciphertext_length(size_t ptext_len) const {
110
0
   return m_op->ciphertext_length(ptext_len);
111
0
}
112
113
0
std::vector<uint8_t> PK_Encryptor_EME::enc(const uint8_t in[], size_t length, RandomNumberGenerator& rng) const {
114
0
   return m_op->encrypt(std::span{in, length}, rng);
115
0
}
116
117
0
size_t PK_Encryptor_EME::maximum_input_size() const {
118
0
   return m_op->max_input_bits() / 8;
119
0
}
120
121
PK_Decryptor_EME::PK_Decryptor_EME(const Private_Key& key,
122
                                   RandomNumberGenerator& rng,
123
                                   std::string_view padding,
124
0
                                   std::string_view provider) {
125
0
   m_op = key.create_decryption_op(rng, padding, provider);
126
0
   if(!m_op) {
127
0
      throw Invalid_Argument(fmt("Key type {} does not support decryption", key.algo_name()));
128
0
   }
129
0
}
130
131
0
PK_Decryptor_EME::~PK_Decryptor_EME() = default;
132
133
0
PK_Decryptor_EME::PK_Decryptor_EME(PK_Decryptor_EME&&) noexcept = default;
134
0
PK_Decryptor_EME& PK_Decryptor_EME::operator=(PK_Decryptor_EME&&) noexcept = default;
135
136
0
size_t PK_Decryptor_EME::plaintext_length(size_t ctext_len) const {
137
0
   return m_op->plaintext_length(ctext_len);
138
0
}
139
140
0
secure_vector<uint8_t> PK_Decryptor_EME::do_decrypt(uint8_t& valid_mask, const uint8_t in[], size_t in_len) const {
141
0
   return m_op->decrypt(valid_mask, {in, in_len});
142
0
}
143
144
0
PK_KEM_Encryptor::PK_KEM_Encryptor(const Public_Key& key, std::string_view param, std::string_view provider) {
145
0
   m_op = key.create_kem_encryption_op(param, provider);
146
0
   if(!m_op) {
147
0
      throw Invalid_Argument(fmt("Key type {} does not support KEM encryption", key.algo_name()));
148
0
   }
149
0
}
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
0
      PK_KEM_Encryptor(key, kem_param, provider) {
156
0
   BOTAN_UNUSED(rng);
157
0
}
158
159
0
PK_KEM_Encryptor::~PK_KEM_Encryptor() = default;
160
161
0
PK_KEM_Encryptor::PK_KEM_Encryptor(PK_KEM_Encryptor&&) noexcept = default;
162
0
PK_KEM_Encryptor& PK_KEM_Encryptor::operator=(PK_KEM_Encryptor&&) noexcept = default;
163
164
0
size_t PK_KEM_Encryptor::shared_key_length(size_t desired_shared_key_len) const {
165
0
   return m_op->shared_key_length(desired_shared_key_len);
166
0
}
167
168
0
size_t PK_KEM_Encryptor::encapsulated_key_length() const {
169
0
   return m_op->encapsulated_key_length();
170
0
}
171
172
void PK_KEM_Encryptor::encrypt(std::span<uint8_t> out_encapsulated_key,
173
                               std::span<uint8_t> out_shared_key,
174
                               RandomNumberGenerator& rng,
175
                               size_t desired_shared_key_len,
176
0
                               std::span<const uint8_t> salt) {
177
0
   BOTAN_ARG_CHECK(out_encapsulated_key.size() == encapsulated_key_length(), "not enough space for encapsulated key");
178
0
   BOTAN_ARG_CHECK(out_shared_key.size() == shared_key_length(desired_shared_key_len),
179
0
                   "not enough space for shared key");
180
0
   m_op->kem_encrypt(out_encapsulated_key, out_shared_key, rng, desired_shared_key_len, salt);
181
0
}
182
183
0
size_t PK_KEM_Decryptor::shared_key_length(size_t desired_shared_key_len) const {
184
0
   return m_op->shared_key_length(desired_shared_key_len);
185
0
}
186
187
0
size_t PK_KEM_Decryptor::encapsulated_key_length() const {
188
0
   return m_op->encapsulated_key_length();
189
0
}
190
191
PK_KEM_Decryptor::PK_KEM_Decryptor(const Private_Key& key,
192
                                   RandomNumberGenerator& rng,
193
                                   std::string_view param,
194
0
                                   std::string_view provider) {
195
0
   m_op = key.create_kem_decryption_op(rng, param, provider);
196
0
   if(!m_op) {
197
0
      throw Invalid_Argument(fmt("Key type {} does not support KEM decryption", key.algo_name()));
198
0
   }
199
0
}
200
201
0
PK_KEM_Decryptor::~PK_KEM_Decryptor() = default;
202
203
0
PK_KEM_Decryptor::PK_KEM_Decryptor(PK_KEM_Decryptor&&) noexcept = default;
204
0
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,
207
                               std::span<const uint8_t> encap_key,
208
                               size_t desired_shared_key_len,
209
0
                               std::span<const uint8_t> salt) {
210
0
   BOTAN_ARG_CHECK(out_shared_key.size() == shared_key_length(desired_shared_key_len),
211
0
                   "inconsistent size of shared key output buffer");
212
0
   m_op->kem_decrypt(out_shared_key, encap_key, desired_shared_key_len, salt);
213
0
}
214
215
PK_Key_Agreement::PK_Key_Agreement(const Private_Key& key,
216
                                   RandomNumberGenerator& rng,
217
                                   std::string_view kdf,
218
0
                                   std::string_view provider) {
219
0
   m_op = key.create_key_agreement_op(rng, kdf, provider);
220
0
   if(!m_op) {
221
0
      throw Invalid_Argument(fmt("Key type {} does not support key agreement", key.algo_name()));
222
0
   }
223
0
}
224
225
0
PK_Key_Agreement::~PK_Key_Agreement() = default;
226
227
0
PK_Key_Agreement::PK_Key_Agreement(PK_Key_Agreement&&) noexcept = default;
228
0
PK_Key_Agreement& PK_Key_Agreement::operator=(PK_Key_Agreement&&) noexcept = default;
229
230
0
size_t PK_Key_Agreement::agreed_value_size() const {
231
0
   return m_op->agreed_value_size();
232
0
}
233
234
SymmetricKey PK_Key_Agreement::derive_key(size_t key_len,
235
                                          const uint8_t peer_key[],
236
                                          size_t peer_key_len,
237
0
                                          std::string_view salt) const {
238
0
   return this->derive_key(key_len, peer_key, peer_key_len, cast_char_ptr_to_uint8(salt.data()), salt.length());
239
0
}
240
241
SymmetricKey PK_Key_Agreement::derive_key(size_t key_len,
242
                                          const std::span<const uint8_t> peer_key,
243
0
                                          std::string_view salt) const {
244
0
   return this->derive_key(
245
0
      key_len, peer_key.data(), peer_key.size(), cast_char_ptr_to_uint8(salt.data()), salt.length());
246
0
}
247
248
SymmetricKey PK_Key_Agreement::derive_key(
249
0
   size_t key_len, const uint8_t peer_key[], size_t peer_key_len, const uint8_t salt[], size_t salt_len) const {
250
0
   return SymmetricKey(m_op->agree(key_len, {peer_key, peer_key_len}, {salt, salt_len}));
251
0
}
252
253
PK_Signer::PK_Signer(const Private_Key& key,
254
                     RandomNumberGenerator& rng,
255
                     std::string_view emsa,
256
                     Signature_Format format,
257
                     std::string_view provider) :
258
469
      m_sig_format(format), m_sig_element_size(key._signature_element_size_for_DER_encoding()) {
259
469
   if(m_sig_format == Signature_Format::DerSequence) {
260
469
      BOTAN_ARG_CHECK(m_sig_element_size.has_value(), "This key does not support DER signatures");
261
469
   }
262
263
469
   m_op = key.create_signature_op(rng, emsa, provider);
264
469
   if(!m_op) {
265
0
      throw Invalid_Argument(fmt("Key type {} does not support signature generation", key.algo_name()));
266
0
   }
267
469
}
268
269
0
AlgorithmIdentifier PK_Signer::algorithm_identifier() const {
270
0
   return m_op->algorithm_identifier();
271
0
}
272
273
0
std::string PK_Signer::hash_function() const {
274
0
   return m_op->hash_function();
275
0
}
276
277
469
PK_Signer::~PK_Signer() = default;
278
279
0
PK_Signer::PK_Signer(PK_Signer&&) noexcept = default;
280
0
PK_Signer& PK_Signer::operator=(PK_Signer&&) noexcept = default;
281
282
0
void PK_Signer::update(std::string_view in) {
283
0
   this->update(cast_char_ptr_to_uint8(in.data()), in.size());
284
0
}
285
286
469
void PK_Signer::update(const uint8_t in[], size_t length) {
287
469
   m_op->update({in, length});
288
469
}
289
290
namespace {
291
292
469
std::vector<uint8_t> der_encode_signature(std::span<const uint8_t> sig, size_t parts, size_t part_size) {
293
469
   if(sig.size() % parts != 0 || sig.size() != parts * part_size) {
294
0
      throw Encoding_Error("Unexpected size for DER signature");
295
0
   }
296
297
469
   BufferSlicer bs_sig(sig);
298
469
   std::vector<BigInt> sig_parts;
299
469
   sig_parts.reserve(parts);
300
1.40k
   for(size_t i = 0; i != parts; ++i) {
301
938
      sig_parts.emplace_back(BigInt::from_bytes(bs_sig.take(part_size)));
302
938
   }
303
304
469
   std::vector<uint8_t> output;
305
469
   DER_Encoder(output).start_sequence().encode_list(sig_parts).end_cons();
306
469
   return output;
307
469
}
308
309
}  // namespace
310
311
0
size_t PK_Signer::signature_length() const {
312
0
   if(m_sig_format == Signature_Format::Standard) {
313
0
      return m_op->signature_length();
314
0
   } else if(m_sig_format == Signature_Format::DerSequence) {
315
0
      size_t sig_len = m_op->signature_length();
316
317
0
      size_t der_overhead = [sig_len]() {
318
         /*
319
         This was computed by DER encoding of some maximal value signatures
320
         (since DER is variable length)
321
322
         The first two cases covers all EC schemes since groups are at most 521
323
         bits.
324
325
         The other cases are only for finite field DSA which practically is only
326
         used up to 3072 bit groups but the calculation is correct up to a
327
         262096 (!) bit group so allow it. There are some intermediate sizes but
328
         this function is allowed to (and indeed must) return an over-estimate
329
         rather than an exact value since the actual length will change based on
330
         the computed signature.
331
         */
332
333
0
         if(sig_len <= 120) {
334
            // EC signatures <= 480 bits
335
0
            return 8;
336
0
         } else if(sig_len <= 248) {
337
            // EC signatures > 480 bits (or very small DSA groups...)
338
0
            return 9;
339
0
         } else {
340
            // Everything else. This is an over-estimate for groups under
341
            // 2040 bits but exact otherwise
342
343
            // This requires 15 bytes DER overhead and should never happen
344
0
            BOTAN_ASSERT_NOMSG(sig_len < 65524);
345
0
            return 14;
346
0
         }
347
0
      }();
348
349
0
      return sig_len + der_overhead;
350
0
   } else {
351
0
      throw Internal_Error("PK_Signer: Invalid signature format enum");
352
0
   }
353
0
}
354
355
469
std::vector<uint8_t> PK_Signer::signature(RandomNumberGenerator& rng) {
356
469
   std::vector<uint8_t> sig = m_op->sign(rng);
357
358
469
   if(m_sig_format == Signature_Format::Standard) {
359
0
      return sig;
360
469
   } else if(m_sig_format == Signature_Format::DerSequence) {
361
469
      BOTAN_ASSERT_NOMSG(m_sig_element_size.has_value());
362
469
      return der_encode_signature(sig, 2, m_sig_element_size.value());
363
469
   } else {
364
0
      throw Internal_Error("PK_Signer: Invalid signature format enum");
365
0
   }
366
469
}
367
368
PK_Verifier::PK_Verifier(const Public_Key& key,
369
                         std::string_view emsa,
370
                         Signature_Format format,
371
796
                         std::string_view provider) {
372
796
   m_op = key.create_verification_op(emsa, provider);
373
796
   if(!m_op) {
374
0
      throw Invalid_Argument(fmt("Key type {} does not support signature verification", key.algo_name()));
375
0
   }
376
377
796
   m_sig_format = format;
378
796
   m_sig_element_size = key._signature_element_size_for_DER_encoding();
379
380
796
   if(m_sig_format == Signature_Format::DerSequence) {
381
0
      BOTAN_ARG_CHECK(m_sig_element_size.has_value(), "This key does not support DER signatures");
382
0
   }
383
796
}
384
385
PK_Verifier::PK_Verifier(const Public_Key& key,
386
                         const AlgorithmIdentifier& signature_algorithm,
387
0
                         std::string_view provider) {
388
0
   m_op = key.create_x509_verification_op(signature_algorithm, provider);
389
0
   if(!m_op) {
390
0
      throw Invalid_Argument(fmt("Key type {} does not support X.509 signature verification", key.algo_name()));
391
0
   }
392
393
0
   m_sig_format = key._default_x509_signature_format();
394
0
   m_sig_element_size = key._signature_element_size_for_DER_encoding();
395
0
}
396
397
796
PK_Verifier::~PK_Verifier() = default;
398
399
0
PK_Verifier::PK_Verifier(PK_Verifier&&) noexcept = default;
400
0
PK_Verifier& PK_Verifier::operator=(PK_Verifier&&) noexcept = default;
401
402
0
std::string PK_Verifier::hash_function() const {
403
0
   return m_op->hash_function();
404
0
}
405
406
0
void PK_Verifier::set_input_format(Signature_Format format) {
407
0
   if(format == Signature_Format::DerSequence) {
408
0
      BOTAN_ARG_CHECK(m_sig_element_size.has_value(), "This key does not support DER signatures");
409
0
   }
410
0
   m_sig_format = format;
411
0
}
412
413
796
bool PK_Verifier::verify_message(const uint8_t msg[], size_t msg_length, const uint8_t sig[], size_t sig_length) {
414
796
   update(msg, msg_length);
415
796
   return check_signature(sig, sig_length);
416
796
}
417
418
0
void PK_Verifier::update(std::string_view in) {
419
0
   this->update(cast_char_ptr_to_uint8(in.data()), in.size());
420
0
}
421
422
796
void PK_Verifier::update(const uint8_t in[], size_t length) {
423
796
   m_op->update({in, length});
424
796
}
425
426
namespace {
427
428
0
std::vector<uint8_t> decode_der_signature(const uint8_t sig[], size_t length, size_t sig_parts, size_t sig_part_size) {
429
0
   std::vector<uint8_t> real_sig;
430
0
   BER_Decoder decoder(sig, length);
431
0
   BER_Decoder ber_sig = decoder.start_sequence();
432
433
0
   BOTAN_ASSERT_NOMSG(sig_parts != 0 && sig_part_size != 0);
434
435
0
   size_t count = 0;
436
437
0
   while(ber_sig.more_items()) {
438
0
      BigInt sig_part;
439
0
      ber_sig.decode(sig_part);
440
0
      real_sig += sig_part.serialize(sig_part_size);
441
0
      ++count;
442
0
   }
443
444
0
   if(count != sig_parts) {
445
0
      throw Decoding_Error("PK_Verifier: signature size invalid");
446
0
   }
447
448
0
   const std::vector<uint8_t> reencoded = der_encode_signature(real_sig, sig_parts, sig_part_size);
449
450
0
   if(reencoded.size() != length || CT::is_equal(reencoded.data(), sig, reencoded.size()).as_bool() == false) {
451
0
      throw Decoding_Error("PK_Verifier: signature is not the canonical DER encoding");
452
0
   }
453
0
   return real_sig;
454
0
}
455
456
}  // namespace
457
458
796
bool PK_Verifier::check_signature(const uint8_t sig[], size_t length) {
459
796
   try {
460
796
      if(m_sig_format == Signature_Format::Standard) {
461
796
         return m_op->is_valid_signature({sig, length});
462
796
      } else if(m_sig_format == Signature_Format::DerSequence) {
463
0
         bool decoding_success = false;
464
0
         std::vector<uint8_t> real_sig;
465
466
0
         BOTAN_ASSERT_NOMSG(m_sig_element_size.has_value());
467
468
0
         try {
469
0
            real_sig = decode_der_signature(sig, length, 2, m_sig_element_size.value());
470
0
            decoding_success = true;
471
0
         } catch(Decoding_Error&) {}
472
473
0
         bool accept = m_op->is_valid_signature(real_sig);
474
475
0
         return accept && decoding_success;
476
0
      } else {
477
0
         throw Internal_Error("PK_Verifier: Invalid signature format enum");
478
0
      }
479
796
   } catch(Invalid_Argument&) {
480
0
      return false;
481
0
   } catch(Decoding_Error&) {
482
0
      return false;
483
0
   } catch(Encoding_Error&) {
484
0
      return false;
485
0
   }
486
796
}
487
488
}  // namespace Botan