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

randombit / botan / 16581714815

28 Jul 2025 10:25PM UTC coverage: 90.475% (-0.2%) from 90.685%
16581714815

Pull #5021

github

web-flow
Merge 072983077 into 1eacc5b05
Pull Request #5021: Add PK_Signature_Options

99366 of 109827 relevant lines covered (90.48%)

12349417.34 hits per line

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

85.38
/src/lib/pubkey/pubkey.cpp
1
/*
2
* (C) 1999-2010,2015,2018,2024 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/mem_utils.h>
19
#include <botan/internal/parsing.h>
20
#include <botan/internal/pk_options_impl.h>
21
#include <botan/internal/stl_util.h>
22

23
namespace Botan {
24

25
secure_vector<uint8_t> PK_Decryptor::decrypt(const uint8_t in[], size_t length) const {
6,904✔
26
   uint8_t valid_mask = 0;
6,904✔
27

28
   secure_vector<uint8_t> decoded = do_decrypt(valid_mask, in, length);
6,904✔
29

30
   if(valid_mask == 0) {
6,865✔
31
      throw Decoding_Error("Invalid public key ciphertext, cannot decrypt");
3,176✔
32
   }
33

34
   return decoded;
3,689✔
35
}
3,176✔
36

37
secure_vector<uint8_t> PK_Decryptor::decrypt_or_random(const uint8_t in[],
587✔
38
                                                       size_t length,
39
                                                       size_t expected_pt_len,
40
                                                       RandomNumberGenerator& rng,
41
                                                       const uint8_t required_content_bytes[],
42
                                                       const uint8_t required_content_offsets[],
43
                                                       size_t required_contents_length) const {
44
   const secure_vector<uint8_t> fake_pms = [&]() {
1,761✔
45
      auto pms = rng.random_vec(expected_pt_len);
587✔
46

47
      for(size_t i = 0; i != required_contents_length; ++i) {
2,687✔
48
         const uint8_t exp = required_content_bytes[i];
2,100✔
49

50
         /*
51
         If an offset repeats we don't detect this and just return a PMS that satisfies
52
         the last requested index. If the requested (idx,value) tuple is the same, that's
53
         fine and just redundant. If they disagree, decryption will always fail, since the
54
         same byte cannot possibly have two distinct values.
55
         */
56
         const uint8_t off = required_content_offsets[i];
2,100✔
57
         BOTAN_ASSERT(off < expected_pt_len, "Offset in range of plaintext");
2,100✔
58
         pms[off] = exp;
2,100✔
59
      }
60

61
      return pms;
587✔
62
   }();
587✔
63

64
   uint8_t decrypt_valid = 0;
587✔
65
   secure_vector<uint8_t> decoded = do_decrypt(decrypt_valid, in, length);
587✔
66

67
   auto valid_mask = CT::Mask<uint8_t>::is_equal(decrypt_valid, 0xFF);
587✔
68
   valid_mask &= CT::Mask<uint8_t>(CT::Mask<size_t>::is_equal(decoded.size(), expected_pt_len));
587✔
69

70
   decoded.resize(expected_pt_len);
587✔
71

72
   for(size_t i = 0; i != required_contents_length; ++i) {
2,687✔
73
      const uint8_t exp = required_content_bytes[i];
2,100✔
74

75
      // We know off is in range because we already checked it when creating the fake premaster above
76
      const uint8_t off = required_content_offsets[i];
2,100✔
77

78
      auto eq = CT::Mask<uint8_t>::is_equal(decoded[off], exp);
2,100✔
79

80
      valid_mask &= eq;
2,100✔
81
   }
82

83
   // If valid_mask is false, assign fake pre master instead
84
   valid_mask.select_n(decoded.data(), decoded.data(), fake_pms.data(), expected_pt_len);
587✔
85

86
   return decoded;
587✔
87
}
587✔
88

89
secure_vector<uint8_t> PK_Decryptor::decrypt_or_random(const uint8_t in[],
405✔
90
                                                       size_t length,
91
                                                       size_t expected_pt_len,
92
                                                       RandomNumberGenerator& rng) const {
93
   return decrypt_or_random(in, length, expected_pt_len, rng, nullptr, nullptr, 0);
405✔
94
}
95

96
PK_Encryptor_EME::PK_Encryptor_EME(const Public_Key& key,
899✔
97
                                   RandomNumberGenerator& rng,
98
                                   std::string_view padding,
99
                                   std::string_view provider) {
899✔
100
   m_op = key.create_encryption_op(rng, padding, provider);
899✔
101
   if(!m_op) {
302✔
102
      throw Invalid_Argument(fmt("Key type {} does not support encryption", key.algo_name()));
×
103
   }
104
}
899✔
105

106
PK_Encryptor_EME::~PK_Encryptor_EME() = default;
506✔
107

108
PK_Encryptor_EME::PK_Encryptor_EME(PK_Encryptor_EME&&) noexcept = default;
×
109
PK_Encryptor_EME& PK_Encryptor_EME::operator=(PK_Encryptor_EME&&) noexcept = default;
×
110

111
size_t PK_Encryptor_EME::ciphertext_length(size_t ptext_len) const {
204✔
112
   return m_op->ciphertext_length(ptext_len);
204✔
113
}
114

115
std::vector<uint8_t> PK_Encryptor_EME::enc(const uint8_t ptext[], size_t len, RandomNumberGenerator& rng) const {
370✔
116
   return m_op->encrypt(std::span{ptext, len}, rng);
370✔
117
}
118

119
size_t PK_Encryptor_EME::maximum_input_size() const {
209✔
120
   return m_op->max_input_bits() / 8;
209✔
121
}
122

123
PK_Decryptor_EME::PK_Decryptor_EME(const Private_Key& key,
1,048✔
124
                                   RandomNumberGenerator& rng,
125
                                   std::string_view padding,
126
                                   std::string_view provider) {
1,048✔
127
   m_op = key.create_decryption_op(rng, padding, provider);
1,048✔
128
   if(!m_op) {
325✔
129
      throw Invalid_Argument(fmt("Key type {} does not support decryption", key.algo_name()));
×
130
   }
131
}
1,048✔
132

133
PK_Decryptor_EME::~PK_Decryptor_EME() = default;
571✔
134

135
PK_Decryptor_EME::PK_Decryptor_EME(PK_Decryptor_EME&&) noexcept = default;
×
136
PK_Decryptor_EME& PK_Decryptor_EME::operator=(PK_Decryptor_EME&&) noexcept = default;
×
137

138
size_t PK_Decryptor_EME::plaintext_length(size_t ctext_len) const {
203✔
139
   return m_op->plaintext_length(ctext_len);
203✔
140
}
141

142
secure_vector<uint8_t> PK_Decryptor_EME::do_decrypt(uint8_t& valid_mask, const uint8_t in[], size_t in_len) const {
5,770✔
143
   return m_op->decrypt(valid_mask, {in, in_len});
5,770✔
144
}
145

146
PK_KEM_Encryptor::PK_KEM_Encryptor(const Public_Key& key, std::string_view param, std::string_view provider) {
865✔
147
   m_op = key.create_kem_encryption_op(param, provider);
865✔
148
   if(!m_op) {
865✔
149
      throw Invalid_Argument(fmt("Key type {} does not support KEM encryption", key.algo_name()));
×
150
   }
151
}
865✔
152

153
PK_KEM_Encryptor::PK_KEM_Encryptor(const Public_Key& key,
×
154
                                   RandomNumberGenerator& rng,
155
                                   std::string_view kem_param,
156
                                   std::string_view provider) :
×
157
      PK_KEM_Encryptor(key, kem_param, provider) {
×
158
   BOTAN_UNUSED(rng);
×
159
}
×
160

161
PK_KEM_Encryptor::~PK_KEM_Encryptor() = default;
865✔
162

163
PK_KEM_Encryptor::PK_KEM_Encryptor(PK_KEM_Encryptor&&) noexcept = default;
×
164
PK_KEM_Encryptor& PK_KEM_Encryptor::operator=(PK_KEM_Encryptor&&) noexcept = default;
×
165

166
size_t PK_KEM_Encryptor::shared_key_length(size_t desired_shared_key_len) const {
7,008✔
167
   return m_op->shared_key_length(desired_shared_key_len);
7,008✔
168
}
169

170
size_t PK_KEM_Encryptor::encapsulated_key_length() const {
6,913✔
171
   return m_op->encapsulated_key_length();
6,913✔
172
}
173

174
void PK_KEM_Encryptor::encrypt(std::span<uint8_t> out_encapsulated_key,
3,382✔
175
                               std::span<uint8_t> out_shared_key,
176
                               RandomNumberGenerator& rng,
177
                               size_t desired_shared_key_len,
178
                               std::span<const uint8_t> salt) {
179
   BOTAN_ARG_CHECK(out_encapsulated_key.size() == encapsulated_key_length(), "not enough space for encapsulated key");
3,382✔
180
   BOTAN_ARG_CHECK(out_shared_key.size() == shared_key_length(desired_shared_key_len),
3,382✔
181
                   "not enough space for shared key");
182
   m_op->kem_encrypt(out_encapsulated_key, out_shared_key, rng, desired_shared_key_len, salt);
3,382✔
183
}
3,379✔
184

185
size_t PK_KEM_Decryptor::shared_key_length(size_t desired_shared_key_len) const {
7,162✔
186
   return m_op->shared_key_length(desired_shared_key_len);
7,162✔
187
}
188

189
size_t PK_KEM_Decryptor::encapsulated_key_length() const {
132✔
190
   return m_op->encapsulated_key_length();
132✔
191
}
192

193
PK_KEM_Decryptor::PK_KEM_Decryptor(const Private_Key& key,
807✔
194
                                   RandomNumberGenerator& rng,
195
                                   std::string_view param,
196
                                   std::string_view provider) {
807✔
197
   m_op = key.create_kem_decryption_op(rng, param, provider);
807✔
198
   if(!m_op) {
807✔
199
      throw Invalid_Argument(fmt("Key type {} does not support KEM decryption", key.algo_name()));
×
200
   }
201
}
807✔
202

203
PK_KEM_Decryptor::~PK_KEM_Decryptor() = default;
807✔
204

205
PK_KEM_Decryptor::PK_KEM_Decryptor(PK_KEM_Decryptor&&) noexcept = default;
×
206
PK_KEM_Decryptor& PK_KEM_Decryptor::operator=(PK_KEM_Decryptor&&) noexcept = default;
×
207

208
void PK_KEM_Decryptor::decrypt(std::span<uint8_t> out_shared_key,
3,453✔
209
                               std::span<const uint8_t> encap_key,
210
                               size_t desired_shared_key_len,
211
                               std::span<const uint8_t> salt) {
212
   BOTAN_ARG_CHECK(out_shared_key.size() == shared_key_length(desired_shared_key_len),
3,453✔
213
                   "inconsistent size of shared key output buffer");
214
   m_op->kem_decrypt(out_shared_key, encap_key, desired_shared_key_len, salt);
3,453✔
215
}
3,430✔
216

217
PK_Key_Agreement::PK_Key_Agreement(const Private_Key& key,
11,204✔
218
                                   RandomNumberGenerator& rng,
219
                                   std::string_view kdf,
220
                                   std::string_view provider) {
11,204✔
221
   m_op = key.create_key_agreement_op(rng, kdf, provider);
11,204✔
222
   if(!m_op) {
8,852✔
223
      throw Invalid_Argument(fmt("Key type {} does not support key agreement", key.algo_name()));
×
224
   }
225
}
11,204✔
226

227
PK_Key_Agreement::~PK_Key_Agreement() = default;
8,852✔
228

229
PK_Key_Agreement::PK_Key_Agreement(PK_Key_Agreement&&) noexcept = default;
×
230
PK_Key_Agreement& PK_Key_Agreement::operator=(PK_Key_Agreement&&) noexcept = default;
×
231

232
size_t PK_Key_Agreement::agreed_value_size() const {
946✔
233
   return m_op->agreed_value_size();
946✔
234
}
235

236
SymmetricKey PK_Key_Agreement::derive_key(size_t key_len,
182✔
237
                                          const uint8_t peer_key[],
238
                                          size_t peer_key_len,
239
                                          std::string_view salt) const {
240
   return this->derive_key(key_len, {peer_key, peer_key_len}, as_span_of_bytes(salt));
182✔
241
}
242

243
SymmetricKey PK_Key_Agreement::derive_key(size_t key_len,
10,235✔
244
                                          const std::span<const uint8_t> peer_key,
245
                                          std::string_view salt) const {
246
   return this->derive_key(key_len, peer_key, as_span_of_bytes(salt));
10,235✔
247
}
248

249
SymmetricKey PK_Key_Agreement::derive_key(size_t key_len,
10,433✔
250
                                          std::span<const uint8_t> peer_key,
251
                                          std::span<const uint8_t> salt) const {
252
   return SymmetricKey(m_op->agree(key_len, peer_key, salt));
10,433✔
253
}
254

255
PK_Signer::PK_Signer(const Private_Key& key,
9,731✔
256
                     RandomNumberGenerator& rng,
257
                     std::string_view padding,
258
                     Signature_Format format,
259
                     std::string_view provider) :
9,731✔
260
      PK_Signer(key,
261
                rng,
262
                parse_legacy_sig_options(key, padding)
19,462✔
263
                   .with_der_encoded_signature(format == Signature_Format::DerSequence)
19,462✔
264
                   .with_provider(provider)) {}
15,688✔
265

266
PK_Signer::PK_Signer(const Private_Key& key, RandomNumberGenerator& rng, const PK_Signature_Options& options) {
9,914✔
267
   if(options.using_context() && !key.supports_context_data()) {
9,914✔
268
      throw Invalid_Argument(fmt("Key type {} does not support context information", key.algo_name()));
×
269
   }
270

271
   m_op = key._create_signature_op(rng, options);
9,914✔
272

273
   if(!m_op) {
6,140✔
274
      throw Invalid_Argument(fmt("Key type {} does not support signature generation", key.algo_name()));
×
275
   }
276
   m_sig_format = options.using_der_encoded_signature() ? Signature_Format::DerSequence : Signature_Format::Standard;
6,140✔
277
   m_sig_element_size = key._signature_element_size_for_DER_encoding();
6,140✔
278

279
   if(m_sig_format == Signature_Format::DerSequence && !m_sig_element_size.has_value()) {
6,140✔
280
      throw Invalid_Argument(fmt("Key type {} does not support DER encoded signatures", key.algo_name()));
×
281
   }
282
}
9,914✔
283

284
AlgorithmIdentifier PK_Signer::algorithm_identifier() const {
2,087✔
285
   return m_op->algorithm_identifier();
2,087✔
286
}
287

288
std::string PK_Signer::hash_function() const {
2,605✔
289
   return m_op->hash_function();
2,605✔
290
}
291

292
PK_Signer::~PK_Signer() = default;
6,140✔
293

294
PK_Signer::PK_Signer(PK_Signer&&) noexcept = default;
×
295
PK_Signer& PK_Signer::operator=(PK_Signer&&) noexcept = default;
×
296

297
void PK_Signer::update(std::string_view in) {
1✔
298
   this->update(as_span_of_bytes(in));
1✔
299
}
1✔
300

301
void PK_Signer::update(const uint8_t in[], size_t length) {
10,473✔
302
   m_op->update({in, length});
10,473✔
303
}
10,472✔
304

305
namespace {
306

307
std::vector<uint8_t> der_encode_signature(std::span<const uint8_t> sig, size_t parts, size_t part_size) {
13,450✔
308
   if(sig.size() % parts != 0 || sig.size() != parts * part_size) {
13,450✔
309
      throw Encoding_Error("Unexpected size for DER signature");
×
310
   }
311

312
   BufferSlicer bs_sig(sig);
13,450✔
313
   std::vector<BigInt> sig_parts;
13,450✔
314
   sig_parts.reserve(parts);
13,450✔
315
   for(size_t i = 0; i != parts; ++i) {
40,350✔
316
      sig_parts.emplace_back(BigInt::from_bytes(bs_sig.take(part_size)));
26,900✔
317
   }
318

319
   std::vector<uint8_t> output;
13,450✔
320
   DER_Encoder(output).start_sequence().encode_list(sig_parts).end_cons();
53,800✔
321
   return output;
13,450✔
322
}
13,450✔
323

324
}  // namespace
325

326
size_t PK_Signer::signature_length() const {
1,286✔
327
   if(m_sig_format == Signature_Format::Standard) {
1,286✔
328
      return m_op->signature_length();
1,283✔
329
   } else if(m_sig_format == Signature_Format::DerSequence) {
3✔
330
      size_t sig_len = m_op->signature_length();
3✔
331

332
      size_t der_overhead = [sig_len]() {
9✔
333
         /*
334
         This was computed by DER encoding of some maximal value signatures
335
         (since DER is variable length)
336

337
         The first two cases covers all EC schemes since groups are at most 521
338
         bits.
339

340
         The other cases are only for finite field DSA which practically is only
341
         used up to 3072 bit groups but the calculation is correct up to a
342
         262096 (!) bit group so allow it. There are some intermediate sizes but
343
         this function is allowed to (and indeed must) return an over-estimate
344
         rather than an exact value since the actual length will change based on
345
         the computed signature.
346
         */
347

348
         if(sig_len <= 120) {
3✔
349
            // EC signatures <= 480 bits
350
            return 8;
351
         } else if(sig_len <= 248) {
×
352
            // EC signatures > 480 bits (or very small DSA groups...)
353
            return 9;
354
         } else {
355
            // Everything else. This is an over-estimate for groups under
356
            // 2040 bits but exact otherwise
357

358
            // This requires 15 bytes DER overhead and should never happen
359
            BOTAN_ASSERT_NOMSG(sig_len < 65524);
×
360
            return 14;
361
         }
362
      }();
3✔
363

364
      return sig_len + der_overhead;
3✔
365
   } else {
366
      throw Internal_Error("PK_Signer: Invalid signature format enum");
×
367
   }
368
}
369

370
std::vector<uint8_t> PK_Signer::signature(RandomNumberGenerator& rng) {
10,441✔
371
   std::vector<uint8_t> sig = m_op->sign(rng);
10,441✔
372

373
   if(m_sig_format == Signature_Format::Standard) {
10,438✔
374
      return sig;
7,236✔
375
   } else if(m_sig_format == Signature_Format::DerSequence) {
3,202✔
376
      BOTAN_ASSERT_NOMSG(m_sig_element_size.has_value());
3,202✔
377
      return der_encode_signature(sig, 2, m_sig_element_size.value());
3,202✔
378
   } else {
379
      throw Internal_Error("PK_Signer: Invalid signature format enum");
×
380
   }
381
}
10,438✔
382

383
PK_Verifier::PK_Verifier(const Public_Key& pub_key,
61,773✔
384
                         std::string_view padding,
385
                         Signature_Format format,
386
                         std::string_view provider) :
61,773✔
387
      PK_Verifier(pub_key,
388
                  parse_legacy_sig_options(pub_key, padding)
123,546✔
389
                     .with_der_encoded_signature(format == Signature_Format::DerSequence)
123,546✔
390
                     .with_provider(provider)) {}
74,161✔
391

392
PK_Verifier::PK_Verifier(const Public_Key& key, const PK_Signature_Options& options) {
63,573✔
393
   m_op = key._create_verification_op(options);
63,573✔
394

395
   if(!m_op) {
14,188✔
396
      throw Invalid_Argument(fmt("Key type {} does not support signature verification", key.algo_name()));
×
397
   }
398

399
   m_sig_element_size = key._signature_element_size_for_DER_encoding();
14,188✔
400
   m_sig_format = options.using_der_encoded_signature() ? Signature_Format::DerSequence : Signature_Format::Standard;
14,188✔
401

402
   if(m_sig_format == Signature_Format::DerSequence && !m_sig_element_size.has_value()) {
14,188✔
403
      throw Invalid_Argument(fmt("Key type {} does not support DER encoded signatures", key.algo_name()));
×
404
   }
405
}
63,573✔
406

407
PK_Verifier::PK_Verifier(const Public_Key& key,
17,765✔
408
                         const AlgorithmIdentifier& signature_algorithm,
409
                         std::string_view provider) {
17,765✔
410
   m_op = key.create_x509_verification_op(signature_algorithm, provider);
17,765✔
411
   if(!m_op) {
17,720✔
412
      throw Invalid_Argument(fmt("Key type {} does not support X.509 signature verification", key.algo_name()));
×
413
   }
414

415
   m_sig_format = key._default_x509_signature_format();
17,720✔
416
   m_sig_element_size = key._signature_element_size_for_DER_encoding();
17,720✔
417
}
17,765✔
418

419
PK_Verifier::~PK_Verifier() = default;
31,908✔
420

421
PK_Verifier::PK_Verifier(PK_Verifier&&) noexcept = default;
×
422
PK_Verifier& PK_Verifier::operator=(PK_Verifier&&) noexcept = default;
×
423

424
std::string PK_Verifier::hash_function() const {
17,359✔
425
   return m_op->hash_function();
17,359✔
426
}
427

428
void PK_Verifier::set_input_format(Signature_Format format) {
1✔
429
   if(format == Signature_Format::DerSequence) {
1✔
430
      BOTAN_ARG_CHECK(m_sig_element_size.has_value(), "This key does not support DER signatures");
1✔
431
   }
432
   m_sig_format = format;
1✔
433
}
1✔
434

435
bool PK_Verifier::verify_message(const uint8_t msg[], size_t msg_length, const uint8_t sig[], size_t sig_length) {
88,265✔
436
   update(msg, msg_length);
88,265✔
437
   return check_signature(sig, sig_length);
88,265✔
438
}
439

440
void PK_Verifier::update(std::string_view in) {
48✔
441
   this->update(as_span_of_bytes(in));
48✔
442
}
48✔
443

444
void PK_Verifier::update(const uint8_t in[], size_t length) {
93,002✔
445
   m_op->update({in, length});
93,002✔
446
}
93,002✔
447

448
namespace {
449

450
std::vector<uint8_t> decode_der_signature(const uint8_t sig[], size_t length, size_t sig_parts, size_t sig_part_size) {
12,514✔
451
   std::vector<uint8_t> real_sig;
12,514✔
452
   BER_Decoder decoder(sig, length);
12,514✔
453
   BER_Decoder ber_sig = decoder.start_sequence();
12,514✔
454

455
   BOTAN_ASSERT_NOMSG(sig_parts != 0 && sig_part_size != 0);
12,184✔
456

457
   size_t count = 0;
458

459
   while(ber_sig.more_items()) {
34,088✔
460
      BigInt sig_part;
23,738✔
461
      ber_sig.decode(sig_part);
23,738✔
462
      real_sig += sig_part.serialize(sig_part_size);
22,132✔
463
      ++count;
21,904✔
464
   }
23,738✔
465

466
   if(count != sig_parts) {
10,350✔
467
      throw Decoding_Error("PK_Verifier: signature size invalid");
102✔
468
   }
469

470
   const std::vector<uint8_t> reencoded = der_encode_signature(real_sig, sig_parts, sig_part_size);
10,248✔
471

472
   if(reencoded.size() != length || CT::is_equal(reencoded.data(), sig, reencoded.size()).as_bool() == false) {
20,194✔
473
      throw Decoding_Error("PK_Verifier: signature is not the canonical DER encoding");
707✔
474
   }
475
   return real_sig;
19,082✔
476
}
15,157✔
477

478
}  // namespace
479

480
bool PK_Verifier::check_signature(const uint8_t sig[], size_t length) {
94,288✔
481
   try {
94,288✔
482
      if(m_sig_format == Signature_Format::Standard) {
94,288✔
483
         return m_op->is_valid_signature({sig, length});
81,774✔
484
      } else if(m_sig_format == Signature_Format::DerSequence) {
12,514✔
485
         bool decoding_success = false;
12,514✔
486
         std::vector<uint8_t> real_sig;
12,514✔
487

488
         BOTAN_ASSERT_NOMSG(m_sig_element_size.has_value());
12,514✔
489

490
         try {
12,514✔
491
            real_sig = decode_der_signature(sig, length, 2, m_sig_element_size.value());
22,055✔
492
            decoding_success = true;
9,541✔
493
         } catch(Decoding_Error&) {}
2,973✔
494

495
         bool accept = m_op->is_valid_signature(real_sig);
12,514✔
496

497
         return accept && decoding_success;
12,286✔
498
      } else {
12,514✔
499
         throw Internal_Error("PK_Verifier: Invalid signature format enum");
×
500
      }
501
   } catch(Invalid_Argument&) {
342✔
502
      return false;
228✔
503
   } catch(Decoding_Error&) {
342✔
504
      return false;
114✔
505
   } catch(Encoding_Error&) {
114✔
506
      return false;
×
507
   }
×
508
}
509

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