#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 vector & v) { return v.size () == crypto_sign_PUBLICKEYBYTES; } optional > try_verify_signed_data ( const ExpiringSignature & sig, const vector & pubkey, Instant now ) { try_sodium_init (); if (! is_pubkey_length (pubkey)) { return nullopt; } if (crypto_sign_verify_detached ( sig.sig.data (), (const uint8_t *)sig.cert_s.data (), sig.cert_s.size (), pubkey.data () ) != 0) { return nullopt; } const json j = json::parse (sig.cert_s); const TimeRange tr { j ["not_before"], j ["not_after"] }; if (! tr.contains (now)) { return nullopt; } const string payload_b64 = j ["payload_b64"]; const auto payload = std::move (*BareMinimumCrypto::base64_decode (payload_b64)); return payload; } optional > verify_signed_data ( const ExpiringSignature & sig, const vector & pubkey, Instant now ) { try { return try_verify_signed_data (sig, pubkey, now); } catch (json::exception &) { return nullopt; } } optional > verify_cert_and_data ( const vector & root_pubkey, const ExpiringSignature & signed_cert, const ExpiringSignature & signed_data, Instant now ) { auto subkey_opt = verify_signed_data (signed_cert, root_pubkey, now); if (! subkey_opt) { return nullopt; } const auto subkey = std::move (*subkey_opt); return verify_signed_data (signed_data, subkey, now); } optional > verify_cert_and_data ( const vector & root_pubkey, const ExpiringSignature & signed_cert, const ExpiringSignature & signed_data ) { return verify_cert_and_data (root_pubkey, signed_cert, signed_data, Instant::now ()); } }