From 1c8813256ea95aa596e52859d9886af9f7adcf7d Mon Sep 17 00:00:00 2001 From: Mic Bowman Date: Wed, 11 Jun 2025 14:37:47 -0600 Subject: [PATCH 1/5] Make the exception log go away if shell verbose mode is set Signed-off-by: Mic Bowman --- client/pdo/client/builder/shell.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/pdo/client/builder/shell.py b/client/pdo/client/builder/shell.py index 1384a886..d9287b80 100644 --- a/client/pdo/client/builder/shell.py +++ b/client/pdo/client/builder/shell.py @@ -209,5 +209,5 @@ def run_shell_command(command_name, module_name) : command(state, bindings, args) except Exception as e : builder_command_base.display_error("Command failed: {}".format(str(e))) - logger.exception(e) + if builder_command_base.verbose: logger.exception(e) sys.exit(-1) From a1f06017f558864a3af56af9527548a60ebd9db1 Mon Sep 17 00:00:00 2001 From: Mic Bowman Date: Wed, 11 Jun 2025 16:43:44 -0600 Subject: [PATCH 2/5] Update client/pdo/client/builder/shell.py Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Signed-off-by: Mic Bowman --- client/pdo/client/builder/shell.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/pdo/client/builder/shell.py b/client/pdo/client/builder/shell.py index d9287b80..ad97632a 100644 --- a/client/pdo/client/builder/shell.py +++ b/client/pdo/client/builder/shell.py @@ -209,5 +209,6 @@ def run_shell_command(command_name, module_name) : command(state, bindings, args) except Exception as e : builder_command_base.display_error("Command failed: {}".format(str(e))) - if builder_command_base.verbose: logger.exception(e) + if builder_command_base.verbose: + logger.exception(e) sys.exit(-1) From a7253b952c2795487554f41289d27445b6755e30 Mon Sep 17 00:00:00 2001 From: Mic Bowman Date: Wed, 11 Jun 2025 17:00:24 -0600 Subject: [PATCH 3/5] remove secp256k1 python library Signed-off-by: Mic Bowman --- build/python_requirements.txt | 1 - python/pdo/common/keys.py | 47 ----------------------------------- 2 files changed, 48 deletions(-) diff --git a/build/python_requirements.txt b/build/python_requirements.txt index 00cd3d2a..1a79e20f 100644 --- a/build/python_requirements.txt +++ b/build/python_requirements.txt @@ -6,7 +6,6 @@ loguru>=0.6.0 mergedeep>=1.3.4 requests>=2.28.2 requests-toolbelt>=0.10.1 -secp256k1==0.13.2 toml>=0.10.2 PyYAML>=6.0 Twisted>=22.10.0 diff --git a/python/pdo/common/keys.py b/python/pdo/common/keys.py index 82ada64c..2a24349b 100644 --- a/python/pdo/common/keys.py +++ b/python/pdo/common/keys.py @@ -22,8 +22,6 @@ logger = logging.getLogger(__name__) import binascii -import secp256k1 - # ----------------------------------------------------------------- # ----------------------------------------------------------------- @@ -49,51 +47,6 @@ def read_transaction_keys_from_file(key_file, search_path, \ return txn_keys -# ----------------------------------------------------------------- -# ----------------------------------------------------------------- -class TransactionKeys(object) : - """ - Wrapper for managing Sawtooth transaction keys - """ - - @classmethod - def read_from_file(cls, file_name, search_path = ['.', './keys']) : - full_file = putils.find_file_in_path(file_name, search_path) - with open(full_file, "r") as ff : - hex_encoded_private_key = ff.read() - - priv = binascii.unhexlify(hex_encoded_private_key) - return cls(secp256k1.PrivateKey(priv)) - - @classmethod - def from_hex(cls, hex_encoded_private_key) : - priv = binascii.unhexlify(hex_encoded_private_key) - return cls(secp256k1.PrivateKey(priv)) - - def __init__(self, private_key = None) : - if private_key == None : - private_key = secp256k1.PrivateKey() - - self.public_key = private_key.pubkey - self.private_key = private_key - - @property - def hashed_identity(self) : - key_byte_array = crypto.string_to_byte_array(self.txn_public) - hashed_txn_key = crypto.compute_message_hash(key_byte_array) - encoded_hashed_key = crypto.byte_array_to_hex(hashed_txn_key) - encoded_hashed_key = encoded_hashed_key.lower() - return encoded_hashed_key - - @property - def txn_private(self) : - return self.private_key.serialize() - - @property - def txn_public(self) : - return self.public_key.serialize().hex() - - # ----------------------------------------------------------------- # ----------------------------------------------------------------- class EnclaveKeys(object) : From db0925d9bf7ab853e260c4a1b3d9e7b84bc37f91 Mon Sep 17 00:00:00 2001 From: Mic Bowman Date: Tue, 17 Jun 2025 15:18:28 -0600 Subject: [PATCH 4/5] Address a few more python setuptools upgrade issues The current version of python setuptools no longer puts binary files in the same name directory tree as the python libraries. As a result, the eservice and pservice enclaves could not be found and loaded. This commit addresses the problem with several changes: 1) the names of the enclave libraries are now unique (libpdo-eservice-enclave.signed.so and libpdo-pservice-enclave.signed.so) 2) the enclave libraries are installed into the PDO_HOME directory tree (in the lib directory). This directory is now created when the rest of the enviroment is created. 3) the search path used by the pservice and eservice python modules reflect the new location. 4) cachetools is explicitly installed Signed-off-by: Mic Bowman --- build/Makefile | 1 + build/python_requirements.txt | 1 + eservice/Makefile | 2 +- eservice/lib/libpdo_enclave/CMakeLists.txt | 2 +- eservice/pdo/eservice/pdo_enclave.py | 29 ++++++++++++++-------- eservice/setup.py | 5 ++-- pservice/Makefile | 2 +- pservice/lib/libpdo_enclave/CMakeLists.txt | 2 +- pservice/pdo/pservice/pdo_enclave.py | 24 +++++++++--------- pservice/setup.py | 5 ++-- 10 files changed, 42 insertions(+), 31 deletions(-) diff --git a/build/Makefile b/build/Makefile index c94817dc..d44cde3a 100644 --- a/build/Makefile +++ b/build/Makefile @@ -89,6 +89,7 @@ $(DSTDIR) : @mkdir -p $(DSTDIR)/opt/pdo/etc/keys/sgx @mkdir -p $(DSTDIR)/opt/pdo/etc/keys/ledger @mkdir -p $(DSTDIR)/opt/pdo/keys + @mkdir -p $(DSTDIR)/opt/pdo/lib @mkdir -p $(DSTDIR)/opt/pdo/logs verify-pre-build : diff --git a/build/python_requirements.txt b/build/python_requirements.txt index 1a79e20f..0335cf5d 100644 --- a/build/python_requirements.txt +++ b/build/python_requirements.txt @@ -1,4 +1,5 @@ build>=0.10.0 +cachetools>=5.5.2 colorlog>=6.7.0 importlib_resources>=6.0.0 lmdb>=1.4.0 diff --git a/eservice/Makefile b/eservice/Makefile index f4171176..186debaf 100644 --- a/eservice/Makefile +++ b/eservice/Makefile @@ -25,7 +25,7 @@ endif EGG_FILE=dist/pdo_eservice-${MOD_VERSION}-py${PY_VERSION}-linux-x86_64.egg -ENCLAVE_LIB=deps/bin/libpdo-enclave.signed.so +ENCLAVE_LIB=deps/bin/libpdo-eservice-enclave.signed.so SWIG_SOURCES = \ pdo_enclave_internal.i\ diff --git a/eservice/lib/libpdo_enclave/CMakeLists.txt b/eservice/lib/libpdo_enclave/CMakeLists.txt index 22dcc8c5..58d1b880 100644 --- a/eservice/lib/libpdo_enclave/CMakeLists.txt +++ b/eservice/lib/libpdo_enclave/CMakeLists.txt @@ -14,7 +14,7 @@ CMAKE_MINIMUM_REQUIRED(VERSION 3.10 FATAL_ERROR) -PROJECT(libpdo-enclave CXX C) +PROJECT(libpdo-eservice-enclave CXX C) # XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX # Source Code diff --git a/eservice/pdo/eservice/pdo_enclave.py b/eservice/pdo/eservice/pdo_enclave.py index 5b707e97..a18c8a73 100644 --- a/eservice/pdo/eservice/pdo_enclave.py +++ b/eservice/pdo/eservice/pdo_enclave.py @@ -66,7 +66,7 @@ # ----------------------------------------------------------------- # ----------------------------------------------------------------- def __find_enclave_library(config) : - enclave_file_name = 'libpdo-enclave.signed.so' + enclave_file_name = 'libpdo-eservice-enclave.signed.so' enclave_file_path = None if config : @@ -78,18 +78,18 @@ def __find_enclave_library(config) : if os.path.exists(filep) : return filep else : + install_directory = os.environ.get('PDO_HOME', '/opt/pdo') script_directory = os.path.abspath(os.path.dirname(os.path.realpath(__file__))) + search_path = [ script_directory, - os.path.abspath(os.path.join(script_directory, '..')), - os.path.abspath(os.path.join(script_directory, '..', 'lib')), - os.path.abspath(os.path.join(script_directory, '..', '..')), - os.path.abspath(os.path.join(script_directory, '..', '..', 'lib')), - os.path.abspath(os.path.join('/usr', 'lib')) + os.path.abspath(os.path.join(install_directory, 'lib')), ] return putils.find_file_in_path(enclave_file_name, search_path) + raise IOError("Could not find enclave shared object: {}".format(enclave_file_name)) + # ----------------------------------------------------------------- # ----------------------------------------------------------------- def update_sig_rl(): @@ -149,7 +149,8 @@ def initialize_with_configuration(config) : '{}'.format( ', '.join(sorted(list(missing_keys))))) - NumberOfEnclaves = int(config.get('NumberOfEnclaves', 1)) + # NumberOfEnclaves = int(config.get('NumberOfEnclaves', 1)) + NumberOfEnclaves = 2 try: spid = Path(os.path.join(config['sgx_key_root'], "sgx_spid.txt")).read_text().strip() @@ -166,10 +167,16 @@ def initialize_with_configuration(config) : if not _pdo: signed_enclave = __find_enclave_library(config) - logger.debug("Attempting to load enclave at: %s", signed_enclave) - _pdo = enclave.pdo_enclave_info(signed_enclave, spid, NumberOfEnclaves) - logger.info("Basename: %s", get_enclave_basename()) - logger.info("MRENCLAVE: %s", get_enclave_measurement()) + logger.error("Attempting to load enclave at: %s", signed_enclave) + logger.error(f'SPID: {spid}, NumberOfEnclaves: {NumberOfEnclaves}') + try : + _pdo = enclave.pdo_enclave_info(signed_enclave, spid, NumberOfEnclaves) + except Exception as e: + logger.exception(e) + raise e + + logger.error("Basename: %s", get_enclave_basename()) + logger.error("MRENCLAVE: %s", get_enclave_measurement()) sig_rl_updated = False while not sig_rl_updated: diff --git a/eservice/setup.py b/eservice/setup.py index 96768840..ed32c8b1 100644 --- a/eservice/setup.py +++ b/eservice/setup.py @@ -33,6 +33,7 @@ bin_dir = os.path.join(install_root_dir, "bin") dat_dir = os.path.join(install_root_dir, "data") etc_dir = os.path.join(install_root_dir, "etc") +lib_dir = os.path.join(install_root_dir, "lib") log_dir = os.path.join(install_root_dir, "logs") key_dir = os.path.join(install_root_dir, "keys") @@ -44,11 +45,11 @@ (etc_dir, []), (log_dir, []), (key_dir, []), - ('lib', [ os.path.join(script_dir, 'deps/bin/libpdo-enclave.signed.so')]) + (lib_dir, [ os.path.join(script_dir, 'deps/bin/libpdo-eservice-enclave.signed.so')]) ] ext_deps = [ - 'deps/bin/libpdo-enclave.signed.so' + 'deps/bin/libpdo-eservice-enclave.signed.so' ] ## ----------------------------------------------------------------- diff --git a/pservice/Makefile b/pservice/Makefile index edbc802e..b62945b3 100644 --- a/pservice/Makefile +++ b/pservice/Makefile @@ -25,7 +25,7 @@ endif EGG_FILE=dist/pdo_pservice-${MOD_VERSION}-py${PY_VERSION}-linux-x86_64.egg -ENCLAVE_LIB=deps/bin/libpdo-enclave.signed.so +ENCLAVE_LIB=deps/bin/libpdo-pservice-enclave.signed.so SWIG_SOURCES = \ pdo_enclave_internal.i\ diff --git a/pservice/lib/libpdo_enclave/CMakeLists.txt b/pservice/lib/libpdo_enclave/CMakeLists.txt index 738f21c9..df842eb3 100644 --- a/pservice/lib/libpdo_enclave/CMakeLists.txt +++ b/pservice/lib/libpdo_enclave/CMakeLists.txt @@ -14,7 +14,7 @@ CMAKE_MINIMUM_REQUIRED(VERSION 3.10 FATAL_ERROR) -PROJECT(libpdo-enclave C CXX) +PROJECT(libpdo-pservice-enclave C CXX) # XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX # Source Code diff --git a/pservice/pdo/pservice/pdo_enclave.py b/pservice/pdo/pservice/pdo_enclave.py index bdb8e945..1db91860 100644 --- a/pservice/pdo/pservice/pdo_enclave.py +++ b/pservice/pdo/pservice/pdo_enclave.py @@ -25,6 +25,7 @@ from pdo.pservice.utility import ias_client import pdo.common.crypto as crypto +import pdo.common.utility as putils import pdo.pservice.enclave.pdo_enclave_internal as enclave import logging @@ -59,30 +60,29 @@ # ----------------------------------------------------------------- # ----------------------------------------------------------------- def __find_enclave_library(config) : - enclave_file_name = config.get('enclave_library', 'libpdo-enclave.signed.so') - enclave_file_path = config.get('enclave_library_path') + enclave_file_name = 'libpdo-pservice-enclave.signed.so' + enclave_file_path = None + + if config : + enclave_file_name = config.get('enclave_library', enclave_file_name) + enclave_file_path = config.get('enclave_library_path', enclave_file_path) if enclave_file_path : enclave_file = os.path.join(enclave_file_path, enclave_file_name); if os.path.exists(enclave_file) : return enclave_file else : + install_directory = os.environ.get('PDO_HOME', '/opt/pdo') script_directory = os.path.abspath(os.path.dirname(os.path.realpath(__file__))) + search_path = [ script_directory, - os.path.abspath(os.path.join(script_directory, '..')), - os.path.abspath(os.path.join(script_directory, '..', 'lib')), - os.path.abspath(os.path.join(script_directory, '..', '..')), - os.path.abspath(os.path.join(script_directory, '..', '..', 'lib')), - os.path.abspath(os.path.join('/usr', 'lib')) + os.path.abspath(os.path.join(install_directory, 'lib')), ] - for path in search_path : - enclave_file = os.path.join(path, enclave_file_name) - if os.path.exists(enclave_file) : - return enclave_file + return putils.find_file_in_path(enclave_file_name, search_path) - raise IOError("Could not find enclave shared object") + raise IOError("Could not find enclave shared object: {}".format(enclave_file_name)) # ----------------------------------------------------------------- # ----------------------------------------------------------------- diff --git a/pservice/setup.py b/pservice/setup.py index 47f3d9cf..1019a20b 100644 --- a/pservice/setup.py +++ b/pservice/setup.py @@ -33,6 +33,7 @@ bin_dir = os.path.join(install_root_dir, "bin") dat_dir = os.path.join(install_root_dir, "data") etc_dir = os.path.join(install_root_dir, "etc") +lib_dir = os.path.join(install_root_dir, "lib") log_dir = os.path.join(install_root_dir, "logs") key_dir = os.path.join(install_root_dir, "keys") @@ -42,11 +43,11 @@ (etc_dir, [ 'etc/sample_pservice.toml' ]), (log_dir, []), (key_dir, []), - ('lib', [ os.path.join(script_dir, 'deps/bin/libpdo-enclave.signed.so')]) + (lib_dir, [ os.path.join(script_dir, 'deps/bin/libpdo-pservice-enclave.signed.so')]) ] ext_deps = [ - 'deps/bin/libpdo-enclave.signed.so' + 'deps/bin/libpdo-pservice-enclave.signed.so' ] ## ----------------------------------------------------------------- From 226f21a7cf9fcd6333369a2325fcc79ed69a6509 Mon Sep 17 00:00:00 2001 From: Mic Bowman Date: Tue, 17 Jun 2025 17:39:08 -0600 Subject: [PATCH 5/5] address PR feedback Signed-off-by: Mic Bowman --- eservice/pdo/eservice/pdo_enclave.py | 19 ++++++++----------- pservice/pdo/pservice/pdo_enclave.py | 22 ++++++++++------------ 2 files changed, 18 insertions(+), 23 deletions(-) diff --git a/eservice/pdo/eservice/pdo_enclave.py b/eservice/pdo/eservice/pdo_enclave.py index a18c8a73..b218f9af 100644 --- a/eservice/pdo/eservice/pdo_enclave.py +++ b/eservice/pdo/eservice/pdo_enclave.py @@ -149,8 +149,9 @@ def initialize_with_configuration(config) : '{}'.format( ', '.join(sorted(list(missing_keys))))) - # NumberOfEnclaves = int(config.get('NumberOfEnclaves', 1)) - NumberOfEnclaves = 2 + NumberOfEnclaves = int(config.get('NumberOfEnclaves', 1)) + if NumberOfEnclaves < 1 or NumberOfEnclaves > 16: + raise ValueError("NumberOfEnclaves must be between 1 and 16, found {}".format(NumberOfEnclaves)) try: spid = Path(os.path.join(config['sgx_key_root'], "sgx_spid.txt")).read_text().strip() @@ -159,24 +160,20 @@ def initialize_with_configuration(config) : raise Exception("Unable to access SGX keys: {}".format(str(e))) if not _ias: - _ias = \ - ias_client.IasClient( - IasServer = config['ias_url'], - SpidApiKey = spid_api_key, - Spid = spid) + _ias = ias_client.IasClient(IasServer = config['ias_url'], SpidApiKey = spid_api_key, Spid = spid) if not _pdo: signed_enclave = __find_enclave_library(config) - logger.error("Attempting to load enclave at: %s", signed_enclave) - logger.error(f'SPID: {spid}, NumberOfEnclaves: {NumberOfEnclaves}') + logger.info("Attempting to load enclave at: %s", signed_enclave) + try : _pdo = enclave.pdo_enclave_info(signed_enclave, spid, NumberOfEnclaves) except Exception as e: logger.exception(e) raise e - logger.error("Basename: %s", get_enclave_basename()) - logger.error("MRENCLAVE: %s", get_enclave_measurement()) + logger.info("Basename: %s", get_enclave_basename()) + logger.info("MRENCLAVE: %s", get_enclave_measurement()) sig_rl_updated = False while not sig_rl_updated: diff --git a/pservice/pdo/pservice/pdo_enclave.py b/pservice/pdo/pservice/pdo_enclave.py index 1db91860..d507828b 100644 --- a/pservice/pdo/pservice/pdo_enclave.py +++ b/pservice/pdo/pservice/pdo_enclave.py @@ -138,11 +138,7 @@ def initialize_with_configuration(config) : missing_keys = valid_keys.difference(found_keys) if missing_keys: - raise \ - ValueError( - 'PDO enclave config file missing the following keys: ' - '{}'.format( - ', '.join(sorted(list(missing_keys))))) + raise ValueError('PDO enclave config file missing the following keys: {}'.format(', '.join(list(missing_keys)))) try: spid = Path(os.path.join(config['sgx_key_root'], "sgx_spid.txt")).read_text().strip() @@ -151,16 +147,18 @@ def initialize_with_configuration(config) : raise Exception("Unable to access SGX keys: {}".format(str(e))) if not _ias: - _ias = \ - ias_client.IasClient( - IasServer = config['ias_url'], - SpidApiKey = spid_api_key, - Spid = spid) + _ias = ias_client.IasClient(IasServer = config['ias_url'], SpidApiKey = spid_api_key, Spid = spid) if not _pdo: signed_enclave = __find_enclave_library(config) - logger.debug("Attempting to load enclave at: %s", signed_enclave) - _pdo = enclave.pdo_enclave_info(signed_enclave, spid) + logger.info("Attempting to load enclave at: %s", signed_enclave) + + try : + _pdo = enclave.pdo_enclave_info(signed_enclave, spid) + except Exception as e: + logger.exception(f'Failed to load enclave; {e}') + raise e + logger.info("Basename: %s", get_enclave_basename()) logger.info("MRENCLAVE: %s", get_enclave_measurement())