Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Changes to Fix Ledger APIs used to set Contract Enclave attestation policy #467

Conversation

prakashngit
Copy link
Contributor

This is an enabler PR to improve the current implementation of registration of contract enclave attestation policy with the ledger.

The current register_enclave_attestation_verification_policy member API that is used to register attestation policy with ledger is replaced with two member APIs: set_contract_enclave_check_attestation_flag and set_contract_enclave_expected_sgx_measurements.

set_contract_enclave_check_attestation_flag is invoked as part of ledger start up, and simply specifies whether attestation check should be enabled or not for contract enclaves. The expectation is to disable the flag for SGX_SIM mode and enable the flag for HW mode. If the flag is enabled, the second API set_contract_enclave_expected_sgx_measurements must be subsquently invoked by the member to provide expected values for mrenclave, basename and ias_public_key.

This PR does not specify when/how the second API gets invoked with HW mode. That will be addressed in a separate PR.

@prakashngit prakashngit added the enhancement New feature or request label Feb 13, 2024
Copy link
Member

@bvavala bvavala left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor comments, but it's good and other PRs can go from here.

Comment on lines 29 to 30
ContractHome = os.environ.get("PDO_HOME") or os.path.realpath("/opt/pdo")
CCF_Keys = os.environ.get("PDO_LEDGER_KEY_ROOT") or os.path.join(ContractHome, "ccf", "keys")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be cleaned up. ContractHome is not used and the keys should be in the ledger key root.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line 30 is consistent with other variable definitions, see for example line 29. We use this pattern all over pdo. nothing unique about 30.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, because it's old code that gets copy-pasted every time, but it's not used and never cleaned up.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think it is reasonable to have default values for variables. at best, this should be discussed as separate PR. the pattern is not restricted to ccf scripts.

Copy link
Contributor

@cmickeyb cmickeyb Feb 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there is a lot of clean up to be done on these scripts to make them match expectations. suggest we not worry too much about optimization and clarity & focus this PR on flow and function. See issue #469


# -----------------------------------------------------------------
def Main() :
default_output = os.path.join(CCF_Keys, 'ledger_authority.pem')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unused

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks, will remove.

ledgers/ccf/transaction_processor/pdo_tp.cpp Show resolved Hide resolved
@@ -36,6 +36,8 @@
log_dir = os.path.join(install_root_dir, "logs")
key_dir = os.path.join(install_root_dir, "keys")

register_sgx_expected_measurements_script = os.path.join(pdo_root_dir, "ledgers/ccf/scripts/set_contract_enclave_expected_sgx_measurements.py")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would maintain some naming consistency here, either register... or set....
Or maybe simply remove the variable and dump the path directly in datafile below.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks, will fix.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i would suggest we address issue #469 with all of the scripts. this is a reasonable start. but its going to be very difficult to manage in general.

Copy link
Contributor

@cmickeyb cmickeyb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally looks like what we need.
At a high level, I think we should address the general problem of installing the ccf python scripts as a high priority task that you can take advantage of.

@@ -36,6 +36,8 @@
log_dir = os.path.join(install_root_dir, "logs")
key_dir = os.path.join(install_root_dir, "keys")

register_sgx_expected_measurements_script = os.path.join(pdo_root_dir, "ledgers/ccf/scripts/set_contract_enclave_expected_sgx_measurements.py")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i would suggest we address issue #469 with all of the scripts. this is a reasonable start. but its going to be very difficult to manage in general.


# -----------------------------------------------------------------
# -----------------------------------------------------------------
Main()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

all of these would be a lot cleaner if we could assume that pdo client modules were installed. it would also make everything else a LOT more consistent and easy to maintain. we do not need these for ledger nodes, but they should be installable/runnable in the same way that every other pdo script is run on every other pdo node.

Copy link
Member

@bvavala bvavala left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there are inconsistencies in error handling.
The question is: how does a CCF client recognize errors (success + error string; or error + error string)?

CCF provides the make_success and make_error APIs for that. However, many times the current code seems to return success (instead of error) with an error string.
I would argue that "error + error string" is preferable -- but one way or the other is fine, so long as it's consistent.

// 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_success("Attesation check flag can be set only once");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be make_error? (besides, it says that an error is returned)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thats right will fix

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_success("Please enable attesation check before providing expected measurements");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(same as above)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks, fixed

}
auto check_attestation_flag = check_attestation_flag_global.value();
if (!check_attestation_flag.check_attestation){
return ccf::make_success("Please enable attesation check before providing expected measurements");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(same as above)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks, fixed

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_success("No attestation verification policy has been set. Enclave cannot be registered");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(same as above)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks, fixed

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_success("Expected sgx measurents have not been set. Enclave cannot be registered");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(same as above)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks, fixed

ledgers/ccf/transaction_processor/pdo_tp.cpp Show resolved Hide resolved
@prakashngit prakashngit force-pushed the Prakash.Fix_Ledger_APIs_for_attestation_policy_registration branch from 3366b95 to 68430c2 Compare February 21, 2024 05:03
@prakashngit prakashngit marked this pull request as ready for review February 21, 2024 05:04
Copy link
Member

@bvavala bvavala left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor corrections, I think it's good.

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()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
parser.print_help()
LOG.error('missing parameters')
parser.print_help()

Copy link
Contributor

@cmickeyb cmickeyb Feb 21, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually the print_help is standard. its an interactive command and any other command line parameter would generate the same response. in general... we are relying far too much on the logs for the response to interactive commands but we can address that separately. this one absolutely should not be logged however.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

leaving it as is.

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 attestation check flag: {}', str(e))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
LOG.error('failed to set contract enclave attestation check flag: {}', str(e))
LOG.error('failed to set contract enclave expected sgx measurements: {}', str(e))

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks, fixed

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 enable attesation check before providing expected measurements");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
HTTP_STATUS_BAD_REQUEST, ccf::errors::InvalidInput,"Please enable attesation check before providing expected measurements");
HTTP_STATUS_BAD_REQUEST, ccf::errors::InvalidInput,"Please set the check-attestation flag before providing expected measurements");

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks, fixed

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 attestation verification policy has been set. Enclave cannot be registered");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
HTTP_STATUS_BAD_REQUEST, ccf::errors::InvalidInput, "No attestation verification policy has been set. Enclave cannot be registered");
HTTP_STATUS_BAD_REQUEST, ccf::errors::InvalidInput, "No check-attestation flag has been set. Enclave cannot be registered");

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks, fixed

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");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
HTTP_STATUS_BAD_REQUEST, ccf::errors::InvalidInput,"Attesation check flag can be set only once");
HTTP_STATUS_BAD_REQUEST, ccf::errors::InvalidInput,"Check-attestation flag can be set only once");

ledgers/ccf/transaction_processor/pdo_tp.cpp Show resolved Hide resolved
ledgers/ccf/transaction_processor/pdo_tp.cpp Show resolved Hide resolved
…policy. Changes to address Review Comments have been squashed into the same commit.

Signed-off-by: Prakash Narayana Moorthy <[email protected]>
@prakashngit prakashngit force-pushed the Prakash.Fix_Ledger_APIs_for_attestation_policy_registration branch from 2dad0bd to 99a7478 Compare February 22, 2024 20:36
Copy link
Contributor

@cmickeyb cmickeyb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would still like a lot more documentation on what each of these scripts does. Please plan to provide updates to the readme (or use the docstrings in the python files) to provide a human readable (as in something that could be understood by someone who might want to use the script, NOT someone who wants to develop it).

@bvavala bvavala merged commit 955e2b7 into hyperledger-labs:main Feb 26, 2024
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants