Coverage Report

Created: 2021-02-21 07:20

/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
10.4k
   {
85
10.4k
   const std::string oid_str = alg_id.get_oid().to_formatted_string();
86
10.4k
   const std::vector<std::string> alg_info = split_on(oid_str, '/');
87
10.4k
   const std::string alg_name = alg_info[0];
88
89
10.4k
#if defined(BOTAN_HAS_RSA)
90
10.4k
   if(alg_name == "RSA")
91
6.53k
      return std::unique_ptr<Public_Key>(new RSA_PublicKey(alg_id, key_bits));
92
3.93k
#endif
93
94
3.93k
#if defined(BOTAN_HAS_CURVE_25519)
95
3.93k
   if(alg_name == "Curve25519")
96
7
      return std::unique_ptr<Public_Key>(new Curve25519_PublicKey(alg_id, key_bits));
97
3.92k
#endif
98
99
3.92k
#if defined(BOTAN_HAS_MCELIECE)
100
3.92k
   if(alg_name == "McEliece")
101
0
      return std::unique_ptr<Public_Key>(new McEliece_PublicKey(key_bits));
102
3.92k
#endif
103
104
3.92k
#if defined(BOTAN_HAS_ECDSA)
105
3.92k
   if(alg_name == "ECDSA")
106
3.07k
      return std::unique_ptr<Public_Key>(new ECDSA_PublicKey(alg_id, key_bits));
107
854
#endif
108
109
854
#if defined(BOTAN_HAS_ECDH)
110
854
   if(alg_name == "ECDH")
111
5
      return std::unique_ptr<Public_Key>(new ECDH_PublicKey(alg_id, key_bits));
112
849
#endif
113
114
849
#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
115
849
   if(alg_name == "DH")
116
103
      return std::unique_ptr<Public_Key>(new DH_PublicKey(alg_id, key_bits));
117
746
#endif
118
119
746
#if defined(BOTAN_HAS_DSA)
120
746
   if(alg_name == "DSA")
121
157
      return std::unique_ptr<Public_Key>(new DSA_PublicKey(alg_id, key_bits));
122
589
#endif
123
124
589
#if defined(BOTAN_HAS_ELGAMAL)
125
589
   if(alg_name == "ElGamal")
126
0
      return std::unique_ptr<Public_Key>(new ElGamal_PublicKey(alg_id, key_bits));
127
589
#endif
128
129
589
#if defined(BOTAN_HAS_ECGDSA)
130
589
   if(alg_name == "ECGDSA")
131
0
      return std::unique_ptr<Public_Key>(new ECGDSA_PublicKey(alg_id, key_bits));
132
589
#endif
133
134
589
#if defined(BOTAN_HAS_ECKCDSA)
135
589
   if(alg_name == "ECKCDSA")
136
0
      return std::unique_ptr<Public_Key>(new ECKCDSA_PublicKey(alg_id, key_bits));
137
589
#endif
138
139
589
#if defined(BOTAN_HAS_ED25519)
140
589
   if(alg_name == "Ed25519")
141
206
      return std::unique_ptr<Public_Key>(new Ed25519_PublicKey(alg_id, key_bits));
142
383
#endif
143
144
383
#if defined(BOTAN_HAS_GOST_34_10_2001)
145
383
   if(alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256" || alg_name == "GOST-34.10-2012-512")
146
0
      return std::unique_ptr<Public_Key>(new GOST_3410_PublicKey(alg_id, key_bits));
147
383
#endif
148
149
383
#if defined(BOTAN_HAS_SM2)
150
383
   if(alg_name == "SM2" || alg_name == "SM2_Sig" || alg_name == "SM2_Enc")
151
0
      return std::unique_ptr<Public_Key>(new SM2_PublicKey(alg_id, key_bits));
152
383
#endif
153
154
383
#if defined(BOTAN_HAS_XMSS_RFC8391)
155
383
   if(alg_name == "XMSS")
156
0
      return std::unique_ptr<Public_Key>(new XMSS_PublicKey(key_bits));
157
383
#endif
158
159
383
   throw Decoding_Error("Unknown or unavailable public key algorithm " + alg_name);
160
383
   }
161
162
std::unique_ptr<Private_Key>
163
load_private_key(const AlgorithmIdentifier& alg_id,
164
                 const secure_vector<uint8_t>& key_bits)
165
1.97k
   {
166
1.97k
   const std::string alg_name = alg_id.get_oid().to_formatted_string();
167
168
1.97k
#if defined(BOTAN_HAS_RSA)
169
1.97k
   if(alg_name == "RSA")
170
70
      return std::unique_ptr<Private_Key>(new RSA_PrivateKey(alg_id, key_bits));
171
1.90k
#endif
172
173
1.90k
#if defined(BOTAN_HAS_CURVE_25519)
174
1.90k
   if(alg_name == "Curve25519")
175
40
      return std::unique_ptr<Private_Key>(new Curve25519_PrivateKey(alg_id, key_bits));
176
1.86k
#endif
177
178
1.86k
#if defined(BOTAN_HAS_ECDSA)
179
1.86k
   if(alg_name == "ECDSA")
180
500
      return std::unique_ptr<Private_Key>(new ECDSA_PrivateKey(alg_id, key_bits));
181
1.36k
#endif
182
183
1.36k
#if defined(BOTAN_HAS_ECDH)
184
1.36k
   if(alg_name == "ECDH")
185
1.12k
      return std::unique_ptr<Private_Key>(new ECDH_PrivateKey(alg_id, key_bits));
186
241
#endif
187
188
241
#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
189
241
   if(alg_name == "DH")
190
54
      return std::unique_ptr<Private_Key>(new DH_PrivateKey(alg_id, key_bits));
191
187
#endif
192
193
187
#if defined(BOTAN_HAS_DSA)
194
187
   if(alg_name == "DSA")
195
164
      return std::unique_ptr<Private_Key>(new DSA_PrivateKey(alg_id, key_bits));
196
23
#endif
197
198
23
#if defined(BOTAN_HAS_MCELIECE)
199
23
   if(alg_name == "McEliece")
200
0
      return std::unique_ptr<Private_Key>(new McEliece_PrivateKey(key_bits));
201
23
#endif
202
203
23
#if defined(BOTAN_HAS_ECGDSA)
204
23
   if(alg_name == "ECGDSA")
205
0
      return std::unique_ptr<Private_Key>(new ECGDSA_PrivateKey(alg_id, key_bits));
206
23
#endif
207
208
23
#if defined(BOTAN_HAS_ECKCDSA)
209
23
   if(alg_name == "ECKCDSA")
210
0
      return std::unique_ptr<Private_Key>(new ECKCDSA_PrivateKey(alg_id, key_bits));
211
23
#endif
212
213
23
#if defined(BOTAN_HAS_ED25519)
214
23
   if(alg_name == "Ed25519")
215
17
      return std::unique_ptr<Private_Key>(new 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::unique_ptr<Private_Key>(new 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::unique_ptr<Private_Key>(new 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::unique_ptr<Private_Key>(new 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::unique_ptr<Private_Key>(new 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
std::unique_ptr<Private_Key>
264
create_private_key(const std::string& alg_name,
265
                   RandomNumberGenerator& rng,
266
                   const std::string& params,
267
                   const std::string& provider)
268
0
   {
269
   /*
270
   * Default paramaters are chosen for work factor > 2**128 where possible
271
   */
272
273
0
#if defined(BOTAN_HAS_CURVE_25519)
274
0
   if(alg_name == "Curve25519")
275
0
      return std::unique_ptr<Private_Key>(new Curve25519_PrivateKey(rng));
276
0
#endif
277
278
0
#if defined(BOTAN_HAS_RSA)
279
0
   if(alg_name == "RSA")
280
0
      {
281
0
      const size_t rsa_bits = (params.empty() ? 3072 : to_u32bit(params));
282
#if defined(BOTAN_HAS_OPENSSL)
283
      if(provider.empty() || provider == "openssl")
284
         {
285
         std::unique_ptr<Botan::Private_Key> pk;
286
         if((pk = make_openssl_rsa_private_key(rng, rsa_bits)))
287
            return pk;
288
289
         if(!provider.empty())
290
            return nullptr;
291
         }
292
#endif
293
0
      return std::unique_ptr<Private_Key>(new RSA_PrivateKey(rng, rsa_bits));
294
0
      }
295
0
#endif
296
297
0
#if defined(BOTAN_HAS_MCELIECE)
298
0
   if(alg_name == "McEliece")
299
0
      {
300
0
      std::vector<std::string> mce_param =
301
0
         Botan::split_on(params.empty() ? "2960,57" : params, ',');
302
303
0
      if(mce_param.size() != 2)
304
0
         throw Invalid_Argument("create_private_key bad McEliece parameters " + params);
305
306
0
      size_t mce_n = Botan::to_u32bit(mce_param[0]);
307
0
      size_t mce_t = Botan::to_u32bit(mce_param[1]);
308
309
0
      return std::unique_ptr<Botan::Private_Key>(new Botan::McEliece_PrivateKey(rng, mce_n, mce_t));
310
0
      }
311
0
#endif
312
313
0
#if defined(BOTAN_HAS_XMSS_RFC8391)
314
0
   if(alg_name == "XMSS")
315
0
      {
316
0
      return std::unique_ptr<Private_Key>(
317
0
         new XMSS_PrivateKey(XMSS_Parameters(params.empty() ? "XMSS-SHA2_10_512" : params).oid(), rng));
318
0
      }
319
0
#endif
320
321
0
#if defined(BOTAN_HAS_ED25519)
322
0
   if(alg_name == "Ed25519")
323
0
      {
324
0
      return std::unique_ptr<Private_Key>(new Ed25519_PrivateKey(rng));
325
0
      }
326
0
#endif
327
328
   // ECC crypto
329
0
#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
330
331
0
   if(alg_name == "ECDSA" ||
332
0
      alg_name == "ECDH" ||
333
0
      alg_name == "ECKCDSA" ||
334
0
      alg_name == "ECGDSA" ||
335
0
      alg_name == "SM2" ||
336
0
      alg_name == "SM2_Sig" ||
337
0
      alg_name == "SM2_Enc" ||
338
0
      alg_name == "GOST-34.10" ||
339
0
      alg_name == "GOST-34.10-2012-256" ||
340
0
      alg_name == "GOST-34.10-2012-512")
341
0
      {
342
0
      const EC_Group ec_group(params.empty() ? default_ec_group_for(alg_name) : params);
343
344
0
#if defined(BOTAN_HAS_ECDSA)
345
0
      if(alg_name == "ECDSA")
346
0
         return std::unique_ptr<Private_Key>(new ECDSA_PrivateKey(rng, ec_group));
347
0
#endif
348
349
0
#if defined(BOTAN_HAS_ECDH)
350
0
      if(alg_name == "ECDH")
351
0
         return std::unique_ptr<Private_Key>(new ECDH_PrivateKey(rng, ec_group));
352
0
#endif
353
354
0
#if defined(BOTAN_HAS_ECKCDSA)
355
0
      if(alg_name == "ECKCDSA")
356
0
         return std::unique_ptr<Private_Key>(new ECKCDSA_PrivateKey(rng, ec_group));
357
0
#endif
358
359
0
#if defined(BOTAN_HAS_GOST_34_10_2001)
360
0
      if(alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256" || alg_name == "GOST-34.10-2012-512")
361
0
         return std::unique_ptr<Private_Key>(new GOST_3410_PrivateKey(rng, ec_group));
362
0
#endif
363
364
0
#if defined(BOTAN_HAS_SM2)
365
0
      if(alg_name == "SM2" || alg_name == "SM2_Sig" || alg_name == "SM2_Enc")
366
0
         return std::unique_ptr<Private_Key>(new SM2_PrivateKey(rng, ec_group));
367
0
#endif
368
369
0
#if defined(BOTAN_HAS_ECGDSA)
370
0
      if(alg_name == "ECGDSA")
371
0
         return std::unique_ptr<Private_Key>(new ECGDSA_PrivateKey(rng, ec_group));
372
0
#endif
373
0
      }
374
0
#endif
375
376
   // DL crypto
377
0
#if defined(BOTAN_HAS_DL_GROUP)
378
0
   if(alg_name == "DH" || alg_name == "DSA" || alg_name == "ElGamal")
379
0
      {
380
0
      std::string default_group = (alg_name == "DSA") ? "dsa/botan/2048" : "modp/ietf/2048";
381
0
      DL_Group modp_group(params.empty() ? default_group : params);
382
383
0
#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
384
0
      if(alg_name == "DH")
385
0
         return std::unique_ptr<Private_Key>(new DH_PrivateKey(rng, modp_group));
386
0
#endif
387
388
0
#if defined(BOTAN_HAS_DSA)
389
0
      if(alg_name == "DSA")
390
0
         return std::unique_ptr<Private_Key>(new DSA_PrivateKey(rng, modp_group));
391
0
#endif
392
393
0
#if defined(BOTAN_HAS_ELGAMAL)
394
0
      if(alg_name == "ElGamal")
395
0
         return std::unique_ptr<Private_Key>(new ElGamal_PrivateKey(rng, modp_group));
396
0
#endif
397
0
      }
398
0
#endif
399
400
0
   BOTAN_UNUSED(alg_name, rng, params, provider);
401
402
0
   return std::unique_ptr<Private_Key>();
403
0
   }
404
405
std::vector<std::string>
406
probe_provider_private_key(const std::string& alg_name,
407
                           const std::vector<std::string> possible)
408
0
   {
409
0
   std::vector<std::string> providers;
410
0
   for(auto&& prov : possible)
411
0
      {
412
0
      if(prov == "base" ||
413
#if defined(BOTAN_HAS_OPENSSL)
414
         (prov == "openssl" && alg_name == "RSA") ||
415
#endif
416
0
         0)
417
0
         {
418
0
         providers.push_back(prov); // available
419
0
         }
420
0
      }
421
422
0
   BOTAN_UNUSED(alg_name);
423
424
0
   return providers;
425
0
   }
426
}