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

randombit / botan / 37260255903

04 Oct 2026 11:30PM UTC coverage: 92.214% (+0.02%) from 92.191%
37260255903

push

github

web-flow
Merge pull request #5995 from randombit/jack/ec-key-valiation

Harden EC key loading and validation

133278 of 144531 relevant lines covered (92.21%)

8668723.51 hits per line

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

89.2
/src/tests/test_roughtime.cpp
1
/*
2
* (C) 2019 Nuno Goncalves <nunojpg@gmail.com>
3
*
4
* Botan is released under the Simplified BSD License (see license.txt)
5
*/
6

7
#include "tests.h"
8

9
#if defined(BOTAN_HAS_BIGINT)
10
   #include <botan/bigint.h>
11
#endif
12

13
#if defined(BOTAN_HAS_ROUGHTIME)
14
   #include <botan/base64.h>
15
   #include <botan/ed25519.h>
16
   #include <botan/mem_ops.h>
17
   #include <botan/rng.h>
18
   #include <botan/roughtime.h>
19
#endif
20

21
namespace Botan_Tests {
22

23
namespace {
24

25
#if defined(BOTAN_HAS_ROUGHTIME)
26

27
class Roughtime_Request_Tests final : public Text_Based_Test {
×
28
   public:
29
      Roughtime_Request_Tests() : Text_Based_Test("roughtime/roughtime_request.vec", "Nonce,Request") {}
2 ✔
30

31
      Test::Result run_one_test(const std::string& type, const VarMap& vars) override {
2 ✔
32
         Test::Result result("Roughtime request");
2 ✔
33

34
         const auto nonce = Botan::Roughtime::Nonce(vars.get_req_bin("Nonce"));
2 ✔
35
         const auto request_v = vars.get_req_bin("Request");
2 ✔
36

37
         const auto request = Botan::Roughtime::encode_request(nonce);
2 ✔
38

39
         if(type == "Valid") {
2 ✔
40
            result.test_bin_eq("encode", request, request_v);
1 ✔
41
         } else {
42
            result.test_bin_ne("encode", request, request_v);
1 ✔
43
         }
44

45
         return result;
2 ✔
46
      }
2 ✔
47
};
48

49
BOTAN_REGISTER_TEST("roughtime", "roughtime_request", Roughtime_Request_Tests);
50

51
class Roughtime_Response_Tests final : public Text_Based_Test {
×
52
   public:
53
      Roughtime_Response_Tests() :
1 ✔
54
            Text_Based_Test(
55
               "roughtime/roughtime_response.vec", "Response", "Nonce,Pubkey,MidpointMicroSeconds,RadiusMicroSeconds") {
2 ✔
56
      }
1 ✔
57

58
      Test::Result run_one_test(const std::string& type, const VarMap& vars) override {
18 ✔
59
         Test::Result result("Roughtime response");
18 ✔
60

61
         const auto response_v = vars.get_req_bin("Response");
18 ✔
62
         const auto nonce_bits = vars.has_key("Nonce") ? vars.get_opt_bin("Nonce") : std::vector<uint8_t>(64);
18 ✔
63

64
         const Botan::Roughtime::Nonce nonce(nonce_bits);
18 ✔
65
         try {
18 ✔
66
            const auto response = Botan::Roughtime::Response::from_bits(response_v, nonce);
18 ✔
67

68
            const auto pubkey = vars.get_req_bin("Pubkey");
5 ✔
69
            if(pubkey.size() != 32) {
5 ✔
70
               throw Test_Error("Unexpected Roughtime Ed25519 pubkey size");
×
71
            }
72

73
            if(!response.validate(Botan::Ed25519_PublicKey(pubkey))) {
5 ✔
74
               result.test_is_true("fail_validation", type == "Invalid");
1 ✔
75
            } else {
76
               const auto midpoint = Botan::Roughtime::Response::sys_microseconds64(
3 ✔
77
                  std::chrono::microseconds(vars.get_req_u64("MidpointMicroSeconds")));
3 ✔
78
               const auto radius = std::chrono::microseconds(vars.get_req_u32("RadiusMicroSeconds"));
3 ✔
79

80
               result.test_is_true("midpoint", response.utc_midpoint() == midpoint);
3 ✔
81
               result.test_is_true("radius", response.utc_radius() == radius);
3 ✔
82
               result.test_is_true("OK", type == "Valid");
4 ✔
83
            }
84
         } catch(const Botan::Roughtime::Roughtime_Error& e) {
18 ✔
85
            result.test_is_true(e.what(), type == "Invalid");
13 ✔
86
         } catch(const Botan::Decoding_Error& e) {
14 ✔
87
            // An invalid Ed25519 public key is rejected when it is decoded
88
            result.test_is_true(e.what(), type == "Invalid");
1 ✔
89
         }
1 ✔
90

91
         return result;
18 ✔
92
      }
36 ✔
93
};
94

95
BOTAN_REGISTER_TEST("roughtime", "roughtime_response", Roughtime_Response_Tests);
96

97
class Roughtime_nonce_from_blind_Tests final : public Text_Based_Test {
×
98
   public:
99
      Roughtime_nonce_from_blind_Tests() :
1 ✔
100
            Text_Based_Test("roughtime/roughtime_nonce_from_blind.vec", "Response,Blind,Nonce") {}
2 ✔
101

102
      Test::Result run_one_test(const std::string& type, const VarMap& vars) override {
2 ✔
103
         Test::Result result("roughtime nonce_from_blind");
2 ✔
104

105
         const auto response = vars.get_req_bin("Response");
2 ✔
106
         const auto blind = Botan::Roughtime::Nonce(vars.get_req_bin("Blind"));
2 ✔
107
         const auto nonce = Botan::Roughtime::Nonce(vars.get_req_bin("Nonce"));
2 ✔
108

109
         const auto from_blind = Botan::Roughtime::nonce_from_blind(response, blind);
2 ✔
110

111
         if(type == "Valid") {
2 ✔
112
            result.test_is_true("valid nonce_from_blind", nonce == from_blind);
1 ✔
113
         } else {
114
            result.test_is_false("valid nonce_from_blind", nonce == from_blind);
1 ✔
115
         }
116

117
         return result;
2 ✔
118
      }
2 ✔
119
};
120

121
BOTAN_REGISTER_TEST("roughtime", "roughtime_nonce_from_blind", Roughtime_nonce_from_blind_Tests);
122

123
class Roughtime final : public Test {
1 ✔
124
   private:
125
      static Test::Result test_nonce(Botan::RandomNumberGenerator& rng) {
1 ✔
126
         Test::Result result("roughtime nonce");
1 ✔
127

128
         auto rand64 = Botan::unlock(rng.random_vec(64));
2 ✔
129
         const Botan::Roughtime::Nonce nonce_v(rand64);
1 ✔
130
         result.test_is_true("nonce from vector",
1 ✔
131
                             nonce_v.get_nonce() == Botan::typecast_copy<std::array<uint8_t, 64>>(rand64.data()));
1 ✔
132
         const Botan::Roughtime::Nonce nonce_a(Botan::typecast_copy<std::array<uint8_t, 64>>(rand64.data()));
1 ✔
133
         result.test_is_true("nonce from array",
1 ✔
134
                             nonce_v.get_nonce() == Botan::typecast_copy<std::array<uint8_t, 64>>(rand64.data()));
1 ✔
135
         rand64.push_back(10);
1 ✔
136
         result.test_throws("vector oversize",
1 ✔
137
                            [&rand64]() { const Botan::Roughtime::Nonce nonce_v2(rand64); });  //size 65
2 ✔
138
         rand64.pop_back();
1 ✔
139
         rand64.pop_back();
1 ✔
140
         result.test_throws("vector undersize",
1 ✔
141
                            [&rand64]() { const Botan::Roughtime::Nonce nonce_v2(rand64); });  //size 63
2 ✔
142

143
         return result;
1 ✔
144
      }
1 ✔
145

146
      static Test::Result test_chain(Botan::RandomNumberGenerator& rng) {
1 ✔
147
         Test::Result result("roughtime chain");
1 ✔
148

149
         Botan::Roughtime::Chain c1;
1 ✔
150
         result.test_is_true("default constructed is empty", c1.links().empty() && c1.responses().empty());
1 ✔
151

152
         auto rand64 = Botan::unlock(rng.random_vec(64));
2 ✔
153
         const Botan::Roughtime::Nonce nonce_v(rand64);
1 ✔
154
         result.test_is_true(
2 ✔
155
            "empty chain nonce is blind",
156
            c1.next_nonce(nonce_v).get_nonce() == Botan::typecast_copy<std::array<uint8_t, 64>>(rand64.data()));
1 ✔
157

158
         const std::string chain_str =
1 ✔
159
            "ed25519 bbT+RPS7zKX6w71ssPibzmwWqU9ffRV5oj2OresSmhE= eu9yhsJfVfguVSqGZdE8WKIxaBBM0ZG3Vmuc+IyZmG2YVmrIktUByDdwIFw6F4rZqmSFsBO85ljoVPz5bVPCOw== BQAAAEAAAABAAAAApAAAADwBAABTSUcAUEFUSFNSRVBDRVJUSU5EWBnGOEajOwPA6G7oL47seBP4C7eEpr57H43C2/fK/kMA0UGZVUdf4KNX8oxOK6JIcsbVk8qhghTwA70qtwpYmQkDAAAABAAAAAwAAABSQURJTUlEUFJPT1RAQg8AJrA8tEqPBQAqisiuAxgy2Pj7UJAiWbCdzGz1xcCnja3T+AqhC8fwpeIwW4GPy/vEb/awXW2DgSLKJfzWIAz+2lsR7t4UjNPvAgAAAEAAAABTSUcAREVMRes9Ch4X0HIw5KdOTB8xK4VDFSJBD/G9t7Et/CU7UW61OiTBXYYQTG2JekWZmGa0OHX1JPGG+APkpbsNw0BKUgYDAAAAIAAAACgAAABQVUJLTUlOVE1BWFR/9BWjpsWTQ1f6iUJea3EfZ1MkX3ftJiV3ABqNLpncFwAAAAAAAAAA//////////8AAAAA\n"
160
            "ed25519 gD63hSj3ScS+wuOeGrubXlq35N1c5Lby/S+T7MNTjxo= uLeTON9D+2HqJMzK6sYWLNDEdtBl9t/9yw1cVAOm0/sONH5Oqdq9dVPkC9syjuWbglCiCPVF+FbOtcxCkrgMmA== BQAAAEAAAABAAAAApAAAADwBAABTSUcAUEFUSFNSRVBDRVJUSU5EWOw1jl0uSiBEH9HE8/6r7zxoSc01f48vw+UzH8+VJoPelnvVJBj4lnH8uRLh5Aw0i4Du7XM1dp2u0r/I5PzhMQoDAAAABAAAAAwAAABSQURJTUlEUFJPT1RAQg8AUBo+tEqPBQC47l77to7ESFTVhlw1SC74P5ssx6gpuJ6eP+1916GuUiySGE/x3Fp0c3otUGAdsRQou5p9PDTeane/YEeVq4/8AgAAAEAAAABTSUcAREVMRe5T1ml8wHyWAcEtHP/U5Rg/jFXTEXOSglngSa4aI/CECVdy4ZNWeP6vv+2//ZW7lQsrWo7ZkXpvm9BdBONRSQIDAAAAIAAAACgAAABQVUJLTUlOVE1BWFQpXlenV0OfVisvp9jDHXLw8vymZVK9Pgw9k6Edf8ZEhUgSGEc5jwUASHLvZE2PBQAAAAAA\n";
1 ✔
161

162
         Botan::Roughtime::Chain c2(chain_str);
1 ✔
163
         result.test_is_true("have two elements", c2.links().size() == 2 && c2.responses().size() == 2);
2 ✔
164
         result.test_is_true("serialize loopback", c2.to_string() == chain_str);
1 ✔
165

166
         c1.append(c2.links()[0], 1);
1 ✔
167
         result.test_is_true("append ok", c1.links().size() == 1 && c1.responses().size() == 1);
2 ✔
168
         c1.append(c2.links()[1], 1);
1 ✔
169
         result.test_is_true("max size", c1.links().size() == 1 && c1.responses().size() == 1);
2 ✔
170

171
         result.test_throws("non-positive max chain size", [&]() { c1.append(c2.links()[1], 0); });
2 ✔
172
         result.test_throws("1 field", [&]() { const Botan::Roughtime::Chain a("ed25519"); });
2 ✔
173
         result.test_throws("2 fields", [&]() {
1 ✔
174
            const Botan::Roughtime::Chain a("ed25519 bbT+RPS7zKX6w71ssPibzmwWqU9ffRV5oj2OresSmhE=");
1 ✔
175
         });
×
176
         result.test_throws("3 fields", [&]() {
1 ✔
177
            const Botan::Roughtime::Chain a(
1 ✔
178
               "ed25519 bbT+RPS7zKX6w71ssPibzmwWqU9ffRV5oj2OresSmhE= eu9yhsJfVfguVSqGZdE8WKIxaBBM0ZG3Vmuc+IyZmG2YVmrIktUByDdwIFw6F4rZqmSFsBO85ljoVPz5bVPCOw==");
1 ✔
179
         });
×
180
         result.test_throws("5 fields", [&]() {
1 ✔
181
            const Botan::Roughtime::Chain a(
1 ✔
182
               "ed25519 bbT+RPS7zKX6w71ssPibzmwWqU9ffRV5oj2OresSmhE= eu9yhsJfVfguVSqGZdE8WKIxaBBM0ZG3Vmuc+IyZmG2YVmrIktUByDdwIFw6F4rZqmSFsBO85ljoVPz5bVPCOw== BQAAAEAAAABAAAAApAAAADwBAABTSUcAUEFUSFNSRVBDRVJUSU5EWBnGOEajOwPA6G7oL47seBP4C7eEpr57H43C2/fK/kMA0UGZVUdf4KNX8oxOK6JIcsbVk8qhghTwA70qtwpYmQkDAAAABAAAAAwAAABSQURJTUlEUFJPT1RAQg8AJrA8tEqPBQAqisiuAxgy2Pj7UJAiWbCdzGz1xcCnja3T+AqhC8fwpeIwW4GPy/vEb/awXW2DgSLKJfzWIAz+2lsR7t4UjNPvAgAAAEAAAABTSUcAREVMRes9Ch4X0HIw5KdOTB8xK4VDFSJBD/G9t7Et/CU7UW61OiTBXYYQTG2JekWZmGa0OHX1JPGG+APkpbsNw0BKUgYDAAAAIAAAACgAAABQVUJLTUlOVE1BWFR/9BWjpsWTQ1f6iUJea3EfZ1MkX3ftJiV3ABqNLpncFwAAAAAAAAAA//////////8AAAAA abc");
1 ✔
183
         });
×
184
         result.test_throws("invalid key type", [&]() {
1 ✔
185
            const Botan::Roughtime::Chain a(
1 ✔
186
               "rsa bbT+RPS7zKX6w71ssPibzmwWqU9ffRV5oj2OresSmhE= eu9yhsJfVfguVSqGZdE8WKIxaBBM0ZG3Vmuc+IyZmG2YVmrIktUByDdwIFw6F4rZqmSFsBO85ljoVPz5bVPCOw== BQAAAEAAAABAAAAApAAAADwBAABTSUcAUEFUSFNSRVBDRVJUSU5EWBnGOEajOwPA6G7oL47seBP4C7eEpr57H43C2/fK/kMA0UGZVUdf4KNX8oxOK6JIcsbVk8qhghTwA70qtwpYmQkDAAAABAAAAAwAAABSQURJTUlEUFJPT1RAQg8AJrA8tEqPBQAqisiuAxgy2Pj7UJAiWbCdzGz1xcCnja3T+AqhC8fwpeIwW4GPy/vEb/awXW2DgSLKJfzWIAz+2lsR7t4UjNPvAgAAAEAAAABTSUcAREVMRes9Ch4X0HIw5KdOTB8xK4VDFSJBD/G9t7Et/CU7UW61OiTBXYYQTG2JekWZmGa0OHX1JPGG+APkpbsNw0BKUgYDAAAAIAAAACgAAABQVUJLTUlOVE1BWFR/9BWjpsWTQ1f6iUJea3EfZ1MkX3ftJiV3ABqNLpncFwAAAAAAAAAA//////////8AAAAA");
1 ✔
187
         });
×
188
         result.test_throws("invalid key", [&]() {
1 ✔
189
            const Botan::Roughtime::Chain a(
1 ✔
190
               "ed25519 bbT+RPS7zKX6wssPibzmwWqU9ffRV5oj2OresSmhE= eu9yhsJfVfguVSqGZdE8WKIxaBBM0ZG3Vmuc+IyZmG2YVmrIktUByDdwIFw6F4rZqmSFsBO85ljoVPz5bVPCOw== BQAAAEAAAABAAAAApAAAADwBAABTSUcAUEFUSFNSRVBDRVJUSU5EWBnGOEajOwPA6G7oL47seBP4C7eEpr57H43C2/fK/kMA0UGZVUdf4KNX8oxOK6JIcsbVk8qhghTwA70qtwpYmQkDAAAABAAAAAwAAABSQURJTUlEUFJPT1RAQg8AJrA8tEqPBQAqisiuAxgy2Pj7UJAiWbCdzGz1xcCnja3T+AqhC8fwpeIwW4GPy/vEb/awXW2DgSLKJfzWIAz+2lsR7t4UjNPvAgAAAEAAAABTSUcAREVMRes9Ch4X0HIw5KdOTB8xK4VDFSJBD/G9t7Et/CU7UW61OiTBXYYQTG2JekWZmGa0OHX1JPGG+APkpbsNw0BKUgYDAAAAIAAAACgAAABQVUJLTUlOVE1BWFR/9BWjpsWTQ1f6iUJea3EfZ1MkX3ftJiV3ABqNLpncFwAAAAAAAAAA//////////8AAAAA");
1 ✔
191
         });
×
192
         result.test_throws("invalid nonce", [&]() {
1 ✔
193
            const Botan::Roughtime::Chain a(
1 ✔
194
               "ed25519 bbT+RPS7zKX6w71ssPibzmwWqU9ffRV5oj2OresSmhE= eu9yhsJfVfguVSqGZdE8WKIxaBBM0ZG3Vmuc+IyZmG2UByDdwIFw6F4rZqmSFsBO85ljoVPz5bVPCOw== BQAAAEAAAABAAAAApAAAADwBAABTSUcAUEFUSFNSRVBDRVJUSU5EWBnGOEajOwPA6G7oL47seBP4C7eEpr57H43C2/fK/kMA0UGZVUdf4KNX8oxOK6JIcsbVk8qhghTwA70qtwpYmQkDAAAABAAAAAwAAABSQURJTUlEUFJPT1RAQg8AJrA8tEqPBQAqisiuAxgy2Pj7UJAiWbCdzGz1xcCnja3T+AqhC8fwpeIwW4GPy/vEb/awXW2DgSLKJfzWIAz+2lsR7t4UjNPvAgAAAEAAAABTSUcAREVMRes9Ch4X0HIw5KdOTB8xK4VDFSJBD/G9t7Et/CU7UW61OiTBXYYQTG2JekWZmGa0OHX1JPGG+APkpbsNw0BKUgYDAAAAIAAAACgAAABQVUJLTUlOVE1BWFR/9BWjpsWTQ1f6iUJea3EfZ1MkX3ftJiV3ABqNLpncFwAAAAAAAAAA//////////8AAAAA");
1 ✔
195
         });
×
196

197
         return result;
1 ✔
198
      }
2 ✔
199

200
      static Test::Result test_server_information() {
1 ✔
201
         Test::Result result("roughtime server_information");
1 ✔
202

203
         const auto servers = Botan::Roughtime::servers_from_str(
1 ✔
204
            "Chainpoint-Roughtime ed25519 bbT+RPS7zKX6w71ssPibzmwWqU9ffRV5oj2OresSmhE= udp roughtime.chainpoint.org:2002\n"
205
            "Cloudflare-Roughtime ed25519 0GD7c3yP8xEc4Zl2zeuN2SlLvDVVocjsPSL8/Rl/7zg= udp roughtime.cloudflare.com:2003\n"
206
            "Google-Sandbox-Roughtime ed25519 etPaaIxcBMY1oUeGpwvPMCJMwlRVNxv51KK/tktoJTQ= udp roughtime.sandbox.google.com:2002\n"
207
            "int08h-Roughtime ed25519 AW5uAoTSTDfG5NfY1bTh08GUnOqlRb+HVhbJ3ODJvsE= udp roughtime.int08h.com:2002\n"
208
            "ticktock ed25519 cj8GsiNlRkqiDElAeNMSBBMwrAl15hYPgX50+GWX/lA= udp ticktock.mixmin.net:5333\n");
1 ✔
209

210
         result.test_is_true("size", servers.size() == 5);
1 ✔
211
         result.test_str_eq("name", servers[0].name(), "Chainpoint-Roughtime");
1 ✔
212
         result.test_str_eq("name", servers[4].name(), "ticktock");
1 ✔
213
         result.test_is_true(
1 ✔
214
            "public key",
215
            servers[0].public_key().get_public_key() ==
1 ✔
216
               Botan::Ed25519_PublicKey(Botan::base64_decode("bbT+RPS7zKX6w71ssPibzmwWqU9ffRV5oj2OresSmhE="))
2 ✔
217
                  .get_public_key());
218
         result.test_is_true("single address", servers[0].addresses().size() == 1);
1 ✔
219
         result.test_str_eq("address", servers[0].addresses()[0], "roughtime.chainpoint.org:2002");
1 ✔
220

221
         result.test_throws("1 field", [&]() { Botan::Roughtime::servers_from_str("A"); });
2 ✔
222
         result.test_throws("2 fields", [&]() { Botan::Roughtime::servers_from_str("A ed25519"); });
2 ✔
223
         result.test_throws("3 fields", [&]() {
1 ✔
224
            Botan::Roughtime::servers_from_str("A ed25519 bbT+RPS7zKX6w71ssPibzmwWqU9ffRV5oj2OresSmhE=");
1 ✔
225
         });
×
226
         result.test_throws("4 fields", [&]() {
1 ✔
227
            Botan::Roughtime::servers_from_str("A ed25519 bbT+RPS7zKX6w71ssPibzmwWqU9ffRV5oj2OresSmhE= udp");
1 ✔
228
         });
×
229
         result.test_throws("invalid address", [&]() {
1 ✔
230
            Botan::Roughtime::servers_from_str("A ed25519 bbT+RPS7zKX6w71ssPibzmwWqU9ffRV5oj2OresSmhE= udp ");
1 ✔
231
         });
×
232
         result.test_throws("invalid key type", [&]() {
1 ✔
233
            Botan::Roughtime::servers_from_str(
1 ✔
234
               "A rsa bbT+RPS7zKX6w71ssPibzmwWqU9ffRV5oj2OresSmhE= udp roughtime.chainpoint.org:2002");
235
         });
×
236
         result.test_throws("invalid key", [&]() {
1 ✔
237
            Botan::Roughtime::servers_from_str(
1 ✔
238
               "A ed25519 bbT+RP7zKX6w71ssPibzmwWqU9ffRV5oj2OresSmhE= udp roughtime.chainpoint.org:2002");
239
         });
×
240
         result.test_throws("invalid protocol", [&]() {
1 ✔
241
            Botan::Roughtime::servers_from_str(
1 ✔
242
               "A ed25519 bbT+RPS7zKX6w71ssPibzmwWqU9ffRV5oj2OresSmhE= tcp roughtime.chainpoint.org:2002");
243
         });
×
244

245
         return result;
1 ✔
246
      }
1 ✔
247

248
      static Test::Result test_request_online(Botan::RandomNumberGenerator& rng) {
1 ✔
249
         Test::Result result("roughtime request online");
1 ✔
250

251
         const Botan::Roughtime::Nonce nonce(rng);
1 ✔
252
         try {
1 ✔
253
            const auto response_raw =
1 ✔
254
               Botan::Roughtime::online_request("roughtime.cloudflare.com:2003", nonce, std::chrono::seconds(5));
1 ✔
255
            const auto now = std::chrono::system_clock::now();
1 ✔
256
            const auto response = Botan::Roughtime::Response::from_bits(response_raw, nonce);
1 ✔
257
            const std::chrono::milliseconds local_clock_max_error(1000);
1 ✔
258
            const auto diff_abs =
1 ✔
259
               now >= response.utc_midpoint() ? now - response.utc_midpoint() : response.utc_midpoint() - now;
1 ✔
260
            result.test_is_true("online", diff_abs <= (response.utc_radius() + local_clock_max_error));
1 ✔
261
         } catch(const std::exception& e) {
1 ✔
262
            result.test_failure(e.what());
×
263
         }
×
264
         return result;
1 ✔
265
      }
×
266

267
   public:
268
      std::vector<Test::Result> run() override {
1 ✔
269
         auto& rng = this->rng();
1 ✔
270

271
         std::vector<Test::Result> results{test_nonce(rng), test_chain(rng), test_server_information()};
4 ✔
272

273
         if(Test::options().run_online_tests()) {
1 ✔
274
            results.push_back(test_request_online(rng));
2 ✔
275
         }
276

277
         return results;
1 ✔
278
      }
1 ✔
279
};
280

281
BOTAN_REGISTER_TEST("roughtime", "roughtime_tests", Roughtime);
282

283
#endif
284

285
}  // namespace
286

287
}  // namespace Botan_Tests
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc