From 955e2b78a2ad138315a9c3c13eab89383e8933d0 Mon Sep 17 00:00:00 2001 From: prakashngit Date: Mon, 26 Feb 2024 10:26:07 -0800 Subject: [PATCH] Changes to Fix Ledger APIs used to set Contract Enclave atttestation policy. Changes to address Review Comments have been squashed into the same commit. (#467) Signed-off-by: Prakash Narayana Moorthy --- eservice/bin/register-with-ledger.sh | 6 +- ledgers/ccf/MANIFEST | 3 +- ...enclave_attestation_verification_policy.py | 90 -------------- .../ccf/scripts/set_attestation_check_flag.py | 67 +++++++++++ .../scripts/set_expected_sgx_measurements.py | 74 ++++++++++++ ledgers/ccf/scripts/start_ccf_network.sh | 11 +- ledgers/ccf/setup.py | 3 +- .../transaction_processor/enclave_registry.h | 29 +++-- ledgers/ccf/transaction_processor/pdo_tp.cpp | 110 +++++++++++++----- ledgers/ccf/transaction_processor/pdo_tp.h | 13 ++- 10 files changed, 271 insertions(+), 135 deletions(-) delete mode 100755 ledgers/ccf/pdo/ledgers/ccf/scripts/register_enclave_attestation_verification_policy.py create mode 100755 ledgers/ccf/pdo/ledgers/ccf/scripts/set_attestation_check_flag.py create mode 100644 ledgers/ccf/pdo/ledgers/ccf/scripts/set_expected_sgx_measurements.py diff --git a/eservice/bin/register-with-ledger.sh b/eservice/bin/register-with-ledger.sh index 9395ebfe..fdd85526 100755 --- a/eservice/bin/register-with-ledger.sh +++ b/eservice/bin/register-with-ledger.sh @@ -88,8 +88,10 @@ function Register { : "PDO_IAS_KEY_PEM" "${PDO_IAS_KEY_PEM:?Registration failed! PDO_IAS_KEY_PEM environment variable not set}" if [ ${PDO_LEDGER_TYPE} == "ccf" ]; then - try ${SRCDIR}/ledgers/ccf/scripts/register_enclave_attestation_verification_policy.py --logfile __screen__ --loglevel INFO \ - --check_attestation --mrenclave ${VAR_MRENCLAVE} --basename ${VAR_BASENAME} --ias-public-key "$(cat $PDO_IAS_KEY_PEM)" + source ${PDO_INSTALL_ROOT}/bin/activate + try ${PDO_INSTALL_ROOT}/bin/ccf_set_expected_sgx_measurements \ + --logfile __screen__ --loglevel INFO --mrenclave ${VAR_MRENCLAVE} \ + --basename ${VAR_BASENAME} --ias-public-key "$(cat $PDO_IAS_KEY_PEM)" else die unsupported ledger ${PDO_LEDGER_TYPE} fi diff --git a/ledgers/ccf/MANIFEST b/ledgers/ccf/MANIFEST index f12ad2a0..e884ab02 100644 --- a/ledgers/ccf/MANIFEST +++ b/ledgers/ccf/MANIFEST @@ -7,6 +7,7 @@ pdo/ledgers/ccf/common.py pdo/ledgers/ccf/scripts/__init__.py pdo/ledgers/ccf/scripts/fetch_ledger_authority.py pdo/ledgers/ccf/scripts/ping_test.py -pdo/ledgers/ccf/scripts/register_enclave_attestation_verification_policy.py +pdo/ledgers/ccf/scripts/set_attestation_check_flag.py +pdo/ledgers/ccf/scripts/set_expected_sgx_measurements.py pdo/ledgers/ccf/scripts/generate_ledger_authority.py pdo/ledgers/ccf/scripts/configure_ccf_network.py diff --git a/ledgers/ccf/pdo/ledgers/ccf/scripts/register_enclave_attestation_verification_policy.py b/ledgers/ccf/pdo/ledgers/ccf/scripts/register_enclave_attestation_verification_policy.py deleted file mode 100755 index d8ee63d6..00000000 --- a/ledgers/ccf/pdo/ledgers/ccf/scripts/register_enclave_attestation_verification_policy.py +++ /dev/null @@ -1,90 +0,0 @@ -#!/usr/bin/env python - -# Copyright 2023 Intel Corporation -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import argparse -import http -import sys - -# pick up the logger used by the rest of CCF -from loguru import logger as LOG - -from pdo.ledgers.ccf.common import parse_common_arguments - -# ----------------------------------------------------------------- -def register_enclave_attestation_policy(client, options): - try : - params = {} - params['check_attestation'] = options.check_attestation - if options.check_attestation: - params['mrenclave'] = options.mrenclave - params['basename'] = options.basename - params['ias_public_key'] = options.ias_public_key - else: - params['mrenclave'] = "" - params['basename'] = "" - params['ias_public_key'] = "" - - r = client.post("/app/set_contract_enclave_attestatation_verification_policy", params) - if r.status_code != http.HTTPStatus.OK.value: - LOG.error('failed to register enclave expected measurements: {}, code: {}'.format( - r.body, r.status_code)) - sys.exit(-1) - except Exception as e: - LOG.error('failed to register enclave expected measurements: {}'.format(str(e))) - sys.exit(-1) - -# ----------------------------------------------------------------- -def Main() : - (_, unprocessed_args, member_client) = parse_common_arguments( - sys.argv[1:], 'Register enclave policy', True) - - parser = argparse.ArgumentParser(description='Register enclave policy') - parser.add_argument( - '--check-attestation', - default=False, - help="enable attestation verification", - action='store_true') - parser.add_argument( - '--mrenclave', - help="Expected MRENCLAVE of pdo enclaves", - type=str) - parser.add_argument( - '--basename', - help="PDO enclave basename", - type=str) - parser.add_argument( - '--ias-public-key', - help="IAS public key derived from cert used to verify report signatures", - type=str) - - local_options = parser.parse_args(unprocessed_args) - - if local_options.check_attestation: - if (not local_options.mrenclave) or (not local_options.basename) or (not local_options.ias_public_key): - parser.print_help() - sys.exit(-1) - - try : - register_enclave_attestation_policy(member_client, local_options) - except Exception as e: - # this just lets the script get back to the original error - # that caused the execption - while e.__context__ : e = e.__context__ - LOG.error('register enclave attestation policy failed: {}', str(e)) - sys.exit(-1) - - LOG.info('successfully registered enclave expected measurements') - sys.exit(0) diff --git a/ledgers/ccf/pdo/ledgers/ccf/scripts/set_attestation_check_flag.py b/ledgers/ccf/pdo/ledgers/ccf/scripts/set_attestation_check_flag.py new file mode 100755 index 00000000..4a93c0c7 --- /dev/null +++ b/ledgers/ccf/pdo/ledgers/ccf/scripts/set_attestation_check_flag.py @@ -0,0 +1,67 @@ +#!/usr/bin/env python + +# Copyright 2023 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import argparse +import http +import sys + +from loguru import logger as LOG + +from pdo.ledgers.ccf.common import parse_common_arguments + + +# ----------------------------------------------------------------- +def set_contract_enclave_check_attestation_flag(client, options): + + params = {} + params['check_attestation'] = options.attestation + + r = client.post("/app/set_contract_enclave_check_attestatation_flag", params) + if r.status_code != http.HTTPStatus.OK.value: + LOG.error('failed to set contract enclave check-attestation flag: {}, code: {}'.format( + r.body, r.status_code)) + sys.exit(-1) + +# ----------------------------------------------------------------- +def Main() : + + (_, unprocessed_args, member_client) = parse_common_arguments( + sys.argv[1:], 'Set contract enclave attestation check flag', True) + + # Parse the arguments that are unique to the script + parser = argparse.ArgumentParser(description='Set contract enclave attestation check flag') + check_attestation_group = parser.add_mutually_exclusive_group(required=True) + check_attestation_group.add_argument('--attestation', dest='attestation', + help="enable attestation verification", action='store_true') + check_attestation_group.add_argument('--no-attestation', dest='attestation', + help="disable attestation verification", action='store_false') + local_options = parser.parse_args(unprocessed_args) + + # ----------------------------------------------------------------- + try : + + set_contract_enclave_check_attestation_flag(member_client, local_options) + except Exception as e: + while e.__context__ : e = e.__context__ + LOG.error('failed to set contract enclave attestation check flag: {}', str(e)) + sys.exit(-1) + + LOG.info('successfully set contract enclave check-attestation flag ') + sys.exit(0) + +# ----------------------------------------------------------------- +# ----------------------------------------------------------------- +Main() diff --git a/ledgers/ccf/pdo/ledgers/ccf/scripts/set_expected_sgx_measurements.py b/ledgers/ccf/pdo/ledgers/ccf/scripts/set_expected_sgx_measurements.py new file mode 100644 index 00000000..da314f99 --- /dev/null +++ b/ledgers/ccf/pdo/ledgers/ccf/scripts/set_expected_sgx_measurements.py @@ -0,0 +1,74 @@ +#!/usr/bin/env python + +# Copyright 2023 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import argparse +import http +import sys + +from loguru import logger as LOG + +from pdo.ledgers.ccf.common import parse_common_arguments + + +# ----------------------------------------------------------------- +def set_contract_enclave_expected_sgx_measurements(client, options): + + params = {} + params['mrenclave'] = options.mrenclave + params['basename'] = options.basename + params['ias_public_key'] = options.ias_public_key + + r = client.post("/app/set_contract_enclave_expected_sgx_measurements", params) + if r.status_code != http.HTTPStatus.OK.value: + LOG.error('failed to set contract enclave expected sgx measurements: {}, code: {}'.format( + r.body, r.status_code)) + sys.exit(-1) + +# ----------------------------------------------------------------- +def Main() : + + (_, unprocessed_args, member_client) = parse_common_arguments( + sys.argv[1:], 'Set contract enclave expected sgx measurements', True) + + # Parse the arguments that are unique to the script + + parser = argparse.ArgumentParser(description='Set contract enclave expected sgx measurements') + parser.add_argument('--mrenclave', help="Expected MRENCLAVE of pdo enclaves", type=str) + parser.add_argument('--basename', help="PDO enclave basename", type=str) + parser.add_argument('--ias-public-key', + help="IAS public key derived from cert used to verify report signatures", type=str) + + local_options = parser.parse_args(unprocessed_args) + + if (not local_options.mrenclave) or (not local_options.basename) or (not local_options.ias_public_key): + parser.print_help() + sys.exit(-1) + + + # ----------------------------------------------------------------- + try : + set_contract_enclave_expected_sgx_measurements(member_client, local_options) + except Exception as e: + while e.__context__ : e = e.__context__ + LOG.error('failed to set contract enclave expected sgx measurements: {}', str(e)) + sys.exit(-1) + + LOG.info('successfully set contract enclave expected sgx measurements') + sys.exit(0) + +# ----------------------------------------------------------------- +# ----------------------------------------------------------------- +Main() diff --git a/ledgers/ccf/scripts/start_ccf_network.sh b/ledgers/ccf/scripts/start_ccf_network.sh index 4298234b..339ac8af 100755 --- a/ledgers/ccf/scripts/start_ccf_network.sh +++ b/ledgers/ccf/scripts/start_ccf_network.sh @@ -152,10 +152,15 @@ try ${F_CCF_PDO_DIR}/bin/ccf_generate_ledger_authority \ # enclave is built. if [ "${SGX_MODE}" == "SIM" ]; then - say set check_attestation to false in SGX SIM mode - try ${F_CCF_PDO_DIR}/bin/ccf_register_enclave_policy \ + say setting check_attestation to false in SGX SIM mode + try ${F_CCF_PDO_DIR}/bin/ccf_set_attestation_check_flag \ --logfile __screen__ --loglevel WARNING \ - --interface ${F_INTERFACE_ADDRESS} --port ${F_PORT} + --interface ${F_INTERFACE_ADDRESS} --port ${F_PORT} --no-attestation +else + say setting check_attestation to true + try ${F_CCF_PDO_DIR}/bin/ccf_set_attestation_check_flag \ + --logfile __screen__ --loglevel WARNING \ + --interface ${F_INTERFACE_ADDRESS} --port ${F_PORT} --attestation fi say save the ledger authority key diff --git a/ledgers/ccf/setup.py b/ledgers/ccf/setup.py index 8cd96621..a2da7b75 100644 --- a/ledgers/ccf/setup.py +++ b/ledgers/ccf/setup.py @@ -71,7 +71,8 @@ 'ccf_ping_test=pdo.ledgers.ccf.scripts.ping_test:Main', 'ccf_generate_ledger_authority=pdo.ledgers.ccf.scripts.generate_ledger_authority:Main', 'ccf_fetch_ledger_authority=pdo.ledgers.ccf.scripts.fetch_ledger_authority:Main', - 'ccf_register_enclave_policy=pdo.ledgers.ccf.scripts.register_enclave_attestation_verification_policy:Main', + 'ccf_set_attestation_check_flag=pdo.ledgers.ccf.scripts.set_attestation_check_flag:Main', + 'ccf_set_expected_sgx_measurements=pdo.ledgers.ccf.scripts.set_expected_sgx_measurements:Main', ] } ) diff --git a/ledgers/ccf/transaction_processor/enclave_registry.h b/ledgers/ccf/transaction_processor/enclave_registry.h index 8e23af2f..97124e87 100644 --- a/ledgers/ccf/transaction_processor/enclave_registry.h +++ b/ledgers/ccf/transaction_processor/enclave_registry.h @@ -19,17 +19,22 @@ using namespace std; namespace ccf { - - struct ContractEnclaveAttestationVerificationPolicy { + struct ContractEnclaveAttestionCheckFlag { bool check_attestation; + }; + + DECLARE_JSON_TYPE(ContractEnclaveAttestionCheckFlag); + DECLARE_JSON_REQUIRED_FIELDS(ContractEnclaveAttestionCheckFlag, + check_attestation); + + struct ContractEnclaveExpectedSGXMeasurements { string mrenclave; string basename; string ias_public_key; }; - DECLARE_JSON_TYPE(ContractEnclaveAttestationVerificationPolicy); - DECLARE_JSON_REQUIRED_FIELDS(ContractEnclaveAttestationVerificationPolicy, - check_attestation, + DECLARE_JSON_TYPE(ContractEnclaveExpectedSGXMeasurements); + DECLARE_JSON_REQUIRED_FIELDS(ContractEnclaveExpectedSGXMeasurements, mrenclave, basename, ias_public_key); @@ -118,9 +123,14 @@ namespace ccf }; }; - struct RegisterContractEnclaveAttestationVerificationPolicy { + struct RegisterContractEnclaveAttestionCheckFlag { struct In { bool check_attestation; + }; + }; + + struct RegisterContractEnclaveExpectedSGXMeasurements { + struct In { string mrenclave; string basename; string ias_public_key; @@ -138,7 +148,10 @@ namespace ccf DECLARE_JSON_REQUIRED_FIELDS(Verify_enclave::Out, verifying_key, encryption_key, proof_data, last_registration_block_context, \ owner_id, signature); - DECLARE_JSON_TYPE(RegisterContractEnclaveAttestationVerificationPolicy::In); - DECLARE_JSON_REQUIRED_FIELDS(RegisterContractEnclaveAttestationVerificationPolicy::In, check_attestation, mrenclave, basename, ias_public_key); + DECLARE_JSON_TYPE(RegisterContractEnclaveAttestionCheckFlag::In); + DECLARE_JSON_REQUIRED_FIELDS(RegisterContractEnclaveAttestionCheckFlag::In, check_attestation); + + DECLARE_JSON_TYPE(RegisterContractEnclaveExpectedSGXMeasurements::In); + DECLARE_JSON_REQUIRED_FIELDS(RegisterContractEnclaveExpectedSGXMeasurements::In, mrenclave, basename, ias_public_key); } diff --git a/ledgers/ccf/transaction_processor/pdo_tp.cpp b/ledgers/ccf/transaction_processor/pdo_tp.cpp index ba72b1d5..149cec10 100644 --- a/ledgers/ccf/transaction_processor/pdo_tp.cpp +++ b/ledgers/ccf/transaction_processor/pdo_tp.cpp @@ -39,7 +39,8 @@ namespace ccfapp TPHandlerRegistry ::TPHandlerRegistry (AbstractNodeContext& context): UserEndpointRegistry(context), - attestation_policy_table("attestation_policy"), + contract_enclave_expected_sgx_measurements("contract_enclave_expected_sgx_measurements"), + contract_enclave_check_attestation_flag("contract_enclave_check_attestation_flag"), enclavetable("enclaves"), contracttable("contracts"), ccltable("ccl_updates"), @@ -54,26 +55,70 @@ namespace ccfapp }; //====================================================================================================== - // register enclave expected measurements (member method) - auto set_contract_enclave_attestatation_verification_policy = [this](auto& ctx, const nlohmann::json& params) { + // register contract enclave attestation check flag (member method) + auto set_contract_enclave_attestation_check_flag = [this](auto& ctx, const nlohmann::json& params) { - const auto in = params.get(); + const auto in = params.get(); - // get the current measurements view - auto attestation_policy_view = ctx.tx.rw(attestation_policy_table); + // get the current view of contract_enclave_check_attestation_flag + auto check_attestation_flag_view = ctx.tx.rw(contract_enclave_check_attestation_flag); + + // Current PDO policy permits the flag to be set only once. Check if already set. + + // Below we check the ccf node has a local copy of the attestation flag. If yes, an error + // is returned. (Note that global commit of the flag might be pending, and this is OK). + auto check_attestation_flag_check = check_attestation_flag_view->get(PDO_ENCLAVE_CHECK_ATTESTATION_FLAG); + if (check_attestation_flag_check.has_value()){ + return ccf::make_error( + HTTP_STATUS_BAD_REQUEST, ccf::errors::InvalidInput,"Attesation check flag can be set only once"); + } // collect the data to be stored - ContractEnclaveAttestationVerificationPolicy attestation_policy; + ContractEnclaveAttestionCheckFlag check_attestation_flag; + check_attestation_flag.check_attestation = in.check_attestation; + + //store the data + check_attestation_flag_view->put(PDO_ENCLAVE_CHECK_ATTESTATION_FLAG, check_attestation_flag); - attestation_policy.check_attestation = in.check_attestation; - if(in.check_attestation){ - attestation_policy.mrenclave = in.mrenclave; - attestation_policy.basename = in.basename; - attestation_policy.ias_public_key = in.ias_public_key; + return ccf::make_success(true); + }; + + // register PDO enclave expected SGX measurements (member method) + // Note that this RPC may be called only setting the + // set_contract_enclave_attestation_check_flag to true. + auto set_contract_enclave_expected_sgx_measurements = [this](auto& ctx, const nlohmann::json& params) { + + //ensure that attestation check flag is true; otherwise throw error + + // get the current view of contract_enclave_check_attestation_flag + auto check_attestation_flag_view = ctx.tx.rw(contract_enclave_check_attestation_flag); + auto check_attestation_flag_global = check_attestation_flag_view->get_globally_committed(PDO_ENCLAVE_CHECK_ATTESTATION_FLAG); + if (!check_attestation_flag_global.has_value()){ + return ccf::make_error( + HTTP_STATUS_BAD_REQUEST, ccf::errors::InvalidInput,"Please set the check-attestation flag before providing expected measurements"); + } + auto check_attestation_flag = check_attestation_flag_global.value(); + if (!check_attestation_flag.check_attestation){ + return ccf::make_error( + HTTP_STATUS_BAD_REQUEST, ccf::errors::InvalidInput,"Please enable attesation check before providing expected measurements"); } + // pre-conditions are met. get expected sgx measurements from input and save them + + // check input schema compliance + const auto in = params.get(); + + // get the current measurements view + auto contract_enclave_expected_sgx_measurements_view = ctx.tx.rw(contract_enclave_expected_sgx_measurements); + + // collect the data to be stored + ContractEnclaveExpectedSGXMeasurements expected_sgx_measurements; + expected_sgx_measurements.mrenclave = in.mrenclave; + expected_sgx_measurements.basename = in.basename; + expected_sgx_measurements.ias_public_key = in.ias_public_key; + //store the data - attestation_policy_view->put(PDO_ENCLAVE_ATTESTATION_POLICY, attestation_policy); + contract_enclave_expected_sgx_measurements_view->put(PDO_ENCLAVE_EXPECTED_SGX_MEASUREMENTS, expected_sgx_measurements); return ccf::make_success(true); }; @@ -166,18 +211,25 @@ namespace ccfapp } //Determine if enclave attestation check is enabled or not - auto attestation_policy_view = ctx.tx.rw(attestation_policy_table); - - // First ensure that any policy has been set. Else, fail the rpc. - auto attestation_policy_global = attestation_policy_view->get_globally_committed(PDO_ENCLAVE_ATTESTATION_POLICY); - if (!attestation_policy_global.has_value()){ + auto check_attestation_flag_view = ctx.tx.rw(contract_enclave_check_attestation_flag); + auto check_attestation_flag_global = check_attestation_flag_view->get_globally_committed(PDO_ENCLAVE_CHECK_ATTESTATION_FLAG); + if (!check_attestation_flag_global.has_value()){ return ccf::make_error( - HTTP_STATUS_BAD_REQUEST, ccf::errors::InvalidInput, "No attestation policy has been set. Enclave cannot be registered"); + HTTP_STATUS_BAD_REQUEST, ccf::errors::InvalidInput, "No value set for attestation-check flag. Enclave cannot be registered"); } - auto attestation_policy=attestation_policy_global.value(); + auto check_attestation_flag = check_attestation_flag_global.value(); + if(check_attestation_flag.check_attestation){ - if(attestation_policy.check_attestation){ + // ensure that expected measurements are set + auto expected_sgx_measurements_view = ctx.tx.rw(contract_enclave_expected_sgx_measurements); + auto expected_sgx_measurements_global = expected_sgx_measurements_view->get_globally_committed(PDO_ENCLAVE_EXPECTED_SGX_MEASUREMENTS); + if (!check_attestation_flag_global.has_value()){ + return ccf::make_error( + HTTP_STATUS_BAD_REQUEST, ccf::errors::InvalidInput, "Expected sgx measurents have not been set. Enclave cannot be registered"); + } + + auto expected_sgx_measurements = expected_sgx_measurements_global.value(); //ensure that proof data is not empty if(in.proof_data.empty()) { @@ -214,7 +266,7 @@ namespace ccfapp string verification_report_string = enclave_proof_data.verification_report; // verify ias report signature - if (!verify_ias_signature(ias_signature, attestation_policy.ias_public_key, verification_report_string)){ + if (!verify_ias_signature(ias_signature, expected_sgx_measurements.ias_public_key, verification_report_string)){ return ccf::make_error( HTTP_STATUS_BAD_REQUEST, ccf::errors::InvalidInput, "unable to verify IAS report signature for registering enclave"); } @@ -259,7 +311,7 @@ namespace ccfapp std::vector mrEnclaveFromReport_vector(mrEnclaveFromReport.m, mrEnclaveFromReport.m + SGX_HASH_SIZE); std::string mrEnclavFromReport_hex = ds::to_hex(mrEnclaveFromReport_vector); transform(mrEnclavFromReport_hex.begin(), mrEnclavFromReport_hex.end(), mrEnclavFromReport_hex.begin(), ::toupper); - if (mrEnclavFromReport_hex != attestation_policy.mrenclave) { + if (mrEnclavFromReport_hex != expected_sgx_measurements.mrenclave) { return ccf::make_error(HTTP_STATUS_BAD_REQUEST, ccf::errors::InvalidInput, "Enclave attestation report verification Failed. Invalid MREnclave"); } @@ -273,7 +325,7 @@ namespace ccfapp std::vector basenameFromReport_vector(mrBasename.name, mrBasename.name + BASENAME_SIZE); std::string basenameFromReport_hex = ds::to_hex(basenameFromReport_vector); transform(basenameFromReport_hex.begin(), basenameFromReport_hex.end(), basenameFromReport_hex.begin(), ::toupper); - if (basenameFromReport_hex != attestation_policy.basename) { + if (basenameFromReport_hex != expected_sgx_measurements.basename) { return ccf::make_error( HTTP_STATUS_BAD_REQUEST, ccf::errors::InvalidInput, "Enclave attestation report verification Failed. Invalid enclave base name"); } @@ -912,9 +964,15 @@ namespace ccfapp member_cert_sign_required).install(); make_endpoint( - SET_CONTRACT_ENCLAVE_ATTESTATION_VERIFICATION_POLICY, + SET_CONTRACT_ENCLAVE_CHECK_ATTESTATION_FLAG, + HTTP_POST, + json_adapter(set_contract_enclave_attestation_check_flag), + member_cert_sign_required).install(); + + make_endpoint( + SET_CONTRACT_ENCLAVE_EXPECTED_SGX_MEASUREMENTS, HTTP_POST, - json_adapter(set_contract_enclave_attestatation_verification_policy), + json_adapter(set_contract_enclave_expected_sgx_measurements), member_cert_sign_required).install(); make_endpoint( diff --git a/ledgers/ccf/transaction_processor/pdo_tp.h b/ledgers/ccf/transaction_processor/pdo_tp.h index 8a16c9d7..e2810aa2 100644 --- a/ledgers/ccf/transaction_processor/pdo_tp.h +++ b/ledgers/ccf/transaction_processor/pdo_tp.h @@ -56,7 +56,8 @@ namespace ccfapp DECLARE_JSON_REQUIRED_FIELDS(Get_Ledger_Key::Out, verifying_key); // utility constants - const string PDO_ENCLAVE_ATTESTATION_POLICY{"pdo_enclave_attestation_policy"}; + const string PDO_ENCLAVE_EXPECTED_SGX_MEASUREMENTS{"pdo_enclave_expected_sgx_measurements"}; + const string PDO_ENCLAVE_CHECK_ATTESTATION_FLAG{"pdo_enclave_check_attestation_flag"}; const string OK_QUOTE_STATUS{"OK"}; const string GROUP_OUT_OF_DATE_QUOTE_STATUS{"GROUP_OUT_OF_DATE"}; const string SW_HARDENING_NEEDED_QUOTE_STATUS{"SW_HARDENING_NEEDED"}; @@ -68,7 +69,8 @@ namespace ccfapp //methods that write static constexpr auto REGISTER_ENCLAVE = "register_enclave"; - static constexpr auto SET_CONTRACT_ENCLAVE_ATTESTATION_VERIFICATION_POLICY = "set_contract_enclave_attestatation_verification_policy"; + static constexpr auto SET_CONTRACT_ENCLAVE_CHECK_ATTESTATION_FLAG = "set_contract_enclave_check_attestatation_flag"; + static constexpr auto SET_CONTRACT_ENCLAVE_EXPECTED_SGX_MEASUREMENTS = "set_contract_enclave_expected_sgx_measurements"; static constexpr auto REGISTER_CONTRACT = "register_contract"; static constexpr auto ADD_ENCLAVE_TO_CONTRACT ="add_enclave_to_contract"; static constexpr auto INITIALIZE_CONTRACT_STATE ="ccl_initialize"; @@ -89,10 +91,13 @@ namespace ccfapp { private: - kv::Map attestation_policy_table; - // There is a single entry with key PDO_ENCLAVE_ATTESTATION_POLICY. + kv::Map contract_enclave_expected_sgx_measurements; + // There is a single entry with key PDO_ENCLAVE_EXPECTED_SGX_MEASUREMENTS. // Only the CCF Governing body can update this entry. // Can be generalized if multiple enclave "types" need to be verified. + // Also, the expected measurements are used only if the check_attestation_flag is True + kv::Map contract_enclave_check_attestation_flag; + // key is PDO_ENCLAVE_CHECK_ATTESTATION_FLAG kv::Map enclavetable; // key is encalve_id kv::Map contracttable; // key is contract_id kv::Map ccltable; // key is contract_id + state_hash (string addition)