Coverage Report

Created: 2020-05-23 13:54

/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/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
9.15k
   {
85
9.15k
   const std::string oid_str = alg_id.get_oid().to_formatted_string();
86
9.15k
   const std::vector<std::string> alg_info = split_on(oid_str, '/');
87
9.15k
   const std::string alg_name = alg_info[0];
88
9.15k
89
9.15k
#if defined(BOTAN_HAS_RSA)
90
9.15k
   if(alg_name == "RSA")
91
6.04k
      return std::unique_ptr<Public_Key>(new RSA_PublicKey(alg_id, key_bits));
92
3.11k
#endif
93
3.11k
94
3.11k
#if defined(BOTAN_HAS_CURVE_25519)
95
3.11k
   if(alg_name == "Curve25519")
96
5
      return std::unique_ptr<Public_Key>(new Curve25519_PublicKey(alg_id, key_bits));
97
3.10k
#endif
98
3.10k
99
3.10k
#if defined(BOTAN_HAS_MCELIECE)
100
3.10k
   if(alg_name == "McEliece")
101
0
      return std::unique_ptr<Public_Key>(new McEliece_PublicKey(key_bits));
102
3.10k
#endif
103
3.10k
104
3.10k
#if defined(BOTAN_HAS_ECDSA)
105
3.10k
   if(alg_name == "ECDSA")
106
2.45k
      return std::unique_ptr<Public_Key>(new ECDSA_PublicKey(alg_id, key_bits));
107
653
#endif
108
653
109
653
#if defined(BOTAN_HAS_ECDH)
110
653
   if(alg_name == "ECDH")
111
7
      return std::unique_ptr<Public_Key>(new ECDH_PublicKey(alg_id, key_bits));
112
646
#endif
113
646
114
646
#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
115
646
   if(alg_name == "DH")
116
72
      return std::unique_ptr<Public_Key>(new DH_PublicKey(alg_id, key_bits));
117
574
#endif
118
574
119
574
#if defined(BOTAN_HAS_DSA)
120
574
   if(alg_name == "DSA")
121
105
      return std::unique_ptr<Public_Key>(new DSA_PublicKey(alg_id, key_bits));
122
469
#endif
123
469
124
469
#if defined(BOTAN_HAS_ELGAMAL)
125
469
   if(alg_name == "ElGamal")
126
0
      return std::unique_ptr<Public_Key>(new ElGamal_PublicKey(alg_id, key_bits));
127
469
#endif
128
469
129
469
#if defined(BOTAN_HAS_ECGDSA)
130
469
   if(alg_name == "ECGDSA")
131
0
      return std::unique_ptr<Public_Key>(new ECGDSA_PublicKey(alg_id, key_bits));
132
469
#endif
133
469
134
469
#if defined(BOTAN_HAS_ECKCDSA)
135
469
   if(alg_name == "ECKCDSA")
136
0
      return std::unique_ptr<Public_Key>(new ECKCDSA_PublicKey(alg_id, key_bits));
137
469
#endif
138
469
139
469
#if defined(BOTAN_HAS_ED25519)
140
469
   if(alg_name == "Ed25519")
141
135
      return std::unique_ptr<Public_Key>(new Ed25519_PublicKey(alg_id, key_bits));
142
334
#endif
143
334
144
334
#if defined(BOTAN_HAS_GOST_34_10_2001)
145
334
   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
334
#endif
148
334
149
334
#if defined(BOTAN_HAS_SM2)
150
334
   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
334
#endif
153
334
154
334
#if defined(BOTAN_HAS_XMSS_RFC8391)
155
334
   if(alg_name == "XMSS")
156
0
      return std::unique_ptr<Public_Key>(new XMSS_PublicKey(key_bits));
157
334
#endif
158
334
159
334
   throw Decoding_Error("Unknown or unavailable public key algorithm " + alg_name);
160
334
   }
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.65k
   {
166
1.65k
   const std::string alg_name = alg_id.get_oid().to_formatted_string();
167
1.65k
168
1.65k
#if defined(BOTAN_HAS_RSA)
169
1.65k
   if(alg_name == "RSA")
170
31
      return std::unique_ptr<Private_Key>(new RSA_PrivateKey(alg_id, key_bits));
171
1.62k
#endif
172
1.62k
173
1.62k
#if defined(BOTAN_HAS_CURVE_25519)
174
1.62k
   if(alg_name == "Curve25519")
175
26
      return std::unique_ptr<Private_Key>(new Curve25519_PrivateKey(alg_id, key_bits));
176
1.59k
#endif
177
1.59k
178
1.59k
#if defined(BOTAN_HAS_ECDSA)
179
1.59k
   if(alg_name == "ECDSA")
180
409
      return std::unique_ptr<Private_Key>(new ECDSA_PrivateKey(alg_id, key_bits));
181
1.19k
#endif
182
1.19k
183
1.19k
#if defined(BOTAN_HAS_ECDH)
184
1.19k
   if(alg_name == "ECDH")
185
993
      return std::unique_ptr<Private_Key>(new ECDH_PrivateKey(alg_id, key_bits));
186
197
#endif
187
197
188
197
#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
189
197
   if(alg_name == "DH")
190
45
      return std::unique_ptr<Private_Key>(new DH_PrivateKey(alg_id, key_bits));
191
152
#endif
192
152
193
152
#if defined(BOTAN_HAS_DSA)
194
152
   if(alg_name == "DSA")
195
136
      return std::unique_ptr<Private_Key>(new DSA_PrivateKey(alg_id, key_bits));
196
16
#endif
197
16
198
16
#if defined(BOTAN_HAS_MCELIECE)
199
16
   if(alg_name == "McEliece")
200
0
      return std::unique_ptr<Private_Key>(new McEliece_PrivateKey(key_bits));
201
16
#endif
202
16
203
16
#if defined(BOTAN_HAS_ECGDSA)
204
16
   if(alg_name == "ECGDSA")
205
0
      return std::unique_ptr<Private_Key>(new ECGDSA_PrivateKey(alg_id, key_bits));
206
16
#endif
207
16
208
16
#if defined(BOTAN_HAS_ECKCDSA)
209
16
   if(alg_name == "ECKCDSA")
210
0
      return std::unique_ptr<Private_Key>(new ECKCDSA_PrivateKey(alg_id, key_bits));
211
16
#endif
212
16
213
16
#if defined(BOTAN_HAS_ED25519)
214
16
   if(alg_name == "Ed25519")
215
11
      return std::unique_ptr<Private_Key>(new Ed25519_PrivateKey(alg_id, key_bits));
216
5
#endif
217
5
218
5
#if defined(BOTAN_HAS_GOST_34_10_2001)
219
5
   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
5
#endif
222
5
223
5
#if defined(BOTAN_HAS_SM2)
224
5
   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
5
#endif
227
5
228
5
#if defined(BOTAN_HAS_ELGAMAL)
229
5
   if(alg_name == "ElGamal")
230
0
      return std::unique_ptr<Private_Key>(new ElGamal_PrivateKey(alg_id, key_bits));
231
5
#endif
232
5
233
5
#if defined(BOTAN_HAS_XMSS_RFC8391)
234
5
   if(alg_name == "XMSS")
235
0
      return std::unique_ptr<Private_Key>(new XMSS_PrivateKey(key_bits));
236
5
#endif
237
5
238
5
   throw Decoding_Error("Unknown or unavailable public key algorithm " + alg_name);
239
5
   }
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
0
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
0
   /*
270
0
   * Default paramaters are chosen for work factor > 2**128 where possible
271
0
   */
272
0
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
0
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
      return std::unique_ptr<Private_Key>(new RSA_PrivateKey(rng, rsa_bits));
294
0
      }
295
0
#endif
296
0
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
0
303
0
      if(mce_param.size() != 2)
304
0
         throw Invalid_Argument("create_private_key bad McEliece parameters " + params);
305
0
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
0
309
0
      return std::unique_ptr<Botan::Private_Key>(new Botan::McEliece_PrivateKey(rng, mce_n, mce_t));
310
0
      }
311
0
#endif
312
0
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
0
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
0
328
0
   // ECC crypto
329
0
#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
330
0
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
0
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
0
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
0
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
0
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
0
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
0
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
0
376
0
   // 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
0
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
0
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
0
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
0
400
0
   BOTAN_UNUSED(alg_name, rng, params, provider);
401
0
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
0
422
0
   BOTAN_UNUSED(alg_name);
423
0
424
0
   return providers;
425
0
   }
426
}