58#ifdef USE_NULL_ENCRYPTOR
59# include "kv/test/null_encryptor.h"
64#define FMT_HEADER_ONLY
65#include <fmt/format.h>
66#include <nlohmann/json.hpp>
68#include <unordered_set>
98 std::vector<ccf::crypto::SubjectAltName> subject_alt_names = {};
100 std::shared_ptr<ccf::crypto::KeyPair_OpenSSL> node_sign_kp;
102 std::shared_ptr<ccf::crypto::RSAKeyPair> node_encrypt_kp;
104 std::optional<ccf::crypto::Pem> endorsed_node_cert = std::nullopt;
107 std::optional<pal::snp::TcbVersionRaw> snp_tcb_version = std::nullopt;
109 std::optional<pal::UVMEndorsements> snp_uvm_endorsements = std::nullopt;
110 std::vector<uint8_t> startup_snapshot;
111 std::shared_ptr<QuoteEndorsementsClient> quote_endorsements_client =
114 std::atomic<bool> stop_noticed =
false;
120 View create_view_ = 0,
121 bool create_consortium_ =
true) :
123 create_view(create_view_),
124 create_consortium(create_consortium_)
128 bool create_consortium;
137 size_t sig_tx_interval;
138 size_t sig_ms_interval;
142 std::shared_ptr<ccf::kv::Consensus>
consensus;
143 std::shared_ptr<RPCMap> rpc_map;
144 std::shared_ptr<indexing::Indexer> indexer;
145 std::shared_ptr<NodeToNode> n2n_channels;
146 std::shared_ptr<Forwarder<NodeToNode>> cmd_forwarder;
147 std::shared_ptr<RPCSessions> rpcsessions;
149 std::shared_ptr<ccf::kv::TxHistory> history;
150 std::shared_ptr<ccf::kv::AbstractTxEncryptor> encryptor;
153 std::shared_ptr<Snapshotter> snapshotter;
158 std::shared_ptr<ccf::kv::Store> recovery_store;
162 std::vector<ccf::kv::Version> view_history;
166 static const size_t recovery_batch_size = 100;
171 std::shared_ptr<JwtKeyAutoRefresh> jwt_key_auto_refresh;
173 std::unique_ptr<StartupSnapshotInfo> startup_snapshot_info =
nullptr;
179 std::map<NodeInfoNetwork::RpcInterfaceID, std::shared_ptr<ACMEClient>>
183 std::shared_ptr<ACMEChallengeHandler>>
184 acme_challenge_handlers;
185 size_t num_acme_interfaces = 0;
187 std::shared_ptr<ccf::kv::AbstractTxEncryptor> make_encryptor()
189#ifdef USE_NULL_ENCRYPTOR
190 return std::make_shared<ccf::kv::NullTxEncryptor>();
197 void initialise_startup_snapshot(
bool recovery =
false)
199 std::shared_ptr<ccf::kv::Store> snapshot_store;
204 auto snapshot_history = std::make_shared<MerkleTxHistory>(
205 *snapshot_store.get(),
212 auto snapshot_encryptor = make_encryptor();
214 snapshot_store->set_history(snapshot_history);
215 snapshot_store->set_encryptor(snapshot_encryptor);
219 snapshot_store = network.
tables;
223 startup_snapshot_info = initialise_from_snapshot(
225 std::move(startup_snapshot),
231 startup_seqno = startup_snapshot_info->seqno;
232 last_recovered_idx = startup_seqno;
233 last_recovered_signed_idx = last_recovered_idx;
240 std::shared_ptr<RPCSessions> rpcsessions,
246 node_encrypt_kp(
ccf::crypto::make_rsa_key_pair()),
247 writer_factory(writer_factory),
248 to_host(writer_factory.create_writer_to_outside()),
250 rpcsessions(rpcsessions),
251 share_manager(network.ledger_secrets)
257 const std::vector<uint8_t>& expected_node_public_key_der,
261 tx, quote_info_, expected_node_public_key_der, measurement);
269 std::shared_ptr<RPCMap> rpc_map_,
270 std::shared_ptr<AbstractRPCResponder> rpc_sessions_,
271 std::shared_ptr<indexing::Indexer> indexer_,
272 size_t sig_tx_interval_,
273 size_t sig_ms_interval_)
275 std::lock_guard<pal::Mutex> guard(lock);
278 consensus_config = consensus_config_;
281 sig_tx_interval = sig_tx_interval_;
282 sig_ms_interval = sig_ms_interval_;
284 n2n_channels = std::make_shared<NodeToNodeChannelManager>(writer_factory);
286 cmd_forwarder = std::make_shared<Forwarder<NodeToNode>>(
287 rpc_sessions_, n2n_channels, rpc_map);
291 for (
auto& [actor, fe] : rpc_map->frontends())
293 fe->set_sig_intervals(sig_tx_interval, sig_ms_interval);
294 fe->set_cmd_forwarder(cmd_forwarder);
304 if (measurement.has_value())
306 node_measurement = measurement.value();
310 throw std::logic_error(
"Failed to extract code id from quote");
313 auto snp_attestation =
315 if (snp_attestation.has_value())
317 snp_tcb_version = snp_attestation.value().reported_tcb;
324 "Security policy not set, skipping check against attestation host "
330 if (!quoted_digest.has_value())
332 throw std::logic_error(
"Unable to find host data in attestation");
335 auto const& security_policy =
338 auto security_policy_digest =
342 if (security_policy_digest != quoted_digest.value())
344 throw std::logic_error(fmt::format(
345 "Digest of decoded security policy \"{}\" {} does not match "
346 "attestation host data {}",
348 security_policy_digest.hex_str(),
349 quoted_digest.value().hex_str()));
352 "Successfully verified attested security policy {}",
353 security_policy_digest);
361 "UVM endorsements not set, skipping check against attestation "
377 uvm_endorsements_raw, node_measurement);
380 "Successfully verified attested UVM endorsements: {}",
381 snp_uvm_endorsements->to_str());
383 catch (
const std::exception& e)
385 throw std::logic_error(
386 fmt::format(
"Error verifying UVM endorsements: {}", e.what()));
395 create_and_send_boot_request(
396 aft::starting_view_change,
true );
401 if (!startup_snapshot.empty())
403 initialise_startup_snapshot();
412 setup_recovery_hook();
413 if (!startup_snapshot.empty())
415 initialise_startup_snapshot(
true);
416 snapshotter->set_last_snapshot_idx(last_recovered_idx);
425 throw std::logic_error(
426 fmt::format(
"Node was launched in unknown mode {}", start_type));
433 auto fetch_endorsements = [
this](
436 EndorsementEndpointsConfiguration&
440 this->quote_info = qi;
452 const auto j = nlohmann::json::parse(raw_data);
453 const auto aci_endorsements =
459 quote_info.
quote.data());
460 const auto reported_tcb = quote->reported_tcb;
464 const uint8_t* tcb_begin =
465 reinterpret_cast<const uint8_t*
>(&reported_tcb);
466 const std::span<const uint8_t> tcb_bytes{
467 tcb_begin, tcb_begin +
sizeof(reported_tcb)};
468 auto tcb_as_hex = fmt::format(
469 "{:02x}", fmt::join(tcb_bytes.rbegin(), tcb_bytes.rend(),
""));
470 ccf::nonstd::to_upper(tcb_as_hex);
472 if (tcb_as_hex == aci_endorsements.tcbm)
475 "Using SNP endorsements loaded from file, endorsing TCB {}",
479 endorsements_pem.insert(
480 endorsements_pem.end(),
481 aci_endorsements.vcek_cert.begin(),
482 aci_endorsements.vcek_cert.end());
483 endorsements_pem.insert(
484 endorsements_pem.end(),
485 aci_endorsements.certificate_chain.begin(),
486 aci_endorsements.certificate_chain.end());
493 catch (
const std::exception& e)
502 "SNP endorsements loaded from disk ({}) contained tcbm {}, "
503 "which does not match reported TCB of current attestation "
505 "Falling back to fetching fresh endorsements from server.",
507 aci_endorsements.tcbm,
511 catch (
const std::exception& e)
514 "Error attempting to use SNP endorsements from file: {}",
521 throw std::runtime_error(
522 "One or more SNP endorsements servers must be specified to fetch "
523 "the collateral for the attestation");
526 quote_endorsements_client = std::make_shared<QuoteEndorsementsClient>(
529 [
this](std::vector<uint8_t>&& endorsements) {
530 std::lock_guard<pal::Mutex> guard(lock);
536 catch (
const std::exception& e)
541 quote_endorsements_client.reset();
544 quote_endorsements_client->fetch_endorsements();
554 throw std::runtime_error(
555 "SGX quote generation should have already fetched endorsements");
574 std::vector<uint8_t>&& startup_snapshot_)
576 std::lock_guard<pal::Mutex> guard(lock);
578 start_type = start_type_;
581 startup_snapshot = std::move(startup_snapshot_);
582 subject_alt_names = get_subject_alternative_names();
585 self_signed_node_cert = create_self_signed_cert(
592 accept_node_tls_connections();
601 setup_acme_clients();
609 network.
identity = std::make_unique<ccf::NetworkIdentity>(
620 history->set_service_signing_identity(
633 return {self_signed_node_cert, network.
identity->cert};
638 return {self_signed_node_cert, {}};
644 throw std::logic_error(
645 "Recovery requires the certificate of the previous service "
652 network.
identity = std::make_unique<ccf::NetworkIdentity>(
659 return {self_signed_node_cert, network.
identity->cert};
663 throw std::logic_error(
664 fmt::format(
"Node was started in unknown mode {}", start_type));
677 auto network_ca = std::make_shared<::tls::CA>(std::string(
680 auto join_client_cert = std::make_unique<::tls::Cert>(
682 self_signed_node_cert,
683 node_sign_kp->private_key_pem(),
689 auto join_client = rpcsessions->create_client(
690 std::move(join_client_cert),
691 rpcsessions->get_app_protocol_main_interface());
693 auto [target_host, target_port] =
696 join_client->connect(
702 std::vector<uint8_t>&& data) {
703 std::lock_guard<pal::Mutex> guard(lock);
709 if (is_http_status_client_error(status))
711 auto error_msg = fmt::format(
712 "Join request to {} returned {} Bad Request: {}. Shutting "
713 "down node gracefully.",
716 std::string(data.begin(), data.end()));
719 AdminMessage::fatal_error_msg, to_host, error_msg);
721 else if (status != HTTP_STATUS_OK)
723 const auto& location = headers.find(http::headers::LOCATION);
726 (status == HTTP_STATUS_PERMANENT_REDIRECT ||
727 status == HTTP_STATUS_TEMPORARY_REDIRECT) &&
728 location != headers.end())
732 make_net_address(url.host, url.port);
733 LOG_INFO_FMT(
"Target node redirected to {}", location->second);
738 "An error occurred while joining the network: {} {}{}",
740 ccf::http_status_str(status),
743 fmt::format(
" '{}'", std::string(data.begin(), data.end())));
748 auto j = nlohmann::json::parse(data);
755 catch (
const std::exception& e)
758 "An error occurred while parsing the join network response");
760 "An error occurred while parsing the join network response: {}",
770 throw std::logic_error(
"Expected network info in join response");
773 network.
identity = std::make_unique<ccf::NetworkIdentity>(
775 seal_ledger_secret(*resp.
network_info->ledger_secrets.rbegin());
779 history->set_service_signing_identity(
785 if (!resp.
network_info->endorsed_certificate.has_value())
788 throw std::logic_error(
789 "Expected endorsed certificate in join response");
791 n2n_channels_cert = resp.
network_info->endorsed_certificate.value();
803 last_recovered_signed_idx =
805 setup_recovery_hook();
806 snapshotter->set_snapshot_generation(
false);
810 std::vector<ccf::kv::Version> view_history_ = {};
811 if (startup_snapshot_info)
816 deserialise_snapshot(
818 startup_snapshot_info->raw,
824 for (
auto& hook : hooks)
829 auto tx = network.
tables->create_read_only_tx();
831 auto sig = signatures->get();
832 if (!sig.has_value())
834 throw std::logic_error(
835 fmt::format(
"No signatures found after applying snapshot"));
844 startup_snapshot_info.reset();
848 "Joiner successfully resumed from snapshot at seqno {} and "
850 network.
tables->current_version(),
855 network.
tables->current_version(),
858 last_recovered_signed_idx);
860 snapshotter->set_last_snapshot_idx(
861 network.
tables->current_version());
862 history->start_signature_emit_timer();
876 "Node has now joined the network as node {}: {}",
878 (resp.
network_info->public_only ?
"public only" :
"all domains"));
883 "Node {} is waiting for votes of members to be trusted", self);
886 [
this](
const std::string& error_msg) {
887 std::lock_guard<pal::Mutex> guard(lock);
888 auto long_error_msg = fmt::format(
889 "Early error when joining existing network at {}: {}. Shutting "
890 "down node gracefully...",
895 AdminMessage::fatal_error_msg, to_host, long_error_msg);
912 const auto body = nlohmann::json(join_params).dump();
919 http::headers::CONTENT_TYPE, http::headervalues::contenttype::JSON);
922 join_client->send_request(std::move(r));
927 std::lock_guard<pal::Mutex> guard(lock);
935 auto timer_msg = std::make_unique<::threading::Tmsg<NodeStateMsg>>(
936 [](std::unique_ptr<::threading::Tmsg<NodeStateMsg>> msg) {
937 std::lock_guard<pal::Mutex> guard(msg->data.self.lock);
940 msg->data.self.initiate_join_unsafe();
941 auto delay = std::chrono::milliseconds(
942 msg->data.self.config.join.retry_timeout);
945 std::move(msg), delay);
959 "JWT key auto-refresh: consensus not initialized, not starting "
963 jwt_key_auto_refresh = std::make_shared<JwtKeyAutoRefresh>(
970 self_signed_node_cert);
971 jwt_key_auto_refresh->start();
973 network.
tables->set_map_hook(
977 jwt_key_auto_refresh->schedule_once();
978 return ccf::kv::ConsensusHookPtr(nullptr);
984 return jwt_key_auto_refresh->get_attempts();
994 throw std::logic_error(fmt::format(
995 "Node should be in state {} to start reading ledger",
1001 read_ledger_entries(
1002 last_recovered_idx + 1, last_recovered_idx + recovery_batch_size);
1007 std::lock_guard<pal::Mutex> guard(lock);
1011 auto data = entries.data();
1012 auto size = entries.size();
1025 "Deserialising public ledger entry #{} [{} bytes]",
1034 auto r = network.
tables->deserialize(entry,
true);
1035 result = r->apply();
1039 "Failed to deserialise public ledger entry: {}", result);
1043 ++last_recovered_idx;
1046 for (
auto& hook : r->get_hooks())
1051 catch (
const std::exception& e)
1054 "Failed to deserialise public ledger entry: {}", e.what());
1063 network.
tables->compact(last_recovered_idx);
1064 auto tx = network.
tables->create_read_only_tx();
1065 auto last_sig = tx.ro(network.
signatures)->get();
1067 if (!last_sig.has_value())
1069 throw std::logic_error(
"Signature missing");
1073 "Read signature at {} for view {}",
1083 const auto view_start_idx =
1084 view_history.empty() ? 1 : last_recovered_signed_idx + 1;
1086 last_sig->view >= 0,
1087 "last_sig->view is invalid, {}",
1089 for (
auto i = view_history.size();
1090 i < static_cast<size_t>(last_sig->view);
1093 view_history.push_back(view_start_idx);
1095 last_recovered_signed_idx = last_recovered_idx;
1099 read_ledger_entries(
1100 last_recovered_idx + 1, last_recovered_idx + recovery_batch_size);
1105 std::lock_guard<pal::Mutex> guard(lock);
1107 history->start_signature_emit_timer();
1113 std::lock_guard<pal::Mutex> guard(lock);
1115 history->start_signature_emit_timer();
1128 const auto last_recovered_term = view_history.size();
1129 auto new_term = last_recovered_term + aft::starting_view_change;
1130 LOG_INFO_FMT(
"Setting term on public recovery store to {}", new_term);
1133 network.
tables->rollback(
1134 {last_recovered_term, last_recovered_signed_idx}, new_term);
1135 ledger_truncate(last_recovered_signed_idx,
true);
1136 snapshotter->rollback(last_recovered_signed_idx);
1139 "End of public ledger recovery - Truncating ledger to last signed "
1141 last_recovered_term,
1142 last_recovered_signed_idx);
1144 auto tx = network.
tables->create_read_only_tx();
1148 snapshotter->init_after_public_recovery();
1149 snapshotter->set_snapshot_generation(
false);
1157 auto s = ls.value();
1163 throw std::logic_error(
"No signature found after recovery");
1168 if (lcs.has_value())
1174 auto [issuer, subject] = cose::extract_iss_sub_from_sig(cs);
1176 "COSE signature issuer: {}, subject: {}", issuer, subject);
1181 LOG_FAIL_FMT(
"COSE signature decode error: {}", e.what());
1187 LOG_INFO_FMT(
"No COSE signature found after recovery");
1190 history->set_service_signing_identity(
1191 network.
identity->get_key_pair(), cs_cfg);
1199 auto service_config = tx.ro(network.
config)->get();
1209 consensus->force_become_primary(index,
view, view_history, index);
1211 create_and_send_boot_request(
1220 std::lock_guard<pal::Mutex> guard(lock);
1224 "Node in state {} cannot recover private ledger entries", sm.
value());
1228 auto data = entries.data();
1229 auto size = entries.size();
1242 "Deserialising private ledger entry {} [{}]",
1243 last_recovered_idx + 1,
1250 result = recovery_store->deserialize(entry)->apply();
1254 "Failed to deserialise private ledger entry: {}", result);
1257 recovery_store->rollback({0, last_recovered_idx}, 0);
1261 ++last_recovered_idx;
1263 catch (
const std::exception& e)
1266 "Failed to deserialise private ledger entry: {}", e.what());
1273 recovery_store->compact(last_recovered_idx);
1277 if (recovery_store->current_version() == recovery_v)
1279 LOG_INFO_FMT(
"Reached recovery final version at {}", recovery_v);
1284 read_ledger_entries(
1285 last_recovered_idx + 1,
1286 std::min(last_recovered_idx + recovery_batch_size, recovery_v));
1298 "Try end private recovery at {}. Is primary: {}",
1302 if (recovery_v != recovery_store->current_version())
1304 throw std::logic_error(fmt::format(
1305 "Private recovery did not reach public ledger seqno: {}/{}",
1306 recovery_store->current_version(),
1312 if (h->get_replicated_state_root() != recovery_root)
1314 throw std::logic_error(fmt::format(
1315 "Root of public store does not match root of private store at {}",
1319 network.
tables->swap_private_maps(*recovery_store.get());
1320 recovery_store.reset();
1326 snapshotter->set_snapshot_generation(
true);
1332 "Try end private recovery at {}. Trigger service opening",
1335 auto tx = network.
tables->create_tx();
1341 auto active_service = service->get();
1343 if (!active_service.has_value())
1345 throw std::logic_error(fmt::format(
1346 "Error in {}: no value in {}", __func__, Tables::SERVICE));
1350 active_service->status !=
1353 throw std::logic_error(fmt::format(
1354 "Error in {}: current service status is {}",
1356 active_service->status));
1371 tx, *network.
identity->get_key_pair()))
1373 throw std::logic_error(
"Service could not be opened");
1383 throw std::logic_error(
1384 "Could not commit transaction when finishing network recovery");
1387 recovered_encrypted_ledger_secrets.clear();
1399 network.
tables->set_map_hook(
1408 throw std::logic_error(fmt::format(
1409 "Unexpected removal from {} table",
1410 network.encrypted_ledger_secrets.get_name()));
1416 network.
tables->unset_map_hook(
1428 std::lock_guard<pal::Mutex> guard(lock);
1430 if (is_reading_public_ledger())
1432 recover_public_ledger_end_unsafe();
1434 else if (is_reading_private_ledger())
1436 recover_private_ledger_end_unsafe();
1441 "Node in state {} cannot finalise ledger recovery", sm.value());
1451 recovery_store = std::make_shared<ccf::kv::Store>(
1454 auto recovery_history = std::make_shared<MerkleTxHistory>(
1455 *recovery_store.get(),
1462 auto recovery_encryptor = make_encryptor();
1464 recovery_store->set_history(recovery_history);
1465 recovery_store->set_encryptor(recovery_encryptor);
1468 recovery_v = network.tables->current_version();
1472 if (startup_snapshot_info)
1474 std::vector<ccf::kv::Version> view_history_;
1476 deserialise_snapshot(
1478 startup_snapshot_info->raw,
1482 config.recover.previous_service_identity);
1483 startup_snapshot_info.reset();
1487 "Recovery store successfully setup at {}. Target recovery seqno: {}",
1488 recovery_store->current_version(),
1494 share_manager.shuffle_recovery_shares(tx);
1502 throw std::logic_error(
"Could not cast tx to CommittableTx");
1511 if (committable_tx ==
nullptr)
1513 throw std::logic_error(
"Could not cast tx to CommittableTx");
1515 committable_tx->set_tx_flag(
1521 const std::optional<std::vector<std::string>>& interfaces =
1522 std::nullopt)
override
1524 if (!network.identity)
1529 num_acme_interfaces = 0;
1531 for (
const auto& [iname, interface] : config.network.rpc_interfaces)
1534 !interface.endorsement ||
1536 !interface.endorsement->acme_configuration)
1541 num_acme_interfaces++;
1545 std::find(interfaces->begin(), interfaces->end(), iname) !=
1548 auto challenge_frontend = find_acme_challenge_frontend();
1550 const std::string& cfg_name =
1551 *interface.endorsement->acme_configuration;
1552 auto cit = config.network.acme->configurations.find(cfg_name);
1553 if (cit == config.network.acme->configurations.end())
1555 LOG_INFO_FMT(
"Unknown ACME configuration '{}'", cfg_name);
1560 !cit->second.directory_url.empty() &&
1561 acme_clients.find(cfg_name) == acme_clients.end())
1563 const auto& cfg = cit->second;
1565 auto client = std::make_shared<ACMEClient>(
1574 auto chit = acme_challenge_handlers.find(iname);
1575 if (chit != acme_challenge_handlers.end())
1577 client->install_custom_challenge_handler(chit->second);
1580 acme_clients.emplace(cfg_name,
client);
1583 auto client = acme_clients[cfg_name];
1587 make_key_pair(network.identity->priv_key),
true);
1594 const std::vector<std::string>& args,
1595 const std::vector<uint8_t>& input)
override
1598 nlohmann::json j = msg;
1599 auto json = j.dump();
1601 "Triggering host process launch: {} size={}",
json, input.size());
1603 AppMessage::launch_host_process, to_host,
json, input);
1610 std::lock_guard<pal::Mutex> guard(lock);
1612 auto service = tx.
rw<
Service>(Tables::SERVICE);
1613 auto service_info = service->get();
1614 if (!service_info.has_value())
1616 throw std::logic_error(
1617 "Service information cannot be found to transition service to "
1628 "Service in state {} is already open", service_info->status);
1634 const auto prev_ident =
1637 if (!prev_ident.has_value() || !identities.
previous.has_value())
1639 throw std::logic_error(
1640 "Recovery with service certificates requires both, a previous "
1641 "service identity written to the KV during recovery genesis and a "
1642 "transition_service_to_open proposal that contains previous and "
1643 "next service certificates");
1648 if (prev_ident.value() != from_proposal)
1650 throw std::logic_error(fmt::format(
1651 "Previous service identity does not match.\nActual:\n{}\nIn "
1654 from_proposal.
str()));
1658 if (identities.
next != service_info->cert)
1660 throw std::logic_error(fmt::format(
1661 "Service identity mismatch: the next service identity in the "
1662 "transition_service_to_open proposal does not match the current "
1663 "service identity:\nNext:\n{}\nCurrent:\n{}",
1665 service_info->cert.str()));
1668 service_info->previous_service_identity_version =
1669 service->get_version_of_previous_write();
1671 if (is_part_of_public_network())
1677 service->put(service_info.value());
1678 if (config.recover.previous_sealed_ledger_secret_location.has_value())
1682 auto unsealed_ls = unseal_ledger_secret();
1683 LOG_INFO_FMT(
"Unsealed ledger secret, initiating private recovery");
1684 initiate_private_recovery_unsafe(tx, unsealed_ls);
1693 else if (is_part_of_network())
1700 share_manager.issue_recovery_shares(tx);
1702 catch (
const std::logic_error& e)
1704 throw std::logic_error(
1705 fmt::format(
"Failed to issue recovery shares: {}", e.what()));
1710 tx, *network.identity->get_key_pair());
1711 trigger_snapshot(tx);
1716 throw std::logic_error(
1717 fmt::format(
"Node in state {} cannot open service", sm.value()));
1726 const std::optional<LedgerSecretPtr>& unsealed_ledger_secret =
1731 share_manager.restore_recovery_shares_info(
1732 tx, recovered_encrypted_ledger_secrets, unsealed_ledger_secret);
1738 tx.
wo(network.secrets),
1739 std::move(recovered_ledger_secrets));
1744 const std::optional<LedgerSecretPtr>& unsealed_ledger_secret =
1745 std::nullopt)
override
1747 std::lock_guard<pal::Mutex> guard(lock);
1748 initiate_private_recovery_unsafe(tx, unsealed_ledger_secret);
1754 void tick(std::chrono::milliseconds elapsed)
1768 const auto tx_id =
consensus->get_committed_txid();
1769 indexer->update_strategies(elapsed, {tx_id.first, tx_id.second});
1772 n2n_channels->tick(elapsed);
1790 stop_noticed =
true;
1795 return stop_noticed;
1800 auto [msg_type, from, payload] =
1801 ringbuffer::read_message<node_inbound>(data, size);
1803 auto payload_data = payload.data;
1804 auto payload_size = payload.size;
1808 cmd_forwarder->recv_message(from, payload_data, payload_size);
1819 "Ignoring node msg received too early - current state is {}",
1828 n2n_channels->recv_channel_message(
1829 from, payload_data, payload_size);
1835 consensus->recv_message(from, payload_data, payload_size);
1841 LOG_FAIL_FMT(
"Unknown node message type: {}", msg_type);
1896 const auto val = sm.value();
1904 std::lock_guard<pal::Mutex> guard(lock);
1905 auto s = sm.value();
1908 return {s, recovery_v, recovery_store->current_version()};
1912 return {s, std::nullopt, std::nullopt};
1918 std::lock_guard<pal::Mutex> guard(lock);
1930 !service_status.has_value() ||
1933 LOG_FAIL_FMT(
"Cannot rekey ledger while the service is not open");
1941 share_manager.issue_recovery_shares(tx, new_ledger_secret);
1944 tx.
wo(network.secrets),
1945 std::move(new_ledger_secret));
1957 std::lock_guard<pal::Mutex> guard(lock);
1958 return startup_seqno;
1963 return rpcsessions->get_session_metrics();
1968 std::lock_guard<pal::Mutex> guard(lock);
1969 return self_signed_node_cert;
1974 if (history ==
nullptr)
1976 throw std::logic_error(
1977 "Attempting to access COSE signatures config before history has been "
1981 return history->get_cose_signatures_config();
1985 bool is_ip(
const std::string_view& hostname)
1993 const auto final_component =
1994 ccf::nonstd::split(ccf::nonstd::split(hostname,
".").back(),
":")
1996 if (final_component.empty())
1998 throw std::runtime_error(fmt::format(
1999 "{} has a trailing period, is not a valid hostname", hostname));
2001 for (
const auto c : final_component)
2003 if (c <
'0' || c >
'9')
2012 std::vector<ccf::crypto::SubjectAltName> get_subject_alternative_names()
2017 if (!config.node_certificate.subject_alt_names.empty())
2019 return ccf::crypto::sans_from_string_list(
2020 config.node_certificate.subject_alt_names);
2026 std::vector<ccf::crypto::SubjectAltName> sans;
2027 for (
const auto& [_, interface] : config.network.rpc_interfaces)
2029 auto host = split_net_address(interface.published_address).first;
2030 sans.push_back({
host, is_ip(
host)});
2036 void accept_node_tls_connections()
2040 rpcsessions->set_node_cert(
2041 self_signed_node_cert, node_sign_kp->private_key_pem());
2045 void accept_network_tls_connections()
2050 endorsed_node_cert.has_value(),
2051 "Node certificate should be endorsed before accepting endorsed "
2054 rpcsessions->set_network_cert(
2055 endorsed_node_cert.value(), node_sign_kp->private_key_pem());
2061 auto fe = rpc_map->find(actor);
2062 if (!fe.has_value())
2064 throw std::logic_error(
2065 fmt::format(
"Cannot find {} frontend", (
int)actor));
2072 find_frontend(actor)->open();
2075 void open_user_frontend()
2080 bool is_member_frontend_open_unsafe()
2085 bool is_member_frontend_open()
override
2087 std::lock_guard<pal::Mutex> guard(lock);
2088 return is_member_frontend_open_unsafe();
2091 bool is_user_frontend_open()
override
2093 std::lock_guard<pal::Mutex> guard(lock);
2097 std::shared_ptr<ACMERpcFrontend> find_acme_challenge_frontend()
2100 if (!acme_challenge_opt)
2102 throw std::runtime_error(
"Missing ACME challenge frontend");
2104 return std::static_pointer_cast<ACMERpcFrontend>(*acme_challenge_opt);
2107 void open_acme_challenge_frontend()
2109 if (config.network.acme && !config.network.acme->configurations.empty())
2119 std::vector<uint8_t> serialize_create_request(
2120 View create_view,
bool create_consortium =
true)
2122 CreateNetworkNodeToNode::In create_params;
2126 if (create_consortium)
2128 create_params.genesis_info = config.start;
2131 create_params.node_id = self;
2132 create_params.certificate_signing_request = node_sign_kp->create_csr(
2133 config.node_certificate.subject_name, subject_alt_names);
2134 create_params.node_endorsed_certificate =
2135 ccf::crypto::create_endorsed_cert(
2136 create_params.certificate_signing_request,
2137 config.startup_host_time,
2138 config.node_certificate.initial_validity_days,
2139 network.identity->priv_key,
2140 network.identity->cert);
2144 history->set_endorsed_certificate(
2145 create_params.node_endorsed_certificate);
2147 create_params.public_key = node_sign_kp->public_key_pem();
2148 create_params.service_cert = network.identity->cert;
2149 create_params.quote_info = quote_info;
2150 create_params.public_encryption_key = node_encrypt_kp->public_key_pem();
2151 create_params.measurement = node_measurement;
2152 create_params.snp_uvm_endorsements = snp_uvm_endorsements;
2153 create_params.snp_security_policy =
2154 config.attestation.environment.security_policy;
2156 create_params.node_info_network = config.network;
2157 create_params.node_data = config.node_data;
2158 create_params.service_data = config.service_data;
2159 create_params.create_txid = {create_view, last_recovered_signed_idx + 1};
2161 const auto body = nlohmann::json(create_params).dump();
2166 ccf::http::headers::CONTENT_TYPE,
2167 ccf::http::headervalues::contenttype::JSON);
2169 request.set_body(body);
2171 return request.build_request();
2174 bool extract_create_result(
const std::shared_ptr<RpcContext>& ctx)
2182 const auto status = ctx->get_response_status();
2183 const auto& raw_body = ctx->get_response_body();
2184 if (status != HTTP_STATUS_OK)
2187 "Create response is error: {} {}\n{}",
2190 std::string(raw_body.begin(), raw_body.end()));
2194 const auto body = nlohmann::json::parse(raw_body);
2195 if (!body.is_boolean())
2197 LOG_FAIL_FMT(
"Expected boolean body in create response");
2199 "Expected boolean body in create response: {}", body.dump());
2206 bool send_create_request(
const std::vector<uint8_t>& packed)
2208 auto node_session = std::make_shared<SessionContext>(
2209 InvalidSessionId, self_signed_node_cert.raw());
2212 std::shared_ptr<ccf::RpcHandler> search =
2213 ::http::fetch_rpc_handler(ctx, this->rpc_map);
2215 search->process(ctx);
2217 return extract_create_result(ctx);
2220 void create_and_send_boot_request(
2221 View create_view,
bool create_consortium =
true)
2225 auto msg = std::make_unique<::threading::Tmsg<NodeStateMsg>>(
2226 [](std::unique_ptr<::threading::Tmsg<NodeStateMsg>> msg) {
2227 if (!msg->data.self.send_create_request(
2228 msg->data.self.serialize_create_request(
2229 msg->data.create_view, msg->data.create_consortium)))
2231 throw std::runtime_error(
2232 "Service creation request could not be committed");
2234 if (msg->data.create_consortium)
2236 msg->data.self.advance_part_of_network();
2240 msg->data.self.advance_part_of_public_network();
2251 void begin_private_recovery()
2257 setup_private_recovery_store();
2259 reset_recovery_hook();
2260 setup_one_off_secret_hook();
2264 last_recovered_idx = recovery_store->current_version();
2265 read_ledger_entries(
2266 last_recovered_idx + 1, last_recovered_idx + recovery_batch_size);
2269 void setup_basic_hooks()
2271 network.tables->set_map_hook(
2272 network.secrets.get_name(),
2273 network.secrets.wrap_map_hook(
2277 if (!is_part_of_network())
2280 return ccf::kv::ConsensusHookPtr(nullptr);
2283 const auto& ledger_secrets_for_nodes = w;
2284 if (!ledger_secrets_for_nodes.has_value())
2286 throw std::logic_error(fmt::format(
2287 "Unexpected removal from {} table",
2288 network.secrets.get_name()));
2291 for (
const auto& [node_id, encrypted_ledger_secrets] :
2292 ledger_secrets_for_nodes.value())
2294 if (node_id != self)
2300 for (
const auto& encrypted_ledger_secret :
2301 encrypted_ledger_secrets)
2304 node_encrypt_kp, encrypted_ledger_secret.encrypted_secret);
2309 auto ledger_secret = std::make_shared<LedgerSecret>(
2310 std::move(plain_ledger_secret), hook_version);
2311 seal_ledger_secret(hook_version + 1, ledger_secret);
2312 network.ledger_secrets->set_secret(
2313 hook_version + 1, std::move(ledger_secret));
2320 network.tables->set_global_hook(
2321 network.secrets.get_name(),
2322 network.secrets.wrap_commit_hook([
this](
2326 if (!is_part_of_public_network())
2331 const auto& ledger_secrets_for_nodes = w;
2332 if (!ledger_secrets_for_nodes.has_value())
2334 throw std::logic_error(fmt::format(
2335 "Unexpected removal from {} table", network.secrets.get_name()));
2338 for (
const auto& [node_id, encrypted_ledger_secrets] :
2339 ledger_secrets_for_nodes.value())
2341 if (node_id != self)
2348 for (
const auto& encrypted_ledger_secret : encrypted_ledger_secrets)
2353 if (!encrypted_ledger_secret.version.has_value())
2355 throw std::logic_error(fmt::format(
2356 "Commit hook at seqno {} for table {}: no version for "
2357 "encrypted ledger secret",
2359 network.secrets.get_name()));
2363 node_encrypt_kp, encrypted_ledger_secret.encrypted_secret);
2365 restored_ledger_secrets.emplace(
2366 encrypted_ledger_secret.version.value(),
2367 std::make_shared<LedgerSecret>(
2368 std::move(plain_ledger_secret),
2369 encrypted_ledger_secret.previous_secret_stored_version));
2372 if (!restored_ledger_secrets.empty())
2376 network.ledger_secrets->restore_historical(
2377 std::move(restored_ledger_secrets));
2378 begin_private_recovery();
2384 "Found no ledger secrets for this node ({}) in global commit hook "
2387 network.secrets.get_name(),
2391 network.tables->set_global_hook(
2392 network.nodes.get_name(),
2393 network.nodes.wrap_commit_hook(
2395 std::vector<NodeId> retired_committed_nodes;
2396 for (
const auto& [node_id, node_info] : w)
2398 if (node_info.has_value() && node_info->retired_committed)
2400 retired_committed_nodes.push_back(node_id);
2404 hook_version, retired_committed_nodes);
2413 network.tables->set_map_hook(
2414 network.node_endorsed_certificates.get_name(),
2415 network.node_endorsed_certificates.wrap_map_hook(
2421 "[local] node_endorsed_certificates local hook at version {}, "
2425 for (
auto const& [node_id, endorsed_certificate] : w)
2427 if (node_id != self)
2430 "[local] Ignoring endorsed certificate for other node {}",
2435 if (!endorsed_certificate.has_value())
2438 "[local] Endorsed cert for self ({}) has been deleted", self);
2439 throw std::logic_error(fmt::format(
2440 "Could not find endorsed node certificate for {}", self));
2443 std::lock_guard<pal::Mutex> guard(lock);
2445 if (endorsed_node_cert.has_value())
2448 "[local] Previous endorsed node cert was:\n{}",
2449 endorsed_node_cert->str());
2452 endorsed_node_cert = endorsed_certificate.value();
2454 "[local] Under lock, setting endorsed node cert to:\n{}",
2455 endorsed_node_cert->str());
2456 history->set_endorsed_certificate(endorsed_node_cert.value());
2457 n2n_channels->set_endorsed_node_cert(endorsed_node_cert.value());
2463 network.tables->set_global_hook(
2464 network.node_endorsed_certificates.get_name(),
2465 network.node_endorsed_certificates.wrap_commit_hook(
2470 "[global] node_endorsed_certificates global hook at version {}, "
2474 for (
auto const& [node_id, endorsed_certificate] : w)
2476 if (node_id != self)
2479 "[global] Ignoring endorsed certificate for other node {}",
2484 if (!endorsed_certificate.has_value())
2487 "[global] Endorsed cert for self ({}) has been deleted",
2489 throw std::logic_error(fmt::format(
2490 "Could not find endorsed node certificate for {}", self));
2493 std::lock_guard<pal::Mutex> guard(lock);
2495 LOG_INFO_FMT(
"[global] Accepting network connections");
2496 accept_network_tls_connections();
2498 if (is_member_frontend_open_unsafe())
2506 auto [valid_from, valid_to] =
2508 ->validity_period();
2510 "[global] Member frontend is open, so refreshing self-signed "
2513 "[global] Previously:\n{}", self_signed_node_cert.str());
2514 self_signed_node_cert = create_self_signed_cert(
2516 config.node_certificate.subject_name,
2520 LOG_INFO_FMT(
"[global] Now:\n{}", self_signed_node_cert.str());
2523 accept_node_tls_connections();
2529 "[global] Self-signed node cert remains:\n{}",
2530 self_signed_node_cert.str());
2538 network.tables->set_global_hook(
2539 network.service.get_name(),
2540 network.service.wrap_commit_hook(
2544 throw std::logic_error(
"Unexpected deletion in service value");
2550 auto current_pubk_pem =
2553 if (hook_pubk_pem != current_pubk_pem)
2556 "Ignoring historical service open at seqno {} for {}",
2563 "Executing global hook for service table at {}, to service "
2564 "status {}. Cert is:\n{}",
2569 network.identity->set_certificate(w->cert);
2572 open_user_frontend();
2575 LOG_INFO_FMT(
"Service open at seqno {}", hook_version);
2579 network.tables->set_global_hook(
2580 network.acme_certificates.get_name(),
2581 network.acme_certificates.wrap_commit_hook(
2584 for (
auto const& [interface_id, interface] :
2585 config.network.rpc_interfaces)
2587 if (interface.endorsement->acme_configuration)
2589 auto cit = w.find(*interface.endorsement->acme_configuration);
2593 "ACME: new certificate for interface '{}' with "
2594 "configuration '{}'",
2596 *interface.endorsement->acme_configuration);
2597 rpcsessions->set_cert(
2600 network.identity->priv_key,
2615 std::lock_guard<pal::Mutex> guard(lock);
2616 return last_recovered_signed_idx;
2619 void setup_recovery_hook()
2621 network.tables->set_map_hook(
2622 network.encrypted_ledger_secrets.get_name(),
2623 network.encrypted_ledger_secrets.wrap_map_hook(
2628 auto encrypted_ledger_secret_info = w;
2629 if (!encrypted_ledger_secret_info.has_value())
2631 throw std::logic_error(fmt::format(
2632 "Unexpected removal from {} table",
2633 network.encrypted_ledger_secrets.get_name()));
2638 if (!encrypted_ledger_secret_info->next_version.has_value())
2640 encrypted_ledger_secret_info->next_version = version + 1;
2643 if (encrypted_ledger_secret_info->previous_ledger_secret
2647 "Recovering encrypted ledger secret valid at seqno {}",
2648 encrypted_ledger_secret_info->previous_ledger_secret->version);
2651 recovered_encrypted_ledger_secrets.emplace_back(
2652 std::move(encrypted_ledger_secret_info.value()));
2658 void reset_recovery_hook()
2660 network.tables->unset_map_hook(
2661 network.encrypted_ledger_secrets.get_name());
2664 void setup_n2n_channels(
2665 const std::optional<ccf::crypto::Pem>& endorsed_node_certificate_ =
2672 n2n_channels->initialize(
2673 self, network.identity->cert, node_sign_kp, endorsed_node_certificate_);
2676 void setup_cmd_forwarder()
2678 cmd_forwarder->initialize(self);
2681 void setup_history()
2685 throw std::logic_error(
"History already initialised");
2688 history = std::make_shared<MerkleTxHistory>(
2689 *network.tables.get(),
2695 network.tables->set_history(history);
2698 void setup_encryptor()
2702 throw std::logic_error(
"Encryptor already initialised");
2705 encryptor = make_encryptor();
2706 network.tables->set_encryptor(encryptor);
2709 void setup_consensus(
2710 ServiceStatus service_status,
2712 bool public_only =
false,
2713 const std::optional<ccf::crypto::Pem>& endorsed_node_certificate_ =
2716 setup_n2n_channels(endorsed_node_certificate_);
2717 setup_cmd_forwarder();
2719 auto shared_state = std::make_shared<aft::State>(self);
2721 auto node_client = std::make_shared<HTTPNodeClient>(
2722 rpc_map, node_sign_kp, self_signed_node_cert, endorsed_node_cert);
2730 std::make_unique<::consensus::LedgerEnclave>(writer_factory),
2736 reconfiguration_type);
2738 network.tables->set_consensus(
consensus);
2739 network.tables->set_snapshotter(snapshotter);
2743 network.tables->set_map_hook(
2744 network.nodes.get_name(),
2745 network.nodes.wrap_map_hook(
2748 return std::make_unique<ConfigurationChangeHook>(version, w);
2757 network.tables->set_map_hook(
2758 network.signatures.get_name(),
2759 network.signatures.wrap_map_hook(
2760 [s = this->snapshotter](
2762 assert(w.has_value());
2763 auto sig = w.value();
2764 s->record_signature(version, sig.sig, sig.node, sig.cert);
2765 return ccf::kv::ConsensusHookPtr(nullptr);
2768 network.tables->set_map_hook(
2769 network.serialise_tree.get_name(),
2770 network.serialise_tree.wrap_map_hook(
2771 [s = this->snapshotter](
2773 assert(w.has_value());
2774 auto tree = w.value();
2775 s->record_serialised_tree(version, tree);
2776 return ccf::kv::ConsensusHookPtr(nullptr);
2779 network.tables->set_map_hook(
2780 network.snapshot_evidence.get_name(),
2781 network.snapshot_evidence.wrap_map_hook(
2782 [s = this->snapshotter](
2784 assert(w.has_value());
2785 auto snapshot_evidence = w.value();
2786 s->record_snapshot_evidence_idx(version, snapshot_evidence);
2787 return ccf::kv::ConsensusHookPtr(nullptr);
2790 setup_basic_hooks();
2793 void setup_snapshotter()
2797 throw std::logic_error(
"Snapshotter already initialised");
2799 snapshotter = std::make_shared<Snapshotter>(
2800 writer_factory, network.tables, config.snapshots.tx_count);
2806 ::consensus::ledger_get_range,
2816 ::consensus::ledger_truncate, to_host, idx, recovery_mode);
2819 void setup_acme_clients()
2821 if (!config.network.acme || config.network.acme->configurations.empty())
2826 open_acme_challenge_frontend();
2828 const auto& ifaces = config.network.rpc_interfaces;
2829 num_acme_interfaces =
2830 std::count_if(ifaces.begin(), ifaces.end(), [](
const auto& id_iface) {
2831 return id_iface.second.endorsement->authority == Authority::ACME;
2834 if (num_acme_interfaces > 0)
2840 auto msg = std::make_unique<::threading::Tmsg<NodeStateMsg>>(
2841 [](std::unique_ptr<::threading::Tmsg<NodeStateMsg>> msg) {
2842 auto& state = msg->data.self;
2844 if (state.consensus && state.consensus->can_replicate())
2846 if (state.acme_clients.size() != state.num_acme_interfaces)
2848 auto tx = state.network.tables->create_tx();
2849 state.trigger_acme_refresh(tx);
2854 for (
auto& [cfg_name,
client] : state.acme_clients)
2859 state.network.tables, state.network.identity);
2865 auto delay = std::chrono::minutes(1);
2867 std::move(msg), delay);
2872 std::move(msg), std::chrono::seconds(2));
2876 void seal_ledger_secret(
const VersionedLedgerSecret& ledger_secret)
2878 seal_ledger_secret(ledger_secret.first, ledger_secret.second);
2881 void seal_ledger_secret(
2882 const kv::Version& version,
const LedgerSecretPtr& ledger_secret)
2884 if (!config.sealed_ledger_secret_location.has_value())
2890 snp_tcb_version.has_value(),
"TCB version must be set before sealing");
2893 config.sealed_ledger_secret_location.value(),
2894 snp_tcb_version.value(),
2902 snp_tcb_version.has_value(),
2903 "TCB version must be set when unsealing ledger secret");
2906 config.recover.previous_sealed_ledger_secret_location.has_value(),
2907 "Previous sealed ledger secret location must be set");
2908 auto ledger_secret_path =
2909 config.recover.previous_sealed_ledger_secret_location.value();
2911 auto max_version = network.tables->current_version();
2914 config.recover.previous_sealed_ledger_secret_location.value(),
2921 n2n_channels->set_message_limit(message_limit);
2926 n2n_channels->set_idle_timeout(idle_timeout);
2936 return network.identity->cert;
2941 std::shared_ptr<ACMEChallengeHandler> h)
override
2943 acme_challenge_handlers[interface_id] = h;
2948 const ::http::URL& url,
2953 const std::vector<std::string>& ca_certs = {},
2954 const std::string& app_protocol =
"HTTP1",
2955 bool authenticate_as_node_client_certificate =
false)
override
2957 std::optional<ccf::crypto::Pem> client_cert = std::nullopt;
2958 std::optional<ccf::crypto::Pem> client_cert_key = std::nullopt;
2959 if (authenticate_as_node_client_certificate)
2962 endorsed_node_cert ? *endorsed_node_cert : self_signed_node_cert;
2963 client_cert_key = node_sign_kp->private_key_pem();
2966 auto ca = std::make_shared<::tls::CA>(ca_certs,
true);
2967 std::shared_ptr<::tls::Cert> ca_cert =
2968 std::make_shared<::tls::Cert>(ca, client_cert, client_cert_key);
2969 auto client = rpcsessions->create_client(ca_cert, app_protocol);
2975 http::HeaderMap&& headers,
2976 std::vector<uint8_t>&& data) {
2977 return callback(status, std::move(headers), std::move(data));
2979 client->send_request(std::move(req));
2984 snapshotter->write_snapshot(snapshot_buf, request_id);
2987 virtual std::shared_ptr<ccf::kv::Store>
get_store()
override
2989 return network.tables;
2994 return writer_factory;
#define CCF_ASSERT_FMT(expr,...)
Definition ccf_assert.h:10
#define CCF_ASSERT(expr, msg)
Definition ccf_assert.h:14
Definition raft_types.h:48
Definition node_interface.h:23
static std::optional< pal::snp::Attestation > get_snp_attestation(const QuoteInfo "e_info)
Definition quote.cpp:145
static std::optional< HostData > get_host_data(const QuoteInfo "e_info)
Definition quote.cpp:168
static QuoteVerificationResult verify_quote_against_store(ccf::kv::ReadOnlyTx &tx, const QuoteInfo "e_info, const std::vector< uint8_t > &expected_node_public_key_der, pal::PlatformAttestationMeasurement &measurement)
Definition quote.cpp:317
static std::optional< pal::PlatformAttestationMeasurement > get_measurement(const QuoteInfo "e_info)
Definition quote.cpp:128
void set_node_id(const NodeId &id_)
Definition history.h:717
ccf::crypto::Sha256Hash get_replicated_state_root() override
Definition history.h:757
static bool endorse_previous_identity(ccf::kv::Tx &tx, const ccf::crypto::KeyPair_OpenSSL &service_key)
Definition internal_tables_access.h:514
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 std::map< NodeId, NodeInfo > get_trusted_nodes(ccf::kv::ReadOnlyTx &tx)
Definition internal_tables_access.h:435
static void broadcast_some(std::map< NodeId, NodeInfo > &&nodes, SecretsWriteHandle *secrets, const LedgerSecretsMap &some_ledger_secrets)
Definition secret_broadcast.h:19
static void broadcast_new(std::map< NodeId, NodeInfo > &&nodes, SecretsWriteHandle *secrets, LedgerSecretPtr &&new_ledger_secret)
Definition secret_broadcast.h:46
static std::vector< uint8_t > decrypt(const ccf::crypto::RSAKeyPairPtr &encryption_key, const std::vector< uint8_t > &cipher)
Definition secret_broadcast.h:70
Definition node_state.h:88
void write_snapshot(std::span< uint8_t > snapshot_buf, size_t request_id)
Definition node_state.h:2982
void start_ledger_recovery_unsafe()
Definition node_state.h:990
bool rekey_ledger(ccf::kv::Tx &tx) override
Definition node_state.h:1916
bool is_part_of_public_network() const override
Definition node_state.h:1889
NodeState(ringbuffer::AbstractWriterFactory &writer_factory, NetworkState &network, std::shared_ptr< RPCSessions > rpcsessions, ccf::crypto::CurveID curve_id_)
Definition node_state.h:237
void setup_one_off_secret_hook()
Definition node_state.h:1393
void tick_end()
Definition node_state.h:1775
virtual std::shared_ptr< ccf::kv::Store > get_store() override
Definition node_state.h:2987
void recover_private_ledger_entries(const std::vector< uint8_t > &entries)
Definition node_state.h:1218
virtual const ccf::StartupConfig & get_node_config() const override
Definition node_state.h:2929
void trigger_acme_refresh(ccf::kv::Tx &tx, const std::optional< std::vector< std::string > > &interfaces=std::nullopt) override
Definition node_state.h:1519
void recv_node_inbound(const uint8_t *data, size_t size)
Definition node_state.h:1798
bool is_reading_private_ledger() const override
Definition node_state.h:1884
void trigger_ledger_chunk(ccf::kv::Tx &tx) override
Definition node_state.h:1497
virtual ringbuffer::AbstractWriterFactory & get_writer_factory() override
Definition node_state.h:2992
bool is_primary() const override
Definition node_state.h:1851
virtual ccf::crypto::Pem get_network_cert() override
Definition node_state.h:2934
void recover_public_ledger_end_unsafe()
Definition node_state.h:1122
SessionMetrics get_session_metrics() override
Definition node_state.h:1961
void initiate_join()
Definition node_state.h:925
void advance_part_of_network()
Definition node_state.h:1111
void advance_part_of_public_network()
Definition node_state.h:1103
ccf::kv::Version get_startup_snapshot_seqno() override
Definition node_state.h:1955
const ccf::COSESignaturesConfig & get_cose_signatures_config() override
Definition node_state.h:1972
void auto_refresh_jwt_keys()
Definition node_state.h:954
void recover_ledger_end()
Definition node_state.h:1426
void initiate_private_recovery(ccf::kv::Tx &tx, const std::optional< LedgerSecretPtr > &unsealed_ledger_secret=std::nullopt) override
Definition node_state.h:1742
void initiate_join_unsafe()
Definition node_state.h:673
void stop_notice() override
Definition node_state.h:1788
virtual void make_http_request(const ::http::URL &url, ::http::Request &&req, std::function< bool(ccf::http_status status, http::HeaderMap &&, std::vector< uint8_t > &&)> callback, const std::vector< std::string > &ca_certs={}, const std::string &app_protocol="HTTP1", bool authenticate_as_node_client_certificate=false) override
Definition node_state.h:2947
void set_n2n_message_limit(size_t message_limit)
Definition node_state.h:2919
bool can_replicate() override
Definition node_state.h:1860
void transition_service_to_open(ccf::kv::Tx &tx, AbstractGovernanceEffects::ServiceIdentities identities) override
Definition node_state.h:1606
QuoteVerificationResult verify_quote(ccf::kv::ReadOnlyTx &tx, const QuoteInfo "e_info_, const std::vector< uint8_t > &expected_node_public_key_der, pal::PlatformAttestationMeasurement &measurement) override
Definition node_state.h:254
bool is_reading_public_ledger() const override
Definition node_state.h:1879
void launch_node()
Definition node_state.h:301
void initiate_quote_generation()
Definition node_state.h:431
void initialize(const ccf::consensus::Configuration &consensus_config_, std::shared_ptr< RPCMap > rpc_map_, std::shared_ptr< AbstractRPCResponder > rpc_sessions_, std::shared_ptr< indexing::Indexer > indexer_, size_t sig_tx_interval_, size_t sig_ms_interval_)
Definition node_state.h:267
void setup_private_recovery_store()
Definition node_state.h:1449
void trigger_snapshot(ccf::kv::Tx &tx) override
Definition node_state.h:1508
bool is_in_initialised_state() const override
Definition node_state.h:1869
virtual void install_custom_acme_challenge_handler(const ccf::NodeInfoNetwork::RpcInterfaceID &interface_id, std::shared_ptr< ACMEChallengeHandler > h) override
Definition node_state.h:2939
bool has_received_stop_notice() override
Definition node_state.h:1793
bool is_part_of_network() const override
Definition node_state.h:1874
void start_join_timer()
Definition node_state.h:931
ExtendedState state() override
Definition node_state.h:1902
void trigger_recovery_shares_refresh(ccf::kv::Tx &tx) override
Definition node_state.h:1492
void set_n2n_idle_timeout(std::chrono::milliseconds idle_timeout)
Definition node_state.h:2924
NodeId get_node_id() const
Definition node_state.h:1950
void tick(std::chrono::milliseconds elapsed)
Definition node_state.h:1754
NodeCreateInfo create(StartType start_type_, const ccf::StartupConfig &config_, std::vector< uint8_t > &&startup_snapshot_)
Definition node_state.h:571
void trigger_host_process_launch(const std::vector< std::string > &args, const std::vector< uint8_t > &input) override
Definition node_state.h:1593
void recover_public_ledger_entries(const std::vector< uint8_t > &entries)
Definition node_state.h:1005
void recover_private_ledger_end_unsafe()
Definition node_state.h:1290
void initiate_private_recovery_unsafe(ccf::kv::Tx &tx, const std::optional< LedgerSecretPtr > &unsealed_ledger_secret=std::nullopt)
Definition node_state.h:1724
ccf::crypto::Pem get_self_signed_certificate() override
Definition node_state.h:1966
size_t get_jwt_attempts() override
Definition node_state.h:982
bool is_accessible_to_members() const override
Definition node_state.h:1894
Definition share_manager.h:167
static void clear_submitted_recovery_shares(ccf::kv::Tx &tx)
Definition share_manager.h:649
void issue_recovery_shares(ccf::kv::Tx &tx)
Definition share_manager.h:455
const std::string & str() const
Definition pem.h:46
Definition sha256_hash.h:16
Definition committable_tx.h:18
@ LEDGER_CHUNK_AT_NEXT_SIGNATURE
@ SNAPSHOT_AT_NEXT_SIGNATURE
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
std::map< K, std::optional< V > > Write
Definition map.h:40
static ccf::kv::untyped::MapHook wrap_map_hook(const MapHook &hook)
Definition value.h:72
std::optional< V > Write
Definition value.h:38
static std::vector< uint8_t > get_entry(const uint8_t *&data, size_t &size)
Definition ledger_enclave.h:26
Definition state_machine.h:14
void expect(T state_) const
Definition state_machine.h:24
T value() const
Definition state_machine.h:39
void advance(T state_)
Definition state_machine.h:44
bool check(T state_) const
Definition state_machine.h:34
void set_header(std::string k, const std::string &v)
Definition http_builder.h:45
void set_body(const std::vector< uint8_t > *b, bool overwrite_content_length=true)
Definition http_builder.h:74
Definition http_builder.h:118
Definition ring_buffer_types.h:153
static ThreadMessaging & instance()
Definition thread_messaging.h:283
TaskQueue::TimerEntry add_task_after(std::unique_ptr< Tmsg< Payload > > msg, std::chrono::milliseconds ms)
Definition thread_messaging.h:326
void add_task(uint16_t tid, std::unique_ptr< Tmsg< Payload > > msg)
Definition thread_messaging.h:318
StartType
Definition enclave_interface_types.h:92
@ Join
Definition enclave_interface_types.h:94
@ Recover
Definition enclave_interface_types.h:95
@ Start
Definition enclave_interface_types.h:93
#define LOG_INFO_FMT
Definition logger.h:362
#define LOG_TRACE_FMT
Definition logger.h:356
#define LOG_DEBUG_FMT
Definition logger.h:357
#define LOG_FAIL_FMT
Definition logger.h:363
std::vector< uint8_t > raw_from_b64(const std::string_view &b64_string)
Definition base64.cpp:12
ccf::crypto::Pem public_key_pem_from_cert(const std::vector< uint8_t > &der)
Definition verifier.cpp:48
VerifierPtr make_verifier(const std::vector< uint8_t > &cert)
Definition verifier.cpp:18
CurveID
Definition curve.h:18
KeyPairPtr make_key_pair(CurveID curve_id=service_identity_curve_choice)
Definition key_pair.cpp:35
std::string get_subject_name(const Pem &cert)
Definition verifier.cpp:53
std::vector< uint8_t > cert_pem_to_der(const Pem &pem)
Definition verifier.cpp:38
std::map< std::string, std::string, std::less<> > HeaderMap
Definition http_header_map.h:10
if(argc !=1)
Definition kv_helpers.h:71
void register_class_ids()
Definition global_class_ids.cpp:17
std::map< ccf::kv::serialisers::SerialisedEntry, std::optional< ccf::kv::serialisers::SerialisedEntry > > Write
Definition untyped.h:16
uint64_t Term
Definition kv_types.h:48
std::unique_ptr< ConsensusHook > ConsensusHookPtr
Definition hooks.h:21
uint64_t Version
Definition version.h:8
@ SUCCESS
Definition kv_types.h:249
ApplyResult
Definition kv_types.h:341
@ PASS_SIGNATURE
Definition kv_types.h:343
@ FAIL
Definition kv_types.h:350
MembershipState
Definition kv_types.h:155
std::vector< ConsensusHookPtr > ConsensusHookPtrs
Definition hooks.h:22
UVMEndorsements verify_uvm_endorsements_descriptor(const std::vector< uint8_t > &uvm_endorsements_raw, const pal::PlatformAttestationMeasurement &uvm_measurement)
Definition uvm_endorsements.cpp:304
std::mutex Mutex
Definition locking.h:12
uint16_t get_current_thread_id()
Definition thread_local.cpp:15
Definition app_interface.h:14
@ WAITING_FOR_RECOVERY_SHARES
LedgerSecretPtr find_and_unseal_ledger_secret_from_disk(const std::string &sealed_secret_dir, kv::Version max_version)
Definition local_sealing.h:191
constexpr auto get_actor_prefix(ActorsType at)
Definition actors.h:31
NodeId compute_node_id_from_kp(const ccf::crypto::KeyPairPtr &node_sign_kp)
Definition nodes.h:43
std::shared_ptr< ccf::kv::Store > make_store()
Definition network_tables.h:40
std::vector< uint8_t > CoseSignature
Definition signatures.h:64
QuoteVerificationResult
Definition quote.h:18
std::tuple< NodeStartupState, std::optional< ccf::kv::Version >, std::optional< ccf::kv::Version > > ExtendedState
Definition node_operation_interface.h:20
std::list< EncryptedLedgerSecretInfo > RecoveredEncryptedLedgerSecrets
Definition share_manager.h:157
view
Definition signatures.h:54
std::map< ccf::kv::Version, LedgerSecretPtr > LedgerSecretsMap
Definition ledger_secrets.h:20
void reset_data(std::vector< uint8_t > &data)
Definition node_state.h:81
LedgerSecretPtr make_ledger_secret()
Definition ledger_secret.h:77
ReconfigurationType
Definition reconfiguration_type.h:10
@ ONE_TRANSACTION
Definition reconfiguration_type.h:11
llhttp_status http_status
Definition http_status.h:9
@ RECOVERY_SHARES
Definition recovery_type.h:14
@ LOCAL_UNSEALING
Definition recovery_type.h:15
std::shared_ptr< LedgerSecret > LedgerSecretPtr
Definition ledger_secret.h:75
constexpr View VIEW_UNKNOWN
Definition tx_id.h:26
NodeStartupState
Definition node_startup_state.h:10
uint64_t View
Definition tx_id.h:23
void seal_ledger_secret_to_disk(const std::string &sealed_secret_dir, const ccf::pal::snp::TcbVersionRaw &tcb_version, const kv::Version &version, const LedgerSecretPtr &ledger_secret)
Definition local_sealing.h:107
ActorsType
Definition actors.h:11
@ channel_msg
Definition node_types.h:20
@ consensus_msg
Definition node_types.h:21
@ forwarded_msg
Definition node_types.h:22
std::shared_ptr<::http::HttpRpcContext > make_rpc_context(std::shared_ptr< ccf::SessionContext > s, const std::vector< uint8_t > &packed)
Definition http_rpc_context.h:392
Definition perf_client.h:12
Definition consensus_types.h:23
uint64_t Index
Definition ledger_enclave_types.h:11
@ Recovery
Definition ledger_enclave_types.h:15
Definition configuration.h:14
URL parse_url_full(const std::string &url)
Definition http_parser.h:145
Definition json_schema.h:15
std::shared_ptr< AbstractWriter > WriterPtr
Definition ring_buffer_types.h:150
Definition thread_messaging.h:14
#define RINGBUFFER_WRITE_MESSAGE(MSG,...)
Definition ring_buffer_types.h:255
Definition interface.h:51
Definition gov_effects_interface.h:22
std::optional< ccf::crypto::Pem > previous
Definition gov_effects_interface.h:23
ccf::crypto::Pem next
Definition gov_effects_interface.h:24
std::optional< std::string > security_policy
Definition startup_config.h:82
std::optional< std::string > uvm_endorsements
Definition startup_config.h:83
std::optional< std::string > snp_endorsements
Definition startup_config.h:84
ccf::pal::snp::EndorsementsServers snp_endorsements_servers
Definition startup_config.h:73
std::optional< std::string > snp_endorsements_file
Definition startup_config.h:76
Environment environment
Definition startup_config.h:88
ccf::ds::TimeString key_refresh_interval
Definition startup_config.h:65
std::string subject_name
Definition startup_config.h:35
size_t initial_validity_days
Definition startup_config.h:38
ccf::NodeInfoNetwork network
Definition startup_config.h:31
JWT jwt
Definition startup_config.h:69
Attestation attestation
Definition startup_config.h:92
NodeCertificateInfo node_certificate
Definition startup_config.h:42
Definition cose_signatures_config.h:12
Definition node_call_types.h:83
QuoteInfo quote_info
Definition node_call_types.h:85
std::optional< ccf::crypto::Pem > certificate_signing_request
Definition node_call_types.h:88
std::optional< ccf::kv::Version > startup_seqno
Definition node_call_types.h:87
NodeInfoNetwork node_info_network
Definition node_call_types.h:84
nlohmann::json node_data
Definition node_call_types.h:90
ccf::crypto::Pem public_encryption_key
Definition node_call_types.h:86
Definition node_call_types.h:94
std::optional< NetworkInfo > network_info
Definition node_call_types.h:150
NodeStatus node_status
Definition node_call_types.h:95
Definition network_state.h:12
std::shared_ptr< LedgerSecrets > ledger_secrets
Definition network_state.h:14
std::unique_ptr< NetworkIdentity > identity
Definition network_state.h:13
std::shared_ptr< ccf::kv::Store > tables
Definition network_tables.h:47
const JwtIssuers jwt_issuers
Definition network_tables.h:167
const Configuration config
Definition network_tables.h:201
const CoseSignatures cose_signatures
Definition network_tables.h:239
const EncryptedLedgerSecretsInfo encrypted_ledger_secrets
Definition network_tables.h:230
const Signatures signatures
Definition network_tables.h:238
Definition node_state.h:76
ccf::crypto::Pem service_cert
Definition node_state.h:78
ccf::crypto::Pem self_signed_node_cert
Definition node_state.h:77
std::string RpcInterfaceID
Definition node_info_network.h:87
Describes a quote (attestation) from trusted hardware.
Definition quote_info.h:26
QuoteFormat format
Quote format.
Definition quote_info.h:28
std::optional< std::vector< uint8_t > > uvm_endorsements
UVM endorsements (SNP-only)
Definition quote_info.h:34
std::vector< uint8_t > quote
Enclave quote.
Definition quote_info.h:30
std::vector< uint8_t > endorsements
Quote endorsements.
Definition quote_info.h:32
Definition session_metrics.h:13
std::vector< uint8_t > service_cert
Definition startup_config.h:138
bool follow_redirect
Definition startup_config.h:139
ccf::NodeInfoNetwork::NetAddress target_rpc_address
Definition startup_config.h:136
ccf::ds::TimeString retry_timeout
Definition startup_config.h:137
std::optional< std::vector< uint8_t > > previous_service_identity
Definition startup_config.h:145
Definition startup_config.h:106
size_t initial_service_certificate_validity_days
Definition startup_config.h:114
ccf::COSESignaturesConfig cose_signatures
Definition startup_config.h:116
Join join
Definition startup_config.h:141
nlohmann::json node_data
Definition startup_config.h:122
Recover recover
Definition startup_config.h:150
std::string startup_host_time
Definition startup_config.h:110
std::string service_subject_name
Definition startup_config.h:115
Definition consensus_config.h:11
Definition cose_common.h:52
size_t count_s() const
Definition unit_strings.h:190
const std::string & get_name() const
Definition get_name.h:18
Definition attestation_sev_snp_endorsements.h:20
Definition attestation_sev_snp.h:361