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

randombit / botan / 5812729751

09 Aug 2023 06:27PM UTC coverage: 91.702% (-0.03%) from 91.728%
5812729751

push

github

randombit
Merge GH #3655 Allow the pubkey operations wrapper types to move

78544 of 85651 relevant lines covered (91.7%)

12163410.01 hits per line

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

85.65
/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/rng.h>
13
#include <botan/internal/ct_utils.h>
14
#include <botan/internal/fmt.h>
15
#include <botan/internal/parsing.h>
16
#include <botan/internal/pk_ops.h>
17
#include <botan/internal/pss_params.h>
18

19
namespace Botan {
20

21
secure_vector<uint8_t> PK_Decryptor::decrypt(const uint8_t in[], size_t length) const {
5,541✔
22
   uint8_t valid_mask = 0;
5,541✔
23

24
   secure_vector<uint8_t> decoded = do_decrypt(valid_mask, in, length);
5,541✔
25

26
   if(valid_mask == 0) {
5,513✔
27
      throw Decoding_Error("Invalid public key ciphertext, cannot decrypt");
3,185✔
28
   }
29

30
   return decoded;
2,328✔
31
}
3,185✔
32

33
secure_vector<uint8_t> PK_Decryptor::decrypt_or_random(const uint8_t in[],
134✔
34
                                                       size_t length,
35
                                                       size_t expected_pt_len,
36
                                                       RandomNumberGenerator& rng,
37
                                                       const uint8_t required_content_bytes[],
38
                                                       const uint8_t required_content_offsets[],
39
                                                       size_t required_contents_length) const {
40
   const secure_vector<uint8_t> fake_pms = rng.random_vec(expected_pt_len);
134✔
41

42
   uint8_t decrypt_valid = 0;
134✔
43
   secure_vector<uint8_t> decoded = do_decrypt(decrypt_valid, in, length);
134✔
44

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

48
   decoded.resize(expected_pt_len);
134✔
49

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

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

59
      Alternately could always reduce the offset modulo the length?
60
      */
61

62
      const uint8_t exp = required_content_bytes[i];
114✔
63
      const uint8_t off = required_content_offsets[i];
114✔
64

65
      BOTAN_ASSERT(off < expected_pt_len, "Offset in range of plaintext");
114✔
66

67
      auto eq = CT::Mask<uint8_t>::is_equal(decoded[off], exp);
114✔
68

69
      valid_mask &= eq;
114✔
70
   }
71

72
   // If valid_mask is false, assign fake pre master instead
73
   valid_mask.select_n(decoded.data(), decoded.data(), fake_pms.data(), expected_pt_len);
134✔
74

75
   return decoded;
134✔
76
}
134✔
77

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

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

95
PK_Encryptor_EME::~PK_Encryptor_EME() = default;
347✔
96

97
PK_Encryptor_EME::PK_Encryptor_EME(PK_Encryptor_EME&&) noexcept = default;
×
98
PK_Encryptor_EME& PK_Encryptor_EME::operator=(PK_Encryptor_EME&&) noexcept = default;
×
99

100
size_t PK_Encryptor_EME::ciphertext_length(size_t ptext_len) const {
139✔
101
   return m_op->ciphertext_length(ptext_len);
139✔
102
}
103

104
std::vector<uint8_t> PK_Encryptor_EME::enc(const uint8_t in[], size_t length, RandomNumberGenerator& rng) const {
276✔
105
   return unlock(m_op->encrypt(in, length, rng));
552✔
106
}
107

108
size_t PK_Encryptor_EME::maximum_input_size() const {
144✔
109
   return m_op->max_input_bits() / 8;
144✔
110
}
111

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

122
PK_Decryptor_EME::~PK_Decryptor_EME() = default;
437✔
123

124
PK_Decryptor_EME::PK_Decryptor_EME(PK_Decryptor_EME&&) noexcept = default;
×
125
PK_Decryptor_EME& PK_Decryptor_EME::operator=(PK_Decryptor_EME&&) noexcept = default;
×
126

127
size_t PK_Decryptor_EME::plaintext_length(size_t ctext_len) const {
138✔
128
   return m_op->plaintext_length(ctext_len);
138✔
129
}
130

131
secure_vector<uint8_t> PK_Decryptor_EME::do_decrypt(uint8_t& valid_mask, const uint8_t in[], size_t in_len) const {
3,952✔
132
   return m_op->decrypt(valid_mask, in, in_len);
3,952✔
133
}
134

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

142
PK_KEM_Encryptor::~PK_KEM_Encryptor() = default;
720✔
143

144
PK_KEM_Encryptor::PK_KEM_Encryptor(PK_KEM_Encryptor&&) noexcept = default;
×
145
PK_KEM_Encryptor& PK_KEM_Encryptor::operator=(PK_KEM_Encryptor&&) noexcept = default;
×
146

147
size_t PK_KEM_Encryptor::shared_key_length(size_t desired_shared_key_len) const {
6,408✔
148
   return m_op->shared_key_length(desired_shared_key_len);
6,408✔
149
}
150

151
size_t PK_KEM_Encryptor::encapsulated_key_length() const {
6,408✔
152
   return m_op->encapsulated_key_length();
6,408✔
153
}
154

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

166
size_t PK_KEM_Decryptor::shared_key_length(size_t desired_shared_key_len) const {
6,444✔
167
   return m_op->shared_key_length(desired_shared_key_len);
6,444✔
168
}
169

170
size_t PK_KEM_Decryptor::encapsulated_key_length() const {
10✔
171
   return m_op->encapsulated_key_length();
10✔
172
}
173

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

184
PK_KEM_Decryptor::~PK_KEM_Decryptor() = default;
720✔
185

186
PK_KEM_Decryptor::PK_KEM_Decryptor(PK_KEM_Decryptor&&) noexcept = default;
×
187
PK_KEM_Decryptor& PK_KEM_Decryptor::operator=(PK_KEM_Decryptor&&) noexcept = default;
×
188

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

198
PK_Key_Agreement::PK_Key_Agreement(const Private_Key& key,
3,420✔
199
                                   RandomNumberGenerator& rng,
200
                                   std::string_view kdf,
201
                                   std::string_view provider) {
3,420✔
202
   m_op = key.create_key_agreement_op(rng, kdf, provider);
3,420✔
203
   if(!m_op) {
2,616✔
204
      throw Invalid_Argument(fmt("Key type {} does not support key agreement", key.algo_name()));
×
205
   }
206
}
3,420✔
207

208
PK_Key_Agreement::~PK_Key_Agreement() = default;
2,616✔
209

210
PK_Key_Agreement::PK_Key_Agreement(PK_Key_Agreement&&) noexcept = default;
×
211
PK_Key_Agreement& PK_Key_Agreement::operator=(PK_Key_Agreement&&) noexcept = default;
×
212

213
size_t PK_Key_Agreement::agreed_value_size() const {
264✔
214
   return m_op->agreed_value_size();
264✔
215
}
216

217
SymmetricKey PK_Key_Agreement::derive_key(
4,201✔
218
   size_t key_len, const uint8_t in[], size_t in_len, const uint8_t salt[], size_t salt_len) const {
219
   return SymmetricKey(m_op->agree(key_len, in, in_len, salt, salt_len));
4,201✔
220
}
221

222
static void check_der_format_supported(Signature_Format format, size_t parts) {
28,225✔
223
   if(format != Signature_Format::Standard && parts == 1) {
28,225✔
224
      throw Invalid_Argument("This algorithm does not support DER encoding");
×
225
   }
226
}
28,225✔
227

228
PK_Signer::PK_Signer(const Private_Key& key,
7,321✔
229
                     RandomNumberGenerator& rng,
230
                     std::string_view emsa,
231
                     Signature_Format format,
232
                     std::string_view provider) {
7,321✔
233
   m_op = key.create_signature_op(rng, emsa, provider);
7,321✔
234
   if(!m_op) {
3,836✔
235
      throw Invalid_Argument(fmt("Key type {} does not support signature generation", key.algo_name()));
×
236
   }
237
   m_sig_format = format;
3,836✔
238
   m_parts = key.message_parts();
3,836✔
239
   m_part_size = key.message_part_size();
3,836✔
240
   check_der_format_supported(format, m_parts);
3,836✔
241
}
7,321✔
242

243
AlgorithmIdentifier PK_Signer::algorithm_identifier() const {
368✔
244
   return m_op->algorithm_identifier();
368✔
245
}
246

247
std::string PK_Signer::hash_function() const {
561✔
248
   return m_op->hash_function();
561✔
249
}
250

251
PK_Signer::~PK_Signer() = default;
3,836✔
252

253
PK_Signer::PK_Signer(PK_Signer&&) noexcept = default;
×
254
PK_Signer& PK_Signer::operator=(PK_Signer&&) noexcept = default;
×
255

256
void PK_Signer::update(const uint8_t in[], size_t length) {
4,565✔
257
   m_op->update(in, length);
4,565✔
258
}
4,564✔
259

260
namespace {
261

262
std::vector<uint8_t> der_encode_signature(const std::vector<uint8_t>& sig, size_t parts, size_t part_size) {
8,064✔
263
   if(sig.size() % parts != 0 || sig.size() != parts * part_size) {
8,064✔
264
      throw Encoding_Error("Unexpected size for DER signature");
×
265
   }
266

267
   std::vector<BigInt> sig_parts(parts);
8,064✔
268
   for(size_t i = 0; i != sig_parts.size(); ++i) {
24,192✔
269
      sig_parts[i].binary_decode(&sig[part_size * i], part_size);
16,128✔
270
   }
271

272
   std::vector<uint8_t> output;
8,064✔
273
   DER_Encoder(output).start_sequence().encode_list(sig_parts).end_cons();
32,256✔
274
   return output;
8,064✔
275
}
8,064✔
276

277
}  // namespace
278

279
size_t PK_Signer::signature_length() const {
1,172✔
280
   if(m_sig_format == Signature_Format::Standard) {
1,172✔
281
      return m_op->signature_length();
1,169✔
282
   } else if(m_sig_format == Signature_Format::DerSequence) {
3✔
283
      // This is a large over-estimate but its easier than computing
284
      // the exact value
285
      return m_op->signature_length() + (8 + 4 * m_parts);
3✔
286
   } else {
287
      throw Internal_Error("PK_Signer: Invalid signature format enum");
×
288
   }
289
}
290

291
std::vector<uint8_t> PK_Signer::signature(RandomNumberGenerator& rng) {
4,308✔
292
   std::vector<uint8_t> sig = unlock(m_op->sign(rng));
8,615✔
293

294
   if(m_sig_format == Signature_Format::Standard) {
4,307✔
295
      return sig;
4,307✔
296
   } else if(m_sig_format == Signature_Format::DerSequence) {
384✔
297
      return der_encode_signature(sig, m_parts, m_part_size);
384✔
298
   } else {
299
      throw Internal_Error("PK_Signer: Invalid signature format enum");
×
300
   }
301
}
4,307✔
302

303
PK_Verifier::PK_Verifier(const Public_Key& key,
60,683✔
304
                         std::string_view emsa,
305
                         Signature_Format format,
306
                         std::string_view provider) {
60,683✔
307
   m_op = key.create_verification_op(emsa, provider);
60,683✔
308
   if(!m_op) {
12,948✔
309
      throw Invalid_Argument(fmt("Key type {} does not support signature verification", key.algo_name()));
×
310
   }
311
   m_sig_format = format;
12,948✔
312
   m_parts = key.message_parts();
12,948✔
313
   m_part_size = key.message_part_size();
12,948✔
314
   check_der_format_supported(format, m_parts);
12,948✔
315
}
60,683✔
316

317
PK_Verifier::PK_Verifier(const Public_Key& key,
11,497✔
318
                         const AlgorithmIdentifier& signature_algorithm,
319
                         std::string_view provider) {
11,497✔
320
   m_op = key.create_x509_verification_op(signature_algorithm, provider);
11,497✔
321

322
   if(!m_op) {
11,441✔
323
      throw Invalid_Argument(fmt("Key type {} does not support X.509 signature verification", key.algo_name()));
×
324
   }
325

326
   m_sig_format = key.default_x509_signature_format();
11,441✔
327
   m_parts = key.message_parts();
11,441✔
328
   m_part_size = key.message_part_size();
11,441✔
329
   check_der_format_supported(m_sig_format, m_parts);
11,441✔
330
}
11,497✔
331

332
PK_Verifier::~PK_Verifier() = default;
24,389✔
333

334
PK_Verifier::PK_Verifier(PK_Verifier&&) noexcept = default;
×
335
PK_Verifier& PK_Verifier::operator=(PK_Verifier&&) noexcept = default;
×
336

337
std::string PK_Verifier::hash_function() const {
10,764✔
338
   return m_op->hash_function();
10,764✔
339
}
340

341
void PK_Verifier::set_input_format(Signature_Format format) {
×
342
   check_der_format_supported(format, m_parts);
×
343
   m_sig_format = format;
×
344
}
×
345

346
bool PK_Verifier::verify_message(const uint8_t msg[], size_t msg_length, const uint8_t sig[], size_t sig_length) {
63,831✔
347
   update(msg, msg_length);
63,831✔
348
   return check_signature(sig, sig_length);
63,831✔
349
}
350

351
void PK_Verifier::update(const uint8_t in[], size_t length) {
67,321✔
352
   m_op->update(in, length);
67,321✔
353
}
67,321✔
354

355
namespace {
356

357
std::vector<uint8_t> decode_der_signature(const uint8_t sig[], size_t length, size_t sig_parts, size_t sig_part_size) {
9,978✔
358
   std::vector<uint8_t> real_sig;
9,978✔
359
   BER_Decoder decoder(sig, length);
9,978✔
360
   BER_Decoder ber_sig = decoder.start_sequence();
9,978✔
361

362
   BOTAN_ASSERT_NOMSG(sig_parts != 0 && sig_part_size != 0);
9,636✔
363

364
   size_t count = 0;
365

366
   while(ber_sig.more_items()) {
26,813✔
367
      BigInt sig_part;
19,018✔
368
      ber_sig.decode(sig_part);
19,018✔
369
      real_sig += BigInt::encode_1363(sig_part, sig_part_size);
19,018✔
370
      ++count;
17,177✔
371
   }
19,018✔
372

373
   if(count != sig_parts) {
7,795✔
374
      throw Decoding_Error("PK_Verifier: signature size invalid");
115✔
375
   }
376

377
   const std::vector<uint8_t> reencoded = der_encode_signature(real_sig, sig_parts, sig_part_size);
7,680✔
378

379
   if(reencoded.size() != length || same_mem(reencoded.data(), sig, reencoded.size()) == false) {
14,922✔
380
      throw Decoding_Error("PK_Verifier: signature is not the canonical DER encoding");
926✔
381
   }
382
   return real_sig;
13,508✔
383
}
12,860✔
384

385
}  // namespace
386

387
bool PK_Verifier::check_signature(const uint8_t sig[], size_t length) {
67,708✔
388
   try {
67,708✔
389
      if(m_sig_format == Signature_Format::Standard) {
67,708✔
390
         return m_op->is_valid_signature(sig, length);
57,730✔
391
      } else if(m_sig_format == Signature_Format::DerSequence) {
9,978✔
392
         bool decoding_success = false;
9,978✔
393
         std::vector<uint8_t> real_sig;
9,978✔
394

395
         try {
9,978✔
396
            real_sig = decode_der_signature(sig, length, m_parts, m_part_size);
16,732✔
397
            decoding_success = true;
6,754✔
398
         } catch(Decoding_Error&) {}
3,224✔
399

400
         bool accept = m_op->is_valid_signature(real_sig.data(), real_sig.size());
9,753✔
401

402
         return accept && decoding_success;
9,753✔
403
      } else {
9,978✔
404
         throw Internal_Error("PK_Verifier: Invalid signature format enum");
×
405
      }
406
   } catch(Invalid_Argument&) {
329✔
407
      return false;
×
408
   } catch(Decoding_Error&) {
104✔
409
      return false;
104✔
410
   } catch(Encoding_Error&) {
329✔
411
      return false;
225✔
412
   }
225✔
413
}
414

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

© 2025 Coveralls, Inc