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

randombit / botan / 5230455705

10 Jun 2023 02:30PM UTC coverage: 91.715% (-0.03%) from 91.746%
5230455705

push

github

randombit
Merge GH #3584 Change clang-format AllowShortFunctionsOnASingleLine config from All to Inline

77182 of 84154 relevant lines covered (91.72%)

11975295.43 hits per line

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

90.69
/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,186✔
28
   }
29

30
   return decoded;
2,327✔
31
}
3,186✔
32

33
secure_vector<uint8_t> PK_Decryptor::decrypt_or_random(const uint8_t in[],
135✔
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);
135✔
41

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

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

48
   decoded.resize(expected_pt_len);
135✔
49

50
   for(size_t i = 0; i != required_contents_length; ++i) {
251✔
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];
116✔
63
      const uint8_t off = required_content_offsets[i];
116✔
64

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

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

69
      valid_mask &= eq;
116✔
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);
135✔
74

75
   return decoded;
135✔
76
}
135✔
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,
611✔
86
                                   RandomNumberGenerator& rng,
87
                                   std::string_view padding,
88
                                   std::string_view provider) {
611✔
89
   m_op = key.create_encryption_op(rng, padding, provider);
611✔
90
   if(!m_op) {
209✔
91
      throw Invalid_Argument(fmt("Key type {} does not support encryption", key.algo_name()));
×
92
   }
93
}
611✔
94

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

97
size_t PK_Encryptor_EME::ciphertext_length(size_t ptext_len) const {
139✔
98
   return m_op->ciphertext_length(ptext_len);
139✔
99
}
100

101
std::vector<uint8_t> PK_Encryptor_EME::enc(const uint8_t in[], size_t length, RandomNumberGenerator& rng) const {
277✔
102
   return unlock(m_op->encrypt(in, length, rng));
554✔
103
}
104

105
size_t PK_Encryptor_EME::maximum_input_size() const {
144✔
106
   return m_op->max_input_bits() / 8;
144✔
107
}
108

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

119
PK_Decryptor_EME::~PK_Decryptor_EME() = default;
438✔
120

121
size_t PK_Decryptor_EME::plaintext_length(size_t ctext_len) const {
138✔
122
   return m_op->plaintext_length(ctext_len);
138✔
123
}
124

125
secure_vector<uint8_t> PK_Decryptor_EME::do_decrypt(uint8_t& valid_mask, const uint8_t in[], size_t in_len) const {
3,953✔
126
   return m_op->decrypt(valid_mask, in, in_len);
3,953✔
127
}
128

129
PK_KEM_Encryptor::PK_KEM_Encryptor(const Public_Key& key, std::string_view param, std::string_view provider) {
720✔
130
   m_op = key.create_kem_encryption_op(param, provider);
720✔
131
   if(!m_op) {
720✔
132
      throw Invalid_Argument(fmt("Key type {} does not support KEM encryption"));
×
133
   }
134
}
720✔
135

136
PK_KEM_Encryptor::~PK_KEM_Encryptor() = default;
720✔
137

138
size_t PK_KEM_Encryptor::shared_key_length(size_t desired_shared_key_len) const {
12✔
139
   return m_op->shared_key_length(desired_shared_key_len);
12✔
140
}
141

142
size_t PK_KEM_Encryptor::encapsulated_key_length() const {
12✔
143
   return m_op->encapsulated_key_length();
12✔
144
}
145

146
void PK_KEM_Encryptor::encrypt(secure_vector<uint8_t>& out_encapsulated_key,
3,198✔
147
                               secure_vector<uint8_t>& out_shared_key,
148
                               size_t desired_shared_key_len,
149
                               RandomNumberGenerator& rng,
150
                               const uint8_t salt[],
151
                               size_t salt_len) {
152
   m_op->kem_encrypt(out_encapsulated_key, out_shared_key, desired_shared_key_len, rng, salt, salt_len);
3,198✔
153
}
3,198✔
154

155
size_t PK_KEM_Decryptor::shared_key_length(size_t desired_shared_key_len) const {
12✔
156
   return m_op->shared_key_length(desired_shared_key_len);
12✔
157
}
158

159
PK_KEM_Decryptor::PK_KEM_Decryptor(const Private_Key& key,
720✔
160
                                   RandomNumberGenerator& rng,
161
                                   std::string_view param,
162
                                   std::string_view provider) {
720✔
163
   m_op = key.create_kem_decryption_op(rng, param, provider);
720✔
164
   if(!m_op) {
720✔
165
      throw Invalid_Argument(fmt("Key type {} does not support KEM decryption", key.algo_name()));
×
166
   }
167
}
720✔
168

169
PK_KEM_Decryptor::~PK_KEM_Decryptor() = default;
720✔
170

171
secure_vector<uint8_t> PK_KEM_Decryptor::decrypt(const uint8_t encap_key[],
3,216✔
172
                                                 size_t encap_key_len,
173
                                                 size_t desired_shared_key_len,
174
                                                 const uint8_t salt[],
175
                                                 size_t salt_len) {
176
   return m_op->kem_decrypt(encap_key, encap_key_len, desired_shared_key_len, salt, salt_len);
3,216✔
177
}
178

179
PK_Key_Agreement::PK_Key_Agreement(PK_Key_Agreement&&) noexcept = default;
×
180

181
PK_Key_Agreement::PK_Key_Agreement(const Private_Key& key,
3,403✔
182
                                   RandomNumberGenerator& rng,
183
                                   std::string_view kdf,
184
                                   std::string_view provider) {
3,403✔
185
   m_op = key.create_key_agreement_op(rng, kdf, provider);
3,403✔
186
   if(!m_op) {
2,599✔
187
      throw Invalid_Argument(fmt("Key type {} does not support key agreement", key.algo_name()));
×
188
   }
189
}
3,403✔
190

191
PK_Key_Agreement::~PK_Key_Agreement() = default;
2,599✔
192

193
size_t PK_Key_Agreement::agreed_value_size() const {
264✔
194
   return m_op->agreed_value_size();
264✔
195
}
196

197
SymmetricKey PK_Key_Agreement::derive_key(
4,184✔
198
   size_t key_len, const uint8_t in[], size_t in_len, const uint8_t salt[], size_t salt_len) const {
199
   return SymmetricKey(m_op->agree(key_len, in, in_len, salt, salt_len));
4,184✔
200
}
201

202
static void check_der_format_supported(Signature_Format format, size_t parts) {
27,612✔
203
   if(format != Signature_Format::Standard && parts == 1) {
27,612✔
204
      throw Invalid_Argument("This algorithm does not support DER encoding");
×
205
   }
206
}
27,612✔
207

208
PK_Signer::PK_Signer(const Private_Key& key,
7,304✔
209
                     RandomNumberGenerator& rng,
210
                     std::string_view emsa,
211
                     Signature_Format format,
212
                     std::string_view provider) {
7,304✔
213
   m_op = key.create_signature_op(rng, emsa, provider);
7,304✔
214
   if(!m_op) {
3,819✔
215
      throw Invalid_Argument(fmt("Key type {} does not support signature generation", key.algo_name()));
×
216
   }
217
   m_sig_format = format;
3,819✔
218
   m_parts = key.message_parts();
3,819✔
219
   m_part_size = key.message_part_size();
3,819✔
220
   check_der_format_supported(format, m_parts);
3,819✔
221
}
7,304✔
222

223
AlgorithmIdentifier PK_Signer::algorithm_identifier() const {
368✔
224
   return m_op->algorithm_identifier();
368✔
225
}
226

227
std::string PK_Signer::hash_function() const {
561✔
228
   return m_op->hash_function();
561✔
229
}
230

231
PK_Signer::~PK_Signer() = default;
3,819✔
232

233
void PK_Signer::update(const uint8_t in[], size_t length) {
4,547✔
234
   m_op->update(in, length);
4,547✔
235
}
4,546✔
236

237
namespace {
238

239
std::vector<uint8_t> der_encode_signature(const std::vector<uint8_t>& sig, size_t parts, size_t part_size) {
7,687✔
240
   if(sig.size() % parts != 0 || sig.size() != parts * part_size) {
7,687✔
241
      throw Encoding_Error("Unexpected size for DER signature");
×
242
   }
243

244
   std::vector<BigInt> sig_parts(parts);
7,687✔
245
   for(size_t i = 0; i != sig_parts.size(); ++i) {
23,061✔
246
      sig_parts[i].binary_decode(&sig[part_size * i], part_size);
15,374✔
247
   }
248

249
   std::vector<uint8_t> output;
7,687✔
250
   DER_Encoder(output).start_sequence().encode_list(sig_parts).end_cons();
30,748✔
251
   return output;
7,687✔
252
}
7,687✔
253

254
}  // namespace
255

256
size_t PK_Signer::signature_length() const {
1,172✔
257
   if(m_sig_format == Signature_Format::Standard) {
1,172✔
258
      return m_op->signature_length();
1,169✔
259
   } else if(m_sig_format == Signature_Format::DerSequence) {
3✔
260
      // This is a large over-estimate but its easier than computing
261
      // the exact value
262
      return m_op->signature_length() + (8 + 4 * m_parts);
3✔
263
   } else {
264
      throw Internal_Error("PK_Signer: Invalid signature format enum");
×
265
   }
266
}
267

268
std::vector<uint8_t> PK_Signer::signature(RandomNumberGenerator& rng) {
4,290✔
269
   std::vector<uint8_t> sig = unlock(m_op->sign(rng));
8,579✔
270

271
   if(m_sig_format == Signature_Format::Standard) {
4,289✔
272
      return sig;
4,289✔
273
   } else if(m_sig_format == Signature_Format::DerSequence) {
383✔
274
      return der_encode_signature(sig, m_parts, m_part_size);
383✔
275
   } else {
276
      throw Internal_Error("PK_Signer: Invalid signature format enum");
×
277
   }
278
}
4,289✔
279

280
PK_Verifier::PK_Verifier(const Public_Key& key,
60,676✔
281
                         std::string_view emsa,
282
                         Signature_Format format,
283
                         std::string_view provider) {
60,676✔
284
   m_op = key.create_verification_op(emsa, provider);
60,676✔
285
   if(!m_op) {
12,941✔
286
      throw Invalid_Argument(fmt("Key type {} does not support signature verification", key.algo_name()));
×
287
   }
288
   m_sig_format = format;
12,941✔
289
   m_parts = key.message_parts();
12,941✔
290
   m_part_size = key.message_part_size();
12,941✔
291
   check_der_format_supported(format, m_parts);
12,941✔
292
}
60,676✔
293

294
PK_Verifier::PK_Verifier(const Public_Key& key,
10,908✔
295
                         const AlgorithmIdentifier& signature_algorithm,
296
                         std::string_view provider) {
10,908✔
297
   m_op = key.create_x509_verification_op(signature_algorithm, provider);
10,908✔
298

299
   if(!m_op) {
10,852✔
300
      throw Invalid_Argument(fmt("Key type {} does not support X.509 signature verification", key.algo_name()));
×
301
   }
302

303
   m_sig_format = key.default_x509_signature_format();
10,852✔
304
   m_parts = key.message_parts();
10,852✔
305
   m_part_size = key.message_part_size();
10,852✔
306
   check_der_format_supported(m_sig_format, m_parts);
10,852✔
307
}
10,908✔
308

309
PK_Verifier::~PK_Verifier() = default;
23,793✔
310

311
std::string PK_Verifier::hash_function() const {
10,189✔
312
   return m_op->hash_function();
10,189✔
313
}
314

315
void PK_Verifier::set_input_format(Signature_Format format) {
×
316
   check_der_format_supported(format, m_parts);
×
317
   m_sig_format = format;
×
318
}
×
319

320
bool PK_Verifier::verify_message(const uint8_t msg[], size_t msg_length, const uint8_t sig[], size_t sig_length) {
63,226✔
321
   update(msg, msg_length);
63,226✔
322
   return check_signature(sig, sig_length);
63,226✔
323
}
324

325
void PK_Verifier::update(const uint8_t in[], size_t length) {
66,716✔
326
   m_op->update(in, length);
66,716✔
327
}
66,716✔
328

329
namespace {
330

331
std::vector<uint8_t> decode_der_signature(const uint8_t sig[], size_t length, size_t sig_parts, size_t sig_part_size) {
9,600✔
332
   std::vector<uint8_t> real_sig;
9,600✔
333
   BER_Decoder decoder(sig, length);
9,600✔
334
   BER_Decoder ber_sig = decoder.start_sequence();
9,600✔
335

336
   BOTAN_ASSERT_NOMSG(sig_parts != 0 && sig_part_size != 0);
9,256✔
337

338
   size_t count = 0;
339

340
   while(ber_sig.more_items()) {
25,680✔
341
      BigInt sig_part;
18,261✔
342
      ber_sig.decode(sig_part);
18,261✔
343
      real_sig += BigInt::encode_1363(sig_part, sig_part_size);
18,261✔
344
      ++count;
16,424✔
345
   }
18,261✔
346

347
   if(count != sig_parts) {
7,419✔
348
      throw Decoding_Error("PK_Verifier: signature size invalid");
115✔
349
   }
350

351
   const std::vector<uint8_t> reencoded = der_encode_signature(real_sig, sig_parts, sig_part_size);
7,304✔
352

353
   if(reencoded.size() != length || same_mem(reencoded.data(), sig, reencoded.size()) == false) {
14,170✔
354
      throw Decoding_Error("PK_Verifier: signature is not the canonical DER encoding");
926✔
355
   }
356
   return real_sig;
12,756✔
357
}
12,478✔
358

359
}  // namespace
360

361
bool PK_Verifier::check_signature(const uint8_t sig[], size_t length) {
67,103✔
362
   try {
67,103✔
363
      if(m_sig_format == Signature_Format::Standard) {
67,103✔
364
         return m_op->is_valid_signature(sig, length);
57,503✔
365
      } else if(m_sig_format == Signature_Format::DerSequence) {
9,600✔
366
         bool decoding_success = false;
9,600✔
367
         std::vector<uint8_t> real_sig;
9,600✔
368

369
         try {
9,600✔
370
            real_sig = decode_der_signature(sig, length, m_parts, m_part_size);
15,978✔
371
            decoding_success = true;
6,378✔
372
         } catch(Decoding_Error&) {}
3,222✔
373

374
         bool accept = m_op->is_valid_signature(real_sig.data(), real_sig.size());
9,376✔
375

376
         return accept && decoding_success;
9,376✔
377
      } else {
9,600✔
378
         throw Internal_Error("PK_Verifier: Invalid signature format enum");
×
379
      }
380
   } catch(Invalid_Argument&) {
324✔
381
      return false;
×
382
   } catch(Decoding_Error&) {
100✔
383
      return false;
100✔
384
   } catch(Encoding_Error&) {
324✔
385
      return false;
224✔
386
   }
224✔
387
}
388

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