Botan 3.13.0
Crypto and TLS for C&
Botan::Roughtime Namespace Reference

Classes

class  Chain
class  Nonce
class  Response
class  Roughtime_Error
struct  Server_Information

Functions

std::array< uint8_t, request_min_sizeencode_request (const Nonce &nonce)
Nonce nonce_from_blind (const std::vector< uint8_t > &previous_response, const Nonce &blind)
std::vector< uint8_t > online_request (std::string_view uri, const Nonce &nonce, std::chrono::milliseconds timeout)
std::vector< Server_Informationservers_from_str (std::string_view str)

Variables

const unsigned request_min_size = 1024

Function Documentation

◆ encode_request()

std::array< uint8_t, request_min_size > Botan::Roughtime::encode_request ( const Nonce & nonce)

An Roughtime request.

Parameters
noncethe nonce to include in the request
Returns
the encoded request

Definition at line 174 of file roughtime.cpp.

174 {
175 std::array<uint8_t, request_min_size> buf = {{2, 0, 0, 0, 64, 0, 0, 0, 'N', 'O', 'N', 'C', 'P', 'A', 'D', 0xff}};
176 std::memcpy(buf.data() + 16, nonce.get_nonce().data(), nonce.get_nonce().size());
177 std::memset(buf.data() + 16 + nonce.get_nonce().size(), 0, buf.size() - 16 - nonce.get_nonce().size());
178 return buf;
179}
const std::array< uint8_t, 64 > & get_nonce() const
Definition roughtime.h:85

References Botan::Roughtime::Nonce::get_nonce().

Referenced by online_request().

◆ nonce_from_blind()

Nonce Botan::Roughtime::nonce_from_blind ( const std::vector< uint8_t > & previous_response,
const Nonce & blind )

Derive a nonce from the previous response and a blind

Parameters
previous_responsethe raw bytes of the previous response
blindthe blind to use
Returns
the derived nonce

Definition at line 242 of file roughtime.cpp.

242 {
243 std::array<uint8_t, 64> ret{};
244 const auto blind_arr = blind.get_nonce();
245 auto hash = HashFunction::create_or_throw("SHA-512");
246 hash->update(previous_response);
247 hash->update(hash->final());
248 hash->update(blind_arr.data(), blind_arr.size());
249 hash->final(ret.data());
250
251 return Nonce(ret);
252}
static std::unique_ptr< HashFunction > create_or_throw(std::string_view algo_spec, std::string_view provider="")
Definition hash.cpp:308

References Botan::HashFunction::create_or_throw(), and Botan::Roughtime::Nonce::get_nonce().

Referenced by Botan::Roughtime::Chain::append(), Botan::Roughtime::Chain::next_nonce(), and Botan::Roughtime::Chain::responses().

◆ online_request()

std::vector< uint8_t > Botan::Roughtime::online_request ( std::string_view url,
const Nonce & nonce,
std::chrono::milliseconds timeout = std::chrono::seconds(3) )

Makes an online Roughtime request via UDP and returns the Roughtime response.

Parameters
urlRoughtime server UDP endpoint (host:port)
noncethe nonce to send to the server
timeouta timeout on the UDP request
Returns
Roughtime response

Definition at line 355 of file roughtime.cpp.

355 {
356 const std::chrono::system_clock::time_point start_time = std::chrono::system_clock::now();
357 auto socket = OS::open_socket_udp(uri, timeout);
358 if(!socket) {
359 throw Not_Implemented("No socket support enabled in build");
360 }
361
362 const auto encoded = encode_request(nonce);
363 socket->write(encoded.data(), encoded.size());
364
365 if(std::chrono::system_clock::now() - start_time > timeout) {
366 throw System_Error("Timeout during socket write");
367 }
368
369 std::vector<uint8_t> buffer;
370 buffer.resize(360 + 64 * 10 + 1); //response basic size is 360 bytes + 64 bytes for each level of merkle tree
371 //add one additional byte to be able to differentiate if datagram got truncated
372 const auto n = socket->read(buffer.data(), buffer.size());
373
374 if(n == 0 || std::chrono::system_clock::now() - start_time > timeout) {
375 throw System_Error("Timeout waiting for response");
376 }
377
378 if(n == buffer.size()) {
379 throw System_Error("Buffer too small");
380 }
381
382 buffer.resize(n);
383 return buffer;
384}
std::unique_ptr< SocketUDP > BOTAN_TEST_API open_socket_udp(std::string_view hostname, std::string_view service, std::chrono::microseconds timeout)
std::array< uint8_t, request_min_size > encode_request(const Nonce &nonce)

References encode_request(), and Botan::OS::open_socket_udp().

◆ servers_from_str()

std::vector< Server_Information > Botan::Roughtime::servers_from_str ( std::string_view str)

Parse a list of server descriptions

Parameters
strthe server list to parse
Returns
the parsed servers

Definition at line 386 of file roughtime.cpp.

386 {
387 std::vector<Server_Information> servers;
388 std::istringstream ss{std::string(str)}; // FIXME C++23 avoid copy
389
390 const std::string ERROR_MESSAGE = "Line does not have at least 5 space separated fields";
391 for(std::string s; std::getline(ss, s);) {
392 size_t start = 0;
393 size_t end = 0;
394 end = s.find(' ', start);
395 if(end == std::string::npos) {
396 throw Decoding_Error(ERROR_MESSAGE);
397 }
398 const auto name = s.substr(start, end - start);
399
400 start = end + 1;
401 end = s.find(' ', start);
402 if(end == std::string::npos) {
403 throw Decoding_Error(ERROR_MESSAGE);
404 }
405 const auto publicKeyType = s.substr(start, end - start);
406 if(publicKeyType != "ed25519") {
407 throw Not_Implemented("Only ed25519 publicKeyType is implemented");
408 }
409
410 start = end + 1;
411 end = s.find(' ', start);
412
413 if(end == std::string::npos) {
414 throw Decoding_Error(ERROR_MESSAGE);
415 }
416 const auto publicKeyBase64 = s.substr(start, end - start);
417 const auto publicKey = Ed25519_PublicKey(base64_decode(publicKeyBase64));
418
419 start = end + 1;
420 end = s.find(' ', start);
421 if(end == std::string::npos) {
422 throw Decoding_Error(ERROR_MESSAGE);
423 }
424 const auto protocol = s.substr(start, end - start);
425 if(protocol != "udp") {
426 throw Not_Implemented("Only UDP protocol is implemented");
427 }
428
429 const auto addresses = [&]() {
430 std::vector<std::string> addr;
431 for(;;) {
432 start = end + 1;
433 end = s.find(' ', start);
434 const auto address = s.substr(start, (end == std::string::npos) ? std::string::npos : end - start);
435 if(address.empty()) {
436 return addr;
437 }
438 addr.push_back(address);
439 if(end == std::string::npos) {
440 return addr;
441 }
442 }
443 }();
444 if(addresses.empty()) {
445 throw Decoding_Error(ERROR_MESSAGE);
446 }
447
448 servers.push_back({name, publicKey, addresses});
449 }
450 return servers;
451}
size_t base64_decode(uint8_t out[], const char in[], size_t input_length, size_t &input_consumed, bool final_inputs, bool ignore_ws)
Definition base64.cpp:169

References Botan::base64_decode().

Variable Documentation

◆ request_min_size

const unsigned Botan::Roughtime::request_min_size = 1024

The fixed size of a Roughtime request

Definition at line 26 of file roughtime.h.