Coverage Report

Created: 2021-05-04 09:02

/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
#if defined(BOTAN_HAS_OPENSSL)
76
  #include <botan/internal/openssl.h>
77
#endif
78
79
namespace Botan {
80
81
std::unique_ptr<Public_Key>
82
load_public_key(const AlgorithmIdentifier& alg_id,
83
                const std::vector<uint8_t>& key_bits)
84
8.14k
   {
85
8.14k
   const std::string oid_str = alg_id.get_oid().to_formatted_string();
86
8.14k
   const std::vector<std::string> alg_info = split_on(oid_str, '/');
87
8.14k
   const std::string alg_name = alg_info[0];
88
89
8.14k
#if defined(BOTAN_HAS_RSA)
90
8.14k
   if(alg_name == "RSA")
91
6.85k
      return std::make_unique<RSA_PublicKey>(alg_id, key_bits);
92
1.29k
#endif
93
94
1.29k
#if defined(BOTAN_HAS_CURVE_25519)
95
1.29k
   if(alg_name == "Curve25519")
96
1
      return std::make_unique<Curve25519_PublicKey>(alg_id, key_bits);
97
1.29k
#endif
98
99
1.29k
#if defined(BOTAN_HAS_MCELIECE)
100
1.29k
   if(alg_name == "McEliece")
101
0
      return std::make_unique<McEliece_PublicKey>(key_bits);
102
1.29k
#endif
103
104
1.29k
#if defined(BOTAN_HAS_ECDSA)
105
1.29k
   if(alg_name == "ECDSA")
106
903
      return std::make_unique<ECDSA_PublicKey>(alg_id, key_bits);
107
394
#endif
108
109
394
#if defined(BOTAN_HAS_ECDH)
110
394
   if(alg_name == "ECDH")
111
3
      return std::make_unique<ECDH_PublicKey>(alg_id, key_bits);
112
391
#endif
113
114
391
#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
115
391
   if(alg_name == "DH")
116
13
      return std::make_unique<DH_PublicKey>(alg_id, key_bits);
117
378
#endif
118
119
378
#if defined(BOTAN_HAS_DSA)
120
378
   if(alg_name == "DSA")
121
143
      return std::make_unique<DSA_PublicKey>(alg_id, key_bits);
122
235
#endif
123
124
235
#if defined(BOTAN_HAS_ELGAMAL)
125
235
   if(alg_name == "ElGamal")
126
0
      return std::make_unique<ElGamal_PublicKey>(alg_id, key_bits);
127
235
#endif
128
129
235
#if defined(BOTAN_HAS_ECGDSA)
130
235
   if(alg_name == "ECGDSA")
131
0
      return std::make_unique<ECGDSA_PublicKey>(alg_id, key_bits);
132
235
#endif
133
134
235
#if defined(BOTAN_HAS_ECKCDSA)
135
235
   if(alg_name == "ECKCDSA")
136
0
      return std::make_unique<ECKCDSA_PublicKey>(alg_id, key_bits);
137
235
#endif
138
139
235
#if defined(BOTAN_HAS_ED25519)
140
235
   if(alg_name == "Ed25519")
141
1
      return std::make_unique<Ed25519_PublicKey>(alg_id, key_bits);
142
234
#endif
143
144
234
#if defined(BOTAN_HAS_GOST_34_10_2001)
145
234
   if(alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256" || alg_name == "GOST-34.10-2012-512")
146
0
      return std::make_unique<GOST_3410_PublicKey>(alg_id, key_bits);
147
234
#endif
148
149
234
#if defined(BOTAN_HAS_SM2)
150
234
   if(alg_name == "SM2" || alg_name == "SM2_Sig" || alg_name == "SM2_Enc")
151
0
      return std::make_unique<SM2_PublicKey>(alg_id, key_bits);
152
234
#endif
153
154
234
#if defined(BOTAN_HAS_XMSS_RFC8391)
155
234
   if(alg_name == "XMSS")
156
0
      return std::make_unique<XMSS_PublicKey>(key_bits);
157
234
#endif
158
159
234
   throw Decoding_Error("Unknown or unavailable public key algorithm " + alg_name);
160
234
   }
161
162
std::unique_ptr<Private_Key>
163
load_private_key(const AlgorithmIdentifier& alg_id,
164
                 const secure_vector<uint8_t>& key_bits)
165
2.15k
   {
166
2.15k
   const std::string alg_name = alg_id.get_oid().to_formatted_string();
167
168
2.15k
#if defined(BOTAN_HAS_RSA)
169
2.15k
   if(alg_name == "RSA")
170
71
      return std::make_unique<RSA_PrivateKey>(alg_id, key_bits);
171
2.08k
#endif
172
173
2.08k
#if defined(BOTAN_HAS_CURVE_25519)
174
2.08k
   if(alg_name == "Curve25519")
175
19
      return std::make_unique<Curve25519_PrivateKey>(alg_id, key_bits);
176
2.06k
#endif
177
178
2.06k
#if defined(BOTAN_HAS_ECDSA)
179
2.06k
   if(alg_name == "ECDSA")
180
642
      return std::make_unique<ECDSA_PrivateKey>(alg_id, key_bits);
181
1.42k
#endif
182
183
1.42k
#if defined(BOTAN_HAS_ECDH)
184
1.42k
   if(alg_name == "ECDH")
185
1.15k
      return std::make_unique<ECDH_PrivateKey>(alg_id, key_bits);
186
266
#endif
187
188
266
#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
189
266
   if(alg_name == "DH")
190
50
      return std::make_unique<DH_PrivateKey>(alg_id, key_bits);
191
216
#endif
192
193
216
#if defined(BOTAN_HAS_DSA)
194
216
   if(alg_name == "DSA")
195
180
      return std::make_unique<DSA_PrivateKey>(alg_id, key_bits);
196
36
#endif
197
198
36
#if defined(BOTAN_HAS_MCELIECE)
199
36
   if(alg_name == "McEliece")
200
0
      return std::make_unique<McEliece_PrivateKey>(key_bits);
201
36
#endif
202
203
36
#if defined(BOTAN_HAS_ECGDSA)
204
36
   if(alg_name == "ECGDSA")
205
0
      return std::make_unique<ECGDSA_PrivateKey>(alg_id, key_bits);
206
36
#endif
207
208
36
#if defined(BOTAN_HAS_ECKCDSA)
209
36
   if(alg_name == "ECKCDSA")
210
0
      return std::make_unique<ECKCDSA_PrivateKey>(alg_id, key_bits);
211
36
#endif
212
213
36
#if defined(BOTAN_HAS_ED25519)
214
36
   if(alg_name == "Ed25519")
215
30
      return std::make_unique<Ed25519_PrivateKey>(alg_id, key_bits);
216
6
#endif
217
218
6
#if defined(BOTAN_HAS_GOST_34_10_2001)
219
6
   if(alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256" || alg_name == "GOST-34.10-2012-512")
220
0
      return std::make_unique<GOST_3410_PrivateKey>(alg_id, key_bits);
221
6
#endif
222
223
6
#if defined(BOTAN_HAS_SM2)
224
6
   if(alg_name == "SM2" || alg_name == "SM2_Sig" || alg_name == "SM2_Enc")
225
0
      return std::make_unique<SM2_PrivateKey>(alg_id, key_bits);
226
6
#endif
227
228
6
#if defined(BOTAN_HAS_ELGAMAL)
229
6
   if(alg_name == "ElGamal")
230
0
      return std::make_unique<ElGamal_PrivateKey>(alg_id, key_bits);
231
6
#endif
232
233
6
#if defined(BOTAN_HAS_XMSS_RFC8391)
234
6
   if(alg_name == "XMSS")
235
0
      return std::make_unique<XMSS_PrivateKey>(key_bits);
236
6
#endif
237
238
6
   throw Decoding_Error("Unknown or unavailable public key algorithm " + alg_name);
239
6
   }
240
241
#if defined(BOTAN_HAS_ECC_GROUP)
242
243
namespace {
244
245
std::string default_ec_group_for(const std::string& alg_name)
246
0
   {
247
0
   if(alg_name == "SM2" || alg_name == "SM2_Enc" || alg_name == "SM2_Sig")
248
0
      return "sm2p256v1";
249
0
   if(alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256")
250
0
      return "gost_256A";
251
0
   if(alg_name == "GOST-34.10-2012-512")
252
0
      return "gost_512A";
253
0
   if(alg_name == "ECGDSA")
254
0
      return "brainpool256r1";
255
0
   return "secp256r1";
256
257
0
   }
258
259
}
260
261
#endif
262
263
BOTAN_PUBLIC_API(3,0) std::unique_ptr<Private_Key>
264
create_ec_private_key(const std::string& alg_name,
265
                      const EC_Group& ec_group,
266
                      RandomNumberGenerator& rng)
267
0
   {
268
0
#if defined(BOTAN_HAS_ECDSA)
269
0
   if(alg_name == "ECDSA")
270
0
      return std::make_unique<ECDSA_PrivateKey>(rng, ec_group);
271
0
#endif
272
273
0
#if defined(BOTAN_HAS_ECDH)
274
0
   if(alg_name == "ECDH")
275
0
      return std::make_unique<ECDH_PrivateKey>(rng, ec_group);
276
0
#endif
277
278
0
#if defined(BOTAN_HAS_ECKCDSA)
279
0
   if(alg_name == "ECKCDSA")
280
0
      return std::make_unique<ECKCDSA_PrivateKey>(rng, ec_group);
281
0
#endif
282
283
0
#if defined(BOTAN_HAS_GOST_34_10_2001)
284
0
   if(alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256" || alg_name == "GOST-34.10-2012-512")
285
0
      return std::make_unique<GOST_3410_PrivateKey>(rng, ec_group);
286
0
#endif
287
288
0
#if defined(BOTAN_HAS_SM2)
289
0
   if(alg_name == "SM2" || alg_name == "SM2_Sig" || alg_name == "SM2_Enc")
290
0
      return std::make_unique<SM2_PrivateKey>(rng, ec_group);
291
0
#endif
292
293
0
#if defined(BOTAN_HAS_ECGDSA)
294
0
   if(alg_name == "ECGDSA")
295
0
      return std::make_unique<ECGDSA_PrivateKey>(rng, ec_group);
296
0
#endif
297
298
0
   return nullptr;
299
0
   }
300
301
302
std::unique_ptr<Private_Key>
303
create_private_key(const std::string& alg_name,
304
                   RandomNumberGenerator& rng,
305
                   const std::string& params,
306
                   const std::string& provider)
307
0
   {
308
   /*
309
   * Default paramaters are chosen for work factor > 2**128 where possible
310
   */
311
312
0
#if defined(BOTAN_HAS_CURVE_25519)
313
0
   if(alg_name == "Curve25519")
314
0
      return std::make_unique<Curve25519_PrivateKey>(rng);
315
0
#endif
316
317
0
#if defined(BOTAN_HAS_RSA)
318
0
   if(alg_name == "RSA")
319
0
      {
320
0
      const size_t rsa_bits = (params.empty() ? 3072 : to_u32bit(params));
321
#if defined(BOTAN_HAS_OPENSSL)
322
      if(provider.empty() || provider == "openssl")
323
         {
324
         auto pk = make_openssl_rsa_private_key(rng, rsa_bits);
325
326
         // Return nullptr if openssl was specifically requested
327
         if(pk || !provider.empty())
328
            return pk;
329
         }
330
#endif
331
0
      return std::make_unique<RSA_PrivateKey>(rng, rsa_bits);
332
0
      }
333
0
#endif
334
335
0
#if defined(BOTAN_HAS_MCELIECE)
336
0
   if(alg_name == "McEliece")
337
0
      {
338
0
      std::vector<std::string> mce_param =
339
0
         Botan::split_on(params.empty() ? "2960,57" : params, ',');
340
341
0
      if(mce_param.size() != 2)
342
0
         throw Invalid_Argument("create_private_key bad McEliece parameters " + params);
343
344
0
      size_t mce_n = Botan::to_u32bit(mce_param[0]);
345
0
      size_t mce_t = Botan::to_u32bit(mce_param[1]);
346
347
0
      return std::make_unique<Botan::McEliece_PrivateKey>(rng, mce_n, mce_t);
348
0
      }
349
0
#endif
350
351
0
#if defined(BOTAN_HAS_XMSS_RFC8391)
352
0
   if(alg_name == "XMSS")
353
0
      {
354
0
      return std::make_unique<XMSS_PrivateKey>(XMSS_Parameters(params.empty() ? "XMSS-SHA2_10_512" : params).oid(), rng);
355
0
      }
356
0
#endif
357
358
0
#if defined(BOTAN_HAS_ED25519)
359
0
   if(alg_name == "Ed25519")
360
0
      {
361
0
      return std::make_unique<Ed25519_PrivateKey>(rng);
362
0
      }
363
0
#endif
364
365
   // ECC crypto
366
0
#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
367
368
0
   if(alg_name == "ECDSA" ||
369
0
      alg_name == "ECDH" ||
370
0
      alg_name == "ECKCDSA" ||
371
0
      alg_name == "ECGDSA" ||
372
0
      alg_name == "SM2" ||
373
0
      alg_name == "SM2_Sig" ||
374
0
      alg_name == "SM2_Enc" ||
375
0
      alg_name == "GOST-34.10" ||
376
0
      alg_name == "GOST-34.10-2012-256" ||
377
0
      alg_name == "GOST-34.10-2012-512")
378
0
      {
379
0
      const EC_Group ec_group(params.empty() ? default_ec_group_for(alg_name) : params);
380
0
      return create_ec_private_key(alg_name, ec_group, rng);
381
0
      }
382
0
#endif
383
384
   // DL crypto
385
0
#if defined(BOTAN_HAS_DL_GROUP)
386
0
   if(alg_name == "DH" || alg_name == "DSA" || alg_name == "ElGamal")
387
0
      {
388
0
      std::string default_group = (alg_name == "DSA") ? "dsa/botan/2048" : "modp/ietf/2048";
389
0
      DL_Group modp_group(params.empty() ? default_group : params);
390
391
0
#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
392
0
      if(alg_name == "DH")
393
0
         return std::make_unique<DH_PrivateKey>(rng, modp_group);
394
0
#endif
395
396
0
#if defined(BOTAN_HAS_DSA)
397
0
      if(alg_name == "DSA")
398
0
         return std::make_unique<DSA_PrivateKey>(rng, modp_group);
399
0
#endif
400
401
0
#if defined(BOTAN_HAS_ELGAMAL)
402
0
      if(alg_name == "ElGamal")
403
0
         return std::make_unique<ElGamal_PrivateKey>(rng, modp_group);
404
0
#endif
405
0
      }
406
0
#endif
407
408
0
   BOTAN_UNUSED(alg_name, rng, params, provider);
409
410
0
   return std::unique_ptr<Private_Key>();
411
0
   }
412
413
std::vector<std::string>
414
probe_provider_private_key(const std::string& alg_name,
415
                           const std::vector<std::string> possible)
416
0
   {
417
0
   std::vector<std::string> providers;
418
419
0
   for(auto&& prov : possible)
420
0
      {
421
0
      if(prov == "base")
422
0
         providers.push_back(prov);
423
424
#if defined(BOTAN_HAS_OPENSSL)
425
      if(prov == "openssl" && alg_name == "RSA")
426
         providers.push_back(prov);
427
#endif
428
0
      }
429
430
0
   BOTAN_UNUSED(alg_name);
431
432
0
   return providers;
433
0
   }
434
}