35 .
view = txid.
view - aft::starting_view_change, .seqno = txid.
seqno - 1};
40 .
view = txid.
view + aft::starting_view_change, .seqno = txid.
seqno + 1};
60 std::map<NodeId, NodeInfo> nodes_to_delete;
64 nodes_to_delete[nid] = ni;
68 for (
auto [nid, ni] : nodes_to_delete)
78 auto member_encryption_public_keys =
80 Tables::MEMBER_ENCRYPTION_PUBLIC_KEYS);
82 return member_encryption_public_keys->get(member_id).has_value();
96 auto mi = member_info->get(member_id);
102 return mi->recovery_role.has_value() &&
110 auto mi = member_info->get(member_id);
119 static std::map<MemberId, ccf::crypto::Pem>
123 auto member_encryption_public_keys =
125 Tables::MEMBER_ENCRYPTION_PUBLIC_KEYS);
127 std::map<MemberId, ccf::crypto::Pem> active_recovery_participants;
129 member_encryption_public_keys->foreach(
130 [&active_recovery_participants,
131 &member_info](
const auto& mid,
const auto& pem) {
132 auto info = member_info->get(mid);
133 if (!info.has_value())
135 throw std::logic_error(
136 fmt::format(
"Recovery member {} has no member info", mid));
144 active_recovery_participants[mid] = pem;
148 return active_recovery_participants;
155 auto member_encryption_public_keys =
157 Tables::MEMBER_ENCRYPTION_PUBLIC_KEYS);
159 std::map<MemberId, ccf::crypto::Pem> active_recovery_owners;
161 member_encryption_public_keys->foreach(
162 [&active_recovery_owners,
163 &member_info](
const auto& mid,
const auto& pem) {
164 auto info = member_info->get(mid);
165 if (!info.has_value())
167 throw std::logic_error(
168 fmt::format(
"Recovery member {} has no member info", mid));
176 active_recovery_owners[mid] = pem;
180 return active_recovery_owners;
191 auto member_cert_der =
195 auto member = member_certs->get(
id);
196 if (member.has_value())
204 auto member_recovery_role = member_pub_info.
recovery_role.value();
209 throw std::logic_error(fmt::format(
210 "Member {} cannot be added as recovery_role has a value set but "
212 "encryption public key is specified",
222 throw std::logic_error(fmt::format(
223 "Recovery member {} cannot be added as with recovery role value "
227 member_recovery_role));
232 member_certs->put(
id, member_pub_info.
cert);
241 auto member_encryption_public_keys =
243 Tables::MEMBER_ENCRYPTION_PUBLIC_KEYS);
244 member_encryption_public_keys->put(
248 auto s = signatures->get();
255 member_acks->put(
id,
MemberAck(s->root));
264 auto member = member_info->get(member_id);
265 if (!member.has_value())
267 throw std::logic_error(fmt::format(
268 "Member {} cannot be activated as they do not exist", member_id));
274 member_info->put(member_id, member.value());
282 auto member_encryption_public_keys =
284 Tables::MEMBER_ENCRYPTION_PUBLIC_KEYS);
287 auto member_gov_history =
290 auto member_to_remove = member_info->get(member_id);
291 if (!member_to_remove.has_value())
296 "Could not remove member {}: member does not exist", member_id);
307 size_t active_recovery_participants_count_after =
310 auto active_recovery_owners_count =
313 active_recovery_participants_count_after == 0 &&
314 active_recovery_owners_count > 0 && recovery_threshold == 1)
319 "Allowing last active recovery participant member {}: to "
320 "be removed as active recovery owner members ({}) are present "
321 "with recovery threshold ({}).",
323 active_recovery_owners_count,
327 active_recovery_participants_count_after < recovery_threshold)
333 "Failed to remove recovery member {}: number of active recovery "
334 "participant members ({}) would be less than recovery threshold "
337 active_recovery_participants_count_after,
344 size_t active_recovery_owners_count_after =
347 auto active_recovery_participants_count =
349 if (active_recovery_owners_count_after == 0)
351 if (active_recovery_participants_count > 0)
354 "Allowing last active recovery owner member {}: to "
355 "be removed as active recovery owner participants ({}) are "
356 "present with recovery threshold ({}).",
358 active_recovery_participants_count,
364 "Failed to remove last active recovery owner member {}: number "
365 "of active recovery participant members ({}) would be less "
366 "than recovery threshold ({})",
368 active_recovery_participants_count,
376 member_info->remove(member_id);
377 member_encryption_public_keys->remove(member_id);
378 member_certs->remove(member_id);
379 member_acks->remove(member_id);
380 member_gov_history->remove(member_id);
393 auto user_cert = user_certs->get(
id);
394 if (user_cert.has_value())
396 throw std::logic_error(
397 fmt::format(
"Certificate already exists for user {}",
id));
400 user_certs->put(
id, new_user.
cert);
405 auto ui = user_info->get(
id);
408 throw std::logic_error(
409 fmt::format(
"User data already exists for user {}",
id));
412 user_info->put(
id, {new_user.
user_data});
424 user_certs->remove(user_id);
425 user_info->remove(user_id);
432 node->put(
id, node_info);
437 std::map<NodeId, NodeInfo> active_nodes;
445 active_nodes[nid] = ni;
451 auto cni =
nodes->get_globally_committed(nid);
452 if (cni.has_value() && !cni->retired_committed)
454 active_nodes[nid] = ni;
468 nlohmann::json service_data =
nullptr,
469 bool recovering =
false)
473 size_t recovery_count = 0;
477 const auto prev_service_info = service->get();
479 ccf::Tables::PREVIOUS_SERVICE_IDENTITY);
480 previous_service_identity->put(prev_service_info->cert);
483 ccf::Tables::PREVIOUS_SERVICE_LAST_SIGNED_ROOT);
487 throw std::logic_error(
488 "Previous service doesn't have any signed transactions");
490 last_signed_root->put(sigs->get()->root);
495 recovery_count = prev_service_info->recovery_count.value_or(0) + 1;
501 recovering ? service->get_version_of_previous_write() : std::nullopt,
511 return service.has_value() && service->cert == expected_service_cert;
518 auto active_service = service->get();
520 auto previous_identity_endorsement =
522 ccf::Tables::PREVIOUS_SERVICE_IDENTITY_ENDORSEMENT);
525 std::vector<uint8_t> key_to_endorse{};
526 std::vector<uint8_t> previous_root{};
530 if (previous_identity_endorsement->has())
532 const auto prev_endorsement = previous_identity_endorsement->get();
534 endorsement.endorsement_epoch_begin =
535 prev_endorsement->endorsement_epoch_end.has_value() ?
537 prev_endorsement->endorsement_epoch_begin;
540 active_service->current_service_create_txid.value());
542 endorsement.previous_version =
543 previous_identity_endorsement->get_version_of_previous_write();
545 key_to_endorse = prev_endorsement->endorsing_key;
547 auto previous_service_last_signed_root =
549 ccf::Tables::PREVIOUS_SERVICE_LAST_SIGNED_ROOT);
550 if (!previous_service_last_signed_root->has())
553 "Failed to sign previous service identity: no last signed root");
557 const auto root = previous_service_last_signed_root->get().value();
558 previous_root.assign(root.h.begin(), root.h.end());
565 endorsement.endorsement_epoch_begin =
566 active_service->current_service_create_txid.value();
568 key_to_endorse = endorsement.endorsing_key;
571 std::vector<std::shared_ptr<ccf::crypto::COSEParametersFactory>>
574 ccf::crypto::COSE_PHEADER_KEY_RANGE_BEGIN,
575 endorsement.endorsement_epoch_begin.to_str()));
576 if (endorsement.endorsement_epoch_end)
579 ccf::crypto::COSE_PHEADER_KEY_RANGE_END,
580 endorsement.endorsement_epoch_end->to_str()));
582 if (!previous_root.empty())
585 ccf::crypto::COSE_PHEADER_KEY_EPOCH_LAST_MERKLE_ROOT, previous_root));
588 const auto time_since_epoch =
589 std::chrono::duration_cast<std::chrono::seconds>(
590 std::chrono::system_clock::now().time_since_epoch())
594 std::static_pointer_cast<ccf::crypto::COSEParametersFactory>(
595 std::make_shared<ccf::crypto::COSEParametersMap>(
596 std::make_shared<ccf::crypto::COSEMapIntKey>(
597 ccf::crypto::COSE_PHEADER_KEY_CWT),
599 ccf::crypto::COSE_PHEADER_KEY_IAT, time_since_epoch)}));
602 std::static_pointer_cast<ccf::crypto::COSEParametersFactory>(
603 std::make_shared<ccf::crypto::COSEParametersMap>(
604 std::make_shared<ccf::crypto::COSEMapStringKey>(
605 ccf::crypto::COSE_PHEADER_KEY_CCF),
612 endorsement.endorsement = cose_sign1(
621 LOG_FAIL_FMT(
"Failed to sign previous service identity: {}", e.what());
625 previous_identity_endorsement->put(endorsement);
633 auto active_recovery_participants_count =
637 active_recovery_participants_count == 0 &&
638 active_recovery_owners_count != 0)
643 "Cannot open network as a network with only active recovery owners "
645 "a recovery threshold of 1 but current recovery threshold value is "
647 active_recovery_owners_count,
654 "Cannot open network as number of active recovery members ({}) is "
655 "less than recovery threshold ({})",
656 active_recovery_participants_count,
661 auto active_service = service->get();
662 if (!active_service.has_value())
679 "Could not open current service: status is not OPENING or "
680 "WAITING_FOR_RECOVERY_SHARES");
685 active_service->previous_service_identity_version =
686 service->get_version_of_previous_write();
687 service->put(active_service.value());
696 auto active_service = service->get();
697 if (!active_service.has_value())
703 return active_service->status;
712 auto node_info =
nodes->get(node_id);
714 if (!node_info.has_value())
716 throw std::logic_error(fmt::format(
"Node {} does not exist", node_id));
721 throw std::logic_error(fmt::format(
"Node {} is retired", node_id));
725 node_info->ledger_secret_seqno = latest_ledger_secret_seqno;
726 nodes->put(node_id, node_info.value());
728 LOG_INFO_FMT(
"Node {} is now {}", node_id, node_info->status);
749 node_measurement.
data.begin(), node_measurement.
data.end()),
771 throw std::logic_error(fmt::format(
772 "Unexpected quote format {} when trusting node code id", platform));
780 auto host_data_table =
782 host_data_table->insert(host_data);
788 const std::optional<HostDataMetadata>& security_policy = std::nullopt)
791 if (security_policy.has_value())
793 auto raw_security_policy =
795 host_data_table->put(
796 host_data, {raw_security_policy.begin(), raw_security_policy.end()});
801 host_data_table->put(host_data, pal::snp::NO_SECURITY_POLICY);
807 const std::optional<pal::UVMEndorsements>& uvm_endorsements)
809 if (!uvm_endorsements.has_value())
818 uvm_endorsements->did,
819 {{uvm_endorsements->feed, {uvm_endorsements->svn}}});
831 .extended_model = 0x0,
832 .extended_family = 0x0A,
839 .extended_model = 0x0,
840 .extended_family = 0x0A,
843 const auto milan_tcb_policy =
844 pal::snp::TcbVersionRaw::from_hex(
"d315000000000004")
845 .to_policy(pal::snp::ProductName::Milan);
846 h->put(milan_chip_id.hex_str(), milan_tcb_policy);
847 h->put(milan_x_chip_id.hex_str(), milan_tcb_policy);
854 if (attestation.
version < pal::snp::MIN_TCB_VERIF_VERSION)
857 "SNP attestation version {} older than {}, falling back to static "
858 "minimum TCB values",
860 pal::snp::MIN_TCB_VERIF_VERSION);
861 trust_static_snp_tcb_version(tx);
867 auto cpuid = pal::snp::get_cpuid_untrusted();
874 "CPU-sourced cpuid does not match attestation cpuid ({} != {}, {}, "
880 trust_static_snp_tcb_version(tx);
884 auto product = pal::snp::get_sev_snp_product(cpuid);
891 auto config = tx.
rw<ccf::Configuration>(Tables::CONFIGURATION);
894 throw std::logic_error(
895 "Cannot initialise service configuration: configuration already "
899 config->put(configuration);
904 auto config = tx.
rw<ccf::Configuration>(Tables::CONFIGURATION);
912 auto service_status = get_service_status(tx);
913 if (!service_status.has_value())
919 if (service_status.value() == ServiceStatus::WAITING_FOR_RECOVERY_SHARES)
925 "Cannot set recovery threshold: service is currently waiting for "
929 else if (service_status.value() == ServiceStatus::OPEN)
931 auto active_recovery_participants_count =
932 get_active_recovery_participants(tx).size();
933 auto active_recovery_owners_count =
934 get_active_recovery_owners(tx).size();
937 active_recovery_owners_count != 0 &&
938 active_recovery_participants_count == 0)
943 "Cannot set recovery threshold to {} when only "
944 "active consortium members ({}) that are of type recovery owner "
947 active_recovery_owners_count);
951 else if (threshold > active_recovery_participants_count)
954 "Cannot set recovery threshold to {} as it is greater than the "
955 "number of active recovery participant members ({})",
957 active_recovery_participants_count);
962 auto current_config = config->get();
963 if (!current_config.has_value())
965 throw std::logic_error(
"Configuration should already be set");
968 current_config->recovery_threshold = threshold;
969 config->put(current_config.value());
975 auto config = tx.
ro<ccf::Configuration>(Tables::CONFIGURATION);
976 auto current_config = config->get();
977 if (!current_config.has_value())
979 throw std::logic_error(
980 "Failed to get recovery threshold: No active configuration found");
982 return current_config->recovery_threshold;
Definition internal_tables_access.h:50
static bool is_service_created(ccf::kv::ReadOnlyTx &tx, const ccf::crypto::Pem &expected_service_cert)
Definition internal_tables_access.h:507
static std::map< MemberId, ccf::crypto::Pem > get_active_recovery_participants(ccf::kv::ReadOnlyTx &tx)
Definition internal_tables_access.h:120
static bool endorse_previous_identity(ccf::kv::Tx &tx, const ccf::crypto::KeyPair_OpenSSL &service_key)
Definition internal_tables_access.h:514
static bool set_recovery_threshold(ccf::kv::Tx &tx, size_t threshold)
Definition internal_tables_access.h:902
static bool is_recovery_owner(ccf::kv::ReadOnlyTx &tx, const MemberId &member_id)
Definition internal_tables_access.h:92
static void trust_static_snp_tcb_version(ccf::kv::Tx &tx)
Definition internal_tables_access.h:822
static std::optional< ServiceStatus > get_service_status(ccf::kv::ReadOnlyTx &tx)
Definition internal_tables_access.h:692
static bool open_service(ccf::kv::Tx &tx)
Definition internal_tables_access.h:629
static void init_configuration(ccf::kv::Tx &tx, const ServiceConfiguration &configuration)
Definition internal_tables_access.h:888
static std::map< NodeId, NodeInfo > get_trusted_nodes(ccf::kv::ReadOnlyTx &tx)
Definition internal_tables_access.h:435
static UserId add_user(ccf::kv::Tx &tx, const NewUser &new_user)
Definition internal_tables_access.h:385
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:785
static bool remove_member(ccf::kv::Tx &tx, const MemberId &member_id)
Definition internal_tables_access.h:279
static MemberId add_member(ccf::kv::Tx &tx, const NewMember &member_pub_info)
Definition internal_tables_access.h:183
static void set_constitution(ccf::kv::Tx &tx, const std::string &constitution)
Definition internal_tables_access.h:731
static void trust_node_uvm_endorsements(ccf::kv::Tx &tx, const std::optional< pal::UVMEndorsements > &uvm_endorsements)
Definition internal_tables_access.h:805
static bool is_recovery_participant(ccf::kv::ReadOnlyTx &tx, const MemberId &member_id)
Definition internal_tables_access.h:85
static std::map< MemberId, ccf::crypto::Pem > get_active_recovery_owners(ccf::kv::ReadOnlyTx &tx)
Definition internal_tables_access.h:151
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:464
static bool is_active_member(ccf::kv::ReadOnlyTx &tx, const MemberId &member_id)
Definition internal_tables_access.h:106
static void trust_node_measurement(ccf::kv::Tx &tx, const pal::PlatformAttestationMeasurement &node_measurement, const QuoteFormat &platform)
Definition internal_tables_access.h:737
static void retire_active_nodes(ccf::kv::Tx &tx)
Definition internal_tables_access.h:56
static void add_node(ccf::kv::Tx &tx, const NodeId &id, const NodeInfo &node_info)
Definition internal_tables_access.h:428
static void trust_node_virtual_host_data(ccf::kv::Tx &tx, const HostData &host_data)
Definition internal_tables_access.h:777
static bool activate_member(ccf::kv::Tx &tx, const MemberId &member_id)
Definition internal_tables_access.h:260
static void trust_node_snp_tcb_version(ccf::kv::Tx &tx, pal::snp::Attestation &attestation)
Definition internal_tables_access.h:850
static void trust_node(ccf::kv::Tx &tx, const NodeId &node_id, ccf::kv::Version latest_ledger_secret_seqno)
Definition internal_tables_access.h:706
static bool is_recovery_participant_or_owner(ccf::kv::ReadOnlyTx &tx, const MemberId &member_id)
Definition internal_tables_access.h:75
InternalTablesAccess()=delete
static size_t get_recovery_threshold(ccf::kv::ReadOnlyTx &tx)
Definition internal_tables_access.h:973
static void remove_user(ccf::kv::Tx &tx, const UserId &user_id)
Definition internal_tables_access.h:418
virtual std::vector< uint8_t > public_key_der() const override
Definition key_pair.cpp:124
Definition sha256_hash.h:16
std::string hex_str() const
Definition sha256_hash.cpp:61
M::ReadOnlyHandle * ro(M &m)
Definition tx.h:169
M::Handle * rw(M &m)
Definition tx.h:212
M::WriteOnlyHandle * wo(M &m)
Definition tx.h:233
#define LOG_INFO_FMT
Definition logger.h:362
#define LOG_TRACE_FMT
Definition logger.h:356
#define LOG_FAIL_FMT
Definition logger.h:363
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:164
uint64_t Version
Definition version.h:8
std::string VirtualAttestationMeasurement
Definition measurement.h:96
Definition app_interface.h:14
@ WAITING_FOR_RECOVERY_SHARES
ccf::TxID next_tx_if_recovery(ccf::TxID txid)
Definition internal_tables_access.h:37
ccf::TxID previous_tx_if_recovery(ccf::TxID txid)
Definition internal_tables_access.h:32
QuoteFormat
Definition quote_info.h: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 cose_sign.h:167
Definition measurement.h:17
Definition attestation_sev_snp.h:361
TcbVersionRaw reported_tcb
Definition attestation_sev_snp.h:380
uint32_t version
Definition attestation_sev_snp.h:362
uint8_t cpuid_fam_id
Definition attestation_sev_snp.h:381
uint8_t cpuid_step
Definition attestation_sev_snp.h:383
uint8_t cpuid_mod_id
Definition attestation_sev_snp.h:382
Definition sev_snp_cpuid.h:21
uint8_t stepping
Definition sev_snp_cpuid.h:22
TcbVersionPolicy to_policy(ProductName product) const
Definition attestation_sev_snp.h:237