Coverage Report

Created: 2022-05-14 06:06

/src/botan/src/lib/pubkey/pk_algs.cpp
Line
Count
Source (jump to first uncovered line)
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
#include <botan/internal/parsing.h>
10
11
#if defined(BOTAN_HAS_RSA)
12
  #include <botan/rsa.h>
13
#endif
14
15
#if defined(BOTAN_HAS_DSA)
16
  #include <botan/dsa.h>
17
#endif
18
19
#if defined(BOTAN_HAS_DL_GROUP)
20
  #include <botan/dl_group.h>
21
#endif
22
23
#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
24
  #include <botan/dh.h>
25
#endif
26
27
#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
28
  #include <botan/ecc_key.h>
29
#endif
30
31
#if defined(BOTAN_HAS_ECDSA)
32
  #include <botan/ecdsa.h>
33
#endif
34
35
#if defined(BOTAN_HAS_ECGDSA)
36
  #include <botan/ecgdsa.h>
37
#endif
38
39
#if defined(BOTAN_HAS_ECKCDSA)
40
  #include <botan/eckcdsa.h>
41
#endif
42
43
#if defined(BOTAN_HAS_ED25519)
44
  #include <botan/ed25519.h>
45
#endif
46
47
#if defined(BOTAN_HAS_GOST_34_10_2001)
48
  #include <botan/gost_3410.h>
49
#endif
50
51
#if defined(BOTAN_HAS_ELGAMAL)
52
  #include <botan/elgamal.h>
53
#endif
54
55
#if defined(BOTAN_HAS_ECDH)
56
  #include <botan/ecdh.h>
57
#endif
58
59
#if defined(BOTAN_HAS_CURVE_25519)
60
  #include <botan/curve25519.h>
61
#endif
62
63
#if defined(BOTAN_HAS_MCELIECE)
64
  #include <botan/mceliece.h>
65
#endif
66
67
#if defined(BOTAN_HAS_XMSS_RFC8391)
68
  #include <botan/xmss.h>
69
#endif
70
71
#if defined(BOTAN_HAS_SM2)
72
  #include <botan/sm2.h>
73
#endif
74
75
namespace Botan {
76
77
std::unique_ptr<Public_Key>
78
load_public_key(const AlgorithmIdentifier& alg_id,
79
                const std::vector<uint8_t>& key_bits)
80
9.63k
   {
81
9.63k
   const std::string oid_str = alg_id.get_oid().to_formatted_string();
82
9.63k
   const std::vector<std::string> alg_info = split_on(oid_str, '/');
83
9.63k
   const std::string alg_name = alg_info[0];
84
85
9.63k
#if defined(BOTAN_HAS_RSA)
86
9.63k
   if(alg_name == "RSA")
87
7.15k
      return std::make_unique<RSA_PublicKey>(alg_id, key_bits);
88
2.48k
#endif
89
90
2.48k
#if defined(BOTAN_HAS_CURVE_25519)
91
2.48k
   if(alg_name == "Curve25519")
92
1
      return std::make_unique<Curve25519_PublicKey>(alg_id, key_bits);
93
2.48k
#endif
94
95
2.48k
#if defined(BOTAN_HAS_MCELIECE)
96
2.48k
   if(alg_name == "McEliece")
97
0
      return std::make_unique<McEliece_PublicKey>(key_bits);
98
2.48k
#endif
99
100
2.48k
#if defined(BOTAN_HAS_ECDSA)
101
2.48k
   if(alg_name == "ECDSA")
102
1.69k
      return std::make_unique<ECDSA_PublicKey>(alg_id, key_bits);
103
791
#endif
104
105
791
#if defined(BOTAN_HAS_ECDH)
106
791
   if(alg_name == "ECDH")
107
3
      return std::make_unique<ECDH_PublicKey>(alg_id, key_bits);
108
788
#endif
109
110
788
#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
111
788
   if(alg_name == "DH")
112
40
      return std::make_unique<DH_PublicKey>(alg_id, key_bits);
113
748
#endif
114
115
748
#if defined(BOTAN_HAS_DSA)
116
748
   if(alg_name == "DSA")
117
160
      return std::make_unique<DSA_PublicKey>(alg_id, key_bits);
118
588
#endif
119
120
588
#if defined(BOTAN_HAS_ELGAMAL)
121
588
   if(alg_name == "ElGamal")
122
0
      return std::make_unique<ElGamal_PublicKey>(alg_id, key_bits);
123
588
#endif
124
125
588
#if defined(BOTAN_HAS_ECGDSA)
126
588
   if(alg_name == "ECGDSA")
127
0
      return std::make_unique<ECGDSA_PublicKey>(alg_id, key_bits);
128
588
#endif
129
130
588
#if defined(BOTAN_HAS_ECKCDSA)
131
588
   if(alg_name == "ECKCDSA")
132
0
      return std::make_unique<ECKCDSA_PublicKey>(alg_id, key_bits);
133
588
#endif
134
135
588
#if defined(BOTAN_HAS_ED25519)
136
588
   if(alg_name == "Ed25519")
137
1
      return std::make_unique<Ed25519_PublicKey>(alg_id, key_bits);
138
587
#endif
139
140
587
#if defined(BOTAN_HAS_GOST_34_10_2001)
141
587
   if(alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256" || alg_name == "GOST-34.10-2012-512")
142
23
      return std::make_unique<GOST_3410_PublicKey>(alg_id, key_bits);
143
564
#endif
144
145
564
#if defined(BOTAN_HAS_SM2)
146
564
   if(alg_name == "SM2" || alg_name == "SM2_Sig" || alg_name == "SM2_Enc")
147
0
      return std::make_unique<SM2_PublicKey>(alg_id, key_bits);
148
564
#endif
149
150
564
#if defined(BOTAN_HAS_XMSS_RFC8391)
151
564
   if(alg_name == "XMSS")
152
0
      return std::make_unique<XMSS_PublicKey>(key_bits);
153
564
#endif
154
155
564
   throw Decoding_Error("Unknown or unavailable public key algorithm " + alg_name);
156
564
   }
157
158
std::unique_ptr<Private_Key>
159
load_private_key(const AlgorithmIdentifier& alg_id,
160
                 const secure_vector<uint8_t>& key_bits)
161
3.36k
   {
162
3.36k
   const std::string alg_name = alg_id.get_oid().to_formatted_string();
163
164
3.36k
#if defined(BOTAN_HAS_RSA)
165
3.36k
   if(alg_name == "RSA")
166
268
      return std::make_unique<RSA_PrivateKey>(alg_id, key_bits);
167
3.10k
#endif
168
169
3.10k
#if defined(BOTAN_HAS_CURVE_25519)
170
3.10k
   if(alg_name == "Curve25519")
171
19
      return std::make_unique<Curve25519_PrivateKey>(alg_id, key_bits);
172
3.08k
#endif
173
174
3.08k
#if defined(BOTAN_HAS_ECDSA)
175
3.08k
   if(alg_name == "ECDSA")
176
840
      return std::make_unique<ECDSA_PrivateKey>(alg_id, key_bits);
177
2.24k
#endif
178
179
2.24k
#if defined(BOTAN_HAS_ECDH)
180
2.24k
   if(alg_name == "ECDH")
181
1.73k
      return std::make_unique<ECDH_PrivateKey>(alg_id, key_bits);
182
503
#endif
183
184
503
#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
185
503
   if(alg_name == "DH")
186
152
      return std::make_unique<DH_PrivateKey>(alg_id, key_bits);
187
351
#endif
188
189
351
#if defined(BOTAN_HAS_DSA)
190
351
   if(alg_name == "DSA")
191
308
      return std::make_unique<DSA_PrivateKey>(alg_id, key_bits);
192
43
#endif
193
194
43
#if defined(BOTAN_HAS_MCELIECE)
195
43
   if(alg_name == "McEliece")
196
0
      return std::make_unique<McEliece_PrivateKey>(key_bits);
197
43
#endif
198
199
43
#if defined(BOTAN_HAS_ECGDSA)
200
43
   if(alg_name == "ECGDSA")
201
0
      return std::make_unique<ECGDSA_PrivateKey>(alg_id, key_bits);
202
43
#endif
203
204
43
#if defined(BOTAN_HAS_ECKCDSA)
205
43
   if(alg_name == "ECKCDSA")
206
0
      return std::make_unique<ECKCDSA_PrivateKey>(alg_id, key_bits);
207
43
#endif
208
209
43
#if defined(BOTAN_HAS_ED25519)
210
43
   if(alg_name == "Ed25519")
211
30
      return std::make_unique<Ed25519_PrivateKey>(alg_id, key_bits);
212
13
#endif
213
214
13
#if defined(BOTAN_HAS_GOST_34_10_2001)
215
13
   if(alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256" || alg_name == "GOST-34.10-2012-512")
216
0
      return std::make_unique<GOST_3410_PrivateKey>(alg_id, key_bits);
217
13
#endif
218
219
13
#if defined(BOTAN_HAS_SM2)
220
13
   if(alg_name == "SM2" || alg_name == "SM2_Sig" || alg_name == "SM2_Enc")
221
0
      return std::make_unique<SM2_PrivateKey>(alg_id, key_bits);
222
13
#endif
223
224
13
#if defined(BOTAN_HAS_ELGAMAL)
225
13
   if(alg_name == "ElGamal")
226
0
      return std::make_unique<ElGamal_PrivateKey>(alg_id, key_bits);
227
13
#endif
228
229
13
#if defined(BOTAN_HAS_XMSS_RFC8391)
230
13
   if(alg_name == "XMSS")
231
0
      return std::make_unique<XMSS_PrivateKey>(key_bits);
232
13
#endif
233
234
13
   throw Decoding_Error("Unknown or unavailable public key algorithm " + alg_name);
235
13
   }
236
237
#if defined(BOTAN_HAS_ECC_GROUP)
238
239
namespace {
240
241
std::string default_ec_group_for(const std::string& alg_name)
242
0
   {
243
0
   if(alg_name == "SM2" || alg_name == "SM2_Enc" || alg_name == "SM2_Sig")
244
0
      return "sm2p256v1";
245
0
   if(alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256")
246
0
      return "gost_256A";
247
0
   if(alg_name == "GOST-34.10-2012-512")
248
0
      return "gost_512A";
249
0
   if(alg_name == "ECGDSA")
250
0
      return "brainpool256r1";
251
0
   return "secp256r1";
252
253
0
   }
254
255
}
256
257
#endif
258
259
BOTAN_PUBLIC_API(3,0) std::unique_ptr<Private_Key>
260
create_ec_private_key(const std::string& alg_name,
261
                      const EC_Group& ec_group,
262
                      RandomNumberGenerator& rng)
263
0
   {
264
0
#if defined(BOTAN_HAS_ECDSA)
265
0
   if(alg_name == "ECDSA")
266
0
      return std::make_unique<ECDSA_PrivateKey>(rng, ec_group);
267
0
#endif
268
269
0
#if defined(BOTAN_HAS_ECDH)
270
0
   if(alg_name == "ECDH")
271
0
      return std::make_unique<ECDH_PrivateKey>(rng, ec_group);
272
0
#endif
273
274
0
#if defined(BOTAN_HAS_ECKCDSA)
275
0
   if(alg_name == "ECKCDSA")
276
0
      return std::make_unique<ECKCDSA_PrivateKey>(rng, ec_group);
277
0
#endif
278
279
0
#if defined(BOTAN_HAS_GOST_34_10_2001)
280
0
   if(alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256" || alg_name == "GOST-34.10-2012-512")
281
0
      return std::make_unique<GOST_3410_PrivateKey>(rng, ec_group);
282
0
#endif
283
284
0
#if defined(BOTAN_HAS_SM2)
285
0
   if(alg_name == "SM2" || alg_name == "SM2_Sig" || alg_name == "SM2_Enc")
286
0
      return std::make_unique<SM2_PrivateKey>(rng, ec_group);
287
0
#endif
288
289
0
#if defined(BOTAN_HAS_ECGDSA)
290
0
   if(alg_name == "ECGDSA")
291
0
      return std::make_unique<ECGDSA_PrivateKey>(rng, ec_group);
292
0
#endif
293
294
0
   return nullptr;
295
0
   }
296
297
298
std::unique_ptr<Private_Key>
299
create_private_key(const std::string& alg_name,
300
                   RandomNumberGenerator& rng,
301
                   const std::string& params,
302
                   const std::string& provider)
303
0
   {
304
   /*
305
   * Default paramaters are chosen for work factor > 2**128 where possible
306
   */
307
308
0
#if defined(BOTAN_HAS_CURVE_25519)
309
0
   if(alg_name == "Curve25519")
310
0
      return std::make_unique<Curve25519_PrivateKey>(rng);
311
0
#endif
312
313
0
#if defined(BOTAN_HAS_RSA)
314
0
   if(alg_name == "RSA")
315
0
      {
316
0
      const size_t rsa_bits = (params.empty() ? 3072 : to_u32bit(params));
317
0
      return std::make_unique<RSA_PrivateKey>(rng, rsa_bits);
318
0
      }
319
0
#endif
320
321
0
#if defined(BOTAN_HAS_MCELIECE)
322
0
   if(alg_name == "McEliece")
323
0
      {
324
0
      std::vector<std::string> mce_param =
325
0
         Botan::split_on(params.empty() ? "2960,57" : params, ',');
326
327
0
      if(mce_param.size() != 2)
328
0
         throw Invalid_Argument("create_private_key bad McEliece parameters " + params);
329
330
0
      size_t mce_n = Botan::to_u32bit(mce_param[0]);
331
0
      size_t mce_t = Botan::to_u32bit(mce_param[1]);
332
333
0
      return std::make_unique<Botan::McEliece_PrivateKey>(rng, mce_n, mce_t);
334
0
      }
335
0
#endif
336
337
0
#if defined(BOTAN_HAS_XMSS_RFC8391)
338
0
   if(alg_name == "XMSS")
339
0
      {
340
0
      return std::make_unique<XMSS_PrivateKey>(XMSS_Parameters(params.empty() ? "XMSS-SHA2_10_512" : params).oid(), rng);
341
0
      }
342
0
#endif
343
344
0
#if defined(BOTAN_HAS_ED25519)
345
0
   if(alg_name == "Ed25519")
346
0
      {
347
0
      return std::make_unique<Ed25519_PrivateKey>(rng);
348
0
      }
349
0
#endif
350
351
   // ECC crypto
352
0
#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
353
354
0
   if(alg_name == "ECDSA" ||
355
0
      alg_name == "ECDH" ||
356
0
      alg_name == "ECKCDSA" ||
357
0
      alg_name == "ECGDSA" ||
358
0
      alg_name == "SM2" ||
359
0
      alg_name == "SM2_Sig" ||
360
0
      alg_name == "SM2_Enc" ||
361
0
      alg_name == "GOST-34.10" ||
362
0
      alg_name == "GOST-34.10-2012-256" ||
363
0
      alg_name == "GOST-34.10-2012-512")
364
0
      {
365
0
      const EC_Group ec_group(params.empty() ? default_ec_group_for(alg_name) : params);
366
0
      return create_ec_private_key(alg_name, ec_group, rng);
367
0
      }
368
0
#endif
369
370
   // DL crypto
371
0
#if defined(BOTAN_HAS_DL_GROUP)
372
0
   if(alg_name == "DH" || alg_name == "DSA" || alg_name == "ElGamal")
373
0
      {
374
0
      std::string default_group = (alg_name == "DSA") ? "dsa/botan/2048" : "modp/ietf/2048";
375
0
      DL_Group modp_group(params.empty() ? default_group : params);
376
377
0
#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
378
0
      if(alg_name == "DH")
379
0
         return std::make_unique<DH_PrivateKey>(rng, modp_group);
380
0
#endif
381
382
0
#if defined(BOTAN_HAS_DSA)
383
0
      if(alg_name == "DSA")
384
0
         return std::make_unique<DSA_PrivateKey>(rng, modp_group);
385
0
#endif
386
387
0
#if defined(BOTAN_HAS_ELGAMAL)
388
0
      if(alg_name == "ElGamal")
389
0
         return std::make_unique<ElGamal_PrivateKey>(rng, modp_group);
390
0
#endif
391
0
      }
392
0
#endif
393
394
0
   BOTAN_UNUSED(alg_name, rng, params, provider);
395
396
0
   return std::unique_ptr<Private_Key>();
397
0
   }
398
399
std::vector<std::string>
400
probe_provider_private_key(const std::string& alg_name,
401
                           const std::vector<std::string>& possible)
402
0
   {
403
0
   std::vector<std::string> providers;
404
405
0
   for(auto&& prov : possible)
406
0
      {
407
0
      if(prov == "base")
408
0
         providers.push_back(prov);
409
0
      }
410
411
0
   BOTAN_UNUSED(alg_name);
412
413
0
   return providers;
414
0
   }
415
}