37 .
view = txid.
view - aft::starting_view_change, .seqno = txid.
seqno - 1};
42 .
view = txid.
view + aft::starting_view_change, .seqno = txid.
seqno + 1};
62 std::map<NodeId, NodeInfo> nodes_to_delete;
67 nodes_to_delete[nid] = ni;
72 for (
auto [nid, ni] : nodes_to_delete)
82 auto* member_encryption_public_keys =
84 Tables::MEMBER_ENCRYPTION_PUBLIC_KEYS);
86 return member_encryption_public_keys->get(member_id).has_value();
100 auto mi = member_info->get(member_id);
106 return mi->recovery_role.has_value() &&
114 auto mi = member_info->get(member_id);
123 static std::map<MemberId, ccf::crypto::Pem>
127 auto* member_encryption_public_keys =
129 Tables::MEMBER_ENCRYPTION_PUBLIC_KEYS);
131 std::map<MemberId, ccf::crypto::Pem> active_recovery_participants;
133 member_encryption_public_keys->foreach(
134 [&active_recovery_participants,
135 &member_info](
const auto& mid,
const auto& pem) {
136 auto info = member_info->get(mid);
137 if (!info.has_value())
139 throw std::logic_error(
140 fmt::format(
"Recovery member {} has no member info", mid));
148 active_recovery_participants[mid] = pem;
152 return active_recovery_participants;
159 auto* member_encryption_public_keys =
161 Tables::MEMBER_ENCRYPTION_PUBLIC_KEYS);
163 std::map<MemberId, ccf::crypto::Pem> active_recovery_owners;
165 member_encryption_public_keys->foreach(
166 [&active_recovery_owners,
167 &member_info](
const auto& mid,
const auto& pem) {
168 auto info = member_info->get(mid);
169 if (!info.has_value())
171 throw std::logic_error(
172 fmt::format(
"Recovery member {} has no member info", mid));
180 active_recovery_owners[mid] = pem;
184 return active_recovery_owners;
194 auto member_cert_der =
198 auto member = member_certs->get(
id);
199 if (member.has_value())
207 auto member_recovery_role = member_pub_info.
recovery_role.value();
212 throw std::logic_error(fmt::format(
213 "Member {} cannot be added as recovery_role has a value set but "
215 "encryption public key is specified",
225 throw std::logic_error(fmt::format(
226 "Recovery member {} cannot be added as with recovery role value "
230 member_recovery_role));
235 member_certs->put(
id, member_pub_info.
cert);
244 auto* member_encryption_public_keys =
246 Tables::MEMBER_ENCRYPTION_PUBLIC_KEYS);
247 member_encryption_public_keys->put(
253 auto tree = tree_h->get();
254 if (!tree.has_value())
270 auto member = member_info->get(member_id);
271 if (!member.has_value())
273 throw std::logic_error(fmt::format(
274 "Member {} cannot be activated as they do not exist", member_id));
280 member_info->put(member_id, member.value());
288 auto* member_encryption_public_keys =
290 Tables::MEMBER_ENCRYPTION_PUBLIC_KEYS);
293 auto* member_gov_history =
296 auto member_to_remove = member_info->get(member_id);
297 if (!member_to_remove.has_value())
302 "Could not remove member {}: member does not exist", member_id);
313 size_t active_recovery_participants_count_after =
316 auto active_recovery_owners_count =
319 active_recovery_participants_count_after == 0 &&
320 active_recovery_owners_count > 0 && recovery_threshold == 1)
325 "Allowing last active recovery participant member {}: to "
326 "be removed as active recovery owner members ({}) are present "
327 "with recovery threshold ({}).",
329 active_recovery_owners_count,
333 active_recovery_participants_count_after < recovery_threshold)
339 "Failed to remove recovery member {}: number of active recovery "
340 "participant members ({}) would be less than recovery threshold "
343 active_recovery_participants_count_after,
350 size_t active_recovery_owners_count_after =
353 auto active_recovery_participants_count =
355 if (active_recovery_owners_count_after == 0)
357 if (active_recovery_participants_count > 0)
360 "Allowing last active recovery owner member {}: to "
361 "be removed as active recovery owner participants ({}) are "
362 "present with recovery threshold ({}).",
364 active_recovery_participants_count,
370 "Failed to remove last active recovery owner member {}: number "
371 "of active recovery participant members ({}) would be less "
372 "than recovery threshold ({})",
374 active_recovery_participants_count,
382 member_info->remove(member_id);
383 member_encryption_public_keys->remove(member_id);
384 member_certs->remove(member_id);
385 member_acks->remove(member_id);
386 member_gov_history->remove(member_id);
399 auto user_cert = user_certs->get(
id);
400 if (user_cert.has_value())
402 throw std::logic_error(
403 fmt::format(
"Certificate already exists for user {}",
id));
406 user_certs->put(
id, new_user.
cert);
411 auto ui = user_info->get(
id);
414 throw std::logic_error(
415 fmt::format(
"User data already exists for user {}",
id));
418 user_info->put(
id, {new_user.
user_data});
430 user_certs->remove(user_id);
431 user_info->remove(user_id);
438 node->put(
id, node_info);
443 std::map<NodeId, NodeInfo> active_nodes;
451 active_nodes[nid] = ni;
457 auto cni =
nodes->get_globally_committed(nid);
458 if (cni.has_value() && !cni->retired_committed)
460 active_nodes[nid] = ni;
474 nlohmann::json service_data =
nullptr,
475 bool recovering =
false)
479 size_t recovery_count = 0;
480 std::optional<ccf::kv::Version> prev_service_created_at = std::nullopt;
484 const auto prev_service_info = service->get();
485 if (!prev_service_info.has_value())
487 throw std::logic_error(
"Failed to get previous service info");
490 if (!prev_service_info->current_service_create_txid.has_value())
492 throw std::logic_error(
493 "Starting TX for the previous service doesn't have "
494 "current_service_create_txid recorded");
496 prev_service_created_at =
497 prev_service_info->current_service_create_txid.value().seqno;
500 ccf::Tables::PREVIOUS_SERVICE_IDENTITY);
501 previous_service_identity->put(prev_service_info->cert);
504 ccf::Tables::PREVIOUS_SERVICE_LAST_SIGNED_ROOT);
507 if (!tree_handle->has())
509 throw std::logic_error(
510 "Previous service doesn't have a serialised merkle tree");
512 auto tree_opt = tree_handle->get();
513 if (!tree_opt.has_value())
515 throw std::logic_error(
516 "Previous service doesn't have serialised merkle tree value");
519 last_signed_root->put(tree.
get_root());
524 recovery_count = prev_service_info->recovery_count.value_or(0) + 1;
530 prev_service_created_at,
540 auto service_info = service->get();
541 return service_info.has_value() &&
542 service_info->cert == expected_service_cert;
549 auto active_service = service->get();
551 auto* previous_identity_endorsement =
553 ccf::Tables::PREVIOUS_SERVICE_IDENTITY_ENDORSEMENT);
556 std::vector<uint8_t> key_to_endorse{};
557 std::vector<uint8_t> previous_root{};
561 if (previous_identity_endorsement->has())
563 const auto prev_endorsement = previous_identity_endorsement->get();
564 if (!prev_endorsement.has_value())
566 throw std::logic_error(
"Failed to get previous endorsement");
570 !active_service.has_value() ||
571 !active_service->current_service_create_txid.has_value())
573 throw std::logic_error(
574 "Active service or current_service_create_txid is not set");
577 endorsement.endorsement_epoch_begin =
578 prev_endorsement->endorsement_epoch_end.has_value() ?
580 prev_endorsement->endorsement_epoch_begin;
583 active_service->current_service_create_txid.value());
585 endorsement.previous_version =
586 previous_identity_endorsement->get_version_of_previous_write();
588 key_to_endorse = prev_endorsement->endorsing_key;
590 auto* previous_service_last_signed_root =
592 ccf::Tables::PREVIOUS_SERVICE_LAST_SIGNED_ROOT);
593 if (!previous_service_last_signed_root->has())
596 "Failed to sign previous service identity: no last signed root");
600 auto root_opt = previous_service_last_signed_root->get();
601 if (!root_opt.has_value())
604 "Failed to sign previous service identity: no last signed root "
608 const auto root = root_opt.value();
609 previous_root.assign(root.h.begin(), root.h.end());
617 !active_service.has_value() ||
618 !active_service->current_service_create_txid.has_value())
620 throw std::logic_error(
621 "Active service or current_service_create_txid is not set");
624 endorsement.endorsement_epoch_begin =
625 active_service->current_service_create_txid.value();
627 key_to_endorse = endorsement.endorsing_key;
630 auto from_txid = endorsement.endorsement_epoch_begin.to_str();
631 std::string to_txid{};
632 if (endorsement.endorsement_epoch_end)
634 to_txid = endorsement.endorsement_epoch_end->to_str();
637 const auto time_since_epoch =
638 std::chrono::duration_cast<std::chrono::seconds>(
639 std::chrono::system_clock::now().time_since_epoch())
645 CoseKey::from_private(key_der.data(), key_der.size(), key_err);
646 if (key_err.is_set())
648 LOG_FAIL_FMT(
"Failed to create signing key: {}", key_err.to_string());
657 reinterpret_cast<const uint8_t*
>(from_txid.data()),
659 reinterpret_cast<const uint8_t*
>(to_txid.data()),
661 previous_root.data(),
662 previous_root.size(),
663 key_to_endorse.data(),
664 key_to_endorse.size(),
667 if (rc != 0 || !cose_buf.is_set())
670 "Failed to sign previous service identity: {}",
671 cose_err.is_set() ? cose_err.to_string() :
"unknown error");
674 endorsement.endorsement = cose_buf.to_vector();
676 previous_identity_endorsement->put(endorsement);
684 auto active_recovery_participants_count =
688 active_recovery_participants_count == 0 &&
689 active_recovery_owners_count != 0)
694 "Cannot open network as a network with only active recovery owners "
696 "a recovery threshold of 1 but current recovery threshold value is "
698 active_recovery_owners_count,
705 "Cannot open network as number of active recovery members ({}) is "
706 "less than recovery threshold ({})",
707 active_recovery_participants_count,
712 auto active_service = service->get();
713 if (!active_service.has_value())
730 "Could not open current service: status is not OPENING or "
731 "WAITING_FOR_RECOVERY_SHARES");
736 service->put(active_service.value());
745 auto active_service = service->get();
746 if (!active_service.has_value())
752 return active_service->status;
761 auto node_info =
nodes->get(node_id);
763 if (!node_info.has_value())
765 throw std::logic_error(fmt::format(
"Node {} does not exist", node_id));
770 throw std::logic_error(fmt::format(
"Node {} is retired", node_id));
774 node_info->ledger_secret_seqno = latest_ledger_secret_seqno;
775 nodes->put(node_id, node_info.value());
777 LOG_INFO_FMT(
"Node {} is now {}", node_id, node_info->status);
798 node_measurement.
data.begin(), node_measurement.
data.end()),
820 throw std::logic_error(fmt::format(
821 "Unexpected quote format {} when trusting node code id", platform));
829 auto* host_data_table =
831 host_data_table->insert(host_data);
837 const std::optional<HostDataMetadata>& security_policy = std::nullopt)
840 if (security_policy.has_value())
842 auto raw_security_policy =
844 host_data_table->put(
845 host_data, {raw_security_policy.begin(), raw_security_policy.end()});
850 host_data_table->put(host_data, pal::snp::NO_SECURITY_POLICY);
856 const std::optional<pal::UVMEndorsements>& uvm_endorsements,
859 if (!uvm_endorsements.has_value())
871 uvm_endorsements->did,
872 {{uvm_endorsements->feed, {uvm_endorsements->svn}}});
874 "UVM descriptor set to did: {} feed: {} svn: {}",
875 uvm_endorsements->did,
876 uvm_endorsements->feed,
877 uvm_endorsements->svn);
882 uvme->get(uvm_endorsements->did).value_or(FeedToEndorsementsDataMap{});
884 auto feed_it = updated_map.find(uvm_endorsements->feed);
885 if (feed_it == updated_map.end())
887 updated_map[uvm_endorsements->feed] = {uvm_endorsements->svn};
888 uvme->put(uvm_endorsements->did, updated_map);
890 "UVM descriptor set to did: {} feed: {} svn: {} "
891 "(no pre-existing entry for did and feed)",
892 uvm_endorsements->did,
893 uvm_endorsements->feed,
894 uvm_endorsements->svn);
898 auto existing_svn =
parse_svn(feed_it->second.svn);
899 auto new_svn =
parse_svn(uvm_endorsements->svn);
900 auto min_svn = std::to_string(std::min(existing_svn, new_svn));
902 if (min_svn != feed_it->second.svn)
904 updated_map[uvm_endorsements->feed] = {min_svn};
905 uvme->put(uvm_endorsements->did, updated_map);
907 "UVM descriptor set to did: {} feed: {} svn: {} (from {}) ",
908 uvm_endorsements->did,
909 uvm_endorsements->feed,
916 "UVM descriptor unchanged for did: {} feed: {} svn: {} (startup "
917 "svn is not lower: {})",
918 uvm_endorsements->did,
919 uvm_endorsements->feed,
927 if (attestation.
version < pal::snp::minimum_attestation_version)
929 throw std::logic_error(fmt::format(
930 "SEV-SNP: attestation version {} is not supported. Minimum "
931 "supported version is {}",
933 pal::snp::minimum_attestation_version));
937 auto cpuid = pal::snp::get_cpuid_untrusted();
943 throw std::runtime_error(fmt::format(
944 "CPU-sourced cpuid does not match attestation cpuid ({} != {}, {}, "
952 auto product = pal::snp::get_sev_snp_product(cpuid);
962 throw std::logic_error(
963 "Cannot initialise service configuration: configuration already "
967 config->put(configuration);
980 auto service_status = get_service_status(tx);
981 if (!service_status.has_value())
987 if (service_status.value() == ServiceStatus::WAITING_FOR_RECOVERY_SHARES)
993 "Cannot set recovery threshold: service is currently waiting for "
997 if (service_status.value() == ServiceStatus::OPEN)
999 auto active_recovery_participants_count =
1000 get_active_recovery_participants(tx).size();
1001 auto active_recovery_owners_count =
1002 get_active_recovery_owners(tx).size();
1005 active_recovery_owners_count != 0 &&
1006 active_recovery_participants_count == 0)
1011 "Cannot set recovery threshold to {} when only "
1012 "active consortium members ({}) that are of type recovery owner "
1015 active_recovery_owners_count);
1019 else if (threshold > active_recovery_participants_count)
1022 "Cannot set recovery threshold to {} as it is greater than the "
1023 "number of active recovery participant members ({})",
1025 active_recovery_participants_count);
1030 auto current_config = config->get();
1031 if (!current_config.has_value())
1033 throw std::logic_error(
"Configuration should already be set");
1036 current_config->recovery_threshold = threshold;
1037 config->put(current_config.value());
1044 auto current_config = config->get();
1045 if (!current_config.has_value())
1047 throw std::logic_error(
1048 "Failed to get recovery threshold: No active configuration found");
1050 return current_config->recovery_threshold;
Definition internal_tables_access.h:52
static bool is_service_created(ccf::kv::ReadOnlyTx &tx, const ccf::crypto::Pem &expected_service_cert)
Definition internal_tables_access.h:536
static std::map< MemberId, ccf::crypto::Pem > get_active_recovery_participants(ccf::kv::ReadOnlyTx &tx)
Definition internal_tables_access.h:124
static bool set_recovery_threshold(ccf::kv::Tx &tx, size_t threshold)
Definition internal_tables_access.h:970
static bool is_recovery_owner(ccf::kv::ReadOnlyTx &tx, const MemberId &member_id)
Definition internal_tables_access.h:96
static void trust_node_uvm_endorsements(ccf::kv::Tx &tx, const std::optional< pal::UVMEndorsements > &uvm_endorsements, bool recovering)
Definition internal_tables_access.h:854
static std::optional< ServiceStatus > get_service_status(ccf::kv::ReadOnlyTx &tx)
Definition internal_tables_access.h:741
static bool open_service(ccf::kv::Tx &tx)
Definition internal_tables_access.h:680
static void init_configuration(ccf::kv::Tx &tx, const ServiceConfiguration &configuration)
Definition internal_tables_access.h:956
static std::map< NodeId, NodeInfo > get_trusted_nodes(ccf::kv::ReadOnlyTx &tx)
Definition internal_tables_access.h:441
static UserId add_user(ccf::kv::Tx &tx, const NewUser &new_user)
Definition internal_tables_access.h:391
static void trust_node_snp_host_data(ccf::kv::Tx &tx, const HostData &host_data, const std::optional< HostDataMetadata > &security_policy=std::nullopt)
Definition internal_tables_access.h:834
static bool remove_member(ccf::kv::Tx &tx, const MemberId &member_id)
Definition internal_tables_access.h:285
static MemberId add_member(ccf::kv::Tx &tx, const NewMember &member_pub_info)
Definition internal_tables_access.h:187
static void set_constitution(ccf::kv::Tx &tx, const std::string &constitution)
Definition internal_tables_access.h:780
static bool is_recovery_participant(ccf::kv::ReadOnlyTx &tx, const MemberId &member_id)
Definition internal_tables_access.h:89
static std::map< MemberId, ccf::crypto::Pem > get_active_recovery_owners(ccf::kv::ReadOnlyTx &tx)
Definition internal_tables_access.h:155
static void create_service(ccf::kv::Tx &tx, const ccf::crypto::Pem &service_cert, ccf::TxID create_txid, nlohmann::json service_data=nullptr, bool recovering=false)
Definition internal_tables_access.h:470
static bool is_active_member(ccf::kv::ReadOnlyTx &tx, const MemberId &member_id)
Definition internal_tables_access.h:110
static void trust_node_measurement(ccf::kv::Tx &tx, const pal::PlatformAttestationMeasurement &node_measurement, const QuoteFormat &platform)
Definition internal_tables_access.h:786
static void retire_active_nodes(ccf::kv::Tx &tx)
Definition internal_tables_access.h:58
static void add_node(ccf::kv::Tx &tx, const NodeId &id, const NodeInfo &node_info)
Definition internal_tables_access.h:434
static void trust_node_virtual_host_data(ccf::kv::Tx &tx, const HostData &host_data)
Definition internal_tables_access.h:826
static bool endorse_previous_identity(ccf::kv::Tx &tx, const ccf::crypto::ECKeyPair_OpenSSL &service_key)
Definition internal_tables_access.h:545
static bool activate_member(ccf::kv::Tx &tx, const MemberId &member_id)
Definition internal_tables_access.h:266
static void trust_node_snp_tcb_version(ccf::kv::Tx &tx, pal::snp::Attestation &attestation)
Definition internal_tables_access.h:924
static void trust_node(ccf::kv::Tx &tx, const NodeId &node_id, ccf::kv::Version latest_ledger_secret_seqno)
Definition internal_tables_access.h:755
static bool is_recovery_participant_or_owner(ccf::kv::ReadOnlyTx &tx, const MemberId &member_id)
Definition internal_tables_access.h:79
InternalTablesAccess()=delete
static size_t get_recovery_threshold(ccf::kv::ReadOnlyTx &tx)
Definition internal_tables_access.h:1041
static void remove_user(ccf::kv::Tx &tx, const UserId &user_id)
Definition internal_tables_access.h:424
ccf::crypto::Sha256Hash get_root() const
Definition history.h:462
Definition ec_key_pair.h:16
std::vector< uint8_t > private_key_der() const override
Definition ec_key_pair.cpp:132
std::vector< uint8_t > public_key_der() const override
Definition ec_key_pair.cpp:127
Definition sha256_hash.h:16
std::string hex_str() const
Definition sha256_hash.cpp:57
M::ReadOnlyHandle * ro(M &m)
Definition tx.h:168
M::Handle * rw(M &m)
Definition tx.h:211
M::WriteOnlyHandle * wo(M &m)
Definition tx.h:232
int cose_sign_endorsement(const CoseEvpKey *key, int64_t iat, const uint8_t *epoch_begin_ptr, size_t epoch_begin_len, const uint8_t *epoch_end_ptr, size_t epoch_end_len, const uint8_t *prev_root_ptr, size_t prev_root_len, const uint8_t *payload_ptr, size_t payload_len, uint8_t **out_ptr, size_t *out_len, uint8_t **err_ptr, size_t *err_len)
#define LOG_INFO_FMT
Definition internal_logger.h:15
#define LOG_TRACE_FMT
Definition internal_logger.h:13
#define LOG_FAIL_FMT
Definition internal_logger.h:16
std::vector< uint8_t > raw_from_b64(const std::string_view &b64_string)
Definition base64.cpp:12
VerifierPtr make_verifier(const std::vector< uint8_t > &cert)
Definition verifier.cpp:18
uint64_t Version
Definition version.h:10
std::string VirtualAttestationMeasurement
Definition measurement.h:97
Definition app_interface.h:13
ccf::TxID next_tx_if_recovery(ccf::TxID txid)
Definition internal_tables_access.h:39
ccf::TxID previous_tx_if_recovery(ccf::TxID txid)
Definition internal_tables_access.h:34
QuoteFormat
Definition quote_info.h:12
@ WAITING_FOR_RECOVERY_SHARES
size_t parse_svn(const std::string &svn_str)
Definition uvm_endorsements.cpp:12
Definition previous_service_identity.h:18
std::vector< uint8_t > endorsing_key
Service key at the moment of endorsing.
Definition previous_service_identity.h:23
std::optional< MemberRecoveryRole > recovery_role
Definition members.h:49
std::optional< ccf::crypto::Pem > encryption_pub_key
Definition members.h:46
ccf::crypto::Pem cert
Definition members.h:43
nlohmann::json member_data
Definition members.h:47
nlohmann::json user_data
Definition users.h:16
ccf::crypto::Pem cert
Definition users.h:15
Definition node_info.h:30
NodeStatus status
Node status.
Definition node_info.h:36
Definition service_config.h:14
SeqNo seqno
Definition tx_id.h:46
View view
Definition tx_id.h:45
Definition measurement.h:17
Definition attestation_sev_snp.h:387
TcbVersionRaw reported_tcb
Definition attestation_sev_snp.h:406
uint32_t version
Definition attestation_sev_snp.h:388
uint8_t cpuid_fam_id
Definition attestation_sev_snp.h:407
uint8_t cpuid_step
Definition attestation_sev_snp.h:409
uint8_t cpuid_mod_id
Definition attestation_sev_snp.h:408
TcbVersionPolicy to_policy(ProductName product) const
Definition attestation_sev_snp.h:252