Botan 3.13.0
Crypto and TLS for C&
roughtime.h
Go to the documentation of this file.
1/*
2* Roughtime
3* (C) 2019 Nuno Goncalves <nunojpg@gmail.com>
4*
5* Botan is released under the Simplified BSD License (see license.txt)
6*/
7
8#ifndef BOTAN_ROUGHTIME_H_
9#define BOTAN_ROUGHTIME_H_
10
11#include <array>
12#include <chrono>
13#include <vector>
14
15#include <botan/ed25519.h>
16
17namespace Botan {
18
20
21namespace Roughtime {
22
23/**
24* The fixed size of a Roughtime request
25*/
26const unsigned request_min_size = 1024;
27
28/**
29* An error occurred while processing a Roughtime message
30*/
31class BOTAN_PUBLIC_API(2, 13) Roughtime_Error final : public Decoding_Error {
32 public:
33 /**
34 * Create a Roughtime_Error
35 * @param s a description of the failure
36 */
37 explicit Roughtime_Error(std::string_view s) : Decoding_Error("Roughtime", s) {}
38
39 /**
40 * Return the error type of this exception
41 * @return always ErrorType::RoughtimeError
42 */
43 ErrorType error_type() const noexcept override { return ErrorType::RoughtimeError; }
44};
45
46/**
47* A 64 byte Roughtime nonce
48*/
49class BOTAN_PUBLIC_API(2, 13) Nonce final {
50 public:
51 /**
52 * Create an uninitialized nonce
53 */
54 Nonce() = default;
55
56 /**
57 * Create a nonce from a 64 byte vector
58 * @param nonce the nonce bytes
59 */
60 explicit Nonce(const std::vector<uint8_t>& nonce);
61
62 /**
63 * Create a random nonce
64 * @param rng a random number generator
65 */
66 explicit Nonce(RandomNumberGenerator& rng);
67
68 /**
69 * Create a nonce from a 64 byte array
70 * @param nonce the nonce bytes
71 */
72 explicit Nonce(const std::array<uint8_t, 64>& nonce) : m_nonce(nonce) {}
73
74 /**
75 * Compare two nonces
76 * @param rhs the nonce to compare against
77 * @return true if the nonces are equal
78 */
79 bool operator==(const Nonce& rhs) const { return m_nonce == rhs.m_nonce; }
80
81 /**
82 * Access the nonce bytes
83 * @return the 64 nonce bytes
84 */
85 const std::array<uint8_t, 64>& get_nonce() const { return m_nonce; }
86
87 private:
88 std::array<uint8_t, 64> m_nonce;
89};
90
91/**
92* An Roughtime request.
93*
94* @param nonce the nonce to include in the request
95* @return the encoded request
96*/
98std::array<uint8_t, request_min_size> encode_request(const Nonce& nonce);
99
100/**
101* An Roughtime response.
102*/
103class BOTAN_PUBLIC_API(2, 13) Response final {
104 public:
105 /**
106 * A 32 bit microsecond duration
107 */
108 using microseconds32 = std::chrono::duration<uint32_t, std::micro>;
109
110 /**
111 * A 64 bit microsecond duration
112 */
113 using microseconds64 = std::chrono::duration<uint64_t, std::micro>;
114
115 /**
116 * A system clock time point with microsecond resolution
117 */
118 using sys_microseconds64 = std::chrono::time_point<std::chrono::system_clock, microseconds64>;
119
120 /**
121 * Parse a Roughtime response
122 * @param response the raw response bytes
123 * @param nonce the nonce which was sent in the request
124 * @return the parsed response
125 */
126 static Response from_bits(const std::vector<uint8_t>& response, const Nonce& nonce);
127
128 /**
129 * Check the signatures on this response
130 * @param pk the long term public key of the server
131 * @return true if the response is valid
132 */
133 bool validate(const Ed25519_PublicKey& pk) const;
134
135 /**
136 * Return the midpoint of the time interval reported by the server
137 * @return the UTC midpoint
138 */
139 sys_microseconds64 utc_midpoint() const { return m_utc_midpoint; }
140
141 /**
142 * Return the radius of the time interval reported by the server
143 * @return the UTC radius
144 */
145 microseconds32 utc_radius() const { return m_utc_radius; }
146
147 private:
148 Response(const std::array<uint8_t, 72>& dele,
149 const std::array<uint8_t, 64>& sig,
150 sys_microseconds64 utc_midp,
151 microseconds32 utc_radius) :
152 m_cert_dele(dele), m_cert_sig(sig), m_utc_midpoint{utc_midp}, m_utc_radius{utc_radius} {}
153
154 const std::array<uint8_t, 72> m_cert_dele;
155 const std::array<uint8_t, 64> m_cert_sig;
156 const sys_microseconds64 m_utc_midpoint;
157 const microseconds32 m_utc_radius;
158};
159
160/**
161* One response in a Roughtime chain
162*/
163class BOTAN_PUBLIC_API(2, 13) Link final {
164 public:
165 /**
166 * Create a chain link
167 * @param response the raw response bytes
168 * @param public_key the public key of the server which produced it
169 * @param nonce_or_blind the nonce, or for later links the blind
170 */
171 Link(const std::vector<uint8_t>& response, const Ed25519_PublicKey& public_key, const Nonce& nonce_or_blind) :
172 m_response{response}, m_public_key{public_key}, m_nonce_or_blind{nonce_or_blind} {}
173
174 /**
175 * Access the raw response
176 * @return the raw response bytes
177 */
178 const std::vector<uint8_t>& response() const { return m_response; }
179
180 /**
181 * Access the server public key
182 * @return the public key of the server
183 */
184 const Ed25519_PublicKey& public_key() const { return m_public_key; }
185
186 /**
187 * Access the nonce or blind
188 * @return the nonce, or for later links the blind
189 */
190 const Nonce& nonce_or_blind() const { return m_nonce_or_blind; }
191
192 /**
193 * Access the nonce or blind
194 * @return the nonce, or for later links the blind
195 */
196 Nonce& nonce_or_blind() { return m_nonce_or_blind; }
197
198 private:
199 std::vector<uint8_t> m_response;
200 Ed25519_PublicKey m_public_key;
201 Nonce m_nonce_or_blind;
202};
203
204/**
205* A chain of Roughtime responses
206*/
207class BOTAN_PUBLIC_API(2, 13) Chain final {
208 public:
209 /**
210 * Create an empty chain
211 */
212 Chain() = default; //empty
213
214 /**
215 * Parse a chain from its string representation
216 * @param str the chain to parse
217 */
218 explicit Chain(std::string_view str);
219
220 /**
221 * Access the links of this chain
222 * @return the links
223 */
224 const std::vector<Link>& links() const { return m_links; }
225
226 /**
227 * Parse and validate every response in the chain
228 * @return the parsed responses
229 */
230 std::vector<Response> responses() const;
231
232 /**
233 * Compute the nonce to use for the next request
234 * @param blind the blind to use
235 * @return the next nonce
236 */
237 Nonce next_nonce(const Nonce& blind) const;
238
239 /**
240 * Append a link, dropping the oldest links if needed
241 * @param new_link the link to append
242 * @param max_chain_size the maximum number of links to retain
243 */
244 void append(const Link& new_link, size_t max_chain_size);
245
246 /**
247 * Format this chain as a string
248 * @return the string representation of the chain
249 */
250 std::string to_string() const;
251
252 private:
253 std::vector<Link> m_links;
254};
255
256/**
257* Derive a nonce from the previous response and a blind
258* @param previous_response the raw bytes of the previous response
259* @param blind the blind to use
260* @return the derived nonce
261*/
262BOTAN_PUBLIC_API(2, 13)
263Nonce nonce_from_blind(const std::vector<uint8_t>& previous_response, const Nonce& blind);
264
265/**
266* Makes an online Roughtime request via UDP and returns the Roughtime response.
267* @param url Roughtime server UDP endpoint (host:port)
268* @param nonce the nonce to send to the server
269* @param timeout a timeout on the UDP request
270* @return Roughtime response
271*/
272BOTAN_PUBLIC_API(2, 13)
273std::vector<uint8_t> online_request(std::string_view url,
274 const Nonce& nonce,
275 std::chrono::milliseconds timeout = std::chrono::seconds(3));
276
277/**
278* The name, key and addresses of a Roughtime server
279*/
281 public:
282 /**
283 * Create a server description
284 * @param name the name of the server
285 * @param public_key the long term public key of the server
286 * @param addresses the endpoints of the server
287 */
288 Server_Information(std::string_view name,
290 const std::vector<std::string>& addresses) :
291 m_name{name}, m_public_key{public_key}, m_addresses{addresses} {}
292
293 /**
294 * Access the server name
295 * @return the name of the server
296 */
297 const std::string& name() const { return m_name; }
298
299 /**
300 * Access the server public key
301 * @return the long term public key of the server
302 */
303 const Ed25519_PublicKey& public_key() const { return m_public_key; }
304
305 /**
306 * Access the server addresses
307 * @return the endpoints of the server
308 */
309 const std::vector<std::string>& addresses() const { return m_addresses; }
310
311 private:
312 std::string m_name;
313 Ed25519_PublicKey m_public_key;
314 std::vector<std::string> m_addresses;
315};
316
317/**
318* Parse a list of server descriptions
319* @param str the server list to parse
320* @return the parsed servers
321*/
322BOTAN_PUBLIC_API(2, 13)
323std::vector<Server_Information> servers_from_str(std::string_view str);
324
325} // namespace Roughtime
326} // namespace Botan
327
328#endif
#define BOTAN_PUBLIC_API(maj, min)
Definition api.h:21
Decoding_Error(std::string_view name)
Definition exceptn.cpp:125
const std::vector< Link > & links() const
Definition roughtime.h:224
const std::array< uint8_t, 64 > & get_nonce() const
Definition roughtime.h:85
Nonce(const std::array< uint8_t, 64 > &nonce)
Definition roughtime.h:72
bool operator==(const Nonce &rhs) const
Definition roughtime.h:79
std::chrono::time_point< std::chrono::system_clock, microseconds64 > sys_microseconds64
Definition roughtime.h:118
microseconds32 utc_radius() const
Definition roughtime.h:145
sys_microseconds64 utc_midpoint() const
Definition roughtime.h:139
std::chrono::duration< uint32_t, std::micro > microseconds32
Definition roughtime.h:108
static Response from_bits(const std::vector< uint8_t > &response, const Nonce &nonce)
std::chrono::duration< uint64_t, std::micro > microseconds64
Definition roughtime.h:113
bool validate(const Ed25519_PublicKey &pk) const
ErrorType error_type() const noexcept override
Definition roughtime.h:43
Roughtime_Error(std::string_view s)
Definition roughtime.h:37
std::vector< Server_Information > servers_from_str(std::string_view str)
std::vector< uint8_t > online_request(std::string_view uri, const Nonce &nonce, std::chrono::milliseconds timeout)
Nonce nonce_from_blind(const std::vector< uint8_t > &previous_response, const Nonce &blind)
std::array< uint8_t, request_min_size > encode_request(const Nonce &nonce)
const unsigned request_min_size
Definition roughtime.h:26
std::string to_string(ErrorType type)
Convert an ErrorType to string.
Definition exceptn.cpp:13
ErrorType
Definition exceptn.h:21
const std::string & name() const
Definition roughtime.h:297
const Ed25519_PublicKey & public_key() const
Definition roughtime.h:303
const std::vector< std::string > & addresses() const
Definition roughtime.h:309
Server_Information(std::string_view name, const Ed25519_PublicKey &public_key, const std::vector< std::string > &addresses)
Definition roughtime.h:288