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

randombit / botan / 5133556677

31 May 2023 02:11PM UTC coverage: 91.735% (-0.3%) from 92.012%
5133556677

Pull #3568

github

web-flow
Merge de48a2eb6 into 1cbeffafb
Pull Request #3568: Change clang-format AllowShortBlocksOnASingleLine from true to Empty

76059 of 82912 relevant lines covered (91.73%)

12004312.75 hits per line

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

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

30
   return decoded;
2,328✔
31
}
3,189✔
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 { return m_op->ciphertext_length(ptext_len); }
139✔
98

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

103
size_t PK_Encryptor_EME::maximum_input_size() const { return m_op->max_input_bits() / 8; }
144✔
104

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

115
PK_Decryptor_EME::~PK_Decryptor_EME() = default;
438✔
116

117
size_t PK_Decryptor_EME::plaintext_length(size_t ctext_len) const { return m_op->plaintext_length(ctext_len); }
138✔
118

119
secure_vector<uint8_t> PK_Decryptor_EME::do_decrypt(uint8_t& valid_mask, const uint8_t in[], size_t in_len) const {
3,953✔
120
   return m_op->decrypt(valid_mask, in, in_len);
3,953✔
121
}
122

123
PK_KEM_Encryptor::PK_KEM_Encryptor(const Public_Key& key, std::string_view param, std::string_view provider) {
720✔
124
   m_op = key.create_kem_encryption_op(param, provider);
720✔
125
   if(!m_op) {
720✔
126
      throw Invalid_Argument(fmt("Key type {} does not support KEM encryption"));
×
127
   }
128
}
720✔
129

130
PK_KEM_Encryptor::~PK_KEM_Encryptor() = default;
720✔
131

132
size_t PK_KEM_Encryptor::shared_key_length(size_t desired_shared_key_len) const {
12✔
133
   return m_op->shared_key_length(desired_shared_key_len);
12✔
134
}
135

136
size_t PK_KEM_Encryptor::encapsulated_key_length() const { return m_op->encapsulated_key_length(); }
12✔
137

138
void PK_KEM_Encryptor::encrypt(secure_vector<uint8_t>& out_encapsulated_key,
3,198✔
139
                               secure_vector<uint8_t>& out_shared_key,
140
                               size_t desired_shared_key_len,
141
                               RandomNumberGenerator& rng,
142
                               const uint8_t salt[],
143
                               size_t salt_len) {
144
   m_op->kem_encrypt(out_encapsulated_key, out_shared_key, desired_shared_key_len, rng, salt, salt_len);
3,198✔
145
}
3,198✔
146

147
size_t PK_KEM_Decryptor::shared_key_length(size_t desired_shared_key_len) const {
12✔
148
   return m_op->shared_key_length(desired_shared_key_len);
12✔
149
}
150

151
PK_KEM_Decryptor::PK_KEM_Decryptor(const Private_Key& key,
720✔
152
                                   RandomNumberGenerator& rng,
153
                                   std::string_view param,
154
                                   std::string_view provider) {
720✔
155
   m_op = key.create_kem_decryption_op(rng, param, provider);
720✔
156
   if(!m_op) {
720✔
157
      throw Invalid_Argument(fmt("Key type {} does not support KEM decryption", key.algo_name()));
×
158
   }
159
}
720✔
160

161
PK_KEM_Decryptor::~PK_KEM_Decryptor() = default;
720✔
162

163
secure_vector<uint8_t> PK_KEM_Decryptor::decrypt(const uint8_t encap_key[],
3,216✔
164
                                                 size_t encap_key_len,
165
                                                 size_t desired_shared_key_len,
166
                                                 const uint8_t salt[],
167
                                                 size_t salt_len) {
168
   return m_op->kem_decrypt(encap_key, encap_key_len, desired_shared_key_len, salt, salt_len);
3,216✔
169
}
170

171
PK_Key_Agreement::PK_Key_Agreement(PK_Key_Agreement&&) noexcept = default;
×
172

173
PK_Key_Agreement::PK_Key_Agreement(const Private_Key& key,
3,399✔
174
                                   RandomNumberGenerator& rng,
175
                                   std::string_view kdf,
176
                                   std::string_view provider) {
3,399✔
177
   m_op = key.create_key_agreement_op(rng, kdf, provider);
3,399✔
178
   if(!m_op) {
2,595✔
179
      throw Invalid_Argument(fmt("Key type {} does not support key agreement", key.algo_name()));
×
180
   }
181
}
3,399✔
182

183
PK_Key_Agreement::~PK_Key_Agreement() = default;
2,595✔
184

185
size_t PK_Key_Agreement::agreed_value_size() const { return m_op->agreed_value_size(); }
264✔
186

187
SymmetricKey PK_Key_Agreement::derive_key(
4,180✔
188
   size_t key_len, const uint8_t in[], size_t in_len, const uint8_t salt[], size_t salt_len) const {
189
   return SymmetricKey(m_op->agree(key_len, in, in_len, salt, salt_len));
4,180✔
190
}
191

192
static void check_der_format_supported(Signature_Format format, size_t parts) {
27,595✔
193
   if(format != Signature_Format::Standard && parts == 1) {
27,595✔
194
      throw Invalid_Argument("This algorithm does not support DER encoding");
×
195
   }
196
}
27,595✔
197

198
PK_Signer::PK_Signer(const Private_Key& key,
7,299✔
199
                     RandomNumberGenerator& rng,
200
                     std::string_view emsa,
201
                     Signature_Format format,
202
                     std::string_view provider) {
7,299✔
203
   m_op = key.create_signature_op(rng, emsa, provider);
7,299✔
204
   if(!m_op) {
3,814✔
205
      throw Invalid_Argument(fmt("Key type {} does not support signature generation", key.algo_name()));
×
206
   }
207
   m_sig_format = format;
3,814✔
208
   m_parts = key.message_parts();
3,814✔
209
   m_part_size = key.message_part_size();
3,814✔
210
   check_der_format_supported(format, m_parts);
3,814✔
211
}
7,299✔
212

213
AlgorithmIdentifier PK_Signer::algorithm_identifier() const { return m_op->algorithm_identifier(); }
365✔
214

215
std::string PK_Signer::hash_function() const { return m_op->hash_function(); }
559✔
216

217
PK_Signer::~PK_Signer() = default;
3,814✔
218

219
void PK_Signer::update(const uint8_t in[], size_t length) { m_op->update(in, length); }
4,543✔
220

221
namespace {
222

223
std::vector<uint8_t> der_encode_signature(const std::vector<uint8_t>& sig, size_t parts, size_t part_size) {
7,688✔
224
   if(sig.size() % parts != 0 || sig.size() != parts * part_size) {
7,688✔
225
      throw Encoding_Error("Unexpected size for DER signature");
×
226
   }
227

228
   std::vector<BigInt> sig_parts(parts);
7,688✔
229
   for(size_t i = 0; i != sig_parts.size(); ++i) {
23,064✔
230
      sig_parts[i].binary_decode(&sig[part_size * i], part_size);
15,376✔
231
   }
232

233
   std::vector<uint8_t> output;
7,688✔
234
   DER_Encoder(output).start_sequence().encode_list(sig_parts).end_cons();
30,752✔
235
   return output;
7,688✔
236
}
7,688✔
237

238
}  // namespace
239

240
size_t PK_Signer::signature_length() const {
1,172✔
241
   if(m_sig_format == Signature_Format::Standard) {
1,172✔
242
      return m_op->signature_length();
1,169✔
243
   } else if(m_sig_format == Signature_Format::DerSequence) {
3✔
244
      // This is a large over-estimate but its easier than computing
245
      // the exact value
246
      return m_op->signature_length() + (8 + 4 * m_parts);
3✔
247
   } else {
248
      throw Internal_Error("PK_Signer: Invalid signature format enum");
×
249
   }
250
}
251

252
std::vector<uint8_t> PK_Signer::signature(RandomNumberGenerator& rng) {
4,286✔
253
   std::vector<uint8_t> sig = unlock(m_op->sign(rng));
8,571✔
254

255
   if(m_sig_format == Signature_Format::Standard) {
4,285✔
256
      return sig;
4,285✔
257
   } else if(m_sig_format == Signature_Format::DerSequence) {
383✔
258
      return der_encode_signature(sig, m_parts, m_part_size);
383✔
259
   } else {
260
      throw Internal_Error("PK_Signer: Invalid signature format enum");
×
261
   }
262
}
4,285✔
263

264
PK_Verifier::PK_Verifier(const Public_Key& key,
60,674✔
265
                         std::string_view emsa,
266
                         Signature_Format format,
267
                         std::string_view provider) {
60,674✔
268
   m_op = key.create_verification_op(emsa, provider);
60,674✔
269
   if(!m_op) {
12,939✔
270
      throw Invalid_Argument(fmt("Key type {} does not support signature verification", key.algo_name()));
×
271
   }
272
   m_sig_format = format;
12,939✔
273
   m_parts = key.message_parts();
12,939✔
274
   m_part_size = key.message_part_size();
12,939✔
275
   check_der_format_supported(format, m_parts);
12,939✔
276
}
60,674✔
277

278
PK_Verifier::PK_Verifier(const Public_Key& key,
10,898✔
279
                         const AlgorithmIdentifier& signature_algorithm,
280
                         std::string_view provider) {
10,898✔
281
   m_op = key.create_x509_verification_op(signature_algorithm, provider);
10,898✔
282

283
   if(!m_op) {
10,842✔
284
      throw Invalid_Argument(fmt("Key type {} does not support X.509 signature verification", key.algo_name()));
×
285
   }
286

287
   m_sig_format = key.default_x509_signature_format();
10,842✔
288
   m_parts = key.message_parts();
10,842✔
289
   m_part_size = key.message_part_size();
10,842✔
290
   check_der_format_supported(m_sig_format, m_parts);
10,842✔
291
}
10,898✔
292

293
PK_Verifier::~PK_Verifier() = default;
23,781✔
294

295
std::string PK_Verifier::hash_function() const { return m_op->hash_function(); }
10,179✔
296

297
void PK_Verifier::set_input_format(Signature_Format format) {
×
298
   check_der_format_supported(format, m_parts);
×
299
   m_sig_format = format;
×
300
}
×
301

302
bool PK_Verifier::verify_message(const uint8_t msg[], size_t msg_length, const uint8_t sig[], size_t sig_length) {
63,218✔
303
   update(msg, msg_length);
63,218✔
304
   return check_signature(sig, sig_length);
63,218✔
305
}
306

307
void PK_Verifier::update(const uint8_t in[], size_t length) { m_op->update(in, length); }
66,708✔
308

309
namespace {
310

311
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✔
312
   std::vector<uint8_t> real_sig;
9,600✔
313
   BER_Decoder decoder(sig, length);
9,600✔
314
   BER_Decoder ber_sig = decoder.start_sequence();
9,600✔
315

316
   BOTAN_ASSERT_NOMSG(sig_parts != 0 && sig_part_size != 0);
9,257✔
317

318
   size_t count = 0;
319

320
   while(ber_sig.more_items()) {
25,682✔
321
      BigInt sig_part;
18,262✔
322
      ber_sig.decode(sig_part);
18,262✔
323
      real_sig += BigInt::encode_1363(sig_part, sig_part_size);
18,262✔
324
      ++count;
16,425✔
325
   }
18,262✔
326

327
   if(count != sig_parts) {
7,420✔
328
      throw Decoding_Error("PK_Verifier: signature size invalid");
115✔
329
   }
330

331
   const std::vector<uint8_t> reencoded = der_encode_signature(real_sig, sig_parts, sig_part_size);
7,305✔
332

333
   if(reencoded.size() != length || same_mem(reencoded.data(), sig, reencoded.size()) == false) {
14,172✔
334
      throw Decoding_Error("PK_Verifier: signature is not the canonical DER encoding");
926✔
335
   }
336
   return real_sig;
12,758✔
337
}
12,478✔
338

339
}  // namespace
340

341
bool PK_Verifier::check_signature(const uint8_t sig[], size_t length) {
67,095✔
342
   try {
67,095✔
343
      if(m_sig_format == Signature_Format::Standard) {
67,095✔
344
         return m_op->is_valid_signature(sig, length);
57,495✔
345
      } else if(m_sig_format == Signature_Format::DerSequence) {
9,600✔
346
         bool decoding_success = false;
9,600✔
347
         std::vector<uint8_t> real_sig;
9,600✔
348

349
         try {
9,600✔
350
            real_sig = decode_der_signature(sig, length, m_parts, m_part_size);
15,979✔
351
            decoding_success = true;
6,379✔
352
         } catch(Decoding_Error&) {}
3,221✔
353

354
         bool accept = m_op->is_valid_signature(real_sig.data(), real_sig.size());
9,377✔
355

356
         return accept && decoding_success;
9,377✔
357
      } else {
9,600✔
358
         throw Internal_Error("PK_Verifier: Invalid signature format enum");
×
359
      }
360
   } catch(Invalid_Argument&) {
334✔
361
      return false;
×
362
   } catch(Decoding_Error&) {
111✔
363
      return false;
111✔
364
   } catch(Encoding_Error&) {
334✔
365
      return false;
223✔
366
   }
223✔
367
}
368

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