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

randombit / botan / 14732017105

29 Apr 2025 01:07PM UTC coverage: 90.895% (-0.01%) from 90.907%
14732017105

Pull #4776

github

web-flow
Merge f137f1d27 into dbe524bf5
Pull Request #4776: Add support for null ciphers

95954 of 105566 relevant lines covered (90.89%)

12971514.27 hits per line

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

83.28
/src/tests/test_tls.cpp
1
/*
2
* (C) 2014,2015,2017,2018 Jack Lloyd
3
*
4
* Botan is released under the Simplified BSD License (see license.txt)
5
*/
6

7
#include "tests.h"
8
#include <fstream>
9
#include <memory>
10

11
#if defined(BOTAN_HAS_TLS)
12
   #include "test_rng.h"
13

14
   #include <botan/tls_alert.h>
15
   #include <botan/tls_policy.h>
16
   #include <botan/tls_session.h>
17
   #include <botan/tls_version.h>
18
   #include <botan/internal/fmt.h>
19

20
   #if defined(BOTAN_HAS_TLS_CBC)
21
      #include <botan/internal/tls_cbc.h>
22
   #endif
23

24
   #if defined(BOTAN_HAS_TLS_NULL)
25
      #include <botan/internal/tls_null.h>
26
   #endif
27

28
#endif
29

30
namespace Botan_Tests {
31

32
#if defined(BOTAN_HAS_TLS)
33

34
class TLS_Session_Tests final : public Test {
×
35
   public:
36
      std::vector<Test::Result> run() override {
1✔
37
         Test::Result result("TLS::Session");
1✔
38

39
         Botan::TLS::Session session(Botan::secure_vector<uint8_t>{0xCC, 0xDD},
1✔
40
                                     Botan::TLS::Protocol_Version::TLS_V12,
41
                                     0xC02F,
42
                                     Botan::TLS::Connection_Side::Client,
43
                                     true,
44
                                     false,
45
                                     std::vector<Botan::X509_Certificate>(),
1✔
46
                                     Botan::TLS::Server_Information("server"),
1✔
47
                                     0x0000,
48
                                     std::chrono::system_clock::now());
2✔
49

50
         const std::string pem = session.PEM_encode();
1✔
51
         Botan::TLS::Session session_from_pem(pem);
1✔
52
         result.test_eq("Roundtrip from pem", session.DER_encode(), session_from_pem.DER_encode());
3✔
53

54
         const auto der = session.DER_encode();
1✔
55
         Botan::TLS::Session session_from_der(der);
1✔
56
         result.test_eq("Roundtrip from der", session.DER_encode(), session_from_der.DER_encode());
3✔
57

58
         const Botan::SymmetricKey key("ABCDEF");
1✔
59
         const std::vector<uint8_t> ctext1 = session.encrypt(key, this->rng());
1✔
60
         const std::vector<uint8_t> ctext2 = session.encrypt(key, this->rng());
1✔
61

62
         result.test_ne(
1✔
63
            "TLS session encryption is non-determinsitic", ctext1.data(), ctext1.size(), ctext2.data(), ctext2.size());
64

65
         const std::vector<uint8_t> expected_hdr = Botan::hex_decode("068B5A9D396C0000F2322CAE");
1✔
66

67
         result.test_eq("tls", "TLS session encryption same header", ctext1.data(), 12, expected_hdr.data(), 12);
1✔
68
         result.test_eq("tls", "TLS session encryption same header", ctext2.data(), 12, expected_hdr.data(), 12);
1✔
69

70
         Botan::TLS::Session dsession = Botan::TLS::Session::decrypt(ctext1.data(), ctext1.size(), key);
1✔
71

72
         Fixed_Output_RNG frng1("00112233445566778899AABBCCDDEEFF802802802802802802802802");
1✔
73
         const std::vector<uint8_t> ctextf1 = session.encrypt(key, frng1);
1✔
74
         Fixed_Output_RNG frng2("00112233445566778899AABBCCDDEEFF802802802802802802802802");
1✔
75
         const std::vector<uint8_t> ctextf2 = session.encrypt(key, frng2);
1✔
76

77
         result.test_eq("Only randomness comes from RNG", ctextf1, ctextf2);
2✔
78

79
         Botan::TLS::Session session2(Botan::secure_vector<uint8_t>{0xCC, 0xEE},
1✔
80
                                      Botan::TLS::Protocol_Version::TLS_V12,
81
                                      0xBAAD,  // cipher suite does not exist
82
                                      Botan::TLS::Connection_Side::Client,
83
                                      true,
84
                                      false,
85
                                      std::vector<Botan::X509_Certificate>(),
1✔
86
                                      Botan::TLS::Server_Information("server"),
1✔
87
                                      0x0000,
88
                                      std::chrono::system_clock::now());
2✔
89
         const std::string pem_with_unknown_ciphersuite = session2.PEM_encode();
1✔
90

91
         result.test_throws("unknown ciphersuite during session parsing",
2✔
92
                            "Serialized TLS session contains unknown cipher suite (47789)",
93
                            [&] { Botan::TLS::Session{pem_with_unknown_ciphersuite}; });
2✔
94

95
         return {result};
3✔
96
      }
9✔
97
};
98

99
BOTAN_REGISTER_TEST("tls", "tls_session", TLS_Session_Tests);
100

101
   #if defined(BOTAN_HAS_TLS_CBC)
102

103
class TLS_CBC_Padding_Tests final : public Text_Based_Test {
×
104
   public:
105
      TLS_CBC_Padding_Tests() : Text_Based_Test("tls_cbc_padding.vec", "Record,Output") {}
2✔
106

107
      Test::Result run_one_test(const std::string& /*header*/, const VarMap& vars) override {
22✔
108
         const std::vector<uint8_t> record = vars.get_req_bin("Record");
22✔
109
         const size_t output = vars.get_req_sz("Output");
22✔
110

111
         uint16_t res = Botan::TLS::check_tls_cbc_padding(record.data(), record.size());
22✔
112

113
         Test::Result result("TLS CBC padding check");
22✔
114
         result.test_eq("Expected", res, output);
22✔
115
         return result;
22✔
116
      }
22✔
117
};
118

119
BOTAN_REGISTER_TEST("tls", "tls_cbc_padding", TLS_CBC_Padding_Tests);
120

121
class TLS_CBC_Tests final : public Text_Based_Test {
×
122
   public:
123
      class ZeroMac : public Botan::MessageAuthenticationCode {
124
         public:
125
            explicit ZeroMac(size_t mac_len) : m_mac_len(mac_len) {}
10✔
126

127
            void clear() override {}
×
128

129
            std::string name() const override { return "ZeroMac"; }
16✔
130

131
            size_t output_length() const override { return m_mac_len; }
20✔
132

133
            void add_data(std::span<const uint8_t> /*input*/) override {}
26✔
134

135
            void final_result(std::span<uint8_t> out) override {
10✔
136
               for(size_t i = 0; i != m_mac_len; ++i) {
206✔
137
                  out[i] = 0;
196✔
138
               }
139
            }
10✔
140

141
            bool has_keying_material() const override { return true; }
×
142

143
            Botan::Key_Length_Specification key_spec() const override {
10✔
144
               return Botan::Key_Length_Specification(0, 0, 1);
10✔
145
            }
146

147
            std::unique_ptr<MessageAuthenticationCode> new_object() const override {
×
148
               return std::make_unique<ZeroMac>(m_mac_len);
×
149
            }
150

151
         private:
152
            void key_schedule(std::span<const uint8_t> /* key */) override {}
10✔
153

154
            size_t m_mac_len;
155
      };
156

157
      class Noop_Block_Cipher : public Botan::BlockCipher {
158
         public:
159
            explicit Noop_Block_Cipher(size_t bs) : m_bs(bs) {}
10✔
160

161
            void encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override {
×
162
               Botan::copy_mem(out, in, blocks * m_bs);
×
163
            }
×
164

165
            void decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override {
10✔
166
               Botan::copy_mem(out, in, blocks * m_bs);
10✔
167
            }
10✔
168

169
            size_t block_size() const override { return m_bs; }
40✔
170

171
            void clear() override {}
×
172

173
            std::string name() const override { return "noop"; }
10✔
174

175
            bool has_keying_material() const override { return true; }
×
176

177
            Botan::Key_Length_Specification key_spec() const override {
20✔
178
               return Botan::Key_Length_Specification(0, 0, 1);
20✔
179
            }
180

181
            std::unique_ptr<BlockCipher> new_object() const override {
×
182
               return std::make_unique<Noop_Block_Cipher>(m_bs);
×
183
            }
184

185
         private:
186
            void key_schedule(std::span<const uint8_t> /*key*/) override {}
10✔
187

188
            size_t m_bs;
189
      };
190

191
      TLS_CBC_Tests() : Text_Based_Test("tls_cbc.vec", "Blocksize,MACsize,Record,Valid") {}
2✔
192

193
      Test::Result run_one_test(const std::string& /*header*/, const VarMap& vars) override {
10✔
194
         Test::Result result("TLS CBC");
10✔
195

196
         const size_t block_size = vars.get_req_sz("Blocksize");
10✔
197
         const size_t mac_len = vars.get_req_sz("MACsize");
10✔
198
         const std::vector<uint8_t> record = vars.get_req_bin("Record");
10✔
199
         const bool is_valid = vars.get_req_sz("Valid") == 1;
10✔
200

201
         // todo test permutations
202
         bool encrypt_then_mac = false;
10✔
203

204
         Botan::TLS::TLS_CBC_HMAC_AEAD_Decryption tls_cbc(std::make_unique<Noop_Block_Cipher>(block_size),
20✔
205
                                                          std::make_unique<ZeroMac>(mac_len),
10✔
206
                                                          0,
207
                                                          0,
208
                                                          Botan::TLS::Protocol_Version::TLS_V12,
209
                                                          encrypt_then_mac);
20✔
210

211
         tls_cbc.set_key(std::vector<uint8_t>(0));
10✔
212
         std::vector<uint8_t> ad(13);
10✔
213
         tls_cbc.set_associated_data(ad.data(), ad.size());
10✔
214

215
         Botan::secure_vector<uint8_t> vec(record.begin(), record.end());
10✔
216

217
         try {
10✔
218
            tls_cbc.finish(vec, 0);
10✔
219
            if(is_valid) {
4✔
220
               result.test_success("Accepted valid TLS-CBC ciphertext");
8✔
221
            } else {
222
               result.test_failure("Accepted invalid TLS-CBC ciphertext");
×
223
            }
224
         } catch(std::exception&) {
6✔
225
            if(is_valid) {
6✔
226
               result.test_failure("Rejected valid TLS-CBC ciphertext");
×
227
            } else {
228
               result.test_success("Accepted invalid TLS-CBC ciphertext");
12✔
229
            }
230
         }
6✔
231

232
         return result;
10✔
233
      }
30✔
234
};
235

236
BOTAN_REGISTER_TEST("tls", "tls_cbc", TLS_CBC_Tests);
237

238
   #endif
239

240
   #if defined(BOTAN_HAS_TLS_NULL)
241

242
class TLS_Null_Tests final : public Text_Based_Test {
×
243
   public:
244
      TLS_Null_Tests() : Text_Based_Test("tls_null.vec", "Hash,Key,AssociatedData,Message,Fragment") {}
2✔
245

246
      void encryption_test(Test::Result& result,
3✔
247
                           const std::string& hash,
248
                           const std::vector<uint8_t>& key,
249
                           const std::vector<uint8_t>& associated_data,
250
                           const std::vector<uint8_t>& message,
251
                           const std::vector<uint8_t>& expected_tls_fragment) {
252
         auto mac = Botan::MessageAuthenticationCode::create_or_throw(Botan::fmt("HMAC({})", hash));
3✔
253

254
         const auto mac_output_length = mac->output_length();
3✔
255
         Botan::TLS::TLS_NULL_HMAC_AEAD_Encryption tls_null_encrypt(std::move(mac), mac_output_length);
3✔
256

257
         tls_null_encrypt.set_key(key);
3✔
258
         tls_null_encrypt.set_associated_data(associated_data);
3✔
259

260
         Botan::secure_vector<uint8_t> buffer(message.begin(), message.end());
3✔
261
         tls_null_encrypt.finish(buffer);
3✔
262

263
         result.test_eq("Encrypted TLS fragment matches expectation", Botan::unlock(buffer), expected_tls_fragment);
9✔
264
      }
3✔
265

266
      void decryption_test(Test::Result& result,
4✔
267
                           const std::string& hash,
268
                           const std::vector<uint8_t>& key,
269
                           const std::vector<uint8_t>& associated_data,
270
                           const std::vector<uint8_t>& expected_message,
271
                           const std::vector<uint8_t>& tls_fragment,
272
                           const std::string& header) {
273
         auto mac = Botan::MessageAuthenticationCode::create_or_throw(Botan::fmt("HMAC({})", hash));
4✔
274

275
         const auto mac_output_length = mac->output_length();
4✔
276
         Botan::TLS::TLS_NULL_HMAC_AEAD_Decryption tls_null_decrypt(std::move(mac), mac_output_length);
4✔
277

278
         tls_null_decrypt.set_key(key);
4✔
279
         tls_null_decrypt.set_associated_data(associated_data);
4✔
280

281
         Botan::secure_vector<uint8_t> buffer(tls_fragment.begin(), tls_fragment.end());
4✔
282

283
         if(header == "InvalidMAC") {
4✔
284
            result.test_throws("TLS_NULL_HMAC_AEAD_Decryption::finish()", "Message authentication failure", [&]() {
3✔
285
               tls_null_decrypt.finish(buffer, 0);
1✔
286
            });
287
         } else {
288
            tls_null_decrypt.finish(buffer, 0);
3✔
289
            result.test_eq("Decrypted TLS fragment matches expectation", Botan::unlock(buffer), expected_message);
9✔
290
         }
291
      }
4✔
292

293
      void invalid_ad_length_test(Test::Result& result,
×
294
                                  const std::string& hash,
295
                                  const std::vector<uint8_t>& associated_data) {
296
         auto mac = Botan::MessageAuthenticationCode::create_or_throw(Botan::fmt("HMAC({})", hash));
×
297

298
         const auto mac_output_length = mac->output_length();
×
299
         Botan::TLS::TLS_NULL_HMAC_AEAD_Decryption tls_null_decrypt(std::move(mac), mac_output_length);
×
300

301
         result.test_throws("TLS_NULL_HMAC_AEAD_Decryption::set_associated_data()",
×
302
                            "Invalid TLS AEAD associated data length",
303
                            [&]() { tls_null_decrypt.set_associated_data(associated_data); });
×
304
         return;
×
305
      }
×
306

307
      Test::Result run_one_test(const std::string& header, const VarMap& vars) override {
4✔
308
         Test::Result result("TLS Null Cipher");
4✔
309

310
         const std::string hash = vars.get_req_str("Hash");
4✔
311
         const std::vector<uint8_t> key = vars.get_req_bin("Key");
4✔
312
         const std::vector<uint8_t> associated_data = vars.get_req_bin("AssociatedData");
4✔
313
         const std::vector<uint8_t> expected_message = vars.get_req_bin("Message");
4✔
314
         const std::vector<uint8_t> tls_fragment = vars.get_req_bin("Fragment");
4✔
315

316
         if(header.empty()) {
4✔
317
            encryption_test(result, hash, key, associated_data, expected_message, tls_fragment);
3✔
318
            decryption_test(result, hash, key, associated_data, expected_message, tls_fragment, header);
3✔
319
         }
320

321
         if(header == "InvalidMAC") {
4✔
322
            decryption_test(result, hash, key, associated_data, expected_message, tls_fragment, header);
1✔
323
         }
324

325
         if(header == "InvalidAssociatedDataLength") {
4✔
326
            invalid_ad_length_test(result, hash, associated_data);
×
327
         }
328

329
         return result;
4✔
330
      }
16✔
331
};
332

333
BOTAN_REGISTER_TEST("tls", "tls_null", TLS_Null_Tests);
334

335
   #endif
336

337
class Test_TLS_Alert_Strings : public Test {
1✔
338
   public:
339
      std::vector<Test::Result> run() override {
1✔
340
         Test::Result result("TLS::Alert::type_string");
1✔
341

342
         const std::vector<Botan::TLS::Alert::Type> alert_types = {
1✔
343
            Botan::TLS::Alert::CloseNotify,
344
            Botan::TLS::Alert::UnexpectedMessage,
345
            Botan::TLS::Alert::BadRecordMac,
346
            Botan::TLS::Alert::DecryptionFailed,
347
            Botan::TLS::Alert::RecordOverflow,
348
            Botan::TLS::Alert::DecompressionFailure,
349
            Botan::TLS::Alert::HandshakeFailure,
350
            Botan::TLS::Alert::NoCertificate,
351
            Botan::TLS::Alert::BadCertificate,
352
            Botan::TLS::Alert::UnsupportedCertificate,
353
            Botan::TLS::Alert::CertificateRevoked,
354
            Botan::TLS::Alert::CertificateExpired,
355
            Botan::TLS::Alert::CertificateUnknown,
356
            Botan::TLS::Alert::IllegalParameter,
357
            Botan::TLS::Alert::UnknownCA,
358
            Botan::TLS::Alert::AccessDenied,
359
            Botan::TLS::Alert::DecodeError,
360
            Botan::TLS::Alert::DecryptError,
361
            Botan::TLS::Alert::ExportRestriction,
362
            Botan::TLS::Alert::ProtocolVersion,
363
            Botan::TLS::Alert::InsufficientSecurity,
364
            Botan::TLS::Alert::InternalError,
365
            Botan::TLS::Alert::InappropriateFallback,
366
            Botan::TLS::Alert::UserCanceled,
367
            Botan::TLS::Alert::NoRenegotiation,
368
            Botan::TLS::Alert::MissingExtension,
369
            Botan::TLS::Alert::UnsupportedExtension,
370
            Botan::TLS::Alert::CertificateUnobtainable,
371
            Botan::TLS::Alert::UnrecognizedName,
372
            Botan::TLS::Alert::BadCertificateStatusResponse,
373
            Botan::TLS::Alert::BadCertificateHashValue,
374
            Botan::TLS::Alert::UnknownPSKIdentity,
375
            Botan::TLS::Alert::NoApplicationProtocol,
376
         };
1✔
377

378
         std::set<std::string> seen;
1✔
379

380
         for(auto alert : alert_types) {
34✔
381
            const std::string str = Botan::TLS::Alert(alert).type_string();
33✔
382
            result.test_eq("No duplicate strings", seen.count(str), 0);
33✔
383
            seen.insert(str);
33✔
384
         }
33✔
385

386
         Botan::TLS::Alert unknown_alert = Botan::TLS::Alert({01, 66});
1✔
387

388
         result.test_eq("Unknown alert str", unknown_alert.type_string(), "unrecognized_alert_66");
2✔
389

390
         return {result};
3✔
391
      }
2✔
392
};
393

394
BOTAN_REGISTER_TEST("tls", "tls_alert_strings", Test_TLS_Alert_Strings);
395

396
   #if defined(BOTAN_HAS_TLS_13) && defined(BOTAN_HAS_TLS_13_PQC) && defined(BOTAN_HAS_X25519) && \
397
      defined(BOTAN_HAS_X448)
398

399
class Test_TLS_Policy_Text : public Test {
1✔
400
   public:
401
      std::vector<Test::Result> run() override {
1✔
402
         Test::Result result("TLS Policy");
1✔
403

404
         const std::vector<std::string> policies = {"default", "suiteb_128", "suiteb_192", "strict", "datagram", "bsi"};
1✔
405

406
         for(const std::string& policy : policies) {
7✔
407
            const std::string from_policy_obj = tls_policy_string(policy);
6✔
408

409
            const std::string policy_file = policy + (policy == "default" || policy == "strict" ? "_tls13" : "");
8✔
410

411
            const std::string from_file = read_tls_policy(policy_file);
6✔
412

413
            if(from_policy_obj != from_file) {
6✔
414
               std::string d = diff(from_policy_obj, from_file);
×
415
               result.test_failure(Botan::fmt("Values for TLS policy from {} don't match (diff {})", policy_file, d));
×
416
            } else {
×
417
               result.test_success("Values from TLS policy from " + policy_file + " match");
18✔
418
            }
419
         }
6✔
420

421
         return {result};
3✔
422
      }
2✔
423

424
   private:
425
      static std::string diff(const std::string& a_str, const std::string& b_str) {
×
426
         std::istringstream a_ss(a_str);
×
427
         std::istringstream b_ss(b_str);
×
428

429
         std::ostringstream diff;
×
430

431
         for(;;) {
×
432
            if(!a_ss && !b_ss) {
×
433
               break;  // done
434
            }
435

436
            std::string a_line;
×
437
            std::getline(a_ss, a_line, '\n');
×
438

439
            std::string b_line;
×
440
            std::getline(b_ss, b_line, '\n');
×
441

442
            if(a_line != b_line) {
×
443
               diff << "- " << a_line << "\n"
×
444
                    << "+ " << b_line << "\n";
×
445
            }
446
         }
×
447

448
         return diff.str();
×
449
      }
×
450

451
      static std::string read_tls_policy(const std::string& policy_str) {
6✔
452
         const std::string fspath = Test::data_file("tls-policy/" + policy_str + ".txt");
18✔
453

454
         std::ifstream is(fspath.c_str());
6✔
455
         if(!is.good()) {
6✔
456
            throw Test_Error("Missing policy file " + fspath);
×
457
         }
458

459
         Botan::TLS::Text_Policy policy(is);
6✔
460
         return policy.to_string();
6✔
461
      }
6✔
462

463
      static std::string tls_policy_string(const std::string& policy_str) {
6✔
464
         std::unique_ptr<Botan::TLS::Policy> policy;
6✔
465
         if(policy_str == "default") {
6✔
466
            policy = std::make_unique<Botan::TLS::Policy>();
1✔
467
         } else if(policy_str == "suiteb_128") {
5✔
468
            policy = std::make_unique<Botan::TLS::NSA_Suite_B_128>();
1✔
469
         } else if(policy_str == "suiteb_192") {
4✔
470
            policy = std::make_unique<Botan::TLS::NSA_Suite_B_192>();
1✔
471
         } else if(policy_str == "bsi") {
3✔
472
            policy = std::make_unique<Botan::TLS::BSI_TR_02102_2>();
1✔
473
         } else if(policy_str == "strict") {
2✔
474
            policy = std::make_unique<Botan::TLS::Strict_Policy>();
1✔
475
         } else if(policy_str == "datagram") {
1✔
476
            policy = std::make_unique<Botan::TLS::Datagram_Policy>();
1✔
477
         } else {
478
            throw Test_Error("Unknown TLS policy type '" + policy_str + "'");
×
479
         }
480

481
         return policy->to_string();
6✔
482
      }
6✔
483
};
484

485
BOTAN_REGISTER_TEST("tls", "tls_policy_text", Test_TLS_Policy_Text);
486
   #endif
487

488
class Test_TLS_Ciphersuites : public Test {
1✔
489
   public:
490
      std::vector<Test::Result> run() override {
1✔
491
         Test::Result result("TLS::Ciphersuite");
1✔
492

493
         for(size_t csuite_id = 0; csuite_id <= 0xFFFF; ++csuite_id) {
65,537✔
494
            const uint16_t csuite_id16 = static_cast<uint16_t>(csuite_id);
65,536✔
495
            auto ciphersuite = Botan::TLS::Ciphersuite::by_id(csuite_id16);
65,536✔
496

497
            if(ciphersuite && ciphersuite->valid()) {
65,536✔
498
               result.test_eq("Valid Ciphersuite is not SCSV", Botan::TLS::Ciphersuite::is_scsv(csuite_id16), false);
102✔
499

500
               if(ciphersuite->cbc_ciphersuite() == false && ciphersuite->null_ciphersuite() == false) {
102✔
501
                  result.test_eq("Expected AEAD ciphersuite", ciphersuite->aead_ciphersuite(), true);
64✔
502
                  result.test_eq("Expected MAC name for AEAD ciphersuites", ciphersuite->mac_algo(), "AEAD");
128✔
503
               } else {
504
                  result.test_eq("Did not expect AEAD ciphersuite", ciphersuite->aead_ciphersuite(), false);
38✔
505
                  result.test_eq("MAC algo and PRF algo same for CBC and NULL suites",
114✔
506
                                 ciphersuite->prf_algo(),
76✔
507
                                 ciphersuite->mac_algo());
76✔
508
               }
509

510
               if(ciphersuite->null_ciphersuite()) {
102✔
511
                  result.test_eq("Expected NULL ciphersuite", ciphersuite->cipher_algo(), "NullCipher");
16✔
512
               };
513

514
               // TODO more tests here
515
            }
516
         }
517

518
         return {result};
3✔
519
      }
2✔
520
};
521

522
BOTAN_REGISTER_TEST("tls", "tls_ciphersuites", Test_TLS_Ciphersuites);
523

524
class Test_TLS_Algo_Strings : public Test {
1✔
525
   public:
526
      std::vector<Test::Result> run() override {
1✔
527
         std::vector<Test::Result> results;
1✔
528

529
         results.push_back(test_auth_method_strings());
2✔
530
         results.push_back(test_kex_algo_strings());
2✔
531
         results.push_back(test_tls_sig_method_strings());
2✔
532

533
         return results;
1✔
534
      }
×
535

536
   private:
537
      static Test::Result test_tls_sig_method_strings() {
1✔
538
         Test::Result result("TLS::Signature_Scheme");
1✔
539

540
         std::vector<Botan::TLS::Signature_Scheme> schemes = Botan::TLS::Signature_Scheme::all_available_schemes();
1✔
541

542
         std::set<std::string> scheme_strs;
1✔
543
         for(auto scheme : schemes) {
10✔
544
            std::string scheme_str = scheme.to_string();
9✔
545

546
            result.test_eq("Scheme strings unique", scheme_strs.count(scheme_str), 0);
9✔
547

548
            scheme_strs.insert(scheme_str);
9✔
549
         }
9✔
550

551
         return result;
2✔
552
      }
1✔
553

554
      static Test::Result test_auth_method_strings() {
1✔
555
         Test::Result result("TLS::Auth_Method");
1✔
556

557
         const std::vector<Botan::TLS::Auth_Method> auth_methods({
1✔
558
            Botan::TLS::Auth_Method::RSA,
559
            Botan::TLS::Auth_Method::ECDSA,
560
            Botan::TLS::Auth_Method::IMPLICIT,
561
         });
1✔
562

563
         for(Botan::TLS::Auth_Method meth : auth_methods) {
4✔
564
            std::string meth_str = Botan::TLS::auth_method_to_string(meth);
3✔
565
            result.test_ne("Method string is not empty", meth_str, "");
6✔
566
            Botan::TLS::Auth_Method meth2 = Botan::TLS::auth_method_from_string(meth_str);
3✔
567
            result.confirm("Decoded method matches", meth == meth2);
6✔
568
         }
3✔
569

570
         return result;
1✔
571
      }
1✔
572

573
      static Test::Result test_kex_algo_strings() {
1✔
574
         Test::Result result("TLS::Kex_Algo");
1✔
575

576
         const std::vector<Botan::TLS::Kex_Algo> kex_algos({Botan::TLS::Kex_Algo::STATIC_RSA,
1✔
577
                                                            Botan::TLS::Kex_Algo::DH,
578
                                                            Botan::TLS::Kex_Algo::ECDH,
579
                                                            Botan::TLS::Kex_Algo::PSK,
580
                                                            Botan::TLS::Kex_Algo::ECDHE_PSK});
1✔
581

582
         for(Botan::TLS::Kex_Algo meth : kex_algos) {
6✔
583
            std::string meth_str = Botan::TLS::kex_method_to_string(meth);
5✔
584
            result.test_ne("Method string is not empty", meth_str, "");
10✔
585
            Botan::TLS::Kex_Algo meth2 = Botan::TLS::kex_method_from_string(meth_str);
5✔
586
            result.confirm("Decoded method matches", meth == meth2);
10✔
587
         }
5✔
588

589
         return result;
1✔
590
      }
1✔
591
};
592

593
BOTAN_REGISTER_TEST("tls", "tls_algo_strings", Test_TLS_Algo_Strings);
594

595
#endif
596

597
}  // namespace Botan_Tests
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

© 2025 Coveralls, Inc