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

randombit / botan / 12993346889

27 Jan 2025 04:15PM UTC coverage: 91.248% (+0.002%) from 91.246%
12993346889

push

github

butteronarchbtw
add (s)afi encoding & decoding

94261 of 103302 relevant lines covered (91.25%)

11708235.22 hits per line

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

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

32
   return decoded;
3,686✔
33
}
3,183✔
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,870✔
150
   return m_op->shared_key_length(desired_shared_key_len);
6,870✔
151
}
152

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

157
void PK_KEM_Encryptor::encrypt(std::span<uint8_t> out_encapsulated_key,
3,381✔
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,381✔
163
   BOTAN_ARG_CHECK(out_shared_key.size() == shared_key_length(desired_shared_key_len),
3,381✔
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,381✔
166
}
3,378✔
167

168
size_t PK_KEM_Decryptor::shared_key_length(size_t desired_shared_key_len) const {
7,016✔
169
   return m_op->shared_key_length(desired_shared_key_len);
7,016✔
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,452✔
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,452✔
196
                   "inconsistent size of shared key output buffer");
197
   m_op->kem_decrypt(out_shared_key, encap_key, desired_shared_key_len, salt);
3,452✔
198
}
3,429✔
199

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

210
PK_Key_Agreement::~PK_Key_Agreement() = default;
8,831✔
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 in[],
221
                                          size_t in_len,
222
                                          std::string_view params) const {
223
   return this->derive_key(key_len, in, in_len, cast_char_ptr_to_uint8(params.data()), params.length());
185✔
224
}
225

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

232
SymmetricKey PK_Key_Agreement::derive_key(
10,411✔
233
   size_t key_len, const uint8_t in[], size_t in_len, const uint8_t salt[], size_t salt_len) const {
234
   return SymmetricKey(m_op->agree(key_len, {in, in_len}, {salt, salt_len}));
10,411✔
235
}
236

237
namespace {
238

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

245
}  // namespace
246

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

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

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

270
PK_Signer::~PK_Signer() = default;
5,883✔
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) {
8,987✔
280
   m_op->update({in, length});
8,987✔
281
}
8,986✔
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,948✔
286
   if(sig.size() % parts != 0 || sig.size() != parts * part_size) {
8,948✔
287
      throw Encoding_Error("Unexpected size for DER signature");
×
288
   }
289

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

297
   std::vector<uint8_t> output;
8,948✔
298
   DER_Encoder(output).start_sequence().encode_list(sig_parts).end_cons();
35,792✔
299
   return output;
8,948✔
300
}
8,948✔
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 * m_parts);
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) {
8,955✔
317
   std::vector<uint8_t> sig = m_op->sign(rng);
8,955✔
318

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

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

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

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

351
   m_sig_format = key.default_x509_signature_format();
16,545✔
352
   m_parts = key.message_parts();
16,545✔
353
   m_part_size = key.message_part_size();
16,545✔
354
   check_der_format_supported(m_sig_format, m_parts);
16,545✔
355
}
16,590✔
356

357
PK_Verifier::~PK_Verifier() = default;
30,609✔
358

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

362
std::string PK_Verifier::hash_function() const {
16,193✔
363
   return m_op->hash_function();
16,193✔
364
}
365

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

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

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

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

384
namespace {
385

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

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

393
   size_t count = 0;
394

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

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

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

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

414
}  // namespace
415

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

424
         try {
10,794✔
425
            real_sig = decode_der_signature(sig, length, m_parts, m_part_size);
18,634✔
426
            decoding_success = true;
7,840✔
427
         } catch(Decoding_Error&) {}
2,954✔
428

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

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

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