From afbf31501632f76c05b2748a60ca8fd73b7faff3 Mon Sep 17 00:00:00 2001 From: Mic Bowman Date: Fri, 16 Feb 2024 15:49:25 -0800 Subject: [PATCH 1/2] Significant update to build and install process for ccf ledger Several parts of this commit: 1) move the ccf python scripts into their own directory and package them into an installable python wheel file; this should lay the structural foundation for supporting our own version of the CCF python client (which is not included in more recent versions of CCF). 2) canonicalize argument handling for the ccf python scripts; this moves all argument processing (including the common handling of creating the CCF client) into a single routine. All CCF python files should share the same structure and command line API. 3) split the build of the CCF ledger components into two pieces. The first piece builds and installs the python packages. Since these utilities are useful on any PDO node (client, service, ccf ledger), they can now be installed independently from the pdo tp. The second piece is the PDO TP itself which need only be installed on ccf ledger nodes. Signed-off-by: Mic Bowman --- build/cmake/ProjectVariables.cmake | 22 +++ build/cmake/Python.cmake | 53 +++++++ ledgers/ccf/.gitignore | 2 +- ledgers/ccf/CMakeLists.txt | 19 ++- ledgers/ccf/MANIFEST | 12 ++ ledgers/ccf/MANIFEST.in | 0 ledgers/ccf/Makefile | 34 +++-- ledgers/ccf/pdo/__init__.py | 15 ++ ledgers/ccf/pdo/ledgers/__init__.py | 13 ++ ledgers/ccf/pdo/ledgers/ccf/__init__.py | 13 ++ ledgers/ccf/pdo/ledgers/ccf/common.py | 144 ++++++++++++++++++ .../ccf/pdo/ledgers/ccf/scripts/__init__.py | 13 ++ .../ccf/scripts/configure_ccf_network.py | 87 +++++++++++ .../ccf}/scripts/fetch_ledger_authority.py | 57 ++----- .../ccf/scripts/generate_ledger_authority.py | 60 ++++++++ .../ccf/pdo/ledgers/ccf/scripts/ping_test.py | 58 +++++++ ...enclave_attestation_verification_policy.py | 90 +++++++++++ ledgers/ccf/scripts/configure_ccf_network.py | 144 ------------------ .../ccf/scripts/generate_ledger_authority.py | 118 -------------- ledgers/ccf/scripts/ping_test.py | 90 ----------- ...enclave_attestation_verification_policy.py | 132 ---------------- ledgers/ccf/scripts/start_ccf_network.sh | 6 +- ledgers/ccf/setup.py | 77 ++++++++++ .../ccf/transaction_processor/CMakeLists.txt | 29 ++++ 24 files changed, 733 insertions(+), 555 deletions(-) create mode 100644 build/cmake/Python.cmake create mode 100644 ledgers/ccf/MANIFEST create mode 100644 ledgers/ccf/MANIFEST.in create mode 100644 ledgers/ccf/pdo/__init__.py create mode 100644 ledgers/ccf/pdo/ledgers/__init__.py create mode 100644 ledgers/ccf/pdo/ledgers/ccf/__init__.py create mode 100644 ledgers/ccf/pdo/ledgers/ccf/common.py create mode 100644 ledgers/ccf/pdo/ledgers/ccf/scripts/__init__.py create mode 100755 ledgers/ccf/pdo/ledgers/ccf/scripts/configure_ccf_network.py rename ledgers/ccf/{ => pdo/ledgers/ccf}/scripts/fetch_ledger_authority.py (53%) create mode 100755 ledgers/ccf/pdo/ledgers/ccf/scripts/generate_ledger_authority.py create mode 100755 ledgers/ccf/pdo/ledgers/ccf/scripts/ping_test.py create mode 100755 ledgers/ccf/pdo/ledgers/ccf/scripts/register_enclave_attestation_verification_policy.py delete mode 100755 ledgers/ccf/scripts/configure_ccf_network.py delete mode 100755 ledgers/ccf/scripts/generate_ledger_authority.py delete mode 100755 ledgers/ccf/scripts/ping_test.py delete mode 100755 ledgers/ccf/scripts/register_enclave_attestation_verification_policy.py create mode 100644 ledgers/ccf/setup.py create mode 100644 ledgers/ccf/transaction_processor/CMakeLists.txt diff --git a/build/cmake/ProjectVariables.cmake b/build/cmake/ProjectVariables.cmake index a06484c7..36dee4fc 100644 --- a/build/cmake/ProjectVariables.cmake +++ b/build/cmake/ProjectVariables.cmake @@ -55,3 +55,25 @@ ELSE() ADD_COMPILE_OPTIONS(-Wno-deprecated) ADD_COMPILE_OPTIONS(-Wno-deprecated-declarations) ENDIF() + +IF (NOT DEFINED ENV{PDO_INSTALL_ROOT}) + MESSAGE(FATAL_ERROR "PDO_INSTALL_ROOT not defined") +ENDIF() +SET(PDO_INSTALL_ROOT $ENV{PDO_INSTALL_ROOT}) + +IF (NOT DEFINED ENV{PDO_SOURCE_ROOT}) + MESSAGE(FATAL_ERROR "PDO_SOURCE_ROOT not defined") +ENDIF() +SET(PDO_SOURCE_ROOT $ENV{PDO_SOURCE_ROOT}) + +# Get the current version using the get_version +# utility; note that this will provide 0.0.0 as +# the version if something goes wrong (like running +# without any annotated version tags) +EXECUTE_PROCESS( + COMMAND ./get_version + WORKING_DIRECTORY ${PDO_SOURCE_ROOT}/bin + OUTPUT_VARIABLE PDO_VERSION + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE +) diff --git a/build/cmake/Python.cmake b/build/cmake/Python.cmake new file mode 100644 index 00000000..088ae48f --- /dev/null +++ b/build/cmake/Python.cmake @@ -0,0 +1,53 @@ +# 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. + +# assumes that project variables have been +# set including PDO_INSTALL_ROOT and PDO_CONTRACT_VERSION + +IF (NOT DEFINED PDO_INSTALL_ROOT) + MESSAGE(FATAL_ERROR "PDO_INSTALL_ROOT not defined") +ENDIF() + +IF (NOT DEFINED PDO_VERSION) + MESSAGE(FATAL_ERROR "PDO_VERSION not defined") +ENDIF() + +SET(PIP "${PDO_INSTALL_ROOT}/bin/pip3" CACHE STRING "Pip executable in virtual environment") +SET(PYTHON "${PDO_INSTALL_ROOT}/bin/python3" CACHE STRING "Python executable in virtual environment") +SET(RESOURCE_INSTALLER "${PDO_INSTALL_ROOT}/bin/pdo-install-plugin-resources" CACHE STRING "PDO resource installer") +SET(WHEEL_PATH "${CMAKE_BINARY_DIR}/dist" CACHE STRING "Path where python wheels will be placed") + +FUNCTION(BUILD_WHEEL package) + SET(SOURCE ${CMAKE_CURRENT_SOURCE_DIR}) + SET(WHEEL_FILE "${WHEEL_PATH}/${package}-${PDO_VERSION}-py3-none-any.whl") + FILE(STRINGS "${SOURCE}/MANIFEST" MANIFEST) + + # adding the build and egg-info directories to the output means that + # they will be cleaned up with the global clean target + ADD_CUSTOM_COMMAND( + OUTPUT ${WHEEL_FILE} ${SOURCE}/${package}.egg-info + COMMAND ${PYTHON} + ARGS -m build --wheel --outdir ${WHEEL_PATH} + WORKING_DIRECTORY ${SOURCE} + DEPENDS ${MANIFEST}) + + ADD_CUSTOM_TARGET(${package}-package ALL DEPENDS ${WHEEL_FILE}) + + STRING(JOIN "\n" INSTALL_COMMAND + "MESSAGE(\"INSTALL ${package}\")" + "EXECUTE_PROCESS(COMMAND ${PIP} uninstall --yes ${WHEEL_FILE})" + "EXECUTE_PROCESS(COMMAND ${PIP} install ${WHEEL_FILE})" ) + + INSTALL(CODE ${INSTALL_COMMAND}) +ENDFUNCTION() diff --git a/ledgers/ccf/.gitignore b/ledgers/ccf/.gitignore index 378eac25..1b2211df 100644 --- a/ledgers/ccf/.gitignore +++ b/ledgers/ccf/.gitignore @@ -1 +1 @@ -build +build* diff --git a/ledgers/ccf/CMakeLists.txt b/ledgers/ccf/CMakeLists.txt index 457f9d06..fece9cf0 100644 --- a/ledgers/ccf/CMakeLists.txt +++ b/ledgers/ccf/CMakeLists.txt @@ -14,16 +14,15 @@ CMAKE_MINIMUM_REQUIRED(VERSION 3.16) -INCLUDE(${CCF_DIR}/cmake/preproject.cmake) -PROJECT(pdoenc LANGUAGES C CXX) -INCLUDE(${CCF_DIR}/cmake/ccf_app.cmake) +IF (NOT DEFINED ENV{PDO_SOURCE_ROOT}) + MESSAGE(FATAL_ERROR "PDO_SOURCE_ROOT not defined") +ENDIF() +SET(PDO_SOURCE_ROOT $ENV{PDO_SOURCE_ROOT}) -FIND_PACKAGE(ccf_virtual REQUIRED) +LIST(APPEND CMAKE_MODULE_PATH "${PDO_SOURCE_ROOT}/build/cmake") +INCLUDE(ProjectVariables) -# Add the PDO transaction processor target -add_ccf_app(pdoenc - SRCS transaction_processor/pdo_tp.cpp transaction_processor/verify_signatures.cpp - INCLUDE_DIRS ${CCF_DIR}/include/ccf ${CCF_DIR}/include/3rdparty ${CCF_DIR}/include -) +PROJECT(pdo_ccf_ledger) -INSTALL(TARGETS pdoenc.virtual DESTINATION lib) +INCLUDE(Python) +BUILD_WHEEL(pdo_ccf_ledger) diff --git a/ledgers/ccf/MANIFEST b/ledgers/ccf/MANIFEST new file mode 100644 index 00000000..f12ad2a0 --- /dev/null +++ b/ledgers/ccf/MANIFEST @@ -0,0 +1,12 @@ +MANIFEST.in +setup.py +pdo/__init__.py +pdo/ledgers/__init__.py +pdo/ledgers/ccf/__init__.py +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/generate_ledger_authority.py +pdo/ledgers/ccf/scripts/configure_ccf_network.py diff --git a/ledgers/ccf/MANIFEST.in b/ledgers/ccf/MANIFEST.in new file mode 100644 index 00000000..e69de29b diff --git a/ledgers/ccf/Makefile b/ledgers/ccf/Makefile index 1a96e38f..6c67e2cb 100644 --- a/ledgers/ccf/Makefile +++ b/ledgers/ccf/Makefile @@ -35,7 +35,14 @@ CCF_LEDGER_DIR ?= $(PDO_INSTALL_ROOT)/opt/pdo/ccf NINJA ?= ninja $(NINJA_OPTIONS) SCRIPTDIR ?= $(dir $(abspath $(lastword $(MAKEFILE_LIST)))) -BLDDIR := $(SCRIPTDIR)/build + +# Build the PDO TP in the transaction processor subdirectory +PDO_TP_SRCDIR := $(SCRIPTDIR)/transaction_processor +PDO_TP_BLDDIR := $(SCRIPTDIR)/transaction_processor/build + +# Build the Python wheel in this directory +PYTHON_SRCDIR := $(SCRIPTDIR) +PYTHON_BLDDIR := $(SCRIPTDIR)/build all: environment install @@ -76,22 +83,28 @@ $(CCF_LEDGER_DIR)/lib/python3.8 : pdo-environment # ----------------------------------------------------------------- build : build-pdo-tp -build-pdo-tp : $(BLDDIR) - cmake --build $(BLDDIR) +build-pdo-tp : $(PDO_TP_BLDDIR) + cmake --build $(PDO_TP_BLDDIR) -$(BLDDIR) : - cmake -S . -B $(BLDDIR) -GNinja \ +$(PDO_TP_BLDDIR) : + cmake -S $(PDO_TP_SRCDIR) -B $(PDO_TP_BLDDIR) -GNinja \ -DCCF_DIR=$(CCF_BASE) \ -DCOMPILE_TARGET=$(CCF_COMPILE_TARGET) \ -DCMAKE_INSTALL_PREFIX=$(CCF_LEDGER_DIR) +build-python : $(PYTHON_BLDDIR) + cmake --build $(PYTHON_BLDDIR) + +$(PYTHON_BLDDIR) : + cmake -S $(PYTHON_SRCDIR) -B $(PYTHON_BLDDIR) + # ----------------------------------------------------------------- # clean up # ----------------------------------------------------------------- clean : clean-build clean-ledger clean-build: - rm -rf $(BLDDIR) + rm -rf $(PDO_TP_BLDDIR) $(PYTHON_BLDDIR) clean-ledger : rm -rf $(CCF_LEDGER_DIR) @@ -109,15 +122,14 @@ clean-ledger : PDO_BASH_SCRIPTS = $(wildcard scripts/*.sh) PDO_PYTHON_SCRIPTS = $(wildcard scripts/*.py) -install : install-pdo-tp install-pdo-scripts +install : install-pdo-tp install-python -# cd $(BLDDIR) && $(NINJA) install install-pdo-tp : ledger-environment build-pdo-tp - cmake --install $(BLDDIR) + cmake --install $(PDO_TP_BLDDIR) cp $(PDO_BASH_SCRIPTS) $(CCF_LEDGER_DIR)/bin -install-pdo-scripts : pdo-environment - cp $(PDO_PYTHON_SCRIPTS) $(PDO_INSTALL_ROOT)/bin +install-python : pdo-environment build-python + cmake --install $(PYTHON_BLDDIR) # ----------------------------------------------------------------- .PHONY : all diff --git a/ledgers/ccf/pdo/__init__.py b/ledgers/ccf/pdo/__init__.py new file mode 100644 index 00000000..25bb107a --- /dev/null +++ b/ledgers/ccf/pdo/__init__.py @@ -0,0 +1,15 @@ +# Copyright 2018 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__('pkg_resources').declare_namespace('pdo') diff --git a/ledgers/ccf/pdo/ledgers/__init__.py b/ledgers/ccf/pdo/ledgers/__init__.py new file mode 100644 index 00000000..75e4bfe0 --- /dev/null +++ b/ledgers/ccf/pdo/ledgers/__init__.py @@ -0,0 +1,13 @@ +# Copyright 2024 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. diff --git a/ledgers/ccf/pdo/ledgers/ccf/__init__.py b/ledgers/ccf/pdo/ledgers/ccf/__init__.py new file mode 100644 index 00000000..75e4bfe0 --- /dev/null +++ b/ledgers/ccf/pdo/ledgers/ccf/__init__.py @@ -0,0 +1,13 @@ +# Copyright 2024 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. diff --git a/ledgers/ccf/pdo/ledgers/ccf/common.py b/ledgers/ccf/pdo/ledgers/ccf/common.py new file mode 100644 index 00000000..3adf57d1 --- /dev/null +++ b/ledgers/ccf/pdo/ledgers/ccf/common.py @@ -0,0 +1,144 @@ +# Copyright 2024 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 os +import sys +from urllib.parse import urlparse + +from ccf.clients import Identity +from ccf.clients import CCFClient + +from loguru import logger as LOG + +# ----------------------------------------------------------------- +# parse options and initialize the common variables +# ----------------------------------------------------------------- +def parse_common_arguments(args, description, member_keys_required = False) : + + parser = argparse.ArgumentParser(description=description) + + parser.add_argument( + '--logfile', + help='Name of the log file, __screen__ for standard output', + default='__screen__', + type=str) + + parser.add_argument( + '--loglevel', + help='Logging level', + default='WARNING', + type=str) + + parser.add_argument( + '--url', + help='URL for the ledger', + default = os.environ.get("PDO_LEDGER_URL"), + type=str) + + parser.add_argument( + '--interface', + help='Host interface where CCF is listening', + type=str) + + parser.add_argument( + '--port', + help='Port where CCF is listening', + type=int, + default=6600) + + parser.add_argument( + '--key-dir', + help='Directory where certificate files are located, defaults to PDO_LEDGER_KEY_ROOT', + default=os.environ.get("PDO_LEDGER_KEY_ROOT"), + type=str) + + parser.add_argument( + '--cert', + help='Name of the network certificate file', + type=str, + default='networkcert.pem') + + parser.add_argument( + '--member', + help="Name of the network membership certificate", + default = "memberccf", + type=str) + + (options, unprocessed_args) = parser.parse_known_args(args) + + # set up the logging + LOG.remove() + if options.logfile == '__screen__' : + LOG.add(sys.stderr, level=options.loglevel) + else : + LOG.add(options.logfile) + + # precedence is given to ledger interface through the interface/port parameters; the fall back + # is to use the ledger url parameter + if options.interface : + pass + elif options.url : + (options.interface, options.port) = urlparse(options.url).netloc.split(':') + else : + LOG.error('no ledger interface specified') + sys.exit(-1) + + # the key directory must be specified either through the PDO_LEDGER_KEY_ROOT + # environment variable or the key-dir parameter + if not options.key_dir or not os.path.exists(options.key_dir) : + LOG.error('unable to locate key dir') + sys.exit(-1) + + network_cert = os.path.join(options.key_dir, options.cert) + if not os.path.exists(network_cert) : + LOG.error('network certificate ({}) does not exist'.format(network_cert)) + sys.exit(-1) + + # now create the client + if member_keys_required : + member_cert = os.path.join(options.key_dir, "{}_cert.pem".format(options.member)) + if not os.path.exists(member_cert) : + LOG.error('member certificate ({}) does not exist'.format(member_cert)) + sys.exit(-1) + + member_key = os.path.join(options.key_dir, "{}_privk.pem".format(options.member)) + if not os.path.exists(member_key) : + LOG.error('member key ({}) does not exist'.format(member_key)) + sys.exit(-1) + + try : + client = CCFClient( + options.interface, + options.port, + network_cert, + session_auth=Identity(member_key, member_cert, "member"), + signing_auth=Identity(member_key, member_cert, "member"), + ) + except Exception as e: + LOG.error('failed to connect to CCF service : {}'.format(str(e))) + sys.exit(-1) + + else : + try : + client = CCFClient( + options.interface, + options.port, + network_cert) + except Exception as e: + LOG.error('failed to connect to CCF service : {}'.format(str(e))) + sys.exit(-1) + + # and return the client plus any operation-specific arguments that have not been processed + return (options, unprocessed_args, client) diff --git a/ledgers/ccf/pdo/ledgers/ccf/scripts/__init__.py b/ledgers/ccf/pdo/ledgers/ccf/scripts/__init__.py new file mode 100644 index 00000000..75e4bfe0 --- /dev/null +++ b/ledgers/ccf/pdo/ledgers/ccf/scripts/__init__.py @@ -0,0 +1,13 @@ +# Copyright 2024 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. diff --git a/ledgers/ccf/pdo/ledgers/ccf/scripts/configure_ccf_network.py b/ledgers/ccf/pdo/ledgers/ccf/scripts/configure_ccf_network.py new file mode 100755 index 00000000..6b082482 --- /dev/null +++ b/ledgers/ccf/pdo/ledgers/ccf/scripts/configure_ccf_network.py @@ -0,0 +1,87 @@ +#!/usr/bin/env python + +# Copyright 2018 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. + +""" +Return the number of registered endpoints in the exit status +""" + +import argparse +import http +import os +import sys + +from ccf.proposal_generator import transition_service_to_open + +# 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 open_network_script(client) : + # activate the member first + try: + r = client.post("/gov/ack/update_state_digest") + if r.status_code != http.HTTPStatus.OK.value : + LOG.error('failed to update state digest; {}'.format(r.status_code)) + sys.exit(-1) + + r = client.post("/gov/ack", {"state_digest": r.body.json()["state_digest"]}) + if r.status_code != http.HTTPStatus.OK.value and r.status_code != http.HTTPStatus.NO_CONTENT.value: + LOG.error('failed to activate the member: {}, code: {}'.format(r.body, r.status_code)) + sys.exit(-1) + + except Exception as e: + while e.__context__ : e = e.__context__ + LOG.error('failed to activate the member: {}', e) + sys.exit(-1) + + LOG.info('CCF member activated') + + try: + proposal, vote = transition_service_to_open() + r = client.post("/gov/proposals", proposal) + + LOG.info(f'proposal {r}') + if r.status_code != http.HTTPStatus.OK.value: + LOG.error('failed to open network: {}, code: {}'.format(r.body, r.status_code)) + sys.exit(-1) + + LOG.info('successfully created proposal to open network with proposal id {}'.format( + r.body.json()["proposal_id"])) + + except Exception as e: + while e.__context__ : e = e.__context__ + LOG.error('failed to open network: {}', e) + sys.exit(-1) + +# ----------------------------------------------------------------- +def Main() : + (_, unprocessed_args, member_client) = parse_common_arguments( + sys.argv[1:], 'Cofigure CCF policies', True) + + try : + open_network_script(member_client) + 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('configure ccf network failed: {}', str(e)) + sys.exit(-1) + + LOG.info('CCF network ready for use') + sys.exit(0) diff --git a/ledgers/ccf/scripts/fetch_ledger_authority.py b/ledgers/ccf/pdo/ledgers/ccf/scripts/fetch_ledger_authority.py similarity index 53% rename from ledgers/ccf/scripts/fetch_ledger_authority.py rename to ledgers/ccf/pdo/ledgers/ccf/scripts/fetch_ledger_authority.py index 4159729d..4fd34d9b 100755 --- a/ledgers/ccf/scripts/fetch_ledger_authority.py +++ b/ledgers/ccf/pdo/ledgers/ccf/scripts/fetch_ledger_authority.py @@ -19,14 +19,10 @@ import os import sys -from ccf.clients import CCFClient - # pick up the logger used by the rest of CCF from loguru import logger as LOG -## ----------------------------------------------------------------- -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") +from pdo.ledgers.ccf.common import parse_common_arguments # ----------------------------------------------------------------- def fetch_ledger_authority(client, output_file) : @@ -52,59 +48,28 @@ def fetch_ledger_authority(client, output_file) : # ----------------------------------------------------------------- def Main() : - default_output = os.path.join(CCF_Keys, 'ledger_authority_pub.pem') + (options, unprocessed_args, user_client) = parse_common_arguments( + sys.argv[1:], 'Fetch the ledger authority key from a CCF server') + # Parse the arguments that are unique to fetch_ledger_authority parser = argparse.ArgumentParser(description='Fetch the ledger authority key from a CCF server') - - parser.add_argument( - '--logfile', - help='Name of the log file, __screen__ for standard output', - default='__screen__', - type=str) - parser.add_argument( - '--loglevel', - help='Logging level', - default='WARNING', - type=str) - - parser.add_argument('--interface', help='Host interface where CCF is listening', required=True) - parser.add_argument('--port', help='Port where CCF is listening', type=int, default=6600) - parser.add_argument( "--output-file", help="Name of the file where the key will be saved", - default = default_output, + default = os.path.join(options.key_dir, 'ledger_authority_pub.pem'), type=str) - options = parser.parse_args() + local_options = parser.parse_args(unprocessed_args) # ----------------------------------------------------------------- - LOG.remove() - if options.logfile == '__screen__' : - LOG.add(sys.stderr, level=options.loglevel) - else : - LOG.add(options.logfile) - - # ----------------------------------------------------------------- - network_cert = os.path.join(CCF_Keys, "networkcert.pem") - if not os.path.exists(network_cert) : - LOG.error('network certificate ({}) does not exist'.format(network_cert)) - sys.exit(-1) - try : - user_client = CCFClient( - options.interface, - options.port, - network_cert) + fetch_ledger_authority(user_client, local_options.output_file) except Exception as e: - LOG.error('failed to connect to CCF service: {}'.format(str(e))) + # this just lets the script get back to the original error + # that caused the execption + while e.__context__ : e = e.__context__ + LOG.error('fetch ledger authority failed: {}', str(e)) sys.exit(-1) - fetch_ledger_authority(user_client, options.output_file) - LOG.info('successfully fetched ledger authority') sys.exit(0) - -# ----------------------------------------------------------------- -# ----------------------------------------------------------------- -Main() diff --git a/ledgers/ccf/pdo/ledgers/ccf/scripts/generate_ledger_authority.py b/ledgers/ccf/pdo/ledgers/ccf/scripts/generate_ledger_authority.py new file mode 100755 index 00000000..fcf4b995 --- /dev/null +++ b/ledgers/ccf/pdo/ledgers/ccf/scripts/generate_ledger_authority.py @@ -0,0 +1,60 @@ +# Copyright 2020 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 http +import sys +import time + +from loguru import logger as LOG + +from pdo.ledgers.ccf.common import parse_common_arguments + +# ----------------------------------------------------------------- +def generate_ledger_authority(client): + try : + for attempt in range(0,10) : + r = client.post("/app/generate_signing_key_for_read_payloads", dict()) + if r.status_code == http.HTTPStatus.OK.value : + return + if r.body.json()['error']['code'] == 'FrontendNotOpen' : + LOG.warning('ledger not yet open') + time.sleep(5) + else : + LOG.error("RESPONSE: {}".format(str(r))) + LOG.error('failed to generate ledger authority the member: {}'.format(r.body)) + sys.exit(-1) + + LOG.error('Ledger unavailable') + sys.exit(-1) + + except Exception as e: + LOG.error('failed to generate ledger authority the member: {}'.format(str(e))) + sys.exit(-1) + +# ----------------------------------------------------------------- +def Main() : + (_, _, member_client) = parse_common_arguments( + sys.argv[1:], 'Fetch the ledger authority key from a CCF server', True) + + try : + generate_ledger_authority(member_client) + 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('generate ledger authority failed: {}', str(e)) + sys.exit(-1) + + LOG.info('successfully generated ledger authority') + sys.exit(0) diff --git a/ledgers/ccf/pdo/ledgers/ccf/scripts/ping_test.py b/ledgers/ccf/pdo/ledgers/ccf/scripts/ping_test.py new file mode 100755 index 00000000..e5e0f61e --- /dev/null +++ b/ledgers/ccf/pdo/ledgers/ccf/scripts/ping_test.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python + +# Copyright 2020 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 sys +import time + +from loguru import logger as LOG + +from pdo.ledgers.ccf.common import parse_common_arguments + +# ----------------------------------------------------------------- +def ping_test(client, num_pings): + start_time = time.time() + + for _ in range(num_pings): + client.post("/app/ping", dict()) + + end_time = time.time() + + total_time = end_time - start_time + txn_throuput = num_pings/total_time + + LOG.warn("Performed {0} pings. Average throughput is {1} pings per second".format(num_pings, txn_throuput)) + +# ----------------------------------------------------------------- +def Main() : + (_, unprocessed_args, user_client) = parse_common_arguments( + sys.argv[1:], 'Test the connection to a CCF server') + + # Parse the arguments that are unique to ping_test + parser = argparse.ArgumentParser(description='Test the connection to a CCF server') + parser.add_argument("--count", help="Number of ping operations to do", default = 1, type=int) + local_options = parser.parse_args(unprocessed_args) + + try : + ping_test(user_client, local_options.count) + 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('ping test failed: {}', str(e)) + sys.exit(-1) + + sys.exit(0) 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 new file mode 100755 index 00000000..d8ee63d6 --- /dev/null +++ b/ledgers/ccf/pdo/ledgers/ccf/scripts/register_enclave_attestation_verification_policy.py @@ -0,0 +1,90 @@ +#!/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/scripts/configure_ccf_network.py b/ledgers/ccf/scripts/configure_ccf_network.py deleted file mode 100755 index 74d2ac26..00000000 --- a/ledgers/ccf/scripts/configure_ccf_network.py +++ /dev/null @@ -1,144 +0,0 @@ -#!/usr/bin/env python - -# Copyright 2018 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. - -""" -Return the number of registered endpoints in the exit status -""" - -import argparse -import http -import os -import sys - -from ccf.proposal_generator import transition_service_to_open -from ccf.clients import Identity -from ccf.clients import CCFClient - -# pick up the logger used by the rest of CCF -from loguru import logger as LOG - -## ----------------------------------------------------------------- -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") - -# ----------------------------------------------------------------- -# ----------------------------------------------------------------- -def open_network_script(client) : - - # activate the member first - try: - r = client.post("/gov/ack/update_state_digest") - if r.status_code != http.HTTPStatus.OK.value : - LOG.error('failed to update state digest; {}'.format(r.status_code)) - sys.exit(-1) - - r = client.post("/gov/ack", {"state_digest": r.body.json()["state_digest"]}) - if r.status_code != http.HTTPStatus.OK.value and r.status_code != http.HTTPStatus.NO_CONTENT.value: - LOG.error('failed to activate the member: {}, code: {}'.format(r.body, r.status_code)) - sys.exit(-1) - - except Exception as e: - LOG.error('failed to activate the member: {}', e) - sys.exit(-1) - - LOG.info('CCF member activated') - - try: - proposal, vote = transition_service_to_open() - r = client.post("/gov/proposals", proposal) - - LOG.info(f'proposal {r}') - if r.status_code != http.HTTPStatus.OK.value: - LOG.error('failed to open network: {}, code: {}'.format(r.body, r.status_code)) - sys.exit(-1) - - LOG.info('successfully created proposal to open network with proposal id {}'.format( - r.body.json()["proposal_id"])) - - except Exception as e: - LOG.error('failed to open network: {}', e) - sys.exit(-1) - -# ----------------------------------------------------------------- -def Main() : - default_config = os.path.join(CCF_Etc, 'cchost.toml') - parser = argparse.ArgumentParser(description='Script to enable the CCF network') - - parser.add_argument( - '--logfile', - help='Name of the log file, __screen__ for standard output', - default='__screen__', - type=str) - parser.add_argument( - '--loglevel', - help='Logging level', - default='WARNING', - type=str) - - parser.add_argument('--interface', help='Host interface where CCF is listening', required=True) - parser.add_argument('--member-name', help="Name of the user being added", default = "memberccf", type=str) - parser.add_argument('--port', help='Port where CCF is listening', type=int, default=6600) - - # these options are forward looking when we support multiple node ccf networks - parser.add_argument('--user-name', help="Name of the user being added", default = "userccf", type=str) - parser.add_argument('--add-node', help="Add a new node to existing CCF network", action="store_true") - parser.add_argument('--node-id', help="id of the node to be added to the ccf network", type=int) - - options = parser.parse_args() - - # ----------------------------------------------------------------- - LOG.remove() - if options.logfile == '__screen__' : - LOG.add(sys.stderr, level=options.loglevel) - else : - LOG.add(options.logfile) - - # ----------------------------------------------------------------- - network_cert = os.path.join(CCF_Keys, "networkcert.pem") - if not os.path.exists(network_cert) : - LOG.error('network certificate ({}) does not exist'.format(network_cert)) - sys.exit(-1) - - member_cert = os.path.join(CCF_Keys, "{}_cert.pem".format(options.member_name)) - if not os.path.exists(member_cert) : - LOG.error('member certificate ({}) does not exist'.format(member_cert)) - sys.exit(-1) - - member_key = os.path.join(CCF_Keys, "{}_privk.pem".format(options.member_name)) - if not os.path.exists(member_key) : - LOG.error('member key ({}) does not exist'.format(member_key)) - sys.exit(-1) - - try: - member_client = CCFClient( - options.interface, - options.port, - network_cert, - session_auth=Identity(member_key, member_cert, "member"), - signing_auth=Identity(member_key, member_cert, "member"), - ) - except Exception as e: - LOG.error('failed to connect to CCF service : {}'.format(str(e))) - sys.exit(-1) - - open_network_script(member_client) - - LOG.info('CCF network ready for use') - sys.exit(0) - -# ----------------------------------------------------------------- -# ----------------------------------------------------------------- -Main() diff --git a/ledgers/ccf/scripts/generate_ledger_authority.py b/ledgers/ccf/scripts/generate_ledger_authority.py deleted file mode 100755 index e94a93b7..00000000 --- a/ledgers/ccf/scripts/generate_ledger_authority.py +++ /dev/null @@ -1,118 +0,0 @@ -#!/usr/bin/env python - -# Copyright 2020 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 os -import sys -import time - -from ccf.clients import Identity -from ccf.clients import CCFClient - -from loguru import logger as LOG - -## ----------------------------------------------------------------- -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") - -# ----------------------------------------------------------------- -def generate_ledger_authority(client): - try : - for attempt in range(0,10) : - r = client.post("/app/generate_signing_key_for_read_payloads", dict()) - if r.status_code == http.HTTPStatus.OK.value : - return - if r.body.json()['error']['code'] == 'FrontendNotOpen' : - LOG.warning('ledger not yet open') - time.sleep(5) - else : - LOG.error("RESPONSE: {}".format(str(r))) - LOG.error('failed to generate ledger authority the member: {}'.format(r.body)) - sys.exit(-1) - - LOG.error('Ledger unavailable') - sys.exit(-1) - - except Exception as e: - LOG.error('failed to generate ledger authority the member: {}'.format(str(e))) - sys.exit(-1) - -# ----------------------------------------------------------------- -def Main() : - parser = argparse.ArgumentParser(description='Fetch the ledger authority key from a CCF server') - - parser.add_argument( - '--logfile', - help='Name of the log file, __screen__ for standard output', - default='__screen__', - type=str) - parser.add_argument( - '--loglevel', - help='Logging level', - default='WARNING', - type=str) - - parser.add_argument('-i', '--interface', help='Host interface where CCF is listening', required=True) - parser.add_argument('-m', '--member-name', help="Name of the user being added", default = "memberccf", type=str) - parser.add_argument('-p', '--port', help='Port where CCF is listening', type=int, default=6600) - - options = parser.parse_args() - - # ----------------------------------------------------------------- - LOG.remove() - if options.logfile == '__screen__' : - LOG.add(sys.stderr, level=options.loglevel) - else : - LOG.add(options.logfile) - - # ----------------------------------------------------------------- - network_cert = os.path.join(CCF_Keys, "networkcert.pem") - if not os.path.exists(network_cert) : - LOG.error('network certificate ({}) does not exist'.format(network_cert)) - sys.exit(-1) - - member_cert = os.path.join(CCF_Keys, "{}_cert.pem".format(options.member_name)) - if not os.path.exists(member_cert) : - LOG.error('member certificate ({}) does not exist'.format(member_cert)) - sys.exit(-1) - - member_key = os.path.join(CCF_Keys, "{}_privk.pem".format(options.member_name)) - if not os.path.exists(member_key) : - LOG.error('member key ({}) does not exist'.format(member_key)) - sys.exit(-1) - - LOG.warning('generate ledger authority for {}:{}'.format(options.interface, options.port)) - try: - member_client = CCFClient( - options.interface, - options.port, - network_cert, - session_auth=Identity(member_key, member_cert, "member"), - signing_auth=Identity(member_key, member_cert, "member"), - ) - except Exception as e: - LOG.error('failed to connect to CCF service : {}'.format(str(e))) - sys.exit(-1) - - generate_ledger_authority(member_client) - - LOG.info('successfully generated ledger authority') - sys.exit(0) - -# ----------------------------------------------------------------- -# ----------------------------------------------------------------- -Main() diff --git a/ledgers/ccf/scripts/ping_test.py b/ledgers/ccf/scripts/ping_test.py deleted file mode 100755 index 7c4cbac8..00000000 --- a/ledgers/ccf/scripts/ping_test.py +++ /dev/null @@ -1,90 +0,0 @@ -#!/usr/bin/env python - -# Copyright 2020 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 os -import sys -import time -from urllib.parse import urlparse - -from ccf.clients import CCFClient -from loguru import logger as LOG - -# ----------------------------------------------------------------- -def ping_test(client, options): - num_pings = options.num_pings - - start_time = time.time() - - for _ in range(num_pings): - client.post("/app/ping", dict()) - - end_time = time.time() - - total_time = end_time - start_time - txn_throuput = num_pings/total_time - - if options.verbose : - LOG.warning("Performed {0} pings. Average throughput is {1} pings per second".format(num_pings, txn_throuput)) - -# ----------------------------------------------------------------- -def Main() : - parser = argparse.ArgumentParser(description='Test the connection to a CCF server') - - parser.add_argument('--loglevel', help='Logging level', default='WARNING', type=str) - parser.add_argument("--num-pings", help="Number of ping operations to do", default = 1, type=int) - parser.add_argument('--url', type=str, required=True) - parser.add_argument('--cert', type=str, required=True) - group = parser.add_mutually_exclusive_group() - group.add_argument('--verbose', action='store_true', default=True) - group.add_argument('--quiet', action='store_false', dest='verbose') - options = parser.parse_args() - - # ----------------------------------------------------------------- - LOG.remove() - LOG.add(sys.stderr, level=options.loglevel) - - # ----------------------------------------------------------------- - try : - (host, port) = urlparse(options.url).netloc.split(':') - except Exception as e: - if options.verbose : - LOG.error('failed to parse ledger URL: {}'.format(str(e))) - sys.exit(-1) - - try : - user_client = CCFClient(host, port, options.cert) - except Exception as e: - if options.verbose : - LOG.error('failed to connect to CCF service: {}'.format(str(e))) - sys.exit(-1) - - try : - ping_test(user_client, options) - except Exception as e: - # this just lets the script get back to the original error - # that caused the execption - if options.verbose : - while e.__context__ : e = e.__context__ - LOG.error('ping test failed: {}', str(e)) - sys.exit(-1) - - sys.exit(0) - -# ----------------------------------------------------------------- -# ----------------------------------------------------------------- -Main() diff --git a/ledgers/ccf/scripts/register_enclave_attestation_verification_policy.py b/ledgers/ccf/scripts/register_enclave_attestation_verification_policy.py deleted file mode 100755 index de3a5ab7..00000000 --- a/ledgers/ccf/scripts/register_enclave_attestation_verification_policy.py +++ /dev/null @@ -1,132 +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 os -import sys -import toml - -from ccf.clients import Identity -from ccf.clients import CCFClient - -# pick up the logger used by the rest of CCF -from loguru import logger as LOG - -## ----------------------------------------------------------------- -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") - -# ----------------------------------------------------------------- -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() : - default_output = os.path.join(CCF_Keys, 'ledger_authority.pem') - - parser = argparse.ArgumentParser(description='Fetch the ledger authority key from a CCF server') - - parser.add_argument( - '--logfile', - help='Name of the log file, __screen__ for standard output', - default='__screen__', - type=str) - parser.add_argument( - '--loglevel', - help='Logging level', - default='WARNING', - type=str) - - - parser.add_argument('--interface', help='Host interface where CCF is listening', required=True) - parser.add_argument('--member-name', help="Name of the user being added", default = "memberccf", type=str) - parser.add_argument('--port', help='Port where CCF is listening', type=int, default=6600) - - 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) - - options = parser.parse_args() - - if options.check_attestation: - if (not options.mrenclave) or (not options.basename) or (not options.ias_public_key): - parser.print_help() - sys.exit(-1) - - # ----------------------------------------------------------------- - LOG.remove() - if options.logfile == '__screen__' : - LOG.add(sys.stderr, level=options.loglevel) - else : - LOG.add(options.logfile) - - # ----------------------------------------------------------------- - network_cert = os.path.join(CCF_Keys, "networkcert.pem") - if not os.path.exists(network_cert) : - LOG.error('network certificate ({}) does not exist'.format(network_cert)) - sys.exit(-1) - - member_cert = os.path.join(CCF_Keys, "{}_cert.pem".format(options.member_name)) - if not os.path.exists(member_cert) : - LOG.error('member certificate ({}) does not exist'.format(member_cert)) - sys.exit(-1) - - member_key = os.path.join(CCF_Keys, "{}_privk.pem".format(options.member_name)) - if not os.path.exists(member_key) : - LOG.error('member key ({}) does not exist'.format(member_key)) - sys.exit(-1) - - try: - member_client = CCFClient( - options.interface, - options.port, - network_cert, - session_auth=Identity(member_key, member_cert, "member"), - signing_auth=Identity(member_key, member_cert, "member"), - ) - except Exception as e: - LOG.error('failed to connect to CCF service : {}'.format(str(e))) - sys.exit(-1) - - register_enclave_attestation_policy(member_client, options) - - LOG.info('successfully registered enclave expected measurements') - sys.exit(0) - -# ----------------------------------------------------------------- -# ----------------------------------------------------------------- -Main() diff --git a/ledgers/ccf/scripts/start_ccf_network.sh b/ledgers/ccf/scripts/start_ccf_network.sh index 17eb6e8b..4298234b 100755 --- a/ledgers/ccf/scripts/start_ccf_network.sh +++ b/ledgers/ccf/scripts/start_ccf_network.sh @@ -143,7 +143,7 @@ cp ${F_CCF_LEDGER_DIR}/workspace/pdo_tp_common/member0_privk.pem ${PDO_LEDGER_KE source ${F_CCF_PDO_DIR}/bin/activate say generate the ledger authority -try ${F_CCF_PDO_DIR}/bin/generate_ledger_authority.py \ +try ${F_CCF_PDO_DIR}/bin/ccf_generate_ledger_authority \ --logfile __screen__ --loglevel WARNING \ --interface ${F_INTERFACE_ADDRESS} --port ${F_PORT} @@ -153,13 +153,13 @@ try ${F_CCF_PDO_DIR}/bin/generate_ledger_authority.py \ if [ "${SGX_MODE}" == "SIM" ]; then say set check_attestation to false in SGX SIM mode - try ${F_CCF_PDO_DIR}/bin/register_enclave_attestation_verification_policy.py \ + try ${F_CCF_PDO_DIR}/bin/ccf_register_enclave_policy \ --logfile __screen__ --loglevel WARNING \ --interface ${F_INTERFACE_ADDRESS} --port ${F_PORT} fi say save the ledger authority key -try ${F_CCF_PDO_DIR}/bin/fetch_ledger_authority.py \ +try ${F_CCF_PDO_DIR}/bin/ccf_fetch_ledger_authority \ --logfile __screen__ --loglevel WARNING \ --interface ${F_INTERFACE_ADDRESS} --port ${F_PORT} diff --git a/ledgers/ccf/setup.py b/ledgers/ccf/setup.py new file mode 100644 index 00000000..8cd96621 --- /dev/null +++ b/ledgers/ccf/setup.py @@ -0,0 +1,77 @@ +#!/usr/bin/env python + +# Copyright 2024 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 os +import sys +import subprocess +import warnings + +# this should only be run with python3 +import sys +if sys.version_info[0] < 3: + print('ERROR: must run with python3') + sys.exit(1) + +from setuptools import setup, find_packages, find_namespace_packages + +# ----------------------------------------------------------------- +# Versions are tied to tags on the repository; to compute correctly +# it is necessary to be within the repository itself hence the need +# to set the cwd for the bin/get_version command. +# ----------------------------------------------------------------- +root_dir = os.environ.get('PDO_SOURCE_ROOT') +if root_dir is None : + warnings.warn('PDO_SOURCE_ROOT not set') + sys.exit(-1) + +try : + pdo_version = subprocess.check_output('bin/get_version', cwd=root_dir).decode('ascii').strip() +except Exception as e : + warnings.warn('Failed to get pdo version, using the default') + pdo_contracts_version = '0.0.0' + +## ----------------------------------------------------------------- +## ----------------------------------------------------------------- +setup( + name='pdo_ccf_ledger', + version=pdo_version, + description='Support functions for PDO integration with CCF ledger', + author='Mic Bowman, Intel Labs', + author_email='mic.bowman@intel.com', + url='http://www.intel.com', + package_dir = { + 'pdo' : 'pdo', + }, + packages = [ + 'pdo', + 'pdo.ledgers', + 'pdo.ledgers.ccf', + 'pdo.ledgers.ccf.scripts', + ], + include_package_data=True, + install_requires = [ + 'ccf==1.0.19', + ], + entry_points = { + 'console_scripts' : [ + 'ccf_configure_network=pdo.ledgers.ccf.scripts.configure_ccf_network:Main', + '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', + ] + } +) diff --git a/ledgers/ccf/transaction_processor/CMakeLists.txt b/ledgers/ccf/transaction_processor/CMakeLists.txt new file mode 100644 index 00000000..3888acaf --- /dev/null +++ b/ledgers/ccf/transaction_processor/CMakeLists.txt @@ -0,0 +1,29 @@ +# 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. + +CMAKE_MINIMUM_REQUIRED(VERSION 3.16) + +INCLUDE(${CCF_DIR}/cmake/preproject.cmake) +PROJECT(pdoenc LANGUAGES C CXX) +INCLUDE(${CCF_DIR}/cmake/ccf_app.cmake) + +FIND_PACKAGE(ccf_virtual REQUIRED) + +# Add the PDO transaction processor target +add_ccf_app(pdoenc + SRCS pdo_tp.cpp verify_signatures.cpp + INCLUDE_DIRS ${CCF_DIR}/include/ccf ${CCF_DIR}/include/3rdparty ${CCF_DIR}/include +) + +INSTALL(TARGETS pdoenc.virtual DESTINATION lib) From 868afa0369753b17e57415a84205ce2f3fb32cfc Mon Sep 17 00:00:00 2001 From: Mic Bowman Date: Mon, 19 Feb 2024 10:29:25 -0800 Subject: [PATCH 2/2] Update the docker build scripts to include ledger python scripts Signed-off-by: Mic Bowman --- docker/tools/build_client.sh | 2 +- docker/tools/build_services.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docker/tools/build_client.sh b/docker/tools/build_client.sh index 8fd9117f..614f8c0f 100755 --- a/docker/tools/build_client.sh +++ b/docker/tools/build_client.sh @@ -22,5 +22,5 @@ export PDO_HOSTNAME=localhost export PDO_LEDGER_URL=https://127.0.0.1:6600 try make -C ${PDO_SOURCE_ROOT}/build environment -try make -C ${PDO_SOURCE_ROOT}/build template try make -C ${PDO_SOURCE_ROOT}/build build-client +try make -C ${PDO_SOURCE_ROOT}/ledgers/ccf install-python diff --git a/docker/tools/build_services.sh b/docker/tools/build_services.sh index fbc46511..2dbb123c 100755 --- a/docker/tools/build_services.sh +++ b/docker/tools/build_services.sh @@ -27,6 +27,6 @@ check_pdo_build_env yell Build and install services into ${PDO_INSTALL_ROOT} # ----------------------------------------------------------------- try make -C ${PDO_SOURCE_ROOT}/build environment -try make -C ${PDO_SOURCE_ROOT}/build template try make -C ${PDO_SOURCE_ROOT}/build system-keys try make -C ${PDO_SOURCE_ROOT}/build verified-build +try make -C ${PDO_SOURCE_ROOT}/ledgers/ccf install-python