36 .
view = txid.
view - aft::starting_view_change, .seqno = txid.
seqno - 1};
41 .
view = txid.
view + aft::starting_view_change, .seqno = txid.
seqno + 1};
61 std::map<NodeId, NodeInfo> nodes_to_delete;
66 nodes_to_delete[nid] = ni;
71 for (
auto [nid, ni] : nodes_to_delete)
81 auto* member_encryption_public_keys =
83 Tables::MEMBER_ENCRYPTION_PUBLIC_KEYS);
85 return member_encryption_public_keys->get(member_id).has_value();
99 auto mi = member_info->get(member_id);
105 return mi->recovery_role.has_value() &&
113 auto mi = member_info->get(member_id);
122 static std::map<MemberId, ccf::crypto::Pem>
126 auto* member_encryption_public_keys =
128 Tables::MEMBER_ENCRYPTION_PUBLIC_KEYS);
130 std::map<MemberId, ccf::crypto::Pem> active_recovery_participants;
132 member_encryption_public_keys->foreach(
133 [&active_recovery_participants,
134 &member_info](
const auto& mid,
const auto& pem) {
135 auto info = member_info->get(mid);
136 if (!info.has_value())
138 throw std::logic_error(
139 fmt::format(
"Recovery member {} has no member info", mid));
147 active_recovery_participants[mid] = pem;
151 return active_recovery_participants;
158 auto* member_encryption_public_keys =
160 Tables::MEMBER_ENCRYPTION_PUBLIC_KEYS);
162 std::map<MemberId, ccf::crypto::Pem> active_recovery_owners;
164 member_encryption_public_keys->foreach(
165 [&active_recovery_owners,
166 &member_info](
const auto& mid,
const auto& pem) {
167 auto info = member_info->get(mid);
168 if (!info.has_value())
170 throw std::logic_error(
171 fmt::format(
"Recovery member {} has no member info", mid));
179 active_recovery_owners[mid] = pem;
183 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(
251 auto s = signatures->get();
258 member_acks->put(
id,
MemberAck(s->root));
267 auto member = member_info->get(member_id);
268 if (!member.has_value())
270 throw std::logic_error(fmt::format(
271 "Member {} cannot be activated as they do not exist", member_id));
277 member_info->put(member_id, member.value());
285 auto* member_encryption_public_keys =
287 Tables::MEMBER_ENCRYPTION_PUBLIC_KEYS);
290 auto* member_gov_history =
293 auto member_to_remove = member_info->get(member_id);
294 if (!member_to_remove.has_value())
299 "Could not remove member {}: member does not exist", member_id);
310 size_t active_recovery_participants_count_after =
313 auto active_recovery_owners_count =
316 active_recovery_participants_count_after == 0 &&
317 active_recovery_owners_count > 0 && recovery_threshold == 1)
322 "Allowing last active recovery participant member {}: to "
323 "be removed as active recovery owner members ({}) are present "
324 "with recovery threshold ({}).",
326 active_recovery_owners_count,
330 active_recovery_participants_count_after < recovery_threshold)
336 "Failed to remove recovery member {}: number of active recovery "
337 "participant members ({}) would be less than recovery threshold "
340 active_recovery_participants_count_after,
347 size_t active_recovery_owners_count_after =
350 auto active_recovery_participants_count =
352 if (active_recovery_owners_count_after == 0)
354 if (active_recovery_participants_count > 0)
357 "Allowing last active recovery owner member {}: to "
358 "be removed as active recovery owner participants ({}) are "
359 "present with recovery threshold ({}).",
361 active_recovery_participants_count,
367 "Failed to remove last active recovery owner member {}: number "
368 "of active recovery participant members ({}) would be less "
369 "than recovery threshold ({})",
371 active_recovery_participants_count,
379 member_info->remove(member_id);
380 member_encryption_public_keys->remove(member_id);
381 member_certs->remove(member_id);
382 member_acks->remove(member_id);
383 member_gov_history->remove(member_id);
396 auto user_cert = user_certs->get(
id);
397 if (user_cert.has_value())
399 throw std::logic_error(
400 fmt::format(
"Certificate already exists for user {}",
id));
403 user_certs->put(
id, new_user.
cert);
408 auto ui = user_info->get(
id);
411 throw std::logic_error(
412 fmt::format(
"User data already exists for user {}",
id));
415 user_info->put(
id, {new_user.
user_data});
427 user_certs->remove(user_id);
428 user_info->remove(user_id);
435 node->put(
id, node_info);
440 std::map<NodeId, NodeInfo> active_nodes;
448 active_nodes[nid] = ni;
454 auto cni =
nodes->get_globally_committed(nid);
455 if (cni.has_value() && !cni->retired_committed)
457 active_nodes[nid] = ni;
471 nlohmann::json service_data =
nullptr,
472 bool recovering =
false)
476 size_t recovery_count = 0;
477 std::optional<ccf::kv::Version> prev_service_created_at = std::nullopt;
481 const auto prev_service_info = service->get();
482 if (!prev_service_info.has_value())
484 throw std::logic_error(
"Failed to get previous service info");
487 if (!prev_service_info->current_service_create_txid.has_value())
489 throw std::logic_error(
490 "Starting TX for the previous service doesn't have "
491 "current_service_create_txid recorded");
493 prev_service_created_at =
494 prev_service_info->current_service_create_txid.value().seqno;
497 ccf::Tables::PREVIOUS_SERVICE_IDENTITY);
498 previous_service_identity->put(prev_service_info->cert);
501 ccf::Tables::PREVIOUS_SERVICE_LAST_SIGNED_ROOT);
505 throw std::logic_error(
506 "Previous service doesn't have any signed transactions");
508 auto sig_opt = sigs->get();
509 if (!sig_opt.has_value())
511 throw std::logic_error(
512 "Previous service doesn't have signature value");
514 last_signed_root->put(sig_opt->root);
519 recovery_count = prev_service_info->recovery_count.value_or(0) + 1;
525 prev_service_created_at,
535 auto service_info = service->get();
536 return service_info.has_value() &&
537 service_info->cert == expected_service_cert;
544 auto active_service = service->get();
546 auto* previous_identity_endorsement =
548 ccf::Tables::PREVIOUS_SERVICE_IDENTITY_ENDORSEMENT);
551 std::vector<uint8_t> key_to_endorse{};
552 std::vector<uint8_t> previous_root{};
556 if (previous_identity_endorsement->has())
558 const auto prev_endorsement = previous_identity_endorsement->get();
559 if (!prev_endorsement.has_value())
561 throw std::logic_error(
"Failed to get previous endorsement");
565 !active_service.has_value() ||
566 !active_service->current_service_create_txid.has_value())
568 throw std::logic_error(
569 "Active service or current_service_create_txid is not set");
572 endorsement.endorsement_epoch_begin =
573 prev_endorsement->endorsement_epoch_end.has_value() ?
575 prev_endorsement->endorsement_epoch_begin;
578 active_service->current_service_create_txid.value());
580 endorsement.previous_version =
581 previous_identity_endorsement->get_version_of_previous_write();
583 key_to_endorse = prev_endorsement->endorsing_key;
585 auto* previous_service_last_signed_root =
587 ccf::Tables::PREVIOUS_SERVICE_LAST_SIGNED_ROOT);
588 if (!previous_service_last_signed_root->has())
591 "Failed to sign previous service identity: no last signed root");
595 auto root_opt = previous_service_last_signed_root->get();
596 if (!root_opt.has_value())
599 "Failed to sign previous service identity: no last signed root "
603 const auto root = root_opt.value();
604 previous_root.assign(root.h.begin(), root.h.end());
612 !active_service.has_value() ||
613 !active_service->current_service_create_txid.has_value())
615 throw std::logic_error(
616 "Active service or current_service_create_txid is not set");
619 endorsement.endorsement_epoch_begin =
620 active_service->current_service_create_txid.value();
622 key_to_endorse = endorsement.endorsing_key;
625 std::vector<std::shared_ptr<ccf::crypto::COSEParametersFactory>>
628 ccf::crypto::COSE_PHEADER_KEY_RANGE_BEGIN,
629 endorsement.endorsement_epoch_begin.to_str()));
630 if (endorsement.endorsement_epoch_end)
633 ccf::crypto::COSE_PHEADER_KEY_RANGE_END,
634 endorsement.endorsement_epoch_end->to_str()));
636 if (!previous_root.empty())
639 ccf::crypto::COSE_PHEADER_KEY_EPOCH_LAST_MERKLE_ROOT, previous_root));
642 const auto time_since_epoch =
643 std::chrono::duration_cast<std::chrono::seconds>(
644 std::chrono::system_clock::now().time_since_epoch())
648 std::static_pointer_cast<ccf::crypto::COSEParametersFactory>(
649 std::make_shared<ccf::crypto::COSEParametersMap>(
650 std::make_shared<ccf::crypto::COSEMapIntKey>(
651 ccf::crypto::COSE_PHEADER_KEY_CWT),
653 ccf::crypto::COSE_PHEADER_KEY_IAT, time_since_epoch)}));
656 std::static_pointer_cast<ccf::crypto::COSEParametersFactory>(
657 std::make_shared<ccf::crypto::COSEParametersMap>(
658 std::make_shared<ccf::crypto::COSEMapStringKey>(
659 ccf::crypto::COSE_PHEADER_KEY_CCF),
666 endorsement.endorsement = cose_sign1(
675 LOG_FAIL_FMT(
"Failed to sign previous service identity: {}", e.what());
679 previous_identity_endorsement->put(endorsement);
687 auto active_recovery_participants_count =
691 active_recovery_participants_count == 0 &&
692 active_recovery_owners_count != 0)
697 "Cannot open network as a network with only active recovery owners "
699 "a recovery threshold of 1 but current recovery threshold value is "
701 active_recovery_owners_count,
708 "Cannot open network as number of active recovery members ({}) is "
709 "less than recovery threshold ({})",
710 active_recovery_participants_count,
715 auto active_service = service->get();
716 if (!active_service.has_value())
733 "Could not open current service: status is not OPENING or "
734 "WAITING_FOR_RECOVERY_SHARES");
739 service->put(active_service.value());
748 auto active_service = service->get();
749 if (!active_service.has_value())
755 return active_service->status;
764 auto node_info =
nodes->get(node_id);
766 if (!node_info.has_value())
768 throw std::logic_error(fmt::format(
"Node {} does not exist", node_id));
773 throw std::logic_error(fmt::format(
"Node {} is retired", node_id));
777 node_info->ledger_secret_seqno = latest_ledger_secret_seqno;
778 nodes->put(node_id, node_info.value());
780 LOG_INFO_FMT(
"Node {} is now {}", node_id, node_info->status);
801 node_measurement.
data.begin(), node_measurement.
data.end()),
823 throw std::logic_error(fmt::format(
824 "Unexpected quote format {} when trusting node code id", platform));
832 auto* host_data_table =
834 host_data_table->insert(host_data);
840 const std::optional<HostDataMetadata>& security_policy = std::nullopt)
843 if (security_policy.has_value())
845 auto raw_security_policy =
847 host_data_table->put(
848 host_data, {raw_security_policy.begin(), raw_security_policy.end()});
853 host_data_table->put(host_data, pal::snp::NO_SECURITY_POLICY);
859 const std::optional<pal::UVMEndorsements>& uvm_endorsements)
861 if (!uvm_endorsements.has_value())
870 uvm_endorsements->did,
871 {{uvm_endorsements->feed, {uvm_endorsements->svn}}});
877 if (attestation.
version < pal::snp::minimum_attestation_version)
879 throw std::logic_error(fmt::format(
880 "SEV-SNP: attestation version {} is not supported. Minimum "
881 "supported version is {}",
883 pal::snp::minimum_attestation_version));
887 auto cpuid = pal::snp::get_cpuid_untrusted();
893 throw std::runtime_error(fmt::format(
894 "CPU-sourced cpuid does not match attestation cpuid ({} != {}, {}, "
902 auto product = pal::snp::get_sev_snp_product(cpuid);
909 auto* config = tx.
rw<ccf::Configuration>(Tables::CONFIGURATION);
912 throw std::logic_error(
913 "Cannot initialise service configuration: configuration already "
917 config->put(configuration);
922 auto* config = tx.
rw<ccf::Configuration>(Tables::CONFIGURATION);
930 auto service_status = get_service_status(tx);
931 if (!service_status.has_value())
937 if (service_status.value() == ServiceStatus::WAITING_FOR_RECOVERY_SHARES)
943 "Cannot set recovery threshold: service is currently waiting for "
947 if (service_status.value() == ServiceStatus::OPEN)
949 auto active_recovery_participants_count =
950 get_active_recovery_participants(tx).size();
951 auto active_recovery_owners_count =
952 get_active_recovery_owners(tx).size();
955 active_recovery_owners_count != 0 &&
956 active_recovery_participants_count == 0)
961 "Cannot set recovery threshold to {} when only "
962 "active consortium members ({}) that are of type recovery owner "
965 active_recovery_owners_count);
969 else if (threshold > active_recovery_participants_count)
972 "Cannot set recovery threshold to {} as it is greater than the "
973 "number of active recovery participant members ({})",
975 active_recovery_participants_count);
980 auto current_config = config->get();
981 if (!current_config.has_value())
983 throw std::logic_error(
"Configuration should already be set");
986 current_config->recovery_threshold = threshold;
987 config->put(current_config.value());
993 auto* config = tx.
ro<ccf::Configuration>(Tables::CONFIGURATION);
994 auto current_config = config->get();
995 if (!current_config.has_value())
997 throw std::logic_error(
998 "Failed to get recovery threshold: No active configuration found");
1000 return current_config->recovery_threshold;
Definition internal_tables_access.h:51
static bool is_service_created(ccf::kv::ReadOnlyTx &tx, const ccf::crypto::Pem &expected_service_cert)
Definition internal_tables_access.h:531
static std::map< MemberId, ccf::crypto::Pem > get_active_recovery_participants(ccf::kv::ReadOnlyTx &tx)
Definition internal_tables_access.h:123
static bool set_recovery_threshold(ccf::kv::Tx &tx, size_t threshold)
Definition internal_tables_access.h:920
static bool is_recovery_owner(ccf::kv::ReadOnlyTx &tx, const MemberId &member_id)
Definition internal_tables_access.h:95
static std::optional< ServiceStatus > get_service_status(ccf::kv::ReadOnlyTx &tx)
Definition internal_tables_access.h:744
static bool open_service(ccf::kv::Tx &tx)
Definition internal_tables_access.h:683
static void init_configuration(ccf::kv::Tx &tx, const ServiceConfiguration &configuration)
Definition internal_tables_access.h:906
static std::map< NodeId, NodeInfo > get_trusted_nodes(ccf::kv::ReadOnlyTx &tx)
Definition internal_tables_access.h:438
static UserId add_user(ccf::kv::Tx &tx, const NewUser &new_user)
Definition internal_tables_access.h:388
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:837
static bool remove_member(ccf::kv::Tx &tx, const MemberId &member_id)
Definition internal_tables_access.h:282
static MemberId add_member(ccf::kv::Tx &tx, const NewMember &member_pub_info)
Definition internal_tables_access.h:186
static void set_constitution(ccf::kv::Tx &tx, const std::string &constitution)
Definition internal_tables_access.h:783
static void trust_node_uvm_endorsements(ccf::kv::Tx &tx, const std::optional< pal::UVMEndorsements > &uvm_endorsements)
Definition internal_tables_access.h:857
static bool is_recovery_participant(ccf::kv::ReadOnlyTx &tx, const MemberId &member_id)
Definition internal_tables_access.h:88
static std::map< MemberId, ccf::crypto::Pem > get_active_recovery_owners(ccf::kv::ReadOnlyTx &tx)
Definition internal_tables_access.h:154
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:467
static bool is_active_member(ccf::kv::ReadOnlyTx &tx, const MemberId &member_id)
Definition internal_tables_access.h:109
static void trust_node_measurement(ccf::kv::Tx &tx, const pal::PlatformAttestationMeasurement &node_measurement, const QuoteFormat &platform)
Definition internal_tables_access.h:789
static void retire_active_nodes(ccf::kv::Tx &tx)
Definition internal_tables_access.h:57
static void add_node(ccf::kv::Tx &tx, const NodeId &id, const NodeInfo &node_info)
Definition internal_tables_access.h:431
static void trust_node_virtual_host_data(ccf::kv::Tx &tx, const HostData &host_data)
Definition internal_tables_access.h:829
static bool endorse_previous_identity(ccf::kv::Tx &tx, const ccf::crypto::ECKeyPair_OpenSSL &service_key)
Definition internal_tables_access.h:540
static bool activate_member(ccf::kv::Tx &tx, const MemberId &member_id)
Definition internal_tables_access.h:263
static void trust_node_snp_tcb_version(ccf::kv::Tx &tx, pal::snp::Attestation &attestation)
Definition internal_tables_access.h:874
static void trust_node(ccf::kv::Tx &tx, const NodeId &node_id, ccf::kv::Version latest_ledger_secret_seqno)
Definition internal_tables_access.h:758
static bool is_recovery_participant_or_owner(ccf::kv::ReadOnlyTx &tx, const MemberId &member_id)
Definition internal_tables_access.h:78
InternalTablesAccess()=delete
static size_t get_recovery_threshold(ccf::kv::ReadOnlyTx &tx)
Definition internal_tables_access.h:991
static void remove_user(ccf::kv::Tx &tx, const UserId &user_id)
Definition internal_tables_access.h:421
Definition ec_key_pair.h:16
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
#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::shared_ptr< COSEParametersFactory > cose_params_string_bytes(const std::string &key, std::span< const uint8_t > value)
Definition cose_sign.cpp:217
std::shared_ptr< COSEParametersFactory > cose_params_int_int(int64_t key, int64_t value)
Definition cose_sign.cpp:154
std::vector< uint8_t > raw_from_b64(const std::string_view &b64_string)
Definition base64.cpp:12
std::shared_ptr< COSEParametersFactory > cose_params_string_string(const std::string &key, const std::string &value)
Definition cose_sign.cpp:191
VerifierPtr make_verifier(const std::vector< uint8_t > &cert)
Definition verifier.cpp:18
std::vector< std::shared_ptr< ccf::crypto::COSEParametersFactory > > COSEHeadersArray
Definition cose_sign.h:165
uint64_t Version
Definition version.h:8
std::string VirtualAttestationMeasurement
Definition measurement.h:97
Definition app_interface.h:14
ccf::TxID next_tx_if_recovery(ccf::TxID txid)
Definition internal_tables_access.h:38
ccf::TxID previous_tx_if_recovery(ccf::TxID txid)
Definition internal_tables_access.h:33
QuoteFormat
Definition quote_info.h:12
@ WAITING_FOR_RECOVERY_SHARES
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 cose_sign.h:168
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