/* * Roughtime * (C) 2019 Nuno Goncalves * * Botan is released under the Simplified BSD License (see license.txt) */ #ifndef BOTAN_ROUGHTIME_H_ #define BOTAN_ROUGHTIME_H_ #include #include #include #include namespace Botan { class RandomNumberGenerator; namespace Roughtime { const unsigned request_min_size = 1024; class BOTAN_PUBLIC_API(2, 13) Roughtime_Error final : public Decoding_Error { public: explicit Roughtime_Error(const std::string& s) : Decoding_Error("Roughtime " + s) {} ErrorType error_type() const noexcept override { return ErrorType::RoughtimeError; } }; class BOTAN_PUBLIC_API(2, 13) Nonce final { public: Nonce() = default; Nonce(const std::vector& nonce); Nonce(RandomNumberGenerator& rng); Nonce(const std::array& nonce) { m_nonce = nonce; } bool operator==(const Nonce& rhs) const { return m_nonce == rhs.m_nonce; } const std::array& get_nonce() const { return m_nonce; } private: std::array m_nonce; }; /** * An Roughtime request. */ BOTAN_PUBLIC_API(2, 13) std::array encode_request(const Nonce& nonce); /** * An Roughtime response. */ class BOTAN_PUBLIC_API(2, 13) Response final { public: using microseconds32 = std::chrono::duration; using microseconds64 = std::chrono::duration; using sys_microseconds64 = std::chrono::time_point; static Response from_bits(const std::vector& response, const Nonce& nonce); bool validate(const Ed25519_PublicKey& pk) const; sys_microseconds64 utc_midpoint() const { return m_utc_midpoint; } microseconds32 utc_radius() const { return m_utc_radius; } private: Response(const std::array& dele, const std::array& sig, sys_microseconds64 utc_midp, microseconds32 utc_radius) : m_cert_dele(dele) , m_cert_sig(sig) , m_utc_midpoint {utc_midp} , m_utc_radius {utc_radius} {} const std::array m_cert_dele; const std::array m_cert_sig; const sys_microseconds64 m_utc_midpoint; const microseconds32 m_utc_radius; }; class BOTAN_PUBLIC_API(2, 13) Link final { public: Link(const std::vector& response, const Ed25519_PublicKey& public_key, const Nonce& nonce_or_blind) : m_response{response} , m_public_key{public_key} , m_nonce_or_blind{nonce_or_blind} {} const std::vector& response() const { return m_response; } const Ed25519_PublicKey& public_key() const { return m_public_key; } const Nonce& nonce_or_blind() const { return m_nonce_or_blind; } Nonce& nonce_or_blind() { return m_nonce_or_blind; } private: std::vector m_response; Ed25519_PublicKey m_public_key; Nonce m_nonce_or_blind; }; class BOTAN_PUBLIC_API(2, 13) Chain final { public: Chain() = default; //empty Chain(const std::string& str); const std::vector& links() const { return m_links; } std::vector responses() const; Nonce next_nonce(const Nonce& blind) const; void append(const Link& new_link, size_t max_chain_size); std::string to_string() const; private: std::vector m_links; }; /** */ BOTAN_PUBLIC_API(2, 13) Nonce nonce_from_blind(const std::vector& previous_response, const Nonce& blind); /** * Makes an online Roughtime request via UDP and returns the Roughtime response. * @param url Roughtime server UDP endpoint (host:port) * @param nonce the nonce to send to the server * @param timeout a timeout on the UDP request * @return Roughtime response */ BOTAN_PUBLIC_API(2, 13) std::vector online_request(const std::string& url, const Nonce& nonce, std::chrono::milliseconds timeout = std::chrono::seconds(3)); struct BOTAN_PUBLIC_API(2, 13) Server_Information final { public: Server_Information(const std::string& name, const Botan::Ed25519_PublicKey& public_key, const std::vector& addresses) : m_name { name } , m_public_key { public_key } , m_addresses { addresses } {} const std::string& name() const {return m_name;} const Botan::Ed25519_PublicKey& public_key() const {return m_public_key;} const std::vector& addresses() const {return m_addresses;} private: std::string m_name; Botan::Ed25519_PublicKey m_public_key; std::vector m_addresses; }; BOTAN_PUBLIC_API(2, 13) std::vector servers_from_str(const std::string& str); } } #endif