28#include <merklecpp/merklecpp.h>
40#ifdef OVERRIDE_MAX_HISTORY_LEN
46 static std::ostream& operator<<(std::ostream& os,
HashOp flag)
93 sig.template wo<ccf::Signatures>(ccf::Tables::SIGNATURES);
94 auto* cose_signatures =
95 sig.template wo<ccf::CoseSignatures>(ccf::Tables::COSE_SIGNATURES);
97 auto* serialised_tree = sig.template wo<ccf::SerialisedMerkleTree>(
98 ccf::Tables::SERIALISED_MERKLE_TREE);
100 signatures->put(sig_value);
102 serialised_tree->put({});
103 return sig.commit_reserved();
124 void append(
const std::vector<uint8_t>& )
override
131 std::optional<ccf::kv::Term> =
132 std::nullopt)
override
158 const std::vector<uint8_t>& )
override
171 LOG_DEBUG_FMT(
"Issuing signature at {}.{}", txid.view, txid.seqno);
173 txid, std::make_unique<NullTxHistoryPendingTx>(txid, store,
id),
true);
181 std::shared_ptr<ccf::crypto::ECKeyPair_OpenSSL> service_kp_,
184 std::ignore = service_kp_;
189 throw std::logic_error(
"Unimplemented");
197 std::tuple<ccf::TxID, ccf::crypto::Sha256Hash, ccf::kv::Term>
226 static constexpr size_t sha256_byte_size = 32;
227 static inline void sha256_history(
228 const merkle::HashT<sha256_byte_size>& l,
229 const merkle::HashT<sha256_byte_size>& r,
230 merkle::HashT<sha256_byte_size>& out)
233 uint8_t block[sha256_byte_size * 2];
234 memcpy(&block[0], l.bytes, sha256_byte_size);
235 memcpy(&block[sha256_byte_size], r.bytes, sha256_byte_size);
237 ccf::crypto::openssl_sha256(block, out.bytes);
240 using HistoryTree = merkle::TreeT<sha256_byte_size, ccf::sha256_history>;
245 HistoryTree::Hash root;
246 std::shared_ptr<HistoryTree::Path> path =
nullptr;
251 Proof(
const std::vector<uint8_t>& v)
254 root.deserialise(v, position);
255 path = std::make_shared<HistoryTree::Path>(v, position);
258 [[nodiscard]]
const HistoryTree::Hash&
get_root()
const
270 path(tree->path(index))
277 if (path->max_index() > tree->max_index())
282 if (tree->max_index() == path->max_index())
284 return tree->root() == root && path->verify(root);
287 auto past_root = tree->past_root(path->max_index());
288 return path->verify(*past_root);
291 [[nodiscard]] std::vector<uint8_t>
to_v()
const
293 std::vector<uint8_t> v;
327 service_kp(service_kp_),
328 endorsed_cert(endorsed_cert_),
329 cose_signatures_config(cose_signatures_config_)
336 sig.template wo<ccf::Signatures>(ccf::Tables::SIGNATURES);
337 auto* cose_signatures =
338 sig.template wo<ccf::CoseSignatures>(ccf::Tables::COSE_SIGNATURES);
339 auto* serialised_tree = sig.template wo<ccf::SerialisedMerkleTree>(
340 ccf::Tables::SERIALISED_MERKLE_TREE);
343 std::vector<uint8_t> primary_sig;
345 std::vector<uint8_t> root_hash{
346 root.
h.data(), root.
h.data() + root.
h.size()};
347 primary_sig = node_kp.
sign_hash(root_hash.data(), root_hash.size());
360 std::span<const uint8_t> kid_span{
361 reinterpret_cast<const uint8_t*
>(kid.data()), kid.size()};
363 const auto time_since_epoch =
364 std::chrono::duration_cast<std::chrono::seconds>(
365 std::chrono::system_clock::now().time_since_epoch())
369 std::static_pointer_cast<ccf::crypto::COSEParametersFactory>(
370 std::make_shared<ccf::crypto::COSEParametersMap>(
371 std::make_shared<ccf::crypto::COSEMapStringKey>(
372 ccf::crypto::COSE_PHEADER_KEY_CCF),
375 ccf::crypto::COSE_PHEADER_KEY_TXID, txid.
to_str())}));
378 std::static_pointer_cast<ccf::crypto::COSEParametersFactory>(
379 std::make_shared<ccf::crypto::COSEParametersMap>(
380 std::make_shared<ccf::crypto::COSEMapIntKey>(
381 ccf::crypto::COSE_PHEADER_KEY_CWT),
384 ccf::crypto::COSE_PHEADER_KEY_IAT, time_since_epoch),
386 ccf::crypto::COSE_PHEADER_KEY_ISS,
387 cose_signatures_config.
issuer),
389 ccf::crypto::COSE_PHEADER_KEY_SUB,
390 cose_signatures_config.
subject),
393 const auto pheaders = {
395 ccf::crypto::COSE_PHEADER_KEY_ID, kid_span),
398 ccf::crypto::COSE_PHEADER_KEY_VDS,
399 ccf::crypto::COSE_PHEADER_VDS_CCF_LEDGER_SHA256),
407 signatures->put(sig_value);
408 cose_signatures->put(cose_sign);
410 return sig.commit_reserved();
416 std::unique_ptr<HistoryTree> tree;
433 tree = std::make_unique<HistoryTree>(serialised);
438 tree->insert(merkle::Hash(hash.
h));
443 const merkle::Hash& root = tree->root();
445 std::copy(root.bytes, root.bytes + root.size(), result.
h.begin());
454 tree = std::make_unique<HistoryTree>(merkle::Hash(root.
h));
462 tree->flush_to(index);
468 tree->retract_to(index);
475 throw std::logic_error(fmt::format(
476 "Cannot produce proof for {}: index is older than first index {}, "
477 "and has been flushed from memory",
483 throw std::logic_error(fmt::format(
484 "Cannot produce proof for {}: index is later than last index {}",
488 return {tree.get(), index};
493 return r.
verify(tree.get());
498 LOG_TRACE_FMT(
"mt_serialize_size {}", tree->serialised_size());
499 std::vector<uint8_t> output;
500 tree->serialise(output);
507 "mt_serialize_size ({},{}) {}",
510 tree->serialised_size(from, to));
511 std::vector<uint8_t> output;
512 tree->serialise(from, to, output);
518 return tree->min_index();
523 return tree->max_index();
533 const merkle::Hash& leaf = tree->leaf(index);
535 std::copy(leaf.bytes, leaf.bytes + leaf.size(), result.
h.begin());
545 T replicated_state_tree;
549 std::vector<uint8_t> cose_cert_cached;
552 size_t sig_tx_interval;
553 size_t sig_ms_interval;
559 std::optional<ccf::crypto::Pem> endorsed_cert = std::nullopt;
561 struct ServiceSigningIdentity
563 const std::shared_ptr<ccf::crypto::ECKeyPair_OpenSSL> service_kp;
567 std::optional<ServiceSigningIdentity> signing_identity = std::nullopt;
574 size_t sig_tx_interval_ = 0,
575 size_t sig_ms_interval_ = 0,
576 bool signature_timer =
false) :
580 sig_tx_interval(sig_tx_interval_),
581 sig_ms_interval(sig_ms_interval_)
590 std::shared_ptr<ccf::crypto::ECKeyPair_OpenSSL> service_kp_,
593 if (signing_identity.has_value())
595 throw std::logic_error(
596 "Called set_service_signing_identity() multiple times");
599 signing_identity.emplace(
600 ServiceSigningIdentity{service_kp_, cose_signatures_config_});
603 "Setting service signing identity to iss: {} sub: {}",
604 cose_signatures_config_.
issuer,
605 cose_signatures_config_.
subject);
610 if (!signing_identity.has_value())
612 throw std::logic_error(
613 "Called get_cose_signatures_config() before "
614 "set_service_signing_identity()");
617 return signing_identity->cose_signatures_config;
622 const auto delay = std::chrono::milliseconds(sig_ms_interval);
625 std::unique_lock<ccf::pal::Mutex> mguard(
628 bool should_emit_signature =
false;
630 if (mguard.try_lock())
635 auto sig_disp =
consensus->get_signature_disposition();
646 should_emit_signature =
true;
652 should_emit_signature =
true;
659 if (should_emit_signature)
670 if (emit_signature_periodic_task !=
nullptr)
672 emit_signature_periodic_task->cancel_task();
682 const std::vector<uint8_t>& hash_at_snapshot)
override
688 auto* tree_h = tx.template ro<ccf::SerialisedMerkleTree>(
689 ccf::Tables::SERIALISED_MERKLE_TREE);
690 auto tree = tree_h->get();
691 if (!tree.has_value())
699 std::lock_guard<ccf::pal::Mutex> guard(state_lock);
702 !replicated_state_tree.in_range(1),
703 "Tree is not empty before initialising from snapshot");
705 replicated_state_tree.deserialise(tree.value());
709 hash_at_snapshot.begin(),
712 replicated_state_tree.append(hash);
718 std::lock_guard<ccf::pal::Mutex> guard(state_lock);
719 return replicated_state_tree.get_root();
722 std::tuple<ccf::TxID, ccf::crypto::Sha256Hash, ccf::kv::Term>
725 std::lock_guard<ccf::pal::Mutex> guard(state_lock);
727 {term_of_last_version,
729 replicated_state_tree.get_root(),
730 term_of_next_version};
738 tx.template ro<ccf::Signatures>(ccf::Tables::SIGNATURES);
739 auto sig = signatures->get();
740 if (!sig.has_value())
748 if (!verify_node_signature(tx, sig->node, sig->sig, root))
753 auto* cose_signatures =
754 tx.template ro<ccf::CoseSignatures>(ccf::Tables::COSE_SIGNATURES);
755 auto cose_sig = cose_signatures->get();
757 if (!cose_sig.has_value())
767 const auto cose_sig_version =
768 cose_signatures->get_version_of_previous_write();
769 if (cose_sig_version.has_value() && cose_sig_version.value() != version)
772 "Non-monotonic presence of COSE signatures - had one at {} but none "
774 cose_sig_version.value(),
779 auto* service = tx.template ro<ccf::Service>(Tables::SERVICE);
780 auto service_info = service->get();
782 if (!service_info.has_value())
784 LOG_FAIL_FMT(
"No service key found to verify the signature");
788 const auto raw_cert = service_info->cert.raw();
789 std::vector<uint8_t> root_hash{
790 root.h.data(), root.h.data() + root.h.size()};
792 return cose_verifier_cached(raw_cert)->verify_detached(
793 cose_sig.value(), root_hash);
798 std::lock_guard<ccf::pal::Mutex> guard(state_lock);
799 if (to <= replicated_state_tree.end_index())
801 return replicated_state_tree.serialise(
802 replicated_state_tree.begin_index(), to);
812 std::lock_guard<ccf::pal::Mutex> guard(state_lock);
813 term_of_last_version = t;
814 term_of_next_version = t;
820 std::lock_guard<ccf::pal::Mutex> guard(state_lock);
822 term_of_last_version = tx_id.
view;
823 term_of_next_version = term_of_next_version_;
824 replicated_state_tree.retract(tx_id.
seqno);
825 log_hash(replicated_state_tree.get_root(),
ROLLBACK);
830 std::lock_guard<ccf::pal::Mutex> guard(state_lock);
837 log_hash(replicated_state_tree.get_root(),
COMPACT);
844 std::unique_lock<ccf::pal::Mutex> mguard(
signature_lock, std::defer_lock);
866 if (!endorsed_cert.has_value())
868 throw std::logic_error(
869 fmt::format(
"No endorsed certificate set to emit signature"));
874 LOG_DEBUG_FMT(
"Signed at {} in view: {}", txid.seqno, txid.view);
876 if (!signing_identity.has_value())
878 throw std::logic_error(
879 fmt::format(
"No service key has been set yet to sign"));
890 *signing_identity->service_kp,
891 endorsed_cert.value(),
892 signing_identity->cose_signatures_config),
898 std::lock_guard<ccf::pal::Mutex> guard(state_lock);
899 return replicated_state_tree.get_proof(index).to_v();
905 std::lock_guard<ccf::pal::Mutex> guard(state_lock);
906 return replicated_state_tree.verify(proof);
911 std::lock_guard<ccf::pal::Mutex> guard(state_lock);
912 auto leaf = replicated_state_tree.get_leaf(index);
913 return {leaf.h.begin(), leaf.h.end()};
916 void append(
const std::vector<uint8_t>& data)
override
920 std::lock_guard<ccf::pal::Mutex> guard(state_lock);
921 replicated_state_tree.append(rh);
926 std::optional<ccf::kv::Term> expected_term_of_next_version =
927 std::nullopt)
override
930 std::lock_guard<ccf::pal::Mutex> guard(state_lock);
931 if (expected_term_of_next_version.has_value())
933 if (expected_term_of_next_version.value() != term_of_next_version)
938 replicated_state_tree.append(digest);
943 endorsed_cert = cert;
948 const std::vector<uint8_t>& cert)
950 if (cert != cose_cert_cached)
952 cose_cert_cached = cert;
956 return cose_verifier;
#define CCF_ASSERT_FMT(expr,...)
Definition ccf_assert.h:10
void set_service_signing_identity(std::shared_ptr< ccf::crypto::ECKeyPair_OpenSSL > service_kp_, const ccf::COSESignaturesConfig &cose_signatures_config_) override
Definition history.h:589
~HashedTxHistory() override
Definition history.h:668
std::tuple< ccf::TxID, ccf::crypto::Sha256Hash, ccf::kv::Term > get_replicated_state_txid_and_root() override
Definition history.h:723
void set_term(ccf::kv::Term t) override
Definition history.h:808
bool verify_proof(const std::vector< uint8_t > &v) override
Definition history.h:902
void set_endorsed_certificate(const ccf::crypto::Pem &cert) override
Definition history.h:941
HashedTxHistory(ccf::kv::Store &store_, NodeId id_, ccf::crypto::ECKeyPair &node_kp_, size_t sig_tx_interval_=0, size_t sig_ms_interval_=0, bool signature_timer=false)
Definition history.h:570
void compact(ccf::kv::Version v) override
Definition history.h:828
std::vector< uint8_t > get_proof(ccf::kv::Version index) override
Definition history.h:896
ccf::pal::Mutex signature_lock
Definition history.h:840
const ccf::COSESignaturesConfig & get_cose_signatures_config() override
Definition history.h:608
void rollback(const ccf::TxID &tx_id, ccf::kv::Term term_of_next_version_) override
Definition history.h:817
std::vector< uint8_t > serialise_tree(size_t to) override
Definition history.h:796
bool verify_root_signatures(ccf::kv::Version version) override
Definition history.h:733
void append(const std::vector< uint8_t > &data) override
Definition history.h:916
void start_signature_emit_timer() override
Definition history.h:620
void set_node_id(const NodeId &id_)
Definition history.h:676
void try_emit_signature() override
Definition history.h:842
void emit_signature() override
Definition history.h:857
ccf::crypto::Sha256Hash get_replicated_state_root() override
Definition history.h:716
std::vector< uint8_t > get_raw_leaf(uint64_t index) override
Definition history.h:909
void append_entry(const ccf::crypto::Sha256Hash &digest, std::optional< ccf::kv::Term > expected_term_of_next_version=std::nullopt) override
Definition history.h:924
bool init_from_snapshot(const std::vector< uint8_t > &hash_at_snapshot) override
Definition history.h:681
MerkleTreeHistoryPendingTx(ccf::TxID txid_, ccf::kv::Store &store_, ccf::kv::TxHistory &history_, NodeId id_, ccf::crypto::ECKeyPair &node_kp_, ccf::crypto::ECKeyPair_OpenSSL &service_kp_, ccf::crypto::Pem &endorsed_cert_, const ccf::COSESignaturesConfig &cose_signatures_config_)
Definition history.h:313
ccf::kv::PendingTxInfo call() override
Definition history.h:332
void deserialise(const std::vector< uint8_t > &serialised)
Definition history.h:431
void flush(uint64_t index)
Definition history.h:459
ccf::crypto::Sha256Hash get_root() const
Definition history.h:441
std::vector< uint8_t > serialise(size_t from, size_t to)
Definition history.h:504
ccf::crypto::Sha256Hash get_leaf(uint64_t index)
Definition history.h:531
MerkleTreeHistory(const std::vector< uint8_t > &serialised)
Definition history.h:421
~MerkleTreeHistory()=default
MerkleTreeHistory & operator=(const MerkleTreeHistory &rhs)
Definition history.h:449
MerkleTreeHistory(ccf::crypto::Sha256Hash first_hash={})
Definition history.h:425
bool verify(const Proof &r)
Definition history.h:491
MerkleTreeHistory(MerkleTreeHistory const &)=delete
Proof get_proof(uint64_t index)
Definition history.h:471
std::vector< uint8_t > serialise()
Definition history.h:496
uint64_t end_index()
Definition history.h:521
void append(const ccf::crypto::Sha256Hash &hash)
Definition history.h:436
uint64_t begin_index()
Definition history.h:516
void retract(uint64_t index)
Definition history.h:465
bool in_range(uint64_t index)
Definition history.h:526
ccf::kv::PendingTxInfo call() override
Definition history.h:89
NullTxHistoryPendingTx(ccf::TxID txid_, ccf::kv::Store &store_, NodeId id_)
Definition history.h:82
void set_endorsed_certificate(const ccf::crypto::Pem &cert) override
Definition history.h:221
void try_emit_signature() override
Definition history.h:176
void compact(ccf::kv::Version) override
Definition history.h:155
ccf::crypto::Sha256Hash get_replicated_state_root() override
Definition history.h:192
ccf::kv::Term term_of_last_version
Definition history.h:114
void start_signature_emit_timer() override
Definition history.h:178
bool verify_root_signatures(ccf::kv::Version) override
Definition history.h:137
bool init_from_snapshot(const std::vector< uint8_t > &) override
Definition history.h:157
std::vector< uint8_t > serialise_tree(size_t) override
Definition history.h:216
void emit_signature() override
Definition history.h:168
ccf::kv::Term term_of_next_version
Definition history.h:115
bool verify_proof(const std::vector< uint8_t > &) override
Definition history.h:211
void append(const std::vector< uint8_t > &) override
Definition history.h:124
std::vector< uint8_t > get_proof(ccf::kv::Version) override
Definition history.h:206
NullTxHistory(ccf::kv::Store &store_, NodeId id_, ccf::crypto::ECKeyPair &)
Definition history.h:118
void set_term(ccf::kv::Term t) override
Definition history.h:142
std::tuple< ccf::TxID, ccf::crypto::Sha256Hash, ccf::kv::Term > get_replicated_state_txid_and_root() override
Definition history.h:198
void append_entry(const ccf::crypto::Sha256Hash &, std::optional< ccf::kv::Term >=std::nullopt) override
Definition history.h:129
ccf::kv::Version version
Definition history.h:113
const ccf::COSESignaturesConfig & get_cose_signatures_config() override
Definition history.h:187
void set_service_signing_identity(std::shared_ptr< ccf::crypto::ECKeyPair_OpenSSL > service_kp_, const ccf::COSESignaturesConfig &) override
Definition history.h:180
void rollback(const ccf::TxID &tx_id, ccf::kv::Term commit_term_) override
Definition history.h:148
std::vector< uint8_t > get_raw_leaf(uint64_t) override
Definition history.h:163
std::shared_ptr< HistoryTree::Path > get_path()
Definition history.h:263
const HistoryTree::Hash & get_root() const
Definition history.h:258
std::vector< uint8_t > to_v() const
Definition history.h:291
Proof(HistoryTree *tree, uint64_t index)
Definition history.h:268
Proof(const std::vector< uint8_t > &v)
Definition history.h:251
Proof(const Proof &)=delete
bool verify(HistoryTree *tree) const
Definition history.h:275
Definition ec_key_pair.h:16
std::vector< uint8_t > public_key_der() const override
Definition ec_key_pair.cpp:127
Definition ec_key_pair.h:19
virtual std::vector< uint8_t > sign_hash(const uint8_t *hash, size_t hash_size) const =0
Definition sha256_hash.h:16
Representation h
Definition sha256_hash.h:20
std::string hex_str() const
Definition sha256_hash.cpp:57
static constexpr size_t SIZE
Definition sha256_hash.h:18
Definition kv_types.h:439
ReservedTx create_reserved_tx(const TxID &tx_id)
Definition store.h:1292
ReadOnlyTx create_read_only_tx() override
Definition store.h:1267
size_t committable_gap() override
Definition store.h:1121
TxID next_txid() override
Definition store.h:1113
std::shared_ptr< Consensus > get_consensus() override
Definition store.h:182
CommitResult commit(const TxID &txid, std::unique_ptr< PendingTx > pending_tx, bool globally_committable) override
Definition store.h:899
Definition kv_types.h:329
virtual std::vector< uint8_t > serialise_tree(size_t to)=0
virtual ccf::crypto::Sha256Hash get_replicated_state_root()=0
#define LOG_INFO_FMT
Definition internal_logger.h:15
#define LOG_TRACE_FMT
Definition internal_logger.h:13
#define LOG_DEBUG_FMT
Definition internal_logger.h:14
#define LOG_FAIL_FMT
Definition internal_logger.h:16
std::shared_ptr< COSEParametersFactory > cose_params_int_int(int64_t key, int64_t value)
Definition cose_sign.cpp:154
std::shared_ptr< COSEParametersFactory > cose_params_int_bytes(int64_t key, std::span< const uint8_t > value)
Definition cose_sign.cpp:204
std::shared_ptr< COSEParametersFactory > cose_params_int_string(int64_t key, const std::string &value)
Definition cose_sign.cpp:166
std::unique_ptr< COSEVerifier > COSEVerifierUniquePtr
Definition cose_verifier.h:23
std::vector< uint8_t > cose_sign1(const ECKeyPair_OpenSSL &key, const std::vector< std::shared_ptr< COSEParametersFactory > > &protected_headers, std::span< const uint8_t > payload, bool detached_payload)
Definition cose_sign.cpp:231
std::shared_ptr< COSEParametersFactory > cose_params_string_string(const std::string &key, const std::string &value)
Definition cose_sign.cpp:191
COSEVerifierUniquePtr make_cose_verifier_from_cert(const std::vector< uint8_t > &cert)
Definition cose_verifier.cpp:227
std::vector< std::shared_ptr< ccf::crypto::COSEParametersFactory > > COSEHeadersArray
Definition cose_sign.h:165
uint64_t Term
Definition kv_types.h:43
uint64_t Version
Definition version.h:8
std::mutex Mutex
Definition locking.h:12
Task make_basic_task(Ts &&... ts)
Definition basic_task.h:33
void add_periodic_task(Task task, std::chrono::milliseconds initial_delay, std::chrono::milliseconds repeat_period)
Definition task_system.cpp:75
std::shared_ptr< BaseTask > Task
Definition task.h:36
Definition app_interface.h:14
merkle::TreeT< sha256_byte_size, ccf::sha256_history > HistoryTree
Definition history.h:240
constexpr int MAX_HISTORY_LEN
Definition history.h:43
std::vector< uint8_t > CoseSignature
Definition signatures.h:64
HashOp
Definition history.h:33
@ COMPACT
Definition history.h:37
@ VERIFY
Definition history.h:35
@ APPEND
Definition history.h:34
@ ROLLBACK
Definition history.h:36
Definition consensus_types.h:23
Definition cose_signatures_config.h:12
std::string issuer
Definition cose_signatures_config.h:13
std::string subject
Definition cose_signatures_config.h:14
Definition signatures.h:14
SeqNo seqno
Definition tx_id.h:46
View view
Definition tx_id.h:45
std::string to_str() const
Definition tx_id.h:48
Definition kv_types.h:417