/* * @Author: DI JUNKUN * @Date: 2026-11-01 * Copyright (c) 2026 by DI JUNKUN, All Rights Reserved. */ #ifndef _TRUSTED_DEVICES_H_ #define _TRUSTED_DEVICES_H_ #include #include #include #include #include #include #include #include #include #include namespace crossdesk { class TrustedDevices { public: struct Device { std::string public_key, name, device_id; bool operator==(const Device&) const = default; }; TrustedDevices(const std::filesystem::path& directory, const std::filesystem::path& cache); std::string Fingerprint() const; const std::string& PublicKey() const { return public_key_; } // Callers supply a canonical, purpose-specific transcript. std::string Sign(std::string_view transcript) const; static std::string Fingerprint(const std::string& public_key); static std::string Nonce(); nlohmann::json Prove(const std::string& nonce, const std::string& device_id, const std::string& name) const; static std::optional Verify(const nlohmann::json& proof, const std::string& nonce); static constexpr size_t kMaxPairingInfoSize = 2048; std::string PairingInfo(const std::string& device_id, const std::string& name) const; static std::optional ParsePairingInfo(std::string_view text); bool Contains(const std::string& public_key) const; std::vector List() const; // Call only after a local add action for a verified peer or valid pairing info. void Add(const Device& device); void Remove(const std::string& public_key); private: void Save(const std::map& devices) const; std::filesystem::path path_; std::unique_ptr key_{nullptr, EVP_PKEY_free}; std::string public_key_; mutable std::mutex mutex_; std::map devices_; }; } // namespace crossdesk #endif