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

randombit / botan / 17401833297

02 Sep 2025 11:17AM UTC coverage: 90.649% (-0.02%) from 90.671%
17401833297

Pull #4996

github

web-flow
Merge 76653987e into a72cc07c6
Pull Request #4996: Add CertificateParametersBuilder as a replacement for X509_Cert_Options

100376 of 110730 relevant lines covered (90.65%)

12338516.61 hits per line

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

0.0
/src/cli/perf_x509.cpp
1
/*
2
* (C) 2025 Jack Lloyd
3
*     2025 René Meusel - Rohde & Schwarz Cybersecurity
4
*
5
* Botan is released under the Simplified BSD License (see license.txt)
6
*/
7

8
#include "perf.h"
9
#include <algorithm>
10

11
// Always available:
12
#include <botan/assert.h>
13

14
#if defined(BOTAN_HAS_X509)
15
   #include <botan/ber_dec.h>
16
   #include <botan/bigint.h>
17
   #include <botan/der_enc.h>
18
   #include <botan/pk_algs.h>
19
   #include <botan/x509_builder.h>
20
   #include <botan/x509_ca.h>
21
   #include <botan/x509_ext.h>
22
#endif
23

24
namespace Botan_CLI {
25

26
#if defined(BOTAN_HAS_X509) && defined(BOTAN_HAS_ML_DSA)
27

28
class PerfTest_ASN1_Parsing final : public PerfTest {
×
29
   private:
30
      struct CA {
31
            std::unique_ptr<Botan::Private_Key> root_key;
32
            Botan::X509_CA ca;
33
      };
34

35
   private:
36
      static std::string_view get_hash_function() { return "SHAKE-256(512)"; }
×
37

38
      static std::unique_ptr<Botan::Private_Key> create_private_key(Botan::RandomNumberGenerator& rng) {
×
39
         return Botan::create_private_key("ML-DSA", rng, "ML-DSA-6x5");
×
40
      }
41

42
      static CA create_ca(Botan::RandomNumberGenerator& rng) {
×
43
         auto root_key = create_private_key(rng);
×
44
         BOTAN_ASSERT_NONNULL(root_key);
×
45

46
         Botan::CertificateParametersBuilder root_cert_params;
×
47
         root_cert_params.add_common_name("Benchmark Root")
×
48
            .add_country("DE")
×
49
            .add_organization("RS")
×
50
            .add_organizational_unit("CS")
×
51
            .add_dns("unobtainium.example.com")
×
52
            .add_email("idont@exist.com")
×
53
            .set_as_ca_certificate();
×
54

55
         const auto not_before = std::chrono::system_clock::now();
×
56
         const auto not_after = not_before + std::chrono::seconds(86400);
×
57

58
         auto root_cert =
×
59
            root_cert_params.into_self_signed_cert(not_before, not_after, *root_key, rng, get_hash_function());
×
60
         auto ca = Botan::X509_CA(root_cert, *root_key, get_hash_function(), rng);
×
61

62
         return CA{
×
63
            std::move(root_key),
64
            std::move(ca),
65
         };
×
66
      }
×
67

68
      static Botan::X509_Certificate make_certificate(std::string_view common_name,
×
69
                                                      CA& ca,
70
                                                      Botan::RandomNumberGenerator& rng) {
71
         Botan::X509_DN subject;
×
72
         subject.add_attribute("X520.CommonName", common_name);
×
73
         subject.add_attribute("X520.Country", "DE");
×
74
         subject.add_attribute("X520.State", "Berlin");
×
75
         subject.add_attribute("X520.Organization", "RS");
×
76
         subject.add_attribute("X520.OrganizationalUnit", "CS");
×
77

78
         Botan::AlternativeName an;
×
79
         an.add_dns("gibtsnicht.example.com");
×
80
         an.add_email("not.available@anywhere.com");
×
81

82
         Botan::Extensions exts;
×
83
         exts.add(std::make_unique<Botan::Cert_Extension::Subject_Alternative_Name>(an));
×
84

85
         const auto cert_key = create_private_key(rng);
×
86
         BOTAN_ASSERT_NONNULL(cert_key);
×
87
         const auto cert_req = Botan::PKCS10_Request::create(*cert_key, subject, exts, get_hash_function(), rng);
×
88

89
         const auto now = std::chrono::system_clock::now();
×
90
         using namespace std::chrono_literals;
×
91
         return ca.ca.sign_request(cert_req, rng, Botan::X509_Time(now), Botan::X509_Time(now + 24h * 365));
×
92
      }
×
93

94
      static Botan::X509_CRL make_revocation_list(size_t entries, CA& ca, Botan::RandomNumberGenerator& rng) {
×
95
         const auto empty_crl = ca.ca.new_crl(rng);
×
96

97
         std::vector<Botan::CRL_Entry> crl_entries(entries);
×
98
         std::generate(crl_entries.begin(), crl_entries.end(), [&] {
×
99
            std::vector<uint8_t> crl_entry_buffer;
×
100

101
            // Generating the CRL entries through their ASN.1 structure because
102
            // our public API does not allow creating them without the actual
103
            // certificate that is supposed to be revoked.
104
            Botan::Extensions exts;
×
105
            exts.add(std::make_unique<Botan::Cert_Extension::CRL_ReasonCode>(Botan::CRL_Code::KeyCompromise));
×
106
            Botan::DER_Encoder(crl_entry_buffer)
×
107
               .start_sequence()
×
108
               .encode(Botan::BigInt::from_bytes(rng.random_array<16>()))
×
109
               .encode(Botan::X509_Time(std::chrono::system_clock::now()))
×
110
               .start_sequence()
×
111
               .encode(exts)
×
112
               .end_cons()
×
113
               .end_cons();
×
114

115
            Botan::BER_Decoder ber(crl_entry_buffer);
×
116

117
            Botan::CRL_Entry entry;
×
118
            entry.decode_from(ber);
×
119
            return entry;
×
120
         });
×
121

122
         return ca.ca.update_crl(empty_crl, crl_entries, rng);
×
123
      }
×
124

125
   public:
126
      void go(const PerfConfig& config) override {
×
127
         auto ca = create_ca(config.rng());
×
128
         auto cert = make_certificate("Test Certificate", ca, config.rng());
×
129
         auto crl = make_revocation_list(500, ca, config.rng());
×
130

131
         const auto cert_encoded = cert.BER_encode();
×
132
         const auto crl_encoded = crl.BER_encode();
×
133

134
         auto cert_timer = config.make_timer("X509 Certificate Parsing");
×
135
         auto crl_timer = config.make_timer("X509 CRL Parsing");
×
136

137
         const auto runtime = config.runtime();
×
138

139
         while(cert_timer->under(runtime)) {
×
140
            cert_timer->start();
×
141
            std::ignore = Botan::X509_Certificate(cert_encoded);
×
142
            cert_timer->stop();
×
143
         }
144

145
         while(crl_timer->under(runtime)) {
×
146
            crl_timer->start();
×
147
            std::ignore = Botan::X509_CRL(crl_encoded);
×
148
            crl_timer->stop();
×
149
         }
150

151
         config.record_result(*cert_timer);
×
152
         config.record_result(*crl_timer);
×
153
      }
×
154
};
155

156
BOTAN_REGISTER_PERF_TEST("asn1_parsing", PerfTest_ASN1_Parsing);
×
157

158
#endif
159

160
}  // namespace Botan_CLI
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