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

randombit / botan / 5123321399

30 May 2023 04:06PM UTC coverage: 92.213% (+0.004%) from 92.209%
5123321399

Pull #3558

github

web-flow
Merge dd72f7389 into 057bcbc35
Pull Request #3558: Add braces around all if/else statements

75602 of 81986 relevant lines covered (92.21%)

11859779.3 hits per line

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

94.86
/src/lib/pubkey/pk_algs.cpp
1
/*
2
* PK Key
3
* (C) 1999-2010,2016 Jack Lloyd
4
*
5
* Botan is released under the Simplified BSD License (see license.txt)
6
*/
7

8
#include <botan/pk_algs.h>
9

10
#include <botan/internal/fmt.h>
11
#include <botan/internal/parsing.h>
12

13
#if defined(BOTAN_HAS_RSA)
14
   #include <botan/rsa.h>
15
#endif
16

17
#if defined(BOTAN_HAS_DSA)
18
   #include <botan/dsa.h>
19
#endif
20

21
#if defined(BOTAN_HAS_DL_GROUP)
22
   #include <botan/dl_group.h>
23
#endif
24

25
#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
26
   #include <botan/dh.h>
27
#endif
28

29
#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
30
   #include <botan/ecc_key.h>
31
#endif
32

33
#if defined(BOTAN_HAS_ECDSA)
34
   #include <botan/ecdsa.h>
35
#endif
36

37
#if defined(BOTAN_HAS_ECGDSA)
38
   #include <botan/ecgdsa.h>
39
#endif
40

41
#if defined(BOTAN_HAS_ECKCDSA)
42
   #include <botan/eckcdsa.h>
43
#endif
44

45
#if defined(BOTAN_HAS_ED25519)
46
   #include <botan/ed25519.h>
47
#endif
48

49
#if defined(BOTAN_HAS_GOST_34_10_2001)
50
   #include <botan/gost_3410.h>
51
#endif
52

53
#if defined(BOTAN_HAS_ELGAMAL)
54
   #include <botan/elgamal.h>
55
#endif
56

57
#if defined(BOTAN_HAS_ECDH)
58
   #include <botan/ecdh.h>
59
#endif
60

61
#if defined(BOTAN_HAS_CURVE_25519)
62
   #include <botan/curve25519.h>
63
#endif
64

65
#if defined(BOTAN_HAS_MCELIECE)
66
   #include <botan/mceliece.h>
67
#endif
68

69
#if defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S)
70
   #include <botan/kyber.h>
71
#endif
72

73
#if defined(BOTAN_HAS_XMSS_RFC8391)
74
   #include <botan/xmss.h>
75
#endif
76

77
#if defined(BOTAN_HAS_SM2)
78
   #include <botan/sm2.h>
79
#endif
80

81
#if defined(BOTAN_HAS_DILITHIUM) || defined(BOTAN_HAS_DILITHIUM_AES)
82
   #include <botan/dilithium.h>
83
#endif
84

85
namespace Botan {
86

87
std::unique_ptr<Public_Key> load_public_key(const AlgorithmIdentifier& alg_id,
15,313✔
88
                                            [[maybe_unused]] std::span<const uint8_t> key_bits) {
89
   const std::string oid_str = alg_id.oid().to_formatted_string();
15,313✔
90
   const std::vector<std::string> alg_info = split_on(oid_str, '/');
15,313✔
91
   std::string_view alg_name = alg_info[0];
15,313✔
92

93
#if defined(BOTAN_HAS_RSA)
94
   if(alg_name == "RSA") {
15,562✔
95
      return std::make_unique<RSA_PublicKey>(alg_id, key_bits);
22,237✔
96
   }
97
#endif
98

99
#if defined(BOTAN_HAS_CURVE_25519)
100
   if(alg_name == "Curve25519") {
3,769✔
101
      return std::make_unique<Curve25519_PublicKey>(alg_id, key_bits);
44✔
102
   }
103
#endif
104

105
#if defined(BOTAN_HAS_MCELIECE)
106
   if(alg_name == "McEliece") {
3,747✔
107
      return std::make_unique<McEliece_PublicKey>(key_bits);
2✔
108
   }
109
#endif
110

111
#if defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S)
112
   if(alg_name == "Kyber" || alg_name.starts_with("Kyber-")) {
6,030✔
113
      return std::make_unique<Kyber_PublicKey>(alg_id, key_bits);
24✔
114
   }
115
#endif
116

117
#if defined(BOTAN_HAS_ECDSA)
118
   if(alg_name == "ECDSA") {
3,734✔
119
      return std::make_unique<ECDSA_PublicKey>(alg_id, key_bits);
4,339✔
120
   }
121
#endif
122

123
#if defined(BOTAN_HAS_ECDH)
124
   if(alg_name == "ECDH") {
1,487✔
125
      return std::make_unique<ECDH_PublicKey>(alg_id, key_bits);
33✔
126
   }
127
#endif
128

129
#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
130
   if(alg_name == "DH") {
1,432✔
131
      return std::make_unique<DH_PublicKey>(alg_id, key_bits);
16✔
132
   }
133
#endif
134

135
#if defined(BOTAN_HAS_DSA)
136
   if(alg_name == "DSA") {
1,433✔
137
      return std::make_unique<DSA_PublicKey>(alg_id, key_bits);
355✔
138
   }
139
#endif
140

141
#if defined(BOTAN_HAS_ELGAMAL)
142
   if(alg_name == "ElGamal") {
2,018✔
143
      return std::make_unique<ElGamal_PublicKey>(alg_id, key_bits);
8✔
144
   }
145
#endif
146

147
#if defined(BOTAN_HAS_ECGDSA)
148
   if(alg_name == "ECGDSA") {
1,180✔
149
      return std::make_unique<ECGDSA_PublicKey>(alg_id, key_bits);
144✔
150
   }
151
#endif
152

153
#if defined(BOTAN_HAS_ECKCDSA)
154
   if(alg_name == "ECKCDSA") {
1,871✔
155
      return std::make_unique<ECKCDSA_PublicKey>(alg_id, key_bits);
142✔
156
   }
157
#endif
158

159
#if defined(BOTAN_HAS_ED25519)
160
   if(alg_name == "Ed25519") {
1,038✔
161
      return std::make_unique<Ed25519_PublicKey>(alg_id, key_bits);
1,524✔
162
   }
163
#endif
164

165
#if defined(BOTAN_HAS_GOST_34_10_2001)
166
   if(alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256" || alg_name == "GOST-34.10-2012-512") {
353✔
167
      return std::make_unique<GOST_3410_PublicKey>(alg_id, key_bits);
130✔
168
   }
169
#endif
170

171
#if defined(BOTAN_HAS_SM2)
172
   if(alg_name == "SM2" || alg_name == "SM2_Sig" || alg_name == "SM2_Enc") {
226✔
173
      return std::make_unique<SM2_PublicKey>(alg_id, key_bits);
26✔
174
   }
175
#endif
176

177
#if defined(BOTAN_HAS_XMSS_RFC8391)
178
   if(alg_name == "XMSS") {
197✔
179
      return std::make_unique<XMSS_PublicKey>(key_bits);
76✔
180
   }
181
#endif
182

183
#if defined(BOTAN_HAS_DILITHIUM) || defined(BOTAN_HAS_DILITHIUM_AES)
184
   if(alg_name == "Dilithium" || alg_name.starts_with("Dilithium-")) {
162✔
185
      return std::make_unique<Dilithium_PublicKey>(alg_id, key_bits);
166✔
186
   }
187
#endif
188

189
   throw Decoding_Error(fmt("Unknown or unavailable public key algorithm '{}'", alg_name));
152✔
190
}
15,467✔
191

192
std::unique_ptr<Private_Key> load_private_key(const AlgorithmIdentifier& alg_id,
3,356✔
193
                                              [[maybe_unused]] std::span<const uint8_t> key_bits) {
194
   const std::string oid_str = alg_id.oid().to_formatted_string();
3,356✔
195
   const std::vector<std::string> alg_info = split_on(oid_str, '/');
3,356✔
196
   std::string_view alg_name = alg_info[0];
3,356✔
197

198
#if defined(BOTAN_HAS_RSA)
199
   if(alg_name == "RSA") {
3,589✔
200
      return std::make_unique<RSA_PrivateKey>(alg_id, key_bits);
4,181✔
201
   }
202
#endif
203

204
#if defined(BOTAN_HAS_CURVE_25519)
205
   if(alg_name == "Curve25519") {
1,256✔
206
      return std::make_unique<Curve25519_PrivateKey>(alg_id, key_bits);
54✔
207
   }
208
#endif
209

210
#if defined(BOTAN_HAS_ECDSA)
211
   if(alg_name == "ECDSA") {
1,226✔
212
      return std::make_unique<ECDSA_PrivateKey>(alg_id, key_bits);
908✔
213
   }
214
#endif
215

216
#if defined(BOTAN_HAS_ECDH)
217
   if(alg_name == "ECDH") {
606✔
218
      return std::make_unique<ECDH_PrivateKey>(alg_id, key_bits);
158✔
219
   }
220
#endif
221

222
#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
223
   if(alg_name == "DH") {
494✔
224
      return std::make_unique<DH_PrivateKey>(alg_id, key_bits);
24✔
225
   }
226
#endif
227

228
#if defined(BOTAN_HAS_DSA)
229
   if(alg_name == "DSA") {
497✔
230
      return std::make_unique<DSA_PrivateKey>(alg_id, key_bits);
278✔
231
   }
232
#endif
233

234
#if defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S)
235
   if(alg_name == "Kyber" || alg_name.starts_with("Kyber-")) {
264✔
236
      return std::make_unique<Kyber_PrivateKey>(alg_id, key_bits);
36✔
237
   }
238
#endif
239

240
#if defined(BOTAN_HAS_MCELIECE)
241
   if(alg_name == "McEliece") {
228✔
242
      return std::make_unique<McEliece_PrivateKey>(key_bits);
4✔
243
   }
244
#endif
245

246
#if defined(BOTAN_HAS_ECGDSA)
247
   if(alg_name == "ECGDSA") {
224✔
248
      return std::make_unique<ECGDSA_PrivateKey>(alg_id, key_bits);
36✔
249
   }
250
#endif
251

252
#if defined(BOTAN_HAS_ECKCDSA)
253
   if(alg_name == "ECKCDSA") {
230✔
254
      return std::make_unique<ECKCDSA_PrivateKey>(alg_id, key_bits);
36✔
255
   }
256
#endif
257

258
#if defined(BOTAN_HAS_ED25519)
259
   if(alg_name == "Ed25519") {
202✔
260
      return std::make_unique<Ed25519_PrivateKey>(alg_id, key_bits);
17✔
261
   }
262
#endif
263

264
#if defined(BOTAN_HAS_GOST_34_10_2001)
265
   if(alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256" || alg_name == "GOST-34.10-2012-512") {
194✔
266
      return std::make_unique<GOST_3410_PrivateKey>(alg_id, key_bits);
24✔
267
   }
268
#endif
269

270
#if defined(BOTAN_HAS_SM2)
271
   if(alg_name == "SM2" || alg_name == "SM2_Sig" || alg_name == "SM2_Enc") {
215✔
272
      return std::make_unique<SM2_PrivateKey>(alg_id, key_bits);
40✔
273
   }
274
#endif
275

276
#if defined(BOTAN_HAS_ELGAMAL)
277
   if(alg_name == "ElGamal") {
146✔
278
      return std::make_unique<ElGamal_PrivateKey>(alg_id, key_bits);
28✔
279
   }
280
#endif
281

282
#if defined(BOTAN_HAS_XMSS_RFC8391)
283
   if(alg_name == "XMSS") {
132✔
284
      return std::make_unique<XMSS_PrivateKey>(key_bits);
16✔
285
   }
286
#endif
287

288
#if defined(BOTAN_HAS_DILITHIUM) || defined(BOTAN_HAS_DILITHIUM_AES)
289
   if(alg_name == "Dilithium" || alg_name.starts_with("Dilithium-")) {
128✔
290
      return std::make_unique<Dilithium_PrivateKey>(alg_id, key_bits);
55✔
291
   }
292
#endif
293

294
   throw Decoding_Error(fmt("Unknown or unavailable public key algorithm '{}'", alg_name));
122✔
295
}
3,441✔
296

297
std::unique_ptr<Private_Key> create_ec_private_key(std::string_view alg_name,
126✔
298
                                                   const EC_Group& ec_group,
299
                                                   RandomNumberGenerator& rng) {
300
   // Potentially unused if all EC algorthms are disabled
301
   BOTAN_UNUSED(alg_name, ec_group, rng);
126✔
302

303
#if defined(BOTAN_HAS_ECDSA)
304
   if(alg_name == "ECDSA") {
126✔
305
      return std::make_unique<ECDSA_PrivateKey>(rng, ec_group);
84✔
306
   }
307
#endif
308

309
#if defined(BOTAN_HAS_ECDH)
310
   if(alg_name == "ECDH") {
84✔
311
      return std::make_unique<ECDH_PrivateKey>(rng, ec_group);
56✔
312
   }
313
#endif
314

315
#if defined(BOTAN_HAS_ECKCDSA)
316
   if(alg_name == "ECKCDSA") {
64✔
317
      return std::make_unique<ECKCDSA_PrivateKey>(rng, ec_group);
34✔
318
   }
319
#endif
320

321
#if defined(BOTAN_HAS_GOST_34_10_2001)
322
   if(alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256" || alg_name == "GOST-34.10-2012-512") {
50✔
323
      return std::make_unique<GOST_3410_PrivateKey>(rng, ec_group);
22✔
324
   }
325
#endif
326

327
#if defined(BOTAN_HAS_SM2)
328
   if(alg_name == "SM2" || alg_name == "SM2_Sig" || alg_name == "SM2_Enc") {
40✔
329
      return std::make_unique<SM2_PrivateKey>(rng, ec_group);
22✔
330
   }
331
#endif
332

333
#if defined(BOTAN_HAS_ECGDSA)
334
   if(alg_name == "ECGDSA") {
17✔
335
      return std::make_unique<ECGDSA_PrivateKey>(rng, ec_group);
34✔
336
   }
337
#endif
338

339
   return nullptr;
×
340
}
341

342
std::unique_ptr<Private_Key> create_private_key(std::string_view alg_name,
252✔
343
                                                RandomNumberGenerator& rng,
344
                                                std::string_view params,
345
                                                std::string_view provider) {
346
   /*
347
   * Default paramaters are chosen for work factor > 2**128 where possible
348
   */
349

350
#if defined(BOTAN_HAS_CURVE_25519)
351
   if(alg_name == "Curve25519") {
263✔
352
      return std::make_unique<Curve25519_PrivateKey>(rng);
6✔
353
   }
354
#endif
355

356
#if defined(BOTAN_HAS_RSA)
357
   if(alg_name == "RSA") {
265✔
358
      const size_t modulus_bits = params.empty() ? 3072 : to_u32bit(params);
43✔
359
      return std::make_unique<RSA_PrivateKey>(rng, modulus_bits);
43✔
360
   }
361
#endif
362

363
#if defined(BOTAN_HAS_MCELIECE)
364
   if(alg_name == "McEliece") {
206✔
365
      const auto [n, t] = [&]() -> std::pair<size_t, size_t> {
2✔
366
         if(params.empty()) {
2✔
367
            return {2960, 57};
×
368
         }
369

370
         const auto mce_params = split_on(params, ',');
2✔
371

372
         if(mce_params.size() != 2) {
2✔
373
            throw Invalid_Argument(fmt("create_private_key: invalid McEliece parameters '{}'", params));
×
374
         }
375

376
         const size_t mce_n = to_u32bit(mce_params[0]);
2✔
377
         const size_t mce_t = to_u32bit(mce_params[1]);
2✔
378
         return {mce_n, mce_t};
2✔
379
      }();
4✔
380

381
      return std::make_unique<McEliece_PrivateKey>(rng, n, t);
2✔
382
   }
383
#endif
384

385
#if defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S)
386
   if(alg_name == "Kyber") {
246✔
387
      const auto mode = [&]() -> KyberMode {
16✔
388
         if(params.empty()) {
8✔
389
            return KyberMode::Kyber1024;
1✔
390
         }
391
         return KyberMode(params);
7✔
392
      }();
8✔
393

394
      return std::make_unique<Kyber_PrivateKey>(rng, mode);
8✔
395
   }
396
#endif
397

398
#if defined(BOTAN_HAS_DILITHIUM) || defined(BOTAN_HAS_DILITHIUM_AES)
399
   if(alg_name == "Dilithium" || alg_name == "Dilithium-") {
225✔
400
      const auto mode = [&]() -> DilithiumMode {
18✔
401
         if(params.empty()) {
18✔
402
            return DilithiumMode::Dilithium6x5;
403
         }
404
         return DilithiumMode(params);
10✔
405
      }();
18✔
406

407
      return std::make_unique<Dilithium_PrivateKey>(rng, mode);
18✔
408
   }
409
#endif
410

411
#if defined(BOTAN_HAS_XMSS_RFC8391)
412
   if(alg_name == "XMSS") {
206✔
413
      const auto xmss_oid = [&]() -> XMSS_Parameters::xmss_algorithm_t {
8✔
414
         if(params.empty()) {
4✔
415
            return XMSS_Parameters::XMSS_SHA2_10_512;
416
         }
417
         return XMSS_Parameters(params).oid();
3✔
418
      }();
4✔
419

420
      return std::make_unique<XMSS_PrivateKey>(xmss_oid, rng);
4✔
421
   }
422
#endif
423

424
#if defined(BOTAN_HAS_ED25519)
425
   if(alg_name == "Ed25519") {
206✔
426
      return std::make_unique<Ed25519_PrivateKey>(rng);
20✔
427
   }
428
#endif
429

430
   // ECC crypto
431
#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
432

433
   if(alg_name == "ECDSA" || alg_name == "ECDH" || alg_name == "ECKCDSA" || alg_name == "ECGDSA" || alg_name == "SM2" ||
299✔
434
      alg_name == "SM2_Sig" || alg_name == "SM2_Enc" || alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256" ||
91✔
435
      alg_name == "GOST-34.10-2012-512") {
38✔
436
      const std::string group_id = [&]() -> std::string {
252✔
437
         if(!params.empty()) {
126✔
438
            return std::string(params);
117✔
439
         }
440
         if(alg_name == "SM2" || alg_name == "SM2_Enc" || alg_name == "SM2_Sig") {
9✔
441
            return "sm2p256v1";
×
442
         }
443
         if(alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256") {
9✔
444
            return "gost_256A";
×
445
         }
446
         if(alg_name == "GOST-34.10-2012-512") {
9✔
447
            return "gost_512A";
×
448
         }
449
         if(alg_name == "ECGDSA") {
9✔
450
            return "brainpool256r1";
×
451
         }
452
         return "secp256r1";
9✔
453
      }();
126✔
454

455
      const EC_Group ec_group(group_id);
126✔
456
      return create_ec_private_key(alg_name, ec_group, rng);
126✔
457
   }
126✔
458
#endif
459

460
   // DL crypto
461
#if defined(BOTAN_HAS_DL_GROUP)
462
   if(alg_name == "DH" || alg_name == "DSA" || alg_name == "ElGamal") {
76✔
463
      const std::string group_id = [&]() -> std::string {
76✔
464
         if(!params.empty()) {
38✔
465
            return std::string(params);
28✔
466
         }
467
         if(alg_name == "DSA") {
10✔
468
            return "dsa/botan/2048";
8✔
469
         }
470
         return "modp/ietf/2048";
2✔
471
      }();
38✔
472

473
      DL_Group modp_group(group_id);
38✔
474

475
   #if defined(BOTAN_HAS_DIFFIE_HELLMAN)
476
      if(alg_name == "DH") {
38✔
477
         return std::make_unique<DH_PrivateKey>(rng, modp_group);
36✔
478
      }
479
   #endif
480

481
   #if defined(BOTAN_HAS_DSA)
482
      if(alg_name == "DSA") {
20✔
483
         return std::make_unique<DSA_PrivateKey>(rng, modp_group);
26✔
484
      }
485
   #endif
486

487
   #if defined(BOTAN_HAS_ELGAMAL)
488
      if(alg_name == "ElGamal") {
7✔
489
         return std::make_unique<ElGamal_PrivateKey>(rng, modp_group);
14✔
490
      }
491
   #endif
492
   }
38✔
493
#endif
494

495
   BOTAN_UNUSED(alg_name, rng, params, provider);
×
496

497
   return std::unique_ptr<Private_Key>();
252✔
498
}
499

500
std::vector<std::string> probe_provider_private_key(std::string_view alg_name,
43✔
501
                                                    const std::vector<std::string>& possible) {
502
   std::vector<std::string> providers;
43✔
503

504
   for(auto&& prov : possible) {
215✔
505
      if(prov == "base") {
172✔
506
         providers.push_back(prov);
43✔
507
      }
508
   }
509

510
   BOTAN_UNUSED(alg_name);
43✔
511

512
   return providers;
43✔
513
}
×
514
}  // 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