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

Classes

class  Chain
 
class  Link
 
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.

Definition at line 168 of file roughtime.cpp.

168 {
169 std::array<uint8_t, request_min_size> buf = {{2, 0, 0, 0, 64, 0, 0, 0, 'N', 'O', 'N', 'C', 'P', 'A', 'D', 0xff}};
170 std::memcpy(buf.data() + 16, nonce.get_nonce().data(), nonce.get_nonce().size());
171 std::memset(buf.data() + 16 + nonce.get_nonce().size(), 0, buf.size() - 16 - nonce.get_nonce().size());
172 return buf;
173}
const std::array< uint8_t, 64 > & get_nonce() const
Definition roughtime.h:42

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 )

Definition at line 237 of file roughtime.cpp.

237 {
238 std::array<uint8_t, 64> ret{};
239 const auto blind_arr = blind.get_nonce();
240 auto hash = HashFunction::create_or_throw("SHA-512");
241 hash->update(previous_response);
242 hash->update(hash->final());
243 hash->update(blind_arr.data(), blind_arr.size());
244 hash->final(ret.data());
245
246 return ret;
247}

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 349 of file roughtime.cpp.

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

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)

Definition at line 380 of file roughtime.cpp.

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

References Botan::base64_decode(), and name.

Variable Documentation

◆ request_min_size

const unsigned Botan::Roughtime::request_min_size = 1024

Definition at line 23 of file roughtime.h.