From 246995dab39b7be36a0ad2e6a8061e70aca9f907 Mon Sep 17 00:00:00 2001 From: surtur Date: Thu, 20 Jan 2022 05:36:06 +0100 Subject: [PATCH] sfm: fix reads,writes of the seed file, refactor --- seed_file_management.cpp | 80 +++++++++++++++++++++++++++++++--------- seed_file_management.h | 5 ++- 2 files changed, 65 insertions(+), 20 deletions(-) diff --git a/seed_file_management.cpp b/seed_file_management.cpp index b6daf38..8275423 100644 --- a/seed_file_management.cpp +++ b/seed_file_management.cpp @@ -6,10 +6,14 @@ #include "util.h" #include +#include #include +#include +#include #include #include +#include #include #include @@ -37,29 +41,54 @@ auto SeedFileManager::do_stuff() -> void { do_task.thread_pls(config.write_interval, [this] { write_seed_file(); }); } +auto SeedFileManager::seed_file_exists() const -> bool { + // based on https://stackoverflow.com/a/6296808 + struct stat buf; + if (stat(config.seed_f_path.c_str(), &buf) != -1) { + return true; + } + return false; +} + auto SeedFileManager::update_seed_file() -> void { + fortuna::SeedFileManager::RUNNING = true; CryptoPP::SecByteBlock buff{config.seed_f_length}; { - std::ifstream f_stream{config.seed_f_path, std::ios::binary}; - if (!f_stream) { - std::string msg{"error opening seed file"}; - fmt::print("{} {}\n", msg, config.seed_f_path); - fortuna::SeedFileManager::RUNNING = false; - // FIXME: perhaps create a seed file instead of bailing... - throw std::runtime_error("error opening seed file"); + if (!seed_file_exists()) { + fmt::print("\t[i] sfm: SEED FILE NOT PRESENT, creating...\n"); + std::fstream f_stream; + f_stream.open(config.seed_f_path, + std::fstream::out | std::fstream::trunc); + f_stream << ""; + f_stream.close(); + return; + } + + std::ifstream f_stream{config.seed_f_path, std::ios::binary}; + + if (!f_stream.is_open()) { + const std::string msg{"\t[!] sfm: error opening seed file!\n"}; + fmt::print("{} {}\n", msg, config.seed_f_path); + + fortuna::SeedFileManager::RUNNING = false; + throw std::runtime_error(msg); } - fortuna::SeedFileManager::RUNNING = true; f_stream.read(reinterpret_cast(buff.BytePtr()), static_cast(config.seed_f_length)); + if (static_cast(f_stream.gcount()) != config.seed_f_length) { - std::string msg{"error reading seed from file"}; - fmt::print("{} {}, length: {}\n", + const std::string msg{ + "\t[!] sfm: error reading seed from file, length mismatch"}; + fmt::print("{} {}, length: {} vs desired length: {}\n", msg, config.seed_f_path, + f_stream.gcount(), config.seed_f_length); + + fortuna::SeedFileManager::RUNNING = false; throw std::runtime_error(msg); } } @@ -68,21 +97,36 @@ auto SeedFileManager::update_seed_file() -> void { std::string str_buff(reinterpret_cast(&buff[0]), buff.SizeInBytes() * 8); // we need the size in bits + accumulator.call_reseed(str_buff); write_seed_file(); } catch (std::exception& e) { - fmt::print("{}", e.what()); + fmt::print("{}\n", e.what()); + fortuna::SeedFileManager::RUNNING = false; + throw; } } auto SeedFileManager::write_seed_file() -> void { - const std::size_t seed_file_length_blocks{ - fortuna::Util::b2b(config.seed_f_length)}; - CryptoPP::SecByteBlock buff{seed_file_length_blocks * - fortuna::Util::gen_block_size}; - std::string da_buff{accumulator.get_random_data( - static_cast(seed_file_length_blocks))}; + fortuna::SeedFileManager::RUNNING = true; + CryptoPP::SecByteBlock buff{config.seed_f_length}; + const std::string da_buff{accumulator.get_random_data( + static_cast(config.seed_f_length))}; + + assert(da_buff.length() % 2 == 0); + assert(da_buff.size() == config.seed_f_length * 2); // da_buff is + // hex-encoded + + // account for hex encoding that is returned from get_random_data(), i.e. + // the total length is half of the actual number of characters + const size_t length{da_buff.length() / 2}; + + CryptoPP::StringSource src( + da_buff.c_str(), + true /*pumpAll*/, + new CryptoPP::HexDecoder(new CryptoPP::ArraySink(&buff[0], length))); + fmt::print("[*] sfm: writing seed file\n"); try { @@ -90,12 +134,12 @@ auto SeedFileManager::write_seed_file() -> void { std::ios::binary | std::ios::trunc}; f_stream.write(reinterpret_cast(buff.BytePtr()), static_cast(config.seed_f_length)); - fortuna::SeedFileManager::RUNNING = true; } catch (std::exception& e) { fmt::print("[!] sfm: error writing to seed file!\n"); fmt::print("{}\n", e.what()); fortuna::SeedFileManager::RUNNING = false; + throw; } } diff --git a/seed_file_management.h b/seed_file_management.h index bfa85b9..9272443 100644 --- a/seed_file_management.h +++ b/seed_file_management.h @@ -15,8 +15,8 @@ public: // std::chrono::minutes write_interval{10}; // 10 minutes (as the standard recommends) is a lot, go with 120s std::chrono::seconds write_interval{120}; - std::string seed_f_path = "./.fortuna.seed"; - std::size_t seed_f_length = 64; + std::string seed_f_path{"./.fortuna.seed"}; + std::size_t seed_f_length{64}; conf(){}; }; @@ -37,6 +37,7 @@ private: DoTask do_task; fortuna::accumulator::Accumulator accumulator; + auto seed_file_exists() const -> bool; auto write_seed_file() -> void; auto update_seed_file() -> void;