diff --git a/CHANGELOG.md b/CHANGELOG.md index 830cc79057a1..b19ab85b9515 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Slow ledger IO operations will now be logged at level FAIL. The threshold over which logging will activate can be adjusted by the `--io-logging-threshold` CLI argument to cchost (#3067). - Snapshot files now include receipt of evidence transaction. Nodes can now join or recover a service from a standalone snapshot file. 2.x nodes can still make use of snapshots created by a 1.x node, as long as the ledger suffix containing the proof of evidence is also specified at start-up (#2998). - `ccf.historical.getStateRange` / `ccf.historical.dropCachedStates` JavaScript APIs to manually retrieve historical state in endpoints declared as `"mode": "readonly"` (#3033). +- Log more detailed errors on early startup (#3116). ### Changed diff --git a/src/common/enclave_interface_types.h b/src/common/enclave_interface_types.h index a6a3cdd2c158..94b68f0e9238 100644 --- a/src/common/enclave_interface_types.h +++ b/src/common/enclave_interface_types.h @@ -21,6 +21,18 @@ enum CreateNodeStatus /** One of the input buffers is not located outside of the enclave memory */ MemoryNotOutsideEnclave = 5, + + /** Enclave initialisation failed */ + EnclaveInitFailed = 6, + + /** Open Enclave Verifier initialisation failed */ + OEVerifierInitFailed = 7, + + /** Open Enclave Attester initialisation failed */ + OEAttesterInitFailed = 8, + + /** OpenSSL RDRAND Init Failed */ + OpenSSLRDRANDInitFailed = 9 }; constexpr char const* create_node_result_to_str(CreateNodeStatus result) @@ -51,6 +63,22 @@ constexpr char const* create_node_result_to_str(CreateNodeStatus result) { return "MemoryNotOutsideEnclave"; } + case CreateNodeStatus::EnclaveInitFailed: + { + return "EnclaveInitFailed"; + } + case CreateNodeStatus::OEVerifierInitFailed: + { + return "OEVerifierInitFailed"; + } + case CreateNodeStatus::OEAttesterInitFailed: + { + return "OEAttesterInitFailed"; + } + case CreateNodeStatus::OpenSSLRDRANDInitFailed: + { + return "OpenSSLRDRANDInitFailed"; + } default: { return "Unknown CreateNodeStatus"; diff --git a/src/ds/ccf_exception.h b/src/ds/ccf_exception.h index a386f42ba6ae..1c4f49de1149 100644 --- a/src/ds/ccf_exception.h +++ b/src/ds/ccf_exception.h @@ -31,4 +31,28 @@ namespace ccf private: std::string result; }; + + class ccf_oe_attester_init_error : public ccf_logic_error + { + public: + ccf_oe_attester_init_error(const std::string& what_arg) : + ccf_logic_error(what_arg) + {} + }; + + class ccf_oe_verifier_init_error : public ccf_logic_error + { + public: + ccf_oe_verifier_init_error(const std::string& what_arg) : + ccf_logic_error(what_arg) + {} + }; + + class ccf_openssl_rdrand_init_error : public ccf_logic_error + { + public: + ccf_openssl_rdrand_init_error(const std::string& what_arg) : + ccf_logic_error(what_arg) + {} + }; }; diff --git a/src/enclave/enclave.h b/src/enclave/enclave.h index d32cb4abd86d..8dbbacc46c52 100644 --- a/src/enclave/enclave.h +++ b/src/enclave/enclave.h @@ -98,7 +98,7 @@ namespace enclave ENGINE_set_default(rdrand_engine, ENGINE_METHOD_RAND) != 1) { ENGINE_free(rdrand_engine); - throw std::runtime_error( + throw ccf::ccf_openssl_rdrand_init_error( "could not initialize RDRAND engine for OpenSSL"); } @@ -171,7 +171,7 @@ namespace enclave { r = node->create(start_type, std::move(ccf_config_)); } - catch (const std::runtime_error& e) + catch (const std::exception& e) { LOG_FAIL_FMT("Error starting node: {}", e.what()); return false; diff --git a/src/enclave/main.cpp b/src/enclave/main.cpp index 3a2c0de607d1..0aa03a71f6b1 100644 --- a/src/enclave/main.cpp +++ b/src/enclave/main.cpp @@ -2,6 +2,7 @@ // Licensed under the Apache 2.0 License. #include "ccf/version.h" #include "common/enclave_interface_types.h" +#include "ds/ccf_exception.h" #include "ds/json.h" #include "ds/logger.h" #include "enclave.h" @@ -143,9 +144,29 @@ extern "C" #ifdef DEBUG_CONFIG reserved_memory = new uint8_t[ec->debug_config.memory_reserve_startup]; #endif + enclave::Enclave* enclave; - auto enclave = new enclave::Enclave( - ec, cc.signature_intervals, cc.consensus_config, cc.curve_id); + try + { + enclave = new enclave::Enclave( + ec, cc.signature_intervals, cc.consensus_config, cc.curve_id); + } + catch (const ccf::ccf_oe_attester_init_error&) + { + return CreateNodeStatus::OEAttesterInitFailed; + } + catch (const ccf::ccf_oe_verifier_init_error&) + { + return CreateNodeStatus::OEVerifierInitFailed; + } + catch (const ccf::ccf_openssl_rdrand_init_error&) + { + return CreateNodeStatus::OpenSSLRDRANDInitFailed; + } + catch (const std::exception&) + { + return CreateNodeStatus::EnclaveInitFailed; + } if (!enclave->create_new_node( start_type, diff --git a/src/enclave/oe_init.h b/src/enclave/oe_init.h index 6bd4025684ea..9fc60e551e14 100644 --- a/src/enclave/oe_init.h +++ b/src/enclave/oe_init.h @@ -7,6 +7,7 @@ #else # include #endif +#include "ds/ccf_exception.h" namespace ccf { @@ -17,7 +18,7 @@ namespace ccf auto rc = oe_attester_initialize(); if (rc != OE_OK) { - throw std::logic_error(fmt::format( + throw ccf::ccf_oe_attester_init_error(fmt::format( "Failed to initialise evidence attester: {}", oe_result_str(rc))); } } @@ -26,7 +27,7 @@ namespace ccf auto rc = oe_verifier_initialize(); if (rc != OE_OK) { - throw std::logic_error(fmt::format( + throw ccf::ccf_oe_verifier_init_error(fmt::format( "Failed to initialise evidence verifier: {}", oe_result_str(rc))); } }