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

randombit / botan / 5760984433

04 Aug 2023 10:06AM UTC coverage: 91.693% (+0.003%) from 91.69%
5760984433

Pull #3651

github

web-flow
Merge ba484ec0d into 2c748bf9a
Pull Request #3651: TLS Anvil Server Tests in Nightly CI

78277 of 85369 relevant lines covered (91.69%)

12237875.65 hits per line

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

90.95
/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,515✔
27
      throw Decoding_Error("Invalid public key ciphertext, cannot decrypt");
3,183✔
28
   }
29

30
   return decoded;
2,332✔
31
}
3,183✔
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
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 {
276✔
102
   return unlock(m_op->encrypt(in, length, rng));
552✔
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,
784✔
110
                                   RandomNumberGenerator& rng,
111
                                   std::string_view padding,
112
                                   std::string_view provider) {
784✔
113
   m_op = key.create_decryption_op(rng, padding, provider);
784✔
114
   if(!m_op) {
256✔
115
      throw Invalid_Argument(fmt("Key type {} does not support decryption", key.algo_name()));
×
116
   }
117
}
784✔
118

119
PK_Decryptor_EME::~PK_Decryptor_EME() = default;
437✔
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,952✔
126
   return m_op->decrypt(valid_mask, in, in_len);
3,952✔
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 {
6,408✔
139
   return m_op->shared_key_length(desired_shared_key_len);
6,408✔
140
}
141

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

146
void PK_KEM_Encryptor::encrypt(std::span<uint8_t> out_encapsulated_key,
3,198✔
147
                               std::span<uint8_t> out_shared_key,
148
                               RandomNumberGenerator& rng,
149
                               size_t desired_shared_key_len,
150
                               std::span<const uint8_t> salt) {
151
   BOTAN_ARG_CHECK(out_encapsulated_key.size() == encapsulated_key_length(), "not enough space for encapsulated key");
3,198✔
152
   BOTAN_ARG_CHECK(out_shared_key.size() == shared_key_length(desired_shared_key_len),
3,198✔
153
                   "not enough space for shared key");
154
   m_op->kem_encrypt(out_encapsulated_key, out_shared_key, rng, desired_shared_key_len, salt);
3,198✔
155
}
3,198✔
156

157
size_t PK_KEM_Decryptor::shared_key_length(size_t desired_shared_key_len) const {
6,444✔
158
   return m_op->shared_key_length(desired_shared_key_len);
6,444✔
159
}
160

161
size_t PK_KEM_Decryptor::encapsulated_key_length() const {
10✔
162
   return m_op->encapsulated_key_length();
10✔
163
}
164

165
PK_KEM_Decryptor::PK_KEM_Decryptor(const Private_Key& key,
720✔
166
                                   RandomNumberGenerator& rng,
167
                                   std::string_view param,
168
                                   std::string_view provider) {
720✔
169
   m_op = key.create_kem_decryption_op(rng, param, provider);
720✔
170
   if(!m_op) {
720✔
171
      throw Invalid_Argument(fmt("Key type {} does not support KEM decryption", key.algo_name()));
×
172
   }
173
}
720✔
174

175
PK_KEM_Decryptor::~PK_KEM_Decryptor() = default;
720✔
176

177
void PK_KEM_Decryptor::decrypt(std::span<uint8_t> out_shared_key,
3,216✔
178
                               std::span<const uint8_t> encap_key,
179
                               size_t desired_shared_key_len,
180
                               std::span<const uint8_t> salt) {
181
   BOTAN_ARG_CHECK(out_shared_key.size() == shared_key_length(desired_shared_key_len),
3,216✔
182
                   "inconsistent size of shared key output buffer");
183
   m_op->kem_decrypt(out_shared_key, encap_key, desired_shared_key_len, salt);
3,216✔
184
}
3,210✔
185

186
PK_Key_Agreement::PK_Key_Agreement(PK_Key_Agreement&&) noexcept = default;
×
187

188
PK_Key_Agreement::PK_Key_Agreement(const Private_Key& key,
3,406✔
189
                                   RandomNumberGenerator& rng,
190
                                   std::string_view kdf,
191
                                   std::string_view provider) {
3,406✔
192
   m_op = key.create_key_agreement_op(rng, kdf, provider);
3,406✔
193
   if(!m_op) {
2,602✔
194
      throw Invalid_Argument(fmt("Key type {} does not support key agreement", key.algo_name()));
×
195
   }
196
}
3,406✔
197

198
PK_Key_Agreement::~PK_Key_Agreement() = default;
2,602✔
199

200
size_t PK_Key_Agreement::agreed_value_size() const {
264✔
201
   return m_op->agreed_value_size();
264✔
202
}
203

204
SymmetricKey PK_Key_Agreement::derive_key(
4,187✔
205
   size_t key_len, const uint8_t in[], size_t in_len, const uint8_t salt[], size_t salt_len) const {
206
   return SymmetricKey(m_op->agree(key_len, in, in_len, salt, salt_len));
4,187✔
207
}
208

209
static void check_der_format_supported(Signature_Format format, size_t parts) {
28,094✔
210
   if(format != Signature_Format::Standard && parts == 1) {
28,094✔
211
      throw Invalid_Argument("This algorithm does not support DER encoding");
×
212
   }
213
}
28,094✔
214

215
PK_Signer::PK_Signer(const Private_Key& key,
7,316✔
216
                     RandomNumberGenerator& rng,
217
                     std::string_view emsa,
218
                     Signature_Format format,
219
                     std::string_view provider) {
7,316✔
220
   m_op = key.create_signature_op(rng, emsa, provider);
7,316✔
221
   if(!m_op) {
3,831✔
222
      throw Invalid_Argument(fmt("Key type {} does not support signature generation", key.algo_name()));
×
223
   }
224
   m_sig_format = format;
3,831✔
225
   m_parts = key.message_parts();
3,831✔
226
   m_part_size = key.message_part_size();
3,831✔
227
   check_der_format_supported(format, m_parts);
3,831✔
228
}
7,316✔
229

230
AlgorithmIdentifier PK_Signer::algorithm_identifier() const {
368✔
231
   return m_op->algorithm_identifier();
368✔
232
}
233

234
std::string PK_Signer::hash_function() const {
561✔
235
   return m_op->hash_function();
561✔
236
}
237

238
PK_Signer::~PK_Signer() = default;
3,831✔
239

240
void PK_Signer::update(const uint8_t in[], size_t length) {
4,560✔
241
   m_op->update(in, length);
4,560✔
242
}
4,559✔
243

244
namespace {
245

246
std::vector<uint8_t> der_encode_signature(const std::vector<uint8_t>& sig, size_t parts, size_t part_size) {
8,018✔
247
   if(sig.size() % parts != 0 || sig.size() != parts * part_size) {
8,018✔
248
      throw Encoding_Error("Unexpected size for DER signature");
×
249
   }
250

251
   std::vector<BigInt> sig_parts(parts);
8,018✔
252
   for(size_t i = 0; i != sig_parts.size(); ++i) {
24,054✔
253
      sig_parts[i].binary_decode(&sig[part_size * i], part_size);
16,036✔
254
   }
255

256
   std::vector<uint8_t> output;
8,018✔
257
   DER_Encoder(output).start_sequence().encode_list(sig_parts).end_cons();
32,072✔
258
   return output;
8,018✔
259
}
8,018✔
260

261
}  // namespace
262

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

275
std::vector<uint8_t> PK_Signer::signature(RandomNumberGenerator& rng) {
4,303✔
276
   std::vector<uint8_t> sig = unlock(m_op->sign(rng));
8,605✔
277

278
   if(m_sig_format == Signature_Format::Standard) {
4,302✔
279
      return sig;
4,302✔
280
   } else if(m_sig_format == Signature_Format::DerSequence) {
380✔
281
      return der_encode_signature(sig, m_parts, m_part_size);
380✔
282
   } else {
283
      throw Internal_Error("PK_Signer: Invalid signature format enum");
×
284
   }
285
}
4,302✔
286

287
PK_Verifier::PK_Verifier(const Public_Key& key,
60,678✔
288
                         std::string_view emsa,
289
                         Signature_Format format,
290
                         std::string_view provider) {
60,678✔
291
   m_op = key.create_verification_op(emsa, provider);
60,678✔
292
   if(!m_op) {
12,943✔
293
      throw Invalid_Argument(fmt("Key type {} does not support signature verification", key.algo_name()));
×
294
   }
295
   m_sig_format = format;
12,943✔
296
   m_parts = key.message_parts();
12,943✔
297
   m_part_size = key.message_part_size();
12,943✔
298
   check_der_format_supported(format, m_parts);
12,943✔
299
}
60,678✔
300

301
PK_Verifier::PK_Verifier(const Public_Key& key,
11,376✔
302
                         const AlgorithmIdentifier& signature_algorithm,
303
                         std::string_view provider) {
11,376✔
304
   m_op = key.create_x509_verification_op(signature_algorithm, provider);
11,376✔
305

306
   if(!m_op) {
11,320✔
307
      throw Invalid_Argument(fmt("Key type {} does not support X.509 signature verification", key.algo_name()));
×
308
   }
309

310
   m_sig_format = key.default_x509_signature_format();
11,320✔
311
   m_parts = key.message_parts();
11,320✔
312
   m_part_size = key.message_part_size();
11,320✔
313
   check_der_format_supported(m_sig_format, m_parts);
11,320✔
314
}
11,376✔
315

316
PK_Verifier::~PK_Verifier() = default;
24,263✔
317

318
std::string PK_Verifier::hash_function() const {
10,643✔
319
   return m_op->hash_function();
10,643✔
320
}
321

322
void PK_Verifier::set_input_format(Signature_Format format) {
×
323
   check_der_format_supported(format, m_parts);
×
324
   m_sig_format = format;
×
325
}
×
326

327
bool PK_Verifier::verify_message(const uint8_t msg[], size_t msg_length, const uint8_t sig[], size_t sig_length) {
63,707✔
328
   update(msg, msg_length);
63,707✔
329
   return check_signature(sig, sig_length);
63,707✔
330
}
331

332
void PK_Verifier::update(const uint8_t in[], size_t length) {
67,197✔
333
   m_op->update(in, length);
67,197✔
334
}
67,197✔
335

336
namespace {
337

338
std::vector<uint8_t> decode_der_signature(const uint8_t sig[], size_t length, size_t sig_parts, size_t sig_part_size) {
9,932✔
339
   std::vector<uint8_t> real_sig;
9,932✔
340
   BER_Decoder decoder(sig, length);
9,932✔
341
   BER_Decoder ber_sig = decoder.start_sequence();
9,932✔
342

343
   BOTAN_ASSERT_NOMSG(sig_parts != 0 && sig_part_size != 0);
9,590✔
344

345
   size_t count = 0;
346

347
   while(ber_sig.more_items()) {
26,682✔
348
      BigInt sig_part;
18,929✔
349
      ber_sig.decode(sig_part);
18,929✔
350
      real_sig += BigInt::encode_1363(sig_part, sig_part_size);
18,929✔
351
      ++count;
17,092✔
352
   }
18,929✔
353

354
   if(count != sig_parts) {
7,753✔
355
      throw Decoding_Error("PK_Verifier: signature size invalid");
115✔
356
   }
357

358
   const std::vector<uint8_t> reencoded = der_encode_signature(real_sig, sig_parts, sig_part_size);
7,638✔
359

360
   if(reencoded.size() != length || same_mem(reencoded.data(), sig, reencoded.size()) == false) {
14,838✔
361
      throw Decoding_Error("PK_Verifier: signature is not the canonical DER encoding");
926✔
362
   }
363
   return real_sig;
13,424✔
364
}
12,810✔
365

366
}  // namespace
367

368
bool PK_Verifier::check_signature(const uint8_t sig[], size_t length) {
67,584✔
369
   try {
67,584✔
370
      if(m_sig_format == Signature_Format::Standard) {
67,584✔
371
         return m_op->is_valid_signature(sig, length);
57,652✔
372
      } else if(m_sig_format == Signature_Format::DerSequence) {
9,932✔
373
         bool decoding_success = false;
9,932✔
374
         std::vector<uint8_t> real_sig;
9,932✔
375

376
         try {
9,932✔
377
            real_sig = decode_der_signature(sig, length, m_parts, m_part_size);
16,644✔
378
            decoding_success = true;
6,712✔
379
         } catch(Decoding_Error&) {}
3,220✔
380

381
         bool accept = m_op->is_valid_signature(real_sig.data(), real_sig.size());
9,708✔
382

383
         return accept && decoding_success;
9,708✔
384
      } else {
9,932✔
385
         throw Internal_Error("PK_Verifier: Invalid signature format enum");
×
386
      }
387
   } catch(Invalid_Argument&) {
327✔
388
      return false;
×
389
   } catch(Decoding_Error&) {
103✔
390
      return false;
103✔
391
   } catch(Encoding_Error&) {
327✔
392
      return false;
224✔
393
   }
224✔
394
}
395

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