#include "receiver.h" #include #include "json.hpp" #include "expiring_signature.h" #include "sodium_helpers.h" #include "string_helpers.h" #include "time_helpers.h" namespace BareMinimumCrypto::Receiver { using nlohmann::json; bool is_pubkey_length (const Bytes & v) { return v.size () == crypto_sign_PUBLICKEYBYTES; } optional try_verify_signed_data ( const Bytes & pubkey, const ExpiringSignature & sig, Instant now ) { try_sodium_init (); if (! is_pubkey_length (pubkey)) { return nullopt; } if (crypto_sign_verify_detached ( sig.sig.data (), sig.cert.data (), sig.cert.size (), pubkey.data () ) != 0) { return nullopt; } const json j = json::from_msgpack (sig.cert); const TimeRange tr { j ["not_before"], j ["not_after"] }; if (! tr.contains (now)) { return nullopt; } const auto payload = j ["payload"].get_binary (); return payload; } optional verify_signed_data ( const Bytes & pubkey, const ExpiringSignature & sig, Instant now ) { try { return try_verify_signed_data (pubkey, sig, now); } catch (json::exception &) { return nullopt; } } optional try_verify_cert_and_data ( const Bytes & root_pubkey, const Bytes & msgpack, Instant now ) { const auto j = json::from_msgpack (msgpack); ExpiringSignature cert; cert.sig = j ["cert"]["sig"].get_binary (); cert.cert = j ["cert"]["cert"].get_binary (); auto subkey_opt = verify_signed_data (root_pubkey, cert, now); const auto subkey_obj = json::from_msgpack (std::move (*subkey_opt)); const auto subkey = subkey_obj ["key"].get_binary (); ExpiringSignature data; data.sig = j ["data"]["sig"].get_binary (); data.cert = j ["data"]["cert"].get_binary (); return verify_signed_data (subkey, data, now); } optional verify_cert_and_data ( const Bytes & root_pubkey, const Bytes & msgpack ) { try { return try_verify_cert_and_data (root_pubkey, msgpack, Instant::now ()); } catch (json::exception &) { return nullopt; } } }