Botan 3.3.0
Crypto and TLS for C&
Classes | Functions | Variables
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 164 of file roughtime.cpp.

164 {
165 std::array<uint8_t, request_min_size> buf = {{2, 0, 0, 0, 64, 0, 0, 0, 'N', 'O', 'N', 'C', 'P', 'A', 'D', 0xff}};
166 std::memcpy(buf.data() + 16, nonce.get_nonce().data(), nonce.get_nonce().size());
167 std::memset(buf.data() + 16 + nonce.get_nonce().size(), 0, buf.size() - 16 - nonce.get_nonce().size());
168 return buf;
169}
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 233 of file roughtime.cpp.

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

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

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

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

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