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

randombit / botan / 24115861258

08 Apr 2026 03:20AM UTC coverage: 89.45% (-2.4%) from 91.821%
24115861258

Pull #5523

github

web-flow
Merge 8045a4e76 into 570b415e2
Pull Request #5523: Update BoGo shim, various TLS updates

106161 of 118682 relevant lines covered (89.45%)

11530654.21 hits per line

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

60.23
/src/lib/tls/tls_algos.cpp
1
/*
2
* (C) 2017 Jack Lloyd
3
*
4
* Botan is released under the Simplified BSD License (see license.txt)
5
*/
6

7
#include <botan/tls_algos.h>
8

9
#include <botan/exceptn.h>
10
#include <botan/internal/fmt.h>
11

12
#include <algorithm>
13
#include <array>
14

15
namespace Botan::TLS {
16

17
std::string kdf_algo_to_string(KDF_Algo algo) {
242,613✔
18
   switch(algo) {
242,613✔
19
      case KDF_Algo::SHA_1:
50,441✔
20
         return "SHA-1";
50,441✔
21
      case KDF_Algo::SHA_256:
139,429✔
22
         return "SHA-256";
139,429✔
23
      case KDF_Algo::SHA_384:
52,743✔
24
         return "SHA-384";
52,743✔
25
   }
26

27
   throw Invalid_State("kdf_algo_to_string unknown enum value");
×
28
}
29

30
std::string kex_method_to_string(Kex_Algo method) {
8,547✔
31
   switch(method) {
8,547✔
32
      case Kex_Algo::STATIC_RSA:
703✔
33
         return "RSA";
703✔
34
      case Kex_Algo::DH:
1,167✔
35
         return "DH";
1,167✔
36
      case Kex_Algo::ECDH:
4,687✔
37
         return "ECDH";
4,687✔
38
      case Kex_Algo::PSK:
987✔
39
         return "PSK";
987✔
40
      case Kex_Algo::ECDHE_PSK:
962✔
41
         return "ECDHE_PSK";
962✔
42
      case Kex_Algo::DHE_PSK:
×
43
         return "DHE_PSK";
×
44
      case Kex_Algo::KEM:
8✔
45
         return "KEM";
8✔
46
      case Kex_Algo::KEM_PSK:
×
47
         return "KEM_PSK";
×
48
      case Kex_Algo::HYBRID:
31✔
49
         return "HYBRID";
31✔
50
      case Kex_Algo::HYBRID_PSK:
2✔
51
         return "HYBRID_PSK";
2✔
52
      case Kex_Algo::UNDEFINED:
×
53
         return "UNDEFINED";
×
54
   }
55

56
   throw Invalid_State("kex_method_to_string unknown enum value");
×
57
}
58

59
Kex_Algo kex_method_from_string(std::string_view str) {
5✔
60
   if(str == "RSA") {
5✔
61
      return Kex_Algo::STATIC_RSA;
1✔
62
   }
63

64
   if(str == "DH") {
4✔
65
      return Kex_Algo::DH;
1✔
66
   }
67

68
   if(str == "ECDH") {
3✔
69
      return Kex_Algo::ECDH;
1✔
70
   }
71

72
   if(str == "PSK") {
2✔
73
      return Kex_Algo::PSK;
1✔
74
   }
75

76
   if(str == "ECDHE_PSK") {
1✔
77
      return Kex_Algo::ECDHE_PSK;
1✔
78
   }
79

80
   if(str == "DHE_PSK") {
×
81
      return Kex_Algo::DHE_PSK;
×
82
   }
83

84
   if(str == "KEM") {
×
85
      return Kex_Algo::KEM;
×
86
   }
87

88
   if(str == "KEM_PSK") {
×
89
      return Kex_Algo::KEM_PSK;
×
90
   }
91

92
   if(str == "HYBRID") {
×
93
      return Kex_Algo::HYBRID;
×
94
   }
95

96
   if(str == "HYBRID_PSK") {
×
97
      return Kex_Algo::HYBRID_PSK;
×
98
   }
99

100
   if(str == "UNDEFINED") {
×
101
      return Kex_Algo::UNDEFINED;
×
102
   }
103

104
   throw Invalid_Argument(fmt("Unknown kex method '{}'", str));
×
105
}
106

107
std::string auth_method_to_string(Auth_Method method) {
10,364✔
108
   switch(method) {
10,364✔
109
      case Auth_Method::RSA:
7,156✔
110
         return "RSA";
7,156✔
111
      case Auth_Method::ECDSA:
3,042✔
112
         return "ECDSA";
3,042✔
113
      case Auth_Method::IMPLICIT:
166✔
114
         return "IMPLICIT";
166✔
115
      case Auth_Method::UNDEFINED:
×
116
         return "UNDEFINED";
×
117
   }
118

119
   throw Invalid_State("auth_method_to_string unknown enum value");
×
120
}
121

122
Auth_Method auth_method_from_string(std::string_view str) {
3✔
123
   if(str == "RSA") {
3✔
124
      return Auth_Method::RSA;
1✔
125
   }
126
   if(str == "ECDSA") {
2✔
127
      return Auth_Method::ECDSA;
1✔
128
   }
129
   if(str == "IMPLICIT") {
1✔
130
      return Auth_Method::IMPLICIT;
1✔
131
   }
132
   if(str == "UNDEFINED") {
×
133
      return Auth_Method::UNDEFINED;
×
134
   }
135

136
   throw Invalid_Argument(fmt("Unknown TLS signature method '{}'", str));
×
137
}
138

139
namespace {
140

141
consteval auto available_group_params() {
142
   // Currently 36 are defined
143
   constexpr size_t max_groups = 64;
144
   std::array<uint16_t, max_groups> codes{};
145
   size_t n = 0;
146

147
#if defined(BOTAN_HAS_PCURVES_SECP256R1) || defined(BOTAN_HAS_PCURVES_GENERIC)
148
   codes[n++] = static_cast<uint16_t>(Group_Params_Code::SECP256R1);
149
#endif
150

151
#if defined(BOTAN_HAS_PCURVES_SECP384R1) || defined(BOTAN_HAS_PCURVES_GENERIC)
152
   codes[n++] = static_cast<uint16_t>(Group_Params_Code::SECP384R1);
153
#endif
154

155
#if defined(BOTAN_HAS_PCURVES_SECP521R1) || defined(BOTAN_HAS_PCURVES_GENERIC)
156
   codes[n++] = static_cast<uint16_t>(Group_Params_Code::SECP521R1);
157
#endif
158

159
#if defined(BOTAN_HAS_PCURVES_BRAINPOOL256R1) || defined(BOTAN_HAS_PCURVES_GENERIC)
160
   codes[n++] = static_cast<uint16_t>(Group_Params_Code::BRAINPOOL256R1);
161
#endif
162

163
#if defined(BOTAN_HAS_PCURVES_BRAINPOOL384R1) || defined(BOTAN_HAS_PCURVES_GENERIC)
164
   codes[n++] = static_cast<uint16_t>(Group_Params_Code::BRAINPOOL384R1);
165
#endif
166

167
#if defined(BOTAN_HAS_PCURVES_BRAINPOOL512R1) || defined(BOTAN_HAS_PCURVES_GENERIC)
168
   codes[n++] = static_cast<uint16_t>(Group_Params_Code::BRAINPOOL512R1);
169
#endif
170

171
#if defined(BOTAN_HAS_X25519)
172
   codes[n++] = static_cast<uint16_t>(Group_Params_Code::X25519);
173
#endif
174

175
#if defined(BOTAN_HAS_X448)
176
   codes[n++] = static_cast<uint16_t>(Group_Params_Code::X448);
177
#endif
178

179
#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
180
   codes[n++] = static_cast<uint16_t>(Group_Params_Code::FFDHE_2048);
181
   codes[n++] = static_cast<uint16_t>(Group_Params_Code::FFDHE_3072);
182
   codes[n++] = static_cast<uint16_t>(Group_Params_Code::FFDHE_4096);
183
   codes[n++] = static_cast<uint16_t>(Group_Params_Code::FFDHE_6144);
184
   codes[n++] = static_cast<uint16_t>(Group_Params_Code::FFDHE_8192);
185
#endif
186

187
#if defined(BOTAN_HAS_ML_KEM)
188
   codes[n++] = static_cast<uint16_t>(Group_Params_Code::ML_KEM_512);
189
   codes[n++] = static_cast<uint16_t>(Group_Params_Code::ML_KEM_768);
190
   codes[n++] = static_cast<uint16_t>(Group_Params_Code::ML_KEM_1024);
191

192
   #if defined(BOTAN_HAS_PCURVES_SECP256R1) || defined(BOTAN_HAS_PCURVES_GENERIC)
193
   codes[n++] = static_cast<uint16_t>(Group_Params_Code::HYBRID_SECP256R1_ML_KEM_768);
194
   #endif
195

196
   #if defined(BOTAN_HAS_PCURVES_SECP384R1) || defined(BOTAN_HAS_PCURVES_GENERIC)
197
   codes[n++] = static_cast<uint16_t>(Group_Params_Code::HYBRID_SECP384R1_ML_KEM_1024);
198
   #endif
199

200
   #if defined(BOTAN_HAS_X25519)
201
   codes[n++] = static_cast<uint16_t>(Group_Params_Code::HYBRID_X25519_ML_KEM_768);
202
   #endif
203
#endif
204

205
#if defined(BOTAN_HAS_FRODOKEM)
206
   codes[n++] = static_cast<uint16_t>(Group_Params_Code::eFRODOKEM_640_SHAKE_OQS);
207
   codes[n++] = static_cast<uint16_t>(Group_Params_Code::eFRODOKEM_976_SHAKE_OQS);
208
   codes[n++] = static_cast<uint16_t>(Group_Params_Code::eFRODOKEM_1344_SHAKE_OQS);
209
   codes[n++] = static_cast<uint16_t>(Group_Params_Code::eFRODOKEM_640_AES_OQS);
210
   codes[n++] = static_cast<uint16_t>(Group_Params_Code::eFRODOKEM_976_AES_OQS);
211
   codes[n++] = static_cast<uint16_t>(Group_Params_Code::eFRODOKEM_1344_AES_OQS);
212

213
   #if defined(BOTAN_HAS_PCURVES_SECP256R1) || defined(BOTAN_HAS_PCURVES_GENERIC)
214
   codes[n++] = static_cast<uint16_t>(Group_Params_Code::HYBRID_SECP256R1_eFRODOKEM_640_SHAKE_OQS);
215
   codes[n++] = static_cast<uint16_t>(Group_Params_Code::HYBRID_SECP256R1_eFRODOKEM_640_AES_OQS);
216
   #endif
217

218
   #if defined(BOTAN_HAS_PCURVES_SECP384R1) || defined(BOTAN_HAS_PCURVES_GENERIC)
219
   codes[n++] = static_cast<uint16_t>(Group_Params_Code::HYBRID_SECP384R1_eFRODOKEM_976_SHAKE_OQS);
220
   codes[n++] = static_cast<uint16_t>(Group_Params_Code::HYBRID_SECP384R1_eFRODOKEM_976_AES_OQS);
221
   #endif
222

223
   #if defined(BOTAN_HAS_PCURVES_SECP521R1) || defined(BOTAN_HAS_PCURVES_GENERIC)
224
   codes[n++] = static_cast<uint16_t>(Group_Params_Code::HYBRID_SECP521R1_eFRODOKEM_1344_SHAKE_OQS);
225
   codes[n++] = static_cast<uint16_t>(Group_Params_Code::HYBRID_SECP521R1_eFRODOKEM_1344_AES_OQS);
226
   #endif
227

228
   #if defined(BOTAN_HAS_X25519)
229
   codes[n++] = static_cast<uint16_t>(Group_Params_Code::HYBRID_X25519_eFRODOKEM_640_SHAKE_OQS);
230
   codes[n++] = static_cast<uint16_t>(Group_Params_Code::HYBRID_X25519_eFRODOKEM_640_AES_OQS);
231
   #endif
232

233
   #if defined(BOTAN_HAS_X448)
234
   codes[n++] = static_cast<uint16_t>(Group_Params_Code::HYBRID_X448_eFRODOKEM_976_SHAKE_OQS);
235
   codes[n++] = static_cast<uint16_t>(Group_Params_Code::HYBRID_X448_eFRODOKEM_976_AES_OQS);
236
   #endif
237
#endif
238

239
   std::sort(codes.begin(), codes.begin() + n);
240

241
   return std::pair{codes, n};
242
}
243

244
}  // namespace
245

246
bool Group_Params::is_available() const {
1,233✔
247
   // For group codes we recognize, check the build-time availability table.
248
   // Unknown codes may be user-supplied custom groups handled via callbacks.
249
   if(to_string().has_value()) {
2,450✔
250
      static constexpr auto groups = available_group_params();
1,217✔
251
      const auto* begin = groups.first.data();
1,217✔
252
      const auto* end = begin + groups.second;
1,217✔
253
      return std::binary_search(begin, end, wire_code());
2,434✔
254
   }
255
   return true;
256
}
257

258
std::optional<Group_Params_Code> Group_Params::pqc_hybrid_ecc() const {
×
259
   switch(m_code) {
×
260
      case Group_Params_Code::HYBRID_X25519_ML_KEM_768:
×
261

262
      case Group_Params_Code::HYBRID_X25519_eFRODOKEM_640_SHAKE_OQS:
×
263
      case Group_Params_Code::HYBRID_X25519_eFRODOKEM_640_AES_OQS:
×
264
         return Group_Params_Code::X25519;
×
265

266
      case Group_Params_Code::HYBRID_X448_eFRODOKEM_976_SHAKE_OQS:
×
267
      case Group_Params_Code::HYBRID_X448_eFRODOKEM_976_AES_OQS:
×
268
         return Group_Params_Code::X448;
×
269

270
      case Group_Params_Code::HYBRID_SECP256R1_ML_KEM_768:
×
271
      case Group_Params_Code::HYBRID_SECP256R1_eFRODOKEM_640_SHAKE_OQS:
×
272
      case Group_Params_Code::HYBRID_SECP256R1_eFRODOKEM_640_AES_OQS:
×
273
         return Group_Params_Code::SECP256R1;
×
274

275
      case Group_Params_Code::HYBRID_SECP384R1_ML_KEM_1024:
×
276
      case Group_Params_Code::HYBRID_SECP384R1_eFRODOKEM_976_SHAKE_OQS:
×
277
      case Group_Params_Code::HYBRID_SECP384R1_eFRODOKEM_976_AES_OQS:
×
278
         return Group_Params_Code::SECP384R1;
×
279

280
      case Group_Params_Code::HYBRID_SECP521R1_eFRODOKEM_1344_SHAKE_OQS:
×
281
      case Group_Params_Code::HYBRID_SECP521R1_eFRODOKEM_1344_AES_OQS:
×
282
         return Group_Params_Code::SECP521R1;
×
283

284
      default:
×
285
         return {};
×
286
   }
287
}
288

289
std::optional<Group_Params> Group_Params::from_string(std::string_view group_name) {
633✔
290
   if(group_name == "secp256r1") {
633✔
291
      return Group_Params::SECP256R1;
90✔
292
   }
293
   if(group_name == "secp384r1") {
543✔
294
      return Group_Params::SECP384R1;
49✔
295
   }
296
   if(group_name == "secp521r1") {
494✔
297
      return Group_Params::SECP521R1;
44✔
298
   }
299
   if(group_name == "brainpool256r1") {
450✔
300
      return Group_Params::BRAINPOOL256R1;
28✔
301
   }
302
   if(group_name == "brainpool384r1") {
422✔
303
      return Group_Params::BRAINPOOL384R1;
12✔
304
   }
305
   if(group_name == "brainpool512r1") {
410✔
306
      return Group_Params::BRAINPOOL512R1;
12✔
307
   }
308
   if(group_name == "x25519") {
398✔
309
      return Group_Params::X25519;
103✔
310
   }
311
   if(group_name == "x448") {
295✔
312
      return Group_Params::X448;
41✔
313
   }
314

315
   if(group_name == "ffdhe/ietf/2048") {
254✔
316
      return Group_Params::FFDHE_2048;
69✔
317
   }
318
   if(group_name == "ffdhe/ietf/3072") {
185✔
319
      return Group_Params::FFDHE_3072;
28✔
320
   }
321
   if(group_name == "ffdhe/ietf/4096") {
157✔
322
      return Group_Params::FFDHE_4096;
22✔
323
   }
324
   if(group_name == "ffdhe/ietf/6144") {
135✔
325
      return Group_Params::FFDHE_6144;
16✔
326
   }
327
   if(group_name == "ffdhe/ietf/8192") {
119✔
328
      return Group_Params::FFDHE_8192;
16✔
329
   }
330

331
   if(group_name == "ML-KEM-512") {
103✔
332
      return Group_Params::ML_KEM_512;
×
333
   }
334
   if(group_name == "ML-KEM-768") {
103✔
335
      return Group_Params::ML_KEM_768;
30✔
336
   }
337
   if(group_name == "ML-KEM-1024") {
73✔
338
      return Group_Params::ML_KEM_1024;
×
339
   }
340

341
   if(group_name == "eFrodoKEM-640-SHAKE") {
73✔
342
      return Group_Params::eFRODOKEM_640_SHAKE_OQS;
×
343
   }
344
   if(group_name == "eFrodoKEM-976-SHAKE") {
73✔
345
      return Group_Params::eFRODOKEM_976_SHAKE_OQS;
×
346
   }
347
   if(group_name == "eFrodoKEM-1344-SHAKE") {
73✔
348
      return Group_Params::eFRODOKEM_1344_SHAKE_OQS;
×
349
   }
350
   if(group_name == "eFrodoKEM-640-AES") {
73✔
351
      return Group_Params::eFRODOKEM_640_AES_OQS;
×
352
   }
353
   if(group_name == "eFrodoKEM-976-AES") {
73✔
354
      return Group_Params::eFRODOKEM_976_AES_OQS;
×
355
   }
356
   if(group_name == "eFrodoKEM-1344-AES") {
73✔
357
      return Group_Params::eFRODOKEM_1344_AES_OQS;
×
358
   }
359

360
   if(group_name == "x25519/ML-KEM-768") {
73✔
361
      return Group_Params::HYBRID_X25519_ML_KEM_768;
39✔
362
   }
363
   if(group_name == "secp256r1/ML-KEM-768") {
34✔
364
      return Group_Params::HYBRID_SECP256R1_ML_KEM_768;
9✔
365
   }
366
   if(group_name == "secp384r1/ML-KEM-1024") {
25✔
367
      return Group_Params::HYBRID_SECP384R1_ML_KEM_1024;
9✔
368
   }
369

370
   if(group_name == "x25519/eFrodoKEM-640-SHAKE") {
16✔
371
      return Group_Params::HYBRID_X25519_eFRODOKEM_640_SHAKE_OQS;
×
372
   }
373
   if(group_name == "x25519/eFrodoKEM-640-AES") {
16✔
374
      return Group_Params::HYBRID_X25519_eFRODOKEM_640_AES_OQS;
×
375
   }
376
   if(group_name == "x448/eFrodoKEM-976-SHAKE") {
16✔
377
      return Group_Params::HYBRID_X448_eFRODOKEM_976_SHAKE_OQS;
×
378
   }
379
   if(group_name == "x448/eFrodoKEM-976-AES") {
16✔
380
      return Group_Params::HYBRID_X448_eFRODOKEM_976_AES_OQS;
×
381
   }
382

383
   if(group_name == "secp256r1/eFrodoKEM-640-SHAKE") {
16✔
384
      return Group_Params::HYBRID_SECP256R1_eFRODOKEM_640_SHAKE_OQS;
×
385
   }
386
   if(group_name == "secp256r1/eFrodoKEM-640-AES") {
16✔
387
      return Group_Params::HYBRID_SECP256R1_eFRODOKEM_640_AES_OQS;
×
388
   }
389

390
   if(group_name == "secp384r1/eFrodoKEM-976-SHAKE") {
16✔
391
      return Group_Params::HYBRID_SECP384R1_eFRODOKEM_976_SHAKE_OQS;
×
392
   }
393
   if(group_name == "secp384r1/eFrodoKEM-976-AES") {
16✔
394
      return Group_Params::HYBRID_SECP384R1_eFRODOKEM_976_AES_OQS;
×
395
   }
396

397
   if(group_name == "secp521r1/eFrodoKEM-1344-SHAKE") {
16✔
398
      return Group_Params::HYBRID_SECP521R1_eFRODOKEM_1344_SHAKE_OQS;
×
399
   }
400
   if(group_name == "secp521r1/eFrodoKEM-1344-AES") {
16✔
401
      return Group_Params::HYBRID_SECP521R1_eFRODOKEM_1344_AES_OQS;
×
402
   }
403

404
   return std::nullopt;
16✔
405
}
406

407
std::optional<std::string> Group_Params::to_string() const {
2,911✔
408
   switch(m_code) {
2,911✔
409
      case Group_Params::SECP256R1:
365✔
410
         return "secp256r1";
365✔
411
      case Group_Params::SECP384R1:
374✔
412
         return "secp384r1";
374✔
413
      case Group_Params::SECP521R1:
284✔
414
         return "secp521r1";
284✔
415
      case Group_Params::BRAINPOOL256R1:
59✔
416
         return "brainpool256r1";
59✔
417
      case Group_Params::BRAINPOOL384R1:
22✔
418
         return "brainpool384r1";
22✔
419
      case Group_Params::BRAINPOOL512R1:
29✔
420
         return "brainpool512r1";
29✔
421
      case Group_Params::X25519:
1,166✔
422
         return "x25519";
1,166✔
423
      case Group_Params::X448:
49✔
424
         return "x448";
49✔
425

426
      case Group_Params::FFDHE_2048:
93✔
427
         return "ffdhe/ietf/2048";
93✔
428
      case Group_Params::FFDHE_3072:
38✔
429
         return "ffdhe/ietf/3072";
38✔
430
      case Group_Params::FFDHE_4096:
26✔
431
         return "ffdhe/ietf/4096";
26✔
432
      case Group_Params::FFDHE_6144:
18✔
433
         return "ffdhe/ietf/6144";
18✔
434
      case Group_Params::FFDHE_8192:
18✔
435
         return "ffdhe/ietf/8192";
18✔
436

437
      case Group_Params::ML_KEM_512:
×
438
         return "ML-KEM-512";
×
439
      case Group_Params::ML_KEM_768:
34✔
440
         return "ML-KEM-768";
34✔
441
      case Group_Params::ML_KEM_1024:
100✔
442
         return "ML-KEM-1024";
100✔
443

444
      case Group_Params::eFRODOKEM_640_SHAKE_OQS:
×
445
         return "eFrodoKEM-640-SHAKE";
×
446
      case Group_Params::eFRODOKEM_976_SHAKE_OQS:
×
447
         return "eFrodoKEM-976-SHAKE";
×
448
      case Group_Params::eFRODOKEM_1344_SHAKE_OQS:
×
449
         return "eFrodoKEM-1344-SHAKE";
×
450
      case Group_Params::eFRODOKEM_640_AES_OQS:
×
451
         return "eFrodoKEM-640-AES";
×
452
      case Group_Params::eFRODOKEM_976_AES_OQS:
×
453
         return "eFrodoKEM-976-AES";
×
454
      case Group_Params::eFRODOKEM_1344_AES_OQS:
×
455
         return "eFrodoKEM-1344-AES";
×
456

457
      case Group_Params::HYBRID_X25519_eFRODOKEM_640_SHAKE_OQS:
×
458
         return "x25519/eFrodoKEM-640-SHAKE";
×
459
      case Group_Params::HYBRID_X25519_eFRODOKEM_640_AES_OQS:
×
460
         return "x25519/eFrodoKEM-640-AES";
×
461
      case Group_Params::HYBRID_X448_eFRODOKEM_976_SHAKE_OQS:
×
462
         return "x448/eFrodoKEM-976-SHAKE";
×
463
      case Group_Params::HYBRID_X448_eFRODOKEM_976_AES_OQS:
×
464
         return "x448/eFrodoKEM-976-AES";
×
465
      case Group_Params::HYBRID_SECP256R1_eFRODOKEM_640_SHAKE_OQS:
×
466
         return "secp256r1/eFrodoKEM-640-SHAKE";
×
467
      case Group_Params::HYBRID_SECP256R1_eFRODOKEM_640_AES_OQS:
×
468
         return "secp256r1/eFrodoKEM-640-AES";
×
469
      case Group_Params::HYBRID_SECP384R1_eFRODOKEM_976_SHAKE_OQS:
×
470
         return "secp384r1/eFrodoKEM-976-SHAKE";
×
471
      case Group_Params::HYBRID_SECP384R1_eFRODOKEM_976_AES_OQS:
×
472
         return "secp384r1/eFrodoKEM-976-AES";
×
473
      case Group_Params::HYBRID_SECP521R1_eFRODOKEM_1344_SHAKE_OQS:
×
474
         return "secp521r1/eFrodoKEM-1344-SHAKE";
×
475
      case Group_Params::HYBRID_SECP521R1_eFRODOKEM_1344_AES_OQS:
×
476
         return "secp521r1/eFrodoKEM-1344-AES";
×
477

478
      case Group_Params::HYBRID_X25519_ML_KEM_768:
176✔
479
         return "x25519/ML-KEM-768";
176✔
480
      case Group_Params::HYBRID_SECP256R1_ML_KEM_768:
15✔
481
         return "secp256r1/ML-KEM-768";
15✔
482
      case Group_Params::HYBRID_SECP384R1_ML_KEM_1024:
15✔
483
         return "secp384r1/ML-KEM-1024";
15✔
484

485
      default:
30✔
486
         return std::nullopt;
30✔
487
   }
488
}
489

490
std::string certificate_type_to_string(Certificate_Type type) {
24✔
491
   switch(type) {
24✔
492
      case Certificate_Type::X509:
24✔
493
         return "X509";
24✔
494
      case Certificate_Type::RawPublicKey:
×
495
         return "RawPublicKey";
×
496
   }
497

498
   return "Unknown";
×
499
}
500

501
Certificate_Type certificate_type_from_string(const std::string& type_str) {
10✔
502
   if(type_str == "X509") {
10✔
503
      return Certificate_Type::X509;
504
   } else if(type_str == "RawPublicKey") {
4✔
505
      return Certificate_Type::RawPublicKey;
506
   } else {
507
      throw Decoding_Error("Unknown certificate type: " + type_str);
×
508
   }
509
}
510

511
}  // namespace Botan::TLS
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