Coverage Report

Created: 2025-11-24 06:12

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/Botan-3.4.0/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/rng.h>
15
#include <botan/internal/ct_utils.h>
16
#include <botan/internal/fmt.h>
17
#include <botan/internal/parsing.h>
18
#include <botan/internal/pss_params.h>
19
20
namespace Botan {
21
22
0
secure_vector<uint8_t> PK_Decryptor::decrypt(const uint8_t in[], size_t length) const {
23
0
   uint8_t valid_mask = 0;
24
25
0
   secure_vector<uint8_t> decoded = do_decrypt(valid_mask, in, length);
26
27
0
   if(valid_mask == 0) {
28
0
      throw Decoding_Error("Invalid public key ciphertext, cannot decrypt");
29
0
   }
30
31
0
   return decoded;
32
0
}
33
34
secure_vector<uint8_t> PK_Decryptor::decrypt_or_random(const uint8_t in[],
35
                                                       size_t length,
36
                                                       size_t expected_pt_len,
37
                                                       RandomNumberGenerator& rng,
38
                                                       const uint8_t required_content_bytes[],
39
                                                       const uint8_t required_content_offsets[],
40
0
                                                       size_t required_contents_length) const {
41
0
   const secure_vector<uint8_t> fake_pms = rng.random_vec(expected_pt_len);
42
43
0
   uint8_t decrypt_valid = 0;
44
0
   secure_vector<uint8_t> decoded = do_decrypt(decrypt_valid, in, length);
45
46
0
   auto valid_mask = CT::Mask<uint8_t>::is_equal(decrypt_valid, 0xFF);
47
0
   valid_mask &= CT::Mask<uint8_t>(CT::Mask<size_t>::is_zero(decoded.size() ^ expected_pt_len));
48
49
0
   decoded.resize(expected_pt_len);
50
51
0
   for(size_t i = 0; i != required_contents_length; ++i) {
52
      /*
53
      These values are chosen by the application and for TLS are constants,
54
      so this early failure via assert is fine since we know 0,1 < 48
55
56
      If there is a protocol that has content checks on the key where
57
      the expected offsets are controllable by the attacker this could
58
      still leak.
59
60
      Alternately could always reduce the offset modulo the length?
61
      */
62
63
0
      const uint8_t exp = required_content_bytes[i];
64
0
      const uint8_t off = required_content_offsets[i];
65
66
0
      BOTAN_ASSERT(off < expected_pt_len, "Offset in range of plaintext");
67
68
0
      auto eq = CT::Mask<uint8_t>::is_equal(decoded[off], exp);
69
70
0
      valid_mask &= eq;
71
0
   }
72
73
   // If valid_mask is false, assign fake pre master instead
74
0
   valid_mask.select_n(decoded.data(), decoded.data(), fake_pms.data(), expected_pt_len);
75
76
0
   return decoded;
77
0
}
78
79
secure_vector<uint8_t> PK_Decryptor::decrypt_or_random(const uint8_t in[],
80
                                                       size_t length,
81
                                                       size_t expected_pt_len,
82
0
                                                       RandomNumberGenerator& rng) const {
83
0
   return decrypt_or_random(in, length, expected_pt_len, rng, nullptr, nullptr, 0);
84
0
}
85
86
PK_Encryptor_EME::PK_Encryptor_EME(const Public_Key& key,
87
                                   RandomNumberGenerator& rng,
88
                                   std::string_view padding,
89
0
                                   std::string_view provider) {
90
0
   m_op = key.create_encryption_op(rng, padding, provider);
91
0
   if(!m_op) {
92
0
      throw Invalid_Argument(fmt("Key type {} does not support encryption", key.algo_name()));
93
0
   }
94
0
}
95
96
0
PK_Encryptor_EME::~PK_Encryptor_EME() = default;
97
98
0
PK_Encryptor_EME::PK_Encryptor_EME(PK_Encryptor_EME&&) noexcept = default;
99
0
PK_Encryptor_EME& PK_Encryptor_EME::operator=(PK_Encryptor_EME&&) noexcept = default;
100
101
0
size_t PK_Encryptor_EME::ciphertext_length(size_t ptext_len) const {
102
0
   return m_op->ciphertext_length(ptext_len);
103
0
}
104
105
0
std::vector<uint8_t> PK_Encryptor_EME::enc(const uint8_t in[], size_t length, RandomNumberGenerator& rng) const {
106
0
   return unlock(m_op->encrypt(in, length, rng));
107
0
}
108
109
0
size_t PK_Encryptor_EME::maximum_input_size() const {
110
0
   return m_op->max_input_bits() / 8;
111
0
}
112
113
PK_Decryptor_EME::PK_Decryptor_EME(const Private_Key& key,
114
                                   RandomNumberGenerator& rng,
115
                                   std::string_view padding,
116
0
                                   std::string_view provider) {
117
0
   m_op = key.create_decryption_op(rng, padding, provider);
118
0
   if(!m_op) {
119
0
      throw Invalid_Argument(fmt("Key type {} does not support decryption", key.algo_name()));
120
0
   }
121
0
}
122
123
0
PK_Decryptor_EME::~PK_Decryptor_EME() = default;
124
125
0
PK_Decryptor_EME::PK_Decryptor_EME(PK_Decryptor_EME&&) noexcept = default;
126
0
PK_Decryptor_EME& PK_Decryptor_EME::operator=(PK_Decryptor_EME&&) noexcept = default;
127
128
0
size_t PK_Decryptor_EME::plaintext_length(size_t ctext_len) const {
129
0
   return m_op->plaintext_length(ctext_len);
130
0
}
131
132
0
secure_vector<uint8_t> PK_Decryptor_EME::do_decrypt(uint8_t& valid_mask, const uint8_t in[], size_t in_len) const {
133
0
   return m_op->decrypt(valid_mask, in, in_len);
134
0
}
135
136
0
PK_KEM_Encryptor::PK_KEM_Encryptor(const Public_Key& key, std::string_view param, std::string_view provider) {
137
0
   m_op = key.create_kem_encryption_op(param, provider);
138
0
   if(!m_op) {
139
0
      throw Invalid_Argument(fmt("Key type {} does not support KEM encryption", key.algo_name()));
140
0
   }
141
0
}
142
143
0
PK_KEM_Encryptor::~PK_KEM_Encryptor() = default;
144
145
0
PK_KEM_Encryptor::PK_KEM_Encryptor(PK_KEM_Encryptor&&) noexcept = default;
146
0
PK_KEM_Encryptor& PK_KEM_Encryptor::operator=(PK_KEM_Encryptor&&) noexcept = default;
147
148
0
size_t PK_KEM_Encryptor::shared_key_length(size_t desired_shared_key_len) const {
149
0
   return m_op->shared_key_length(desired_shared_key_len);
150
0
}
151
152
0
size_t PK_KEM_Encryptor::encapsulated_key_length() const {
153
0
   return m_op->encapsulated_key_length();
154
0
}
155
156
void PK_KEM_Encryptor::encrypt(std::span<uint8_t> out_encapsulated_key,
157
                               std::span<uint8_t> out_shared_key,
158
                               RandomNumberGenerator& rng,
159
                               size_t desired_shared_key_len,
160
0
                               std::span<const uint8_t> salt) {
161
0
   BOTAN_ARG_CHECK(out_encapsulated_key.size() == encapsulated_key_length(), "not enough space for encapsulated key");
162
0
   BOTAN_ARG_CHECK(out_shared_key.size() == shared_key_length(desired_shared_key_len),
163
0
                   "not enough space for shared key");
164
0
   m_op->kem_encrypt(out_encapsulated_key, out_shared_key, rng, desired_shared_key_len, salt);
165
0
}
166
167
0
size_t PK_KEM_Decryptor::shared_key_length(size_t desired_shared_key_len) const {
168
0
   return m_op->shared_key_length(desired_shared_key_len);
169
0
}
170
171
0
size_t PK_KEM_Decryptor::encapsulated_key_length() const {
172
0
   return m_op->encapsulated_key_length();
173
0
}
174
175
PK_KEM_Decryptor::PK_KEM_Decryptor(const Private_Key& key,
176
                                   RandomNumberGenerator& rng,
177
                                   std::string_view param,
178
0
                                   std::string_view provider) {
179
0
   m_op = key.create_kem_decryption_op(rng, param, provider);
180
0
   if(!m_op) {
181
0
      throw Invalid_Argument(fmt("Key type {} does not support KEM decryption", key.algo_name()));
182
0
   }
183
0
}
184
185
0
PK_KEM_Decryptor::~PK_KEM_Decryptor() = default;
186
187
0
PK_KEM_Decryptor::PK_KEM_Decryptor(PK_KEM_Decryptor&&) noexcept = default;
188
0
PK_KEM_Decryptor& PK_KEM_Decryptor::operator=(PK_KEM_Decryptor&&) noexcept = default;
189
190
void PK_KEM_Decryptor::decrypt(std::span<uint8_t> out_shared_key,
191
                               std::span<const uint8_t> encap_key,
192
                               size_t desired_shared_key_len,
193
0
                               std::span<const uint8_t> salt) {
194
0
   BOTAN_ARG_CHECK(out_shared_key.size() == shared_key_length(desired_shared_key_len),
195
0
                   "inconsistent size of shared key output buffer");
196
0
   m_op->kem_decrypt(out_shared_key, encap_key, desired_shared_key_len, salt);
197
0
}
198
199
PK_Key_Agreement::PK_Key_Agreement(const Private_Key& key,
200
                                   RandomNumberGenerator& rng,
201
                                   std::string_view kdf,
202
0
                                   std::string_view provider) {
203
0
   m_op = key.create_key_agreement_op(rng, kdf, provider);
204
0
   if(!m_op) {
205
0
      throw Invalid_Argument(fmt("Key type {} does not support key agreement", key.algo_name()));
206
0
   }
207
0
}
208
209
0
PK_Key_Agreement::~PK_Key_Agreement() = default;
210
211
0
PK_Key_Agreement::PK_Key_Agreement(PK_Key_Agreement&&) noexcept = default;
212
0
PK_Key_Agreement& PK_Key_Agreement::operator=(PK_Key_Agreement&&) noexcept = default;
213
214
0
size_t PK_Key_Agreement::agreed_value_size() const {
215
0
   return m_op->agreed_value_size();
216
0
}
217
218
SymmetricKey PK_Key_Agreement::derive_key(size_t key_len,
219
                                          const uint8_t in[],
220
                                          size_t in_len,
221
0
                                          std::string_view params) const {
222
0
   return this->derive_key(key_len, in, in_len, cast_char_ptr_to_uint8(params.data()), params.length());
223
0
}
224
225
SymmetricKey PK_Key_Agreement::derive_key(size_t key_len,
226
                                          const std::span<const uint8_t> in,
227
0
                                          std::string_view params) const {
228
0
   return this->derive_key(key_len, in.data(), in.size(), cast_char_ptr_to_uint8(params.data()), params.length());
229
0
}
230
231
SymmetricKey PK_Key_Agreement::derive_key(
232
0
   size_t key_len, const uint8_t in[], size_t in_len, const uint8_t salt[], size_t salt_len) const {
233
0
   return SymmetricKey(m_op->agree(key_len, in, in_len, salt, salt_len));
234
0
}
235
236
namespace {
237
238
201k
void check_der_format_supported(Signature_Format format, size_t parts) {
239
201k
   if(format != Signature_Format::Standard && parts == 1) {
240
0
      throw Invalid_Argument("This algorithm does not support DER encoding");
241
0
   }
242
201k
}
243
244
}  // namespace
245
246
PK_Signer::PK_Signer(const Private_Key& key,
247
                     RandomNumberGenerator& rng,
248
                     std::string_view emsa,
249
                     Signature_Format format,
250
0
                     std::string_view provider) {
251
0
   m_op = key.create_signature_op(rng, emsa, provider);
252
0
   if(!m_op) {
253
0
      throw Invalid_Argument(fmt("Key type {} does not support signature generation", key.algo_name()));
254
0
   }
255
0
   m_sig_format = format;
256
0
   m_parts = key.message_parts();
257
0
   m_part_size = key.message_part_size();
258
0
   check_der_format_supported(format, m_parts);
259
0
}
260
261
0
AlgorithmIdentifier PK_Signer::algorithm_identifier() const {
262
0
   return m_op->algorithm_identifier();
263
0
}
264
265
0
std::string PK_Signer::hash_function() const {
266
0
   return m_op->hash_function();
267
0
}
268
269
0
PK_Signer::~PK_Signer() = default;
270
271
0
PK_Signer::PK_Signer(PK_Signer&&) noexcept = default;
272
0
PK_Signer& PK_Signer::operator=(PK_Signer&&) noexcept = default;
273
274
0
void PK_Signer::update(std::string_view in) {
275
0
   this->update(cast_char_ptr_to_uint8(in.data()), in.size());
276
0
}
277
278
0
void PK_Signer::update(const uint8_t in[], size_t length) {
279
0
   m_op->update(in, length);
280
0
}
281
282
namespace {
283
284
0
std::vector<uint8_t> der_encode_signature(const std::vector<uint8_t>& sig, size_t parts, size_t part_size) {
285
0
   if(sig.size() % parts != 0 || sig.size() != parts * part_size) {
286
0
      throw Encoding_Error("Unexpected size for DER signature");
287
0
   }
288
289
0
   std::vector<BigInt> sig_parts(parts);
290
0
   for(size_t i = 0; i != sig_parts.size(); ++i) {
291
0
      sig_parts[i].binary_decode(&sig[part_size * i], part_size);
292
0
   }
293
294
0
   std::vector<uint8_t> output;
295
0
   DER_Encoder(output).start_sequence().encode_list(sig_parts).end_cons();
296
0
   return output;
297
0
}
298
299
}  // namespace
300
301
0
size_t PK_Signer::signature_length() const {
302
0
   if(m_sig_format == Signature_Format::Standard) {
303
0
      return m_op->signature_length();
304
0
   } else if(m_sig_format == Signature_Format::DerSequence) {
305
      // This is a large over-estimate but its easier than computing
306
      // the exact value
307
0
      return m_op->signature_length() + (8 + 4 * m_parts);
308
0
   } else {
309
0
      throw Internal_Error("PK_Signer: Invalid signature format enum");
310
0
   }
311
0
}
312
313
0
std::vector<uint8_t> PK_Signer::signature(RandomNumberGenerator& rng) {
314
0
   std::vector<uint8_t> sig = unlock(m_op->sign(rng));
315
316
0
   if(m_sig_format == Signature_Format::Standard) {
317
0
      return sig;
318
0
   } else if(m_sig_format == Signature_Format::DerSequence) {
319
0
      return der_encode_signature(sig, m_parts, m_part_size);
320
0
   } else {
321
0
      throw Internal_Error("PK_Signer: Invalid signature format enum");
322
0
   }
323
0
}
324
325
PK_Verifier::PK_Verifier(const Public_Key& key,
326
                         std::string_view emsa,
327
                         Signature_Format format,
328
201k
                         std::string_view provider) {
329
201k
   m_op = key.create_verification_op(emsa, provider);
330
201k
   if(!m_op) {
331
0
      throw Invalid_Argument(fmt("Key type {} does not support signature verification", key.algo_name()));
332
0
   }
333
201k
   m_sig_format = format;
334
201k
   m_parts = key.message_parts();
335
201k
   m_part_size = key.message_part_size();
336
201k
   check_der_format_supported(format, m_parts);
337
201k
}
338
339
PK_Verifier::PK_Verifier(const Public_Key& key,
340
                         const AlgorithmIdentifier& signature_algorithm,
341
0
                         std::string_view provider) {
342
0
   m_op = key.create_x509_verification_op(signature_algorithm, provider);
343
344
0
   if(!m_op) {
345
0
      throw Invalid_Argument(fmt("Key type {} does not support X.509 signature verification", key.algo_name()));
346
0
   }
347
348
0
   m_sig_format = key.default_x509_signature_format();
349
0
   m_parts = key.message_parts();
350
0
   m_part_size = key.message_part_size();
351
0
   check_der_format_supported(m_sig_format, m_parts);
352
0
}
353
354
201k
PK_Verifier::~PK_Verifier() = default;
355
356
0
PK_Verifier::PK_Verifier(PK_Verifier&&) noexcept = default;
357
0
PK_Verifier& PK_Verifier::operator=(PK_Verifier&&) noexcept = default;
358
359
0
std::string PK_Verifier::hash_function() const {
360
0
   return m_op->hash_function();
361
0
}
362
363
0
void PK_Verifier::set_input_format(Signature_Format format) {
364
0
   check_der_format_supported(format, m_parts);
365
0
   m_sig_format = format;
366
0
}
367
368
6.98k
bool PK_Verifier::verify_message(const uint8_t msg[], size_t msg_length, const uint8_t sig[], size_t sig_length) {
369
6.98k
   update(msg, msg_length);
370
6.98k
   return check_signature(sig, sig_length);
371
6.98k
}
372
373
0
void PK_Verifier::update(std::string_view in) {
374
0
   this->update(cast_char_ptr_to_uint8(in.data()), in.size());
375
0
}
376
377
201k
void PK_Verifier::update(const uint8_t in[], size_t length) {
378
201k
   m_op->update(in, length);
379
201k
}
380
381
namespace {
382
383
0
std::vector<uint8_t> decode_der_signature(const uint8_t sig[], size_t length, size_t sig_parts, size_t sig_part_size) {
384
0
   std::vector<uint8_t> real_sig;
385
0
   BER_Decoder decoder(sig, length);
386
0
   BER_Decoder ber_sig = decoder.start_sequence();
387
388
0
   BOTAN_ASSERT_NOMSG(sig_parts != 0 && sig_part_size != 0);
389
390
0
   size_t count = 0;
391
392
0
   while(ber_sig.more_items()) {
393
0
      BigInt sig_part;
394
0
      ber_sig.decode(sig_part);
395
0
      real_sig += BigInt::encode_1363(sig_part, sig_part_size);
396
0
      ++count;
397
0
   }
398
399
0
   if(count != sig_parts) {
400
0
      throw Decoding_Error("PK_Verifier: signature size invalid");
401
0
   }
402
403
0
   const std::vector<uint8_t> reencoded = der_encode_signature(real_sig, sig_parts, sig_part_size);
404
405
0
   if(reencoded.size() != length || CT::is_equal(reencoded.data(), sig, reencoded.size()).as_bool() == false) {
406
0
      throw Decoding_Error("PK_Verifier: signature is not the canonical DER encoding");
407
0
   }
408
0
   return real_sig;
409
0
}
410
411
}  // namespace
412
413
201k
bool PK_Verifier::check_signature(const uint8_t sig[], size_t length) {
414
201k
   try {
415
201k
      if(m_sig_format == Signature_Format::Standard) {
416
201k
         return m_op->is_valid_signature(sig, length);
417
201k
      } else if(m_sig_format == Signature_Format::DerSequence) {
418
0
         bool decoding_success = false;
419
0
         std::vector<uint8_t> real_sig;
420
421
0
         try {
422
0
            real_sig = decode_der_signature(sig, length, m_parts, m_part_size);
423
0
            decoding_success = true;
424
0
         } catch(Decoding_Error&) {}
425
426
0
         bool accept = m_op->is_valid_signature(real_sig.data(), real_sig.size());
427
428
0
         return accept && decoding_success;
429
0
      } else {
430
0
         throw Internal_Error("PK_Verifier: Invalid signature format enum");
431
0
      }
432
201k
   } catch(Invalid_Argument&) {
433
0
      return false;
434
9.04k
   } catch(Decoding_Error&) {
435
9.04k
      return false;
436
9.04k
   } catch(Encoding_Error&) {
437
0
      return false;
438
0
   }
439
201k
}
440
441
}  // namespace Botan