diff --git a/BUILD.md b/BUILD.md index 21db4d446..90c9a2ff2 100644 --- a/BUILD.md +++ b/BUILD.md @@ -42,7 +42,7 @@ Follow the instructions below to execute a Docker-based build and execution. 3. Open a Docker container shell using following command `sudo docker exec -it tcf bash` 4. Activate a virtual environment in the Docker shell using following command - from the Docker working directory, `$TCF_HOME/__tools__/build`, + from the Docker working directory, `$TCF_HOME/tools/build`, which is set in the `docker-compose.yaml` file: ``` source _dev/bin/activate @@ -75,7 +75,7 @@ export TCF_HOME=`pwd` Change to the quickstart build directory: ``` -cd $TCF_HOME/__tools__/build +cd $TCF_HOME/tools/build ``` Check that these variables are set before building the code: diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 000000000..e5e05d4b5 --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,99 @@ +#!groovy + +// Copyright 2019 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. +// ------------------------------------------------------------------------------ + +pipeline { + agent { + node { + label 'master' + customWorkspace "workspace/${env.BUILD_TAG}" + } + } + + options { + timestamps() + buildDiscarder(logRotator(daysToKeepStr: '31')) + } + + stages { + stage('Check for Signed-Off Commits') { + steps { + sh '''#!/bin/bash -l + if [ -v CHANGE_URL ] ; + then + temp_url="$(echo $CHANGE_URL |sed s#github.com/#api.github.com/repos/#)/commits" + pull_url="$(echo $temp_url |sed s#pull#pulls#)" + + IFS=$'\n' + for m in $(curl -s "$pull_url" | grep "message") ; do + if echo "$m" | grep -qi signed-off-by: + then + continue + else + echo "FAIL: Missing Signed-Off Field" + echo "$m" + exit 1 + fi + done + unset IFS; + fi + ''' + } + } + + stage('Build TCF') { + steps { + sh 'docker-compose -f ci/docker-compose-build.yaml up' + sh 'docker-compose -f ci/docker-compose-build.yaml down' + } + } + + stage('Run TCF Tests') { + steps { + sh 'docker-compose -f ci/docker-compose-tests.yaml up' + sh 'docker-compose -f ci/docker-compose-tests.yaml down' + } + } + + stage('Create git archive') { + steps { + sh ''' + REPO=$(git remote show -n origin | grep Fetch | awk -F'[/.]' '{print $6}') + git archive HEAD --format=zip -9 --output=$REPO.zip + git archive HEAD --format=tgz -9 --output=$REPO.tgz + ''' + } + } + + } + + post { + always { + sh 'docker-compose -f ci/docker-compose-build.yaml down' + sh 'docker-compose -f ci/docker-compose-tests.yaml down' + } + success { + archiveArtifacts '*.tgz, *.zip' + } + aborted { + error "Aborted, exiting now" + } + failure { + error "Failed, exiting now" + } + } +} + diff --git a/ci/docker-compose-build.yaml b/ci/docker-compose-build.yaml new file mode 100644 index 000000000..74825087f --- /dev/null +++ b/ci/docker-compose-build.yaml @@ -0,0 +1,36 @@ +# Copyright 2019 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. + +version: '3.5' + +services: + tcf: + container_name: tcf + image: tcf-ci-build + + build: + context: . + dockerfile: ../docker/Dockerfile.tcf-dev + args: + - http_proxy + - https_proxy + - no_proxy + volumes: + - ../:/project/TrustedComputeFramework + working_dir: "/project/TrustedComputeFramework/tools/build" + entrypoint: "bash -c \"\ + if [ ${MAKECLEAN:-1} != 0 ]; then echo \\\"Clean build\\\" && make clean; fi \ + && make \ + && echo \\\"BUILD SUCCESS\\\" \"" + stop_signal: SIGKILL diff --git a/ci/docker-compose-tests.yaml b/ci/docker-compose-tests.yaml new file mode 100644 index 000000000..e6216666d --- /dev/null +++ b/ci/docker-compose-tests.yaml @@ -0,0 +1,36 @@ +# Copyright 2019 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. + +version: '3.5' + +services: + tcf: + container_name: tcf + image: tcf-ci-build + build: + context: . + args: + - http_proxy + - https_proxy + - no_proxy + volumes: + - ../:/project/TrustedComputeFramework + working_dir: "/project/TrustedComputeFramework/tools/build" + entrypoint: "bash -c \"\ + source _dev/bin/activate \ + && cd ../../scripts \ + && source tcs_startup.sh -y \ + && sleep 5 \ + && source ../tools/run_tests.sh \"" + stop_signal: SIGKILL diff --git a/common/service_client/generic.py b/common/service_client/generic.py deleted file mode 100644 index 05333a6db..000000000 --- a/common/service_client/generic.py +++ /dev/null @@ -1,81 +0,0 @@ -# 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 os -import sys -import json -import urllib.request -import urllib.error - -import logging -logger = logging.getLogger(__name__) - -class MessageException(Exception) : - """ - A class to capture communication exceptions when communicating with services - """ - pass - -class GenericServiceClient(object) : - - def __init__(self, url) : - self.ServiceURL = url - self.ProxyHandler = urllib.request.ProxyHandler({}) - - def _postmsg(self, request) : - """ - Post a transaction message to the validator, parse the returning JSON and return - the corresponding dictionary. - """ - - data = json.dumps(request).encode('utf8') - datalen = len(data) - - url = self.ServiceURL - - logger.debug('post transaction to %s with DATALEN=%d, DATA=<%s>', url, datalen, data) - - try : - request = urllib.request.Request(url, data, {'Content-Type': 'application/json', 'Content-Length': datalen}) - opener = urllib.request.build_opener(self.ProxyHandler) - response = opener.open(request, timeout=10) - - except urllib.error.HTTPError as err : - logger.warn('operation failed with response: %s', err.code) - raise MessageException('operation failed with response: {0}'.format(err.code)) - - except urllib.error.URLError as err : - logger.warn('operation failed: %s', err.reason) - raise MessageException('operation failed: {0}'.format(err.reason)) - - except : - logger.exception('no response from server') - raise MessageException('no response from server') - - content = response.read() - headers = response.info() - response.close() - - encoding = headers.get('Content-Type') - if encoding != 'application/json' : - logger.info('server responds with message %s of type %s', content, encoding) - return None - - # Attempt to decode the content if it is not already a string - try: - content = content.decode('utf-8') - except AttributeError: - pass - value = json.loads(content) - return value diff --git a/common/setup.py b/common/setup.py deleted file mode 100644 index 2c77db6b0..000000000 --- a/common/setup.py +++ /dev/null @@ -1,41 +0,0 @@ -# Copyright 2019 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 subprocess -import re - -# 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, Extension - -tcf_root_dir = os.environ.get('TCF_HOME', '../') - -version = subprocess.check_output( - os.path.join(tcf_root_dir, 'bin/get_version')).decode('ascii').strip() - -setup( - name = 'tcf_common', - version = version, - description = 'Common library for tcs core and client', - author = 'Intel', - packages = find_packages(), - install_requires = [], - entry_points = {}) - diff --git a/workloads/CMakeLists.txt b/common/sgx_workload/CMakeLists.txt similarity index 79% rename from workloads/CMakeLists.txt rename to common/sgx_workload/CMakeLists.txt index c8308600b..031b82453 100644 --- a/workloads/CMakeLists.txt +++ b/common/sgx_workload/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright 2018 Intel Corporation +# Copyright 2019 Intel Corporation # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -22,10 +22,11 @@ INCLUDE(CMakeVariables.txt) FILE(GLOB PROJECT_HEADERS *.h) FILE(GLOB PROJECT_SOURCES *.cpp) -SET(GENERIC_PRIVATE_INCLUDE_DIRS "." "${TCF_TOP_DIR}/tcs/core/common" "${TCF_TOP_DIR}/tcs/core/common/work_order_interface" "${TCF_TOP_DIR}/tcs/core/common/crypto" ) +SET(GENERIC_PRIVATE_INCLUDE_DIRS "." "${TCF_TOP_DIR}/tc/sgx/common" + "${TCF_TOP_DIR}/tc/sgx/common/work_order_interface" "${TCF_TOP_DIR}/examples/apps") SET(GENERIC_CXX_FLAGS ${DEBUG_FLAGS} "-Wall" "-fPIC" "-Wno-write-strings" "-std=c++11") -SET(WORKLOAD_STATIC_NAME workloads) +SET(WORKLOAD_STATIC_NAME sgx_workload) PROJECT(${WORKLOAD_STATIC_NAME} CXX) ADD_LIBRARY(${WORKLOAD_STATIC_NAME} STATIC ${PROJECT_HEADERS} ${PROJECT_SOURCES}) @@ -35,8 +36,6 @@ TARGET_INCLUDE_DIRECTORIES(${WORKLOAD_STATIC_NAME} PRIVATE "..") TARGET_INCLUDE_DIRECTORIES(${WORKLOAD_STATIC_NAME} PUBLIC ${GENERIC_PUBLIC_INCLUDE_DIRS}) TARGET_INCLUDE_DIRECTORIES(${WORKLOAD_STATIC_NAME} PUBLIC "${SGX_SDK}/include/tlibc") TARGET_INCLUDE_DIRECTORIES(${WORKLOAD_STATIC_NAME} PUBLIC "${SGX_SDK}/include/libcxx") -TARGET_INCLUDE_DIRECTORIES(${WORKLOAD_STATIC_NAME} PUBLIC "${SGX_SSL}/include") -TARGET_INCLUDE_DIRECTORIES(${PROJECT_NAME} PRIVATE ${TCF_TOP_DIR}/tcs/core/common/packages/parson) TARGET_COMPILE_OPTIONS(${WORKLOAD_STATIC_NAME} PRIVATE "${GENERIC_CXX_FLAGS}") TARGET_COMPILE_OPTIONS(${WORKLOAD_STATIC_NAME} PRIVATE "-nostdinc") @@ -46,6 +45,4 @@ TARGET_COMPILE_OPTIONS(${WORKLOAD_STATIC_NAME} PRIVATE "-fno-builtin-printf") TARGET_COMPILE_DEFINITIONS(${WORKLOAD_STATIC_NAME} PRIVATE "-DUSE_DL=1") ################################################################################ -ADD_SUBDIRECTORY(echo_work_order) -ADD_SUBDIRECTORY(heart_disease_eval) diff --git a/common/sgx_workload/CMakeVariables.txt b/common/sgx_workload/CMakeVariables.txt new file mode 100644 index 000000000..c835394a7 --- /dev/null +++ b/common/sgx_workload/CMakeVariables.txt @@ -0,0 +1,35 @@ +# Copyright 2019 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. + + +################################################################################ +# Configure Environment +################################################################################ + +SET(TCF_TOP_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../") + +if("$ENV{DEBUG} " STREQUAL " ") + SET(DEBUG_FLAGS "-O2") + message(STATUS "Compiling with optimizations (-O2). To use debug flags, set the DEBUG environment variable.") +else() + SET(DEBUG_FLAGS "-Og" "-g" "-DDEBUG") + message(STATUS "Compiling in debug mode without optimizations (-Og -g)") +endif() + +SET(SGX_SDK "$ENV{SGX_SDK}") +if("${SGX_SDK} " STREQUAL " ") + message(FATAL_ERROR "SGX_SDK environment variable not defined!") +endif() + +SET(GENERIC_PUBLIC_INCLUDE_DIRS "${SGX_SDK}/include") diff --git a/workloads/workload_dispatcher.cpp b/common/sgx_workload/workload_dispatcher.cpp similarity index 76% rename from workloads/workload_dispatcher.cpp rename to common/sgx_workload/workload_dispatcher.cpp index 6f4d6bac6..db84fbeb7 100644 --- a/workloads/workload_dispatcher.cpp +++ b/common/sgx_workload/workload_dispatcher.cpp @@ -16,8 +16,8 @@ #include #include "work_order_data.h" #include "workload_processor.h" -#include "echo_work_order/echo_workorder.h" -#include "heart_disease_eval/heart_disease_evaluation.h" +#include "echo/workload/echo.h" +#include "heart_disease_eval/workload/heart_disease_evaluation.h" ByteArray ConvertStringToByteArray(std::string s) { ByteArray ba(s.begin(), s.end()); @@ -27,7 +27,7 @@ ByteArray ConvertStringToByteArray(std::string s) { class EchoResult: public tcf::WorkOrderProcessorInterface { public: void ProcessWorkOrder( - std::string code_id, + std::string workload_id, const ByteArray& participant_address, const ByteArray& enclave_id, const ByteArray& work_order_id, @@ -38,24 +38,21 @@ class EchoResult: public tcf::WorkOrderProcessorInterface { int out_wo_data_size = out_work_order_data.size(); for (auto wo_data : in_work_order_data) { - // Skip first work order data index since it is - // the identifier for the workload - if (i == 0) { - i++; - continue; - } // Execute the input data EchoResultImpl echo_result_impl; - result_str = echo_result_impl.Process(ByteArrayToString(wo_data.decrypted_data)); + result_str = echo_result_impl.Process( + ByteArrayToString(wo_data.decrypted_data)); // If the out_work_order_data has entry to hold the data if (i < out_wo_data_size) { tcf::WorkOrderData& out_wo_data = out_work_order_data.at(i); - out_wo_data.decrypted_data = ConvertStringToByteArray(result_str); + out_wo_data.decrypted_data = + ConvertStringToByteArray(result_str); } else { // Create a new entry - out_work_order_data.emplace_back(wo_data.index, ConvertStringToByteArray(result_str)); + out_work_order_data.emplace_back( + wo_data.index, ConvertStringToByteArray(result_str)); } i++; @@ -67,7 +64,7 @@ class EchoResult: public tcf::WorkOrderProcessorInterface { class HeartDiseaseEvalFactory: public tcf::WorkOrderProcessorInterface { public: void ProcessWorkOrder( - std::string code_id, + std::string workload_id, const ByteArray& participant_address, const ByteArray& enclave_id, const ByteArray& work_order_id, @@ -79,7 +76,8 @@ class HeartDiseaseEvalFactory: public tcf::WorkOrderProcessorInterface { // Clear state - to reset totalRisk and count executeWorkOrder(""); for (auto wo_data : in_work_order_data) { - std::string inputData = ByteArrayToString(wo_data.decrypted_data); + std::string inputData = + ByteArrayToString(wo_data.decrypted_data); try { result_str = executeWorkOrder(inputData); } catch(...) { @@ -91,10 +89,12 @@ class HeartDiseaseEvalFactory: public tcf::WorkOrderProcessorInterface { // If the out_work_order_data has entry to hold the data if (out_wo_data_size) { tcf::WorkOrderData& out_wo_data = out_work_order_data.at(0); - out_wo_data.decrypted_data = ConvertStringToByteArray(result_str); + out_wo_data.decrypted_data = + ConvertStringToByteArray(result_str); } else { // Create a new entry - out_work_order_data.emplace_back(0, ConvertStringToByteArray(result_str)); + out_work_order_data.emplace_back( + 0, ConvertStringToByteArray(result_str)); } } @@ -109,7 +109,7 @@ tcf::WorkOrderProcessorInterface* HeartDiseaseEvalFactory() { } WorkOrderDispatchTableEntry workOrderDispatchTable[] = { - { "echo-result:", EchoResultFactory}, - { "heart-disease-eval:", HeartDiseaseEvalFactory }, + {"echo-result", EchoResultFactory}, + {"heart-disease-eval", HeartDiseaseEvalFactory}, {NULL, NULL} }; diff --git a/workloads/workload_processor.cpp b/common/sgx_workload/workload_processor.cpp similarity index 91% rename from workloads/workload_processor.cpp rename to common/sgx_workload/workload_processor.cpp index 6a89c7d5d..6861f0feb 100644 --- a/workloads/workload_processor.cpp +++ b/common/sgx_workload/workload_processor.cpp @@ -18,9 +18,9 @@ #include #include -tc::WorkOrderProcessorInterface* LookUpWorkOrder(std::string work_order_code) { +tc::WorkOrderProcessorInterface* LookUpWorkOrder(std::string workload_id) { for (int i = 0; workOrderDispatchTable[i].project_name != NULL; i++) { - if (work_order_code.compare(workOrderDispatchTable[i].project_name) == 0) { + if (workload_id.compare(workOrderDispatchTable[i].project_name) == 0) { return workOrderDispatchTable[i].work_order_factory_ptr(); } } @@ -33,19 +33,19 @@ WorkloadProcessor::WorkloadProcessor() {} WorkloadProcessor::~WorkloadProcessor() {} void WorkloadProcessor::ProcessWorkOrder( - std::string code_id, + std::string workload_id, const ByteArray& participant_address, const ByteArray& enclave_id, const ByteArray& work_order_id, const std::vector& in_work_order_data, std::vector& out_work_order_data) { - tcf::WorkOrderProcessorInterface* work_order = LookUpWorkOrder(code_id); + tcf::WorkOrderProcessorInterface* work_order = LookUpWorkOrder(workload_id); if (work_order == nullptr) { tcf::error::RuntimeError("Work order not found in Work order lookup table\n"); return; } work_order->ProcessWorkOrder( - code_id, + workload_id, participant_address, enclave_id, work_order_id, diff --git a/workloads/workload_processor.h b/common/sgx_workload/workload_processor.h similarity index 97% rename from workloads/workload_processor.h rename to common/sgx_workload/workload_processor.h index 01e60ed3d..2ad155e89 100644 --- a/workloads/workload_processor.h +++ b/common/sgx_workload/workload_processor.h @@ -37,7 +37,7 @@ class WorkloadProcessor : public tc::WorkOrderProcessorInterface { virtual ~WorkloadProcessor(void); virtual void ProcessWorkOrder( - std::string code_id, + std::string workload_id, const ByteArray& participant_address, const ByteArray& enclave_id, const ByteArray& work_order_id, diff --git a/common/tcf_connector/unit_tests/test_work_order_encryption_key_jrpc_impl.py b/common/tcf_connector/unit_tests/test_work_order_encryption_key_jrpc_impl.py deleted file mode 100644 index b7e269b69..000000000 --- a/common/tcf_connector/unit_tests/test_work_order_encryption_key_jrpc_impl.py +++ /dev/null @@ -1,36 +0,0 @@ -import logging -from encodings.hex_codec import hex_encode -import base64 -import unittest - -from tcf_connector.work_order_jrpc_impl import WorkOrderJRPCImpl - -logging.basicConfig(format="%(asctime)s - %(levelname)s - %(message)s", level=logging.INFO) - - -class TestWorkOrderEncryptionKeyJRPCImpl(unittest.TestCase): - def __init__(self, listenerUri): - super(TestWorkOrderEncryptionKeyJRPCImpl, self).__init__() - - def testencryption_key_get(self): - req_id = 31 - workerId = "0x1234" - logging.info("Calling encryption_key_get with workerId %s\n lastUsedKeyNonce %s\n \ - tag %s\n requesterId %s\n signatureNonce %s\n, signature %s\n", - workerId, "", "", self.__work_order_submit_request["requesterId"], "","") - res = self.__work_order_wrapper.encryption_key_get(workerId, "", "", - self.__work_order_submit_request["requesterId"], "","", req_id) - logging.info("Result: %s\n", res) - self.assertEqual(res['id'], req_id, "work_order_get_result Response id doesn't match") - - def test_encryption_key_set(self): - req_id = 32 - workerId = "0x1234" - logging.info("Calling encryption_key_set with workerId %s\n encryptionKey %s\n \ - encryptionKeyNonce %s\n tag %s\n signatureNonce %s\n signature %s\n", - workerId, "0x123eff" , "0x1234", "", "", "") - res = self.__work_order_wrapper.encryption_key_set(workerId, "0x123eff" , "0x1234", - "", "", "", req_id) - logging.info("Result: %s\n", res) - self.assertEqual(res['id'], req_id, "encryption_key_set Response id doesn't match") - diff --git a/config/tcs_config.toml b/config/tcs_config.toml index 6d802aee6..7b45964a2 100644 --- a/config/tcs_config.toml +++ b/config/tcs_config.toml @@ -54,6 +54,7 @@ ias_api_key = "7eff11484faabcd7b5d62006f4611122" #enclave library to be used enclave_library = "libtcf-enclave.signed.so" +enclave_library_path = "tc/sgx/trusted_worker_manager/enclave/build/lib/" # ------------------------------------------------------------- # TCS Worker configuration details @@ -66,8 +67,9 @@ WorkOrderSyncUri = "http://localhost:8080" WorkOrderAsyncUri = "http://localhost:8080" WorkOrderPullUri = "http://localhost:8080" WorkOrderNotifyUri = "http://localhost:8080" -ApplicationTypeId = "Application_01" -OrganizationId = "Organization_01" +# Replace ApplicationTypeId and OrganizationId with real hexadecimal values +ApplicationTypeId = "11aa22bb33cc44dd" +OrganizationId = "aabbcc1234ddeeff" # URI used by worker to process work order receipts ReceiptInvocationUri = "http://localhost:8080" diff --git a/docker-compose-sgx.yaml b/docker-compose-sgx.yaml index 280bf91ad..0b02874d4 100644 --- a/docker-compose-sgx.yaml +++ b/docker-compose-sgx.yaml @@ -29,7 +29,7 @@ services: - ./:/project/TrustedComputeFramework devices: - "/dev/isgx:/dev/isgx" - working_dir: "/project/TrustedComputeFramework/__tools__/build" + working_dir: "/project/TrustedComputeFramework/tools/build" environment: - SGX_MODE=HW entrypoint: "bash -c \"\ diff --git a/docker-compose.yaml b/docker-compose.yaml index 81228e186..a06627dba 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -27,7 +27,7 @@ services: - no_proxy volumes: - ./:/project/TrustedComputeFramework - working_dir: "/project/TrustedComputeFramework/__tools__/build" + working_dir: "/project/TrustedComputeFramework/tools/build" entrypoint: "bash -c \"\ if [ ${MAKECLEAN:-1} != 0 ]; then echo \\\"Clean build\\\" && make clean; fi \ && make \ diff --git a/docker/Dockerfile.tcf-dev b/docker/Dockerfile.tcf-dev index 499586c35..82e08e20d 100644 --- a/docker/Dockerfile.tcf-dev +++ b/docker/Dockerfile.tcf-dev @@ -117,7 +117,7 @@ RUN git clone https://github.com/intel/intel-sgx-ssl.git \ WORKDIR /project/TrustedComputeFramework RUN \ - echo "VIRTUAL_ENV=/project/TrustedComputeFramework/__tools__/build/_dev" >> /etc/environment \ + echo "VIRTUAL_ENV=/project/TrustedComputeFramework/tools/build/_dev" >> /etc/environment \ && echo "TCF_HOME=/project/TrustedComputeFramework/" >> /etc/environment \ && if [ ! -z "$http_proxy" ]; then \ echo 'Acquire::http::Proxy "'$http_proxy'";' >> /etc/apt/apt.conf.d/00proxy; \ @@ -152,5 +152,5 @@ ENV SOLC_BINARY=/root/.py-solc/solc-v0.4.25/bin/solc ENV WALLET_PRIVATE_KEY="4F611197A6E82715F4D2446FE015D1667E9C40A351411F3A7300F71F285D01B4" -WORKDIR /project/TrustedComputeFramework/__tools__/build +WORKDIR /project/TrustedComputeFramework/tools/build diff --git a/examples/apps/CMakeLists.txt b/examples/apps/CMakeLists.txt new file mode 100644 index 000000000..1f65da3e5 --- /dev/null +++ b/examples/apps/CMakeLists.txt @@ -0,0 +1,22 @@ +# 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. + +CMAKE_MINIMUM_REQUIRED(VERSION 3.2 FATAL_ERROR) + +INCLUDE(CMakeVariables.txt) + +################################################################################ +ADD_SUBDIRECTORY(echo/workload) +ADD_SUBDIRECTORY(heart_disease_eval/workload) + diff --git a/examples/apps/CMakeVariables.txt b/examples/apps/CMakeVariables.txt new file mode 100644 index 000000000..fa4f98dc6 --- /dev/null +++ b/examples/apps/CMakeVariables.txt @@ -0,0 +1,35 @@ +# 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. + + +################################################################################ +# Configure Environment +################################################################################ + +SET(TCF_TOP_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../") + +if("$ENV{DEBUG} " STREQUAL " ") + SET(DEBUG_FLAGS "-O2") + message(STATUS "Compiling with optimizations (-O2). To use debug flags, set the DEBUG environment variable.") +else() + SET(DEBUG_FLAGS "-Og" "-g" "-DDEBUG") + message(STATUS "Compiling in debug mode without optimizations (-Og -g)") +endif() + +SET(SGX_SDK "$ENV{SGX_SDK}") +if("${SGX_SDK} " STREQUAL " ") + message(FATAL_ERROR "SGX_SDK environment variable not defined!") +endif() + +SET(GENERIC_PUBLIC_INCLUDE_DIRS "${SGX_SDK}/include") diff --git a/workloads/echo_work_order/CMakeLists.txt b/examples/apps/echo/workload/CMakeLists.txt similarity index 95% rename from workloads/echo_work_order/CMakeLists.txt rename to examples/apps/echo/workload/CMakeLists.txt index b6d412858..44d3a1a64 100644 --- a/workloads/echo_work_order/CMakeLists.txt +++ b/examples/apps/echo/workload/CMakeLists.txt @@ -31,7 +31,6 @@ TARGET_INCLUDE_DIRECTORIES(${ECHO_WORK_ORDER_STATIC_NAME} PRIVATE ${GENERIC_PRIV TARGET_INCLUDE_DIRECTORIES(${ECHO_WORK_ORDER_STATIC_NAME} PUBLIC ${GENERIC_PUBLIC_INCLUDE_DIRS}) TARGET_INCLUDE_DIRECTORIES(${ECHO_WORK_ORDER_STATIC_NAME} PUBLIC "${SGX_SDK}/include/tlibc") TARGET_INCLUDE_DIRECTORIES(${ECHO_WORK_ORDER_STATIC_NAME} PUBLIC "${SGX_SDK}/include/libcxx") -TARGET_INCLUDE_DIRECTORIES(${ECHO_WORK_ORDER_STATIC_NAME} PUBLIC "${SGX_SSL}/include") TARGET_COMPILE_OPTIONS(${ECHO_WORK_ORDER_STATIC_NAME} PRIVATE "${GENERIC_CXX_FLAGS}") TARGET_COMPILE_OPTIONS(${ECHO_WORK_ORDER_STATIC_NAME} PRIVATE "-nostdinc") diff --git a/workloads/echo_work_order/echo_workorder.cpp b/examples/apps/echo/workload/echo.cpp similarity index 96% rename from workloads/echo_work_order/echo_workorder.cpp rename to examples/apps/echo/workload/echo.cpp index 5a3939336..1d91cda6d 100644 --- a/workloads/echo_work_order/echo_workorder.cpp +++ b/examples/apps/echo/workload/echo.cpp @@ -13,7 +13,7 @@ * limitations under the License. */ -#include "echo_workorder.h" +#include "echo.h" std::string EchoResultImpl::Process(std::string str_in) { return "RESULT: " + str_in; diff --git a/workloads/echo_work_order/echo_workorder.h b/examples/apps/echo/workload/echo.h similarity index 100% rename from workloads/echo_work_order/echo_workorder.h rename to examples/apps/echo/workload/echo.h diff --git a/workloads/heart_disease_eval/CMakeLists.txt b/examples/apps/heart_disease_eval/workload/CMakeLists.txt similarity index 95% rename from workloads/heart_disease_eval/CMakeLists.txt rename to examples/apps/heart_disease_eval/workload/CMakeLists.txt index 865e8c807..89de1055c 100644 --- a/workloads/heart_disease_eval/CMakeLists.txt +++ b/examples/apps/heart_disease_eval/workload/CMakeLists.txt @@ -31,7 +31,6 @@ TARGET_INCLUDE_DIRECTORIES(${HEART_DISEASE_EVAL_STATIC_NAME} PRIVATE ${GENERIC_P TARGET_INCLUDE_DIRECTORIES(${HEART_DISEASE_EVAL_STATIC_NAME} PUBLIC ${GENERIC_PUBLIC_INCLUDE_DIRS}) TARGET_INCLUDE_DIRECTORIES(${HEART_DISEASE_EVAL_STATIC_NAME} PUBLIC "${SGX_SDK}/include/tlibc") TARGET_INCLUDE_DIRECTORIES(${HEART_DISEASE_EVAL_STATIC_NAME} PUBLIC "${SGX_SDK}/include/libcxx") -TARGET_INCLUDE_DIRECTORIES(${HEART_DISEASE_EVAL_STATIC_NAME} PUBLIC "${SGX_SSL}/include") TARGET_COMPILE_OPTIONS(${HEART_DISEASE_EVAL_STATIC_NAME} PRIVATE "${GENERIC_CXX_FLAGS}") TARGET_COMPILE_OPTIONS(${HEART_DISEASE_EVAL_STATIC_NAME} PRIVATE "-nostdinc") diff --git a/workloads/heart_disease_eval/heart_disease_evaluation.cpp b/examples/apps/heart_disease_eval/workload/heart_disease_evaluation.cpp similarity index 100% rename from workloads/heart_disease_eval/heart_disease_evaluation.cpp rename to examples/apps/heart_disease_eval/workload/heart_disease_evaluation.cpp diff --git a/workloads/heart_disease_eval/heart_disease_evaluation.h b/examples/apps/heart_disease_eval/workload/heart_disease_evaluation.h similarity index 100% rename from workloads/heart_disease_eval/heart_disease_evaluation.h rename to examples/apps/heart_disease_eval/workload/heart_disease_evaluation.h diff --git a/common/Makefile b/examples/common/python/Makefile similarity index 76% rename from common/Makefile rename to examples/common/python/Makefile index 72a1275c4..79799f9d3 100644 --- a/common/Makefile +++ b/examples/common/python/Makefile @@ -13,33 +13,37 @@ # limitations under the License. PY_VERSION=${shell python3 --version | sed 's/Python \(3\.[0-9]\).*/\1/'} -MOD_VERSION=${shell ../bin/get_version} +MOD_VERSION=${shell ../../../bin/get_version} -EGG_FILE=dist/tcf_common-${MOD_VERSION}-py${PY_VERSION}.egg +EGG_FILE=dist/tcf_examples_common-${MOD_VERSION}-py${PY_VERSION}-linux-x86_64.egg SOURCE_DIR=$(shell pwd) all : $(EGG_FILE) -$(EGG_FILE) : +$(EGG_FILE) : build_ext @echo Build Distribution python3 setup.py bdist_egg +build_ext : + @echo Build build_ext + python3 setup.py build_ext + build : mkdir $@ cd $@ -install: $(EGG_FILE) +install: @echo INSTALLING EGG FILE ================= - easy_install $< + easy_install $(EGG_FILE) clean: rm -rf build deps dist *.egg-info + rm -f crypto/crypto.py crypto/crypto_wrap.cpp find . -iname '*.pyc' -delete find . -iname '__pycache__' -delete .phony : all .phony : clean .phone : install -.phony : info diff --git a/common/utils/__init__.py b/examples/common/python/config/__init__.py similarity index 100% rename from common/utils/__init__.py rename to examples/common/python/config/__init__.py diff --git a/tcs/core/common/python/config/config.py b/examples/common/python/config/config.py similarity index 96% rename from tcs/core/common/python/config/config.py rename to examples/common/python/config/config.py index 3dd3bfd03..7edda5411 100644 --- a/tcs/core/common/python/config/config.py +++ b/examples/common/python/config/config.py @@ -13,10 +13,10 @@ # limitations under the License. """ -config.py -- functions to load configuration files with support for +config.py -- Functions to load configuration files with support for variable expansion. -NOTE: functions defined in this file are designed to be run +NOTE: Functions defined in this file are designed to be run before logging is enabled. """ diff --git a/common/tcf_connector/TestingContracts.md b/examples/common/python/connectors/TestingContracts.md similarity index 88% rename from common/tcf_connector/TestingContracts.md rename to examples/common/python/connectors/TestingContracts.md index 26c9e1e13..cf42acc42 100644 --- a/common/tcf_connector/TestingContracts.md +++ b/examples/common/python/connectors/TestingContracts.md @@ -13,7 +13,6 @@ Requirements: python3 -m solc.install v0.4.25 4. Set the solidity compiler binary path, so that it is accessible in python program export SOLC_BINARY=~/.py-solc/solc-v0.4.25/bin/solc - 5. Running smart contract using ropsten network account Install meta mask chrome plugin and create account in ropsten network. After creating account make sure to add fake ether to account using https://faucet.metamask.io/ @@ -22,7 +21,7 @@ https://blog.bankex.org/how-to-buy-ethereum-using-metamask-ccea0703daec Test DirectRegistry and WorkerRegistry contract using ropsten account export WALLET_PRIVATE_KEY= -cd tcf_connector -python3 TestEthereumDirectRegistry.py -python3 TestEthereumWorkerRegistry.py +cd connectors/ethereum/unit_tests +python3 test_ethereum_worker_registry_impl.py +python3 test_ethereum_worker_registry_list_impl.py diff --git a/common/tcf_connector/__init__.py b/examples/common/python/connectors/__init__.py similarity index 99% rename from common/tcf_connector/__init__.py rename to examples/common/python/connectors/__init__.py index 3cecdb3f4..f34c4f48c 100644 --- a/common/tcf_connector/__init__.py +++ b/examples/common/python/connectors/__init__.py @@ -11,6 +11,5 @@ # 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. -# __all__ = [] diff --git a/common/tcf_connector/blockchain_adaptor_factory.py b/examples/common/python/connectors/blockchain_adaptor_factory.py similarity index 90% rename from common/tcf_connector/blockchain_adaptor_factory.py rename to examples/common/python/connectors/blockchain_adaptor_factory.py index 6af9fff85..9baa6a228 100644 --- a/common/tcf_connector/blockchain_adaptor_factory.py +++ b/examples/common/python/connectors/blockchain_adaptor_factory.py @@ -11,18 +11,17 @@ # 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 logging from os.path import isfile, realpath import errno import toml -from tcf_connector.connector_adaptor_factory_interface import \ +from connectors.interfaces.connector_adaptor_factory_interface import \ ConnectorAdaptorFactoryInterface -from tcf_connector.ethereum.ethereum_worker_registry_list_impl import \ +from connectors.ethereum.ethereum_worker_registry_list_impl import \ EthereumWorkerRegistryListImpl -from tcf_connector.ethereum.ethereum_worker_registry_impl import \ +from connectors.ethereum.ethereum_worker_registry_impl import \ EthereumWorkerRegistryImpl logger = logging.getLogger(__name__) @@ -47,8 +46,8 @@ def __init__(self, config_file): raise Exception('Could not open config file: %s' % e) self.__worker_registry_list = None self.__worker_registry = None - self.__worker_order = None - self.__worker_order_receipts = None + self.__work_order = None + self.__work_order_receipts = None self.__blockchain_type = self.__config['blockchain']['type'] def create_worker_registry_list_adaptor(self): @@ -74,4 +73,3 @@ def create_work_order_receipt_adaptor(self, config): TODO: Yet to implement for proxy model """ return None - diff --git a/common/tcf_connector/ethereum/__init__.py b/examples/common/python/connectors/direct/__init__.py similarity index 99% rename from common/tcf_connector/ethereum/__init__.py rename to examples/common/python/connectors/direct/__init__.py index 3cecdb3f4..f34c4f48c 100644 --- a/common/tcf_connector/ethereum/__init__.py +++ b/examples/common/python/connectors/direct/__init__.py @@ -11,6 +11,5 @@ # 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. -# __all__ = [] diff --git a/examples/common/python/connectors/direct/direct_adaptor_factory_wrapper.py b/examples/common/python/connectors/direct/direct_adaptor_factory_wrapper.py new file mode 100644 index 000000000..99a92cdf9 --- /dev/null +++ b/examples/common/python/connectors/direct/direct_adaptor_factory_wrapper.py @@ -0,0 +1,189 @@ +# Copyright 2019 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 json +import logging +import time +import sys +import utility.utility as enclave_helper +import utility.signature as signature +from service_client.generic import GenericServiceClient +from connectors.direct.direct_json_rpc_api_adaptor_factory \ + import DirectJsonRpcApiAdaptorFactory +from utility.hex_utils import hex_to_utf, pretty_ids +import json_rpc_request.json_rpc_request + +logger = logging.getLogger(__name__) +# ----------------------------------------------------------------- +class DirectAdaptorFactoryWrapper: + # Contains the functions needed to submit and retrieve work orders in the Direct Model + def __init__(self, config_file): + self.adaptor_factory = DirectJsonRpcApiAdaptorFactory(config_file) + self.worker_registry_list = None + self.worker_registry = None + self.work_order = None + self.work_order_receipt = None + + def init_worker_registry_list(self, config): + self.worker_registry_list = \ + self.adaptor_factory.create_worker_registry_list_adaptor(config) + + # Lookup worker registries in registry list + def registry_lookup(self, app_type_id=None): + if self.worker_registry_list == None: + logger.error("ERROR: Worker registry list adaptor not initialized") + sys.exit(1) + if app_type_id: + lookup_result = self.worker_registry_list.registry_lookup( + app_type_id=app_type_id) + else: + lookup_result = self.worker_registry_list.registry_lookup() + logger.info("Registry Lookup result: [%d, %s, %s]", + lookup_result[0], lookup_result[1], + pretty_ids(lookup_result[2])) + return lookup_result + + # Retrieve worker registry URI + def registry_retrieve(self, org_id): + if self.worker_registry_list == None: + logger.error("ERROR: Worker registry list adaptor not initialized") + sys.exit(1) + retrieve_result = self.worker_registry_list.registry_retrieve(org_id) + logger.info("Registry retrieved: [%s, %s, %s, %d]", + retrieve_result[0], + hex_to_utf(retrieve_result[1]), + pretty_ids(retrieve_result[2]), + retrieve_result[3]) + return retrieve_result + + def init_worker_registry(self, config): + self.worker_registry = \ + self.adaptor_factory.create_worker_registry_adaptor(config) + + # Lookup worker in worker registry + def worker_lookup(self, worker_lookup_json): + if self.worker_registry == None: + logger.error("ERROR: Worker registry adaptor not initialized") + sys.exit(1) + + logger.info("*********Request Json********* \n%s\n", + worker_lookup_json.get_json_str_indent()) + response = self.worker_registry.worker_lookup( + worker_type=worker_lookup_json.get_worker_type(), + organization_id=worker_lookup_json.get_organization_id(), + application_type_id=worker_lookup_json.get_application_type_id(), + id=worker_lookup_json.get_id()) + logger.info("**********Received Response*********\n%s\n", + json.dumps(response, indent=4)) + + return response + + # Retrieve worker from worker registry + def worker_retrieve(self, worker_retrieve_json): + if self.worker_registry == None: + logger.error("ERROR: Worker registry adaptor not initialized") + sys.exit(1) + + logger.info("*********Request Json********* \n%s\n", + worker_retrieve_json.get_json_str_indent()) + response = self.worker_registry.worker_retrieve( + worker_retrieve_json.get_worker_id(), + id=worker_retrieve_json.get_id()) + logger.info("**********Received Response*********\n%s\n", + json.dumps(response, indent=4)) + + if "result" in response: + return response + else: + logger.error("ERROR: Failed to retrieve worker") + sys.exit(1) + + def init_work_order(self, config): + self.work_order = \ + self.adaptor_factory.create_work_order_adaptor(config) + + # Encrypt work order and submit + def work_order_submit(self, wo_submit_json, encrypted_session_key, + worker_obj, private_key, session_iv): + if self.work_order == None: + logger.error("ERROR: Work order adaptor not initialized") + sys.exit(1) + + input_json_str = wo_submit_json.get_json_str() + sig_obj = signature.ClientSignature() + input_json_str = sig_obj.generate_client_signature( + input_json_str, worker_obj, + private_key, session_iv, encrypted_session_key) + wo_submit_json.load_from_str(input_json_str) + + logger.info("*********Request Json********* \n%s\n", + json.dumps(json.loads(input_json_str), indent=4)) + response = self.work_order.work_order_submit( + wo_submit_json.get_params(), wo_submit_json.get_in_data(), + wo_submit_json.get_out_data(), id=wo_submit_json.get_id()) + logger.info("**********Received Response*********\n%s\n", + json.dumps(response, indent=4)) + + # Return signed workorder json + return input_json_str + + # Retrieve work order result and decrypt response + def work_order_get_result(self, wo_get_result_json, encrypted_session_key): + if self.work_order == None: + logger.error("ERROR: Work order adaptor not initialized") + sys.exit(1) + + logger.info("*********Request Json********* \n%s\n", + wo_get_result_json.get_json_str_indent()) + response = self.work_order.work_order_get_result( + wo_get_result_json.get_work_order_id(), + wo_get_result_json.get_id()) + logger.info("**********Received Response*********\n%s\n", + json.dumps(response)) + + # Poll for the "WorkOrderGetResult" and break when you get the result + while("result" not in response): + if response["error"]["code"] == 9: + break + response = self.work_order.work_order_get_result( + wo_get_result_json.get_work_order_id(), + wo_get_result_json.get_id()) + if "result" not in response: + logger.info(" Received Response : %s, \n \n ", response) + time.sleep(3) + else: + logger.info(" Received Response : %s, \n \n ", + json.dumps(response, indent=4)) + + return enclave_helper.decrypted_response( + json.dumps(response), encrypted_session_key) + + def init_work_order_receipt(self, config): + self.work_order_receipt = \ + self.adaptor_factory.create_work_order_receipt_adaptor(config) + + # Retrieve work order receipt + def work_order_receipt_retrieve(self, wo_receipt_retrieve_json): + if self.work_order_receipt == None: + logger.error("ERROR: Work order adaptor not initialized") + sys.exit(1) + + logger.info("*********Request Json********* \n%s\n", + wo_receipt_retrieve_json.get_json_str_indent()) + response = self.work_order_receipt.work_order_receipt_retrieve( + wo_receipt_retrieve_json.get_work_order_id(), + wo_receipt_retrieve_json.get_id()) + logger.info("**********Received Response*********\n%s\n", + json.dumps(response, indent=4)) + return response diff --git a/common/tcf_connector/direct_json_rpc_api_adaptor_factory.py b/examples/common/python/connectors/direct/direct_json_rpc_api_adaptor_factory.py similarity index 82% rename from common/tcf_connector/direct_json_rpc_api_adaptor_factory.py rename to examples/common/python/connectors/direct/direct_json_rpc_api_adaptor_factory.py index ac472d6b0..8afd1fdc4 100644 --- a/common/tcf_connector/direct_json_rpc_api_adaptor_factory.py +++ b/examples/common/python/connectors/direct/direct_json_rpc_api_adaptor_factory.py @@ -11,20 +11,19 @@ # 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 logging from os.path import isfile, realpath import errno import toml -from tcf_connector.connector_adaptor_factory_interface import \ +from connectors.interfaces.connector_adaptor_factory_interface import \ ConnectorAdaptorFactoryInterface -from tcf_connector.ethereum.ethereum_worker_registry_list_impl import \ +from connectors.ethereum.ethereum_worker_registry_list_impl import \ EthereumWorkerRegistryListImpl -from tcf_connector.worker_registry_jrpc_impl import WorkerRegistryJRPCImpl -from tcf_connector.work_order_jrpc_impl import WorkOrderJRPCImpl -from tcf_connector.work_order_receipt_jrpc_impl import WorkOrderReceiptJRPCImpl +from connectors.direct.worker_registry_jrpc_impl import WorkerRegistryJRPCImpl +from connectors.direct.work_order_jrpc_impl import WorkOrderJRPCImpl +from connectors.direct.work_order_receipt_jrpc_impl import WorkOrderReceiptJRPCImpl logger = logging.getLogger(__name__) @@ -53,7 +52,7 @@ def __init__(self, config_file): self.__worker_registry_list = None self.__worker_registry = None self.__work_order = None - self.__worker_order_receipt = None + self.__work_order_receipts = None self.__blockchain_type = self.__config['blockchain']['type'] def create_worker_registry_list_adaptor(self, config): @@ -73,7 +72,7 @@ def create_work_order_adaptor(self, config): return self.__work_order def create_work_order_receipt_adaptor(self, config): - if self.__worker_order_receipt is None: - self.__worker_order_receipt = WorkOrderReceiptJRPCImpl(config) - return self.__worker_order_receipt + if self.__work_order_receipts is None: + self.__work_order_receipts = WorkOrderReceiptJRPCImpl(config) + return self.__work_order_receipts diff --git a/common/worker/__init__.py b/examples/common/python/connectors/direct/tcs_listener/__init__.py similarity index 100% rename from common/worker/__init__.py rename to examples/common/python/connectors/direct/tcs_listener/__init__.py diff --git a/tcs/tcs_listener/tcs_listener.py b/examples/common/python/connectors/direct/tcs_listener/tcs_listener.py similarity index 84% rename from tcs/tcs_listener/tcs_listener.py rename to examples/common/python/connectors/direct/tcs_listener/tcs_listener.py index 14222d69f..b59a4bb7f 100644 --- a/tcs/tcs_listener/tcs_listener.py +++ b/examples/common/python/connectors/direct/tcs_listener/tcs_listener.py @@ -41,6 +41,7 @@ from tcs_worker_encryption_key_handler import WorkerEncryptionKeyHandler from shared_kv.shared_kv_interface import KvStorage from error_code.error_status import WorkorderError +import utility.utility as utility import logging logger = logging.getLogger(__name__) @@ -119,51 +120,62 @@ def _process_request(self, input_json_str): return response def render_GET(self, request): - response = {} - response['error'] = {} - response['error']['code'] = WorkorderError.INVALID_PARAMETER_FORMAT_OR_VALUE - response['error']['message'] = 'Only POST request is supported' + # JRPC response with id 0 is returned because id parameter + # will not be found in GET request + response = utility.create_error_response( + WorkorderError.INVALID_PARAMETER_FORMAT_OR_VALUE, "0", + "Only POST request is supported") logger.error("GET request is not supported. Only POST request is supported") - + return response def render_POST(self, request): response = {} - response['error'] = {} - response['error']['code'] = WorkorderError.UNKNOWN_ERROR - - logger.info('Received a new request from the client') + logger.info('Received a new request from the client') try : # process the message encoding encoding = request.getHeader('Content-Type') data = request.content.read() - if encoding == 'application/json' : try: - input_json = json.loads(data.decode('utf-8')) - response = self._process_request(input_json) + input_json_str = json.loads(data.decode('utf-8')) + input_json = json.loads(input_json_str) + jrpc_id = input_json["id"] + response = self._process_request(input_json_str) except AttributeError: logger.error("Error while loading input json") - response['error']['message'] = 'UNKNOWN_ERROR: Error while loading the input JSON file' + response = utility.create_error_response( + WorkorderError.UNKNOWN_ERROR, + jrpc_id, + "UNKNOWN_ERROR: Error while loading the input JSON file") return response else : - response['error']['message'] = 'UNKNOWN_ERROR: unknown message encoding' + # JRPC response with 0 as id is returned because id can't be fecthed + # from a request with unknown encoding + response = utility.create_error_response( + WorkorderError.UNKNOWN_ERROR, + 0, + "UNKNOWN_ERROR: unknown message encoding") return response except : logger.exception('exception while decoding http request %s', request.path) - response['error']['message'] = 'UNKNOWN_ERROR: unable to decode incoming request ' + # JRPC response with 0 as id is returned because id can't be + # fetched from improper request + response = utility.create_error_response( + WorkorderError.UNKNOWN_ERROR, + 0, + "UNKNOWN_ERROR: unable to decode incoming request") return response # send back the results try : if encoding == 'application/json' : response = json.dumps(response) - logger.info('response[%s]: %s', encoding, response) request.setHeader('content-type', encoding) request.setResponseCode(http.OK) @@ -171,7 +183,11 @@ def render_POST(self, request): except : logger.exception('unknown exception while processing request %s', request.path) - response['error']['message'] = 'UNKNOWN_ERROR: unknown exception processing http request {0}'.format(request.path) + response = utility.create_error_response( + WorkorderError.UNKNOWN_ERROR, + jrpc_id, + "UNKNOWN_ERROR: unknown exception processing http \ + request {0}".format(request.path)) return response # ----------------------------------------------------------------- diff --git a/tcs/tcs_listener/tcs_work_order_handler.py b/examples/common/python/connectors/direct/tcs_listener/tcs_work_order_handler.py similarity index 80% rename from tcs/tcs_listener/tcs_work_order_handler.py rename to examples/common/python/connectors/direct/tcs_listener/tcs_work_order_handler.py index 987917095..80a9610d0 100644 --- a/tcs/tcs_listener/tcs_work_order_handler.py +++ b/examples/common/python/connectors/direct/tcs_listener/tcs_work_order_handler.py @@ -18,6 +18,7 @@ import crypto.crypto as crypto from error_code.error_status import WorkorderError from shared_kv.shared_kv_interface import KvStorage +import utility.utility as utility logger = logging.getLogger(__name__) @@ -91,15 +92,18 @@ def process_work_order(self, input_json_str): if(input_json['method'] == "WorkOrderSubmit"): return self.__process_work_order_submission(wo_id, input_json_str, response) elif(input_json['method'] == "WorkOrderGetResult"): - return self.__process_work_order_get_result(wo_id, response) + return self.__process_work_order_get_result(wo_id, + input_json['id'], + response) #--------------------------------------------------------------------------------------------- - def __process_work_order_get_result(self, wo_id, response): + def __process_work_order_get_result(self, wo_id, jrpc_id, response): """ Function to process work order get result This API corresponds to TCF API 6.1.4 Work Order Pull Request Payload Parameters: - - wo_id is workorder id + - wo_id is work order id + - jrpc_id is JRPC id of response - response is the response object to be returned """ @@ -112,15 +116,18 @@ def __process_work_order_get_result(self, wo_id, response): else: response['result'] = input_value['error'] else: - response['error'] = {} if(self.kv_helper.get("wo-timestamps", wo_id) is not None): # work order is yet to be processed - response['error']['code'] = WorkorderError.PENDING - response['error']['message'] = 'Workorder result is yet to be updated' + response = utility.create_error_response( + WorkorderError.PENDING, jrpc_id, + "Work order result is yet to be updated") else : # work order not in 'wo-timestamps' table - response['error']['code'] = WorkorderError.INVALID_PARAMETER_FORMAT_OR_VALUE - response['error']['message'] = 'Workorder Id not found in the database. Hence invalid parameter' + response = utility.create_error_response( + WorkorderError.INVALID_PARAMETER_FORMAT_OR_VALUE, + jrpc_id, + "Work order Id not found in the database. \ + Hence invalid parameter") return response @@ -129,12 +136,13 @@ def __process_work_order_submission(self, wo_id, input_json_str, response): """ Function to process work order request Parameters: - - wo_id is workorder id + - wo_id is work order id - input_json_str is a work order request json as per TCF API 6.1.1 Work Order Request Payload - response is the response object to be returned to client """ - response['error'] = {} + input_value_json = json.loads(input_json_str) + jrpc_id = input_value_json["id"] if((self.workorder_count + 1) > self.max_workorder_count): @@ -156,8 +164,10 @@ def __process_work_order_submission(self, wo_id, input_json_str, response): # If no work order is processed then return busy if((self.workorder_count + 1) > self.max_workorder_count): - response['error']['code'] = WorkorderError.BUSY - response['error']['message'] = 'Workorder handler is busy updating the result' + response = utility.create_error_response( + WorkorderError.BUSY, + jrpc_id, + "Work order handler is busy updating the result") return response if(self.kv_helper.get("wo-timestamps",wo_id) is None): @@ -174,13 +184,19 @@ def __process_work_order_submission(self, wo_id, input_json_str, response): self.workorder_list.append(wo_id) self.workorder_count += 1 - response['error']['code'] = WorkorderError.PENDING - response['error']['message'] = 'Work Order is computing. Please query for WorkOrderGetResult to view the result.' + response = utility.create_error_response( + WorkorderError.PENDING, + jrpc_id, + "Work order is computing. Please query for WorkOrderGetResult \ + to view the result") - else: # Workorder id already exists - response['error']['code'] = WorkorderError.INVALID_PARAMETER_FORMAT_OR_VALUE - response['error']['message'] = 'Workorder Id already exists in the database. Hence invalid parameter' + else: + # Workorder id already exists + response = utility.create_error_response( + WorkorderError.INVALID_PARAMETER_FORMAT_OR_VALUE, + jrpc_id, + "Work order id already exists in the database. \ + Hence invalid parameter") return response #--------------------------------------------------------------------------------------------- - diff --git a/tcs/tcs_listener/tcs_worker_encryption_key_handler.py b/examples/common/python/connectors/direct/tcs_listener/tcs_worker_encryption_key_handler.py similarity index 89% rename from tcs/tcs_listener/tcs_worker_encryption_key_handler.py rename to examples/common/python/connectors/direct/tcs_listener/tcs_worker_encryption_key_handler.py index 14469a7c2..a2bf0798e 100644 --- a/tcs/tcs_listener/tcs_worker_encryption_key_handler.py +++ b/examples/common/python/connectors/direct/tcs_listener/tcs_worker_encryption_key_handler.py @@ -15,8 +15,9 @@ import json import logging import crypto.crypto as crypto -from error_code.error_status import WorkorderError +from error_code.error_status import WorkerError from shared_kv.shared_kv_interface import KvStorage +import utility.utility as utility logger = logging.getLogger(__name__) #No of bytes of encryptionKeyNonce to encrypt data @@ -72,9 +73,11 @@ def __process_encryption_key_set(self, input_json_str, response): - response is the response object to be returned """ - response['error'] = {} - response['error']['code'] = WorkorderError.INVALID_PARAMETER_FORMAT_OR_VALUE - response['error']['message'] = 'Operation is not supported. Hence invalid parameter' + input_json = json.loads(input_json_str) + jrpc_id = input_json["id"] + response = utility.create_error_response( + WorkerError.INVALID_PARAMETER_FORMAT_OR_VALUE, jrpc_id, + "Operation is not supported. Hence invalid parameter") return response #--------------------------------------------------------------------------------------------- @@ -87,6 +90,7 @@ def __process_encryption_key_get(self, input_json_str, response): """ input_json = json.loads(input_json_str) + jrpc_id = input_json["id"] worker_id = str(input_json['params']['workerId']) value = self.kv_helper.get("workers", worker_id) @@ -114,9 +118,9 @@ def __process_encryption_key_get(self, input_json_str, response): response["result"]["signature"] = s1 else : # Workorder id already exists - response['error'] = {} - response['error']['code'] = WorkorderError.INVALID_PARAMETER_FORMAT_OR_VALUE - response['error']['message'] = 'Worker Id not found in the database. Hence invalid parameter' + response = utility.create_error_response( + WorkerError.INVALID_PARAMETER_FORMAT_OR_VALUE, jrpc_id, + "Worker id not found in the database. Hence invalid parameter") return response #--------------------------------------------------------------------------------------------- diff --git a/tcs/tcs_listener/tcs_worker_registry_handler.py b/examples/common/python/connectors/direct/tcs_listener/tcs_worker_registry_handler.py similarity index 84% rename from tcs/tcs_listener/tcs_worker_registry_handler.py rename to examples/common/python/connectors/direct/tcs_listener/tcs_worker_registry_handler.py index 87fff6332..86d268d36 100644 --- a/tcs/tcs_listener/tcs_worker_registry_handler.py +++ b/examples/common/python/connectors/direct/tcs_listener/tcs_worker_registry_handler.py @@ -15,7 +15,7 @@ import json import logging from itertools import cycle -from utils.utility import list_difference as list_diff +import utility.utility as utility from error_code.error_status import WorkerError from error_code.error_status import WorkerStatus from shared_kv.shared_kv_interface import KvStorage @@ -100,10 +100,11 @@ def worker_registry_handler(self,input_json_str): if 'workerId' in input_json_str: worker_id = str(input_json['params']['workerId']) else : - response['error'] = {} - response['error']['code'] = WorkerError.INVALID_PARAMETER_FORMAT_OR_VALUE - response['error']['message'] = "Worker Id not found in the database. Hence invalid parameter" - return response + return utility.create_error_response( + WorkerError.INVALID_PARAMETER_FORMAT_OR_VALUE, + input_json["id"], + "Worker Id not found in the database. \ + Hence invalid parameter") if(input_json['method'] == "WorkerRegister"): return self.__process_worker_register(worker_id, input_json_str, response) @@ -124,9 +125,10 @@ def __process_worker_register(self, worker_id, input_json_str, response): - response is the response object to be returned to client. """ - response['error'] = {} + input_value_json = json.loads(input_json_str) + jrpc_id = input_value_json["id"] + if(self.kv_helper.get("workers", worker_id) is None): - input_value_json = json.loads(input_json_str) input_value = {} input_value = input_value_json['params'] @@ -135,11 +137,15 @@ def __process_worker_register(self, worker_id, input_json_str, response): input_json_str = json.dumps(input_value) self.kv_helper.set("workers", worker_id, input_json_str) - response['error']['code'] = WorkerError.SUCCESS - response['error']['message'] = "Successfully Registered" + response = utility.create_error_response( + WorkerError.SUCCESS, jrpc_id, + "Successfully Registered") else: - response['error']['code'] = WorkerError.INVALID_PARAMETER_FORMAT_OR_VALUE - response['error']['message'] = "Worker Id already exists in the database. Hence invalid parameter" + response = utility.create_error_response( + WorkerError.INVALID_PARAMETER_FORMAT_OR_VALUE, + jrpc_id, + "Worker Id already exists in the database. \ + Hence invalid parameter") return response # ------------------------------------------------------------------------------------------------ @@ -153,21 +159,26 @@ def __process_worker_set_status(self, worker_id, input_json_str, response): """ #status can be one of active, offline, decommissioned, or compromised - response['error'] = {} + + input_value = json.loads(input_json_str) + jrpc_id = input_value["id"] value = self.kv_helper.get("workers", worker_id) if value: - input_value = json.loads(input_json_str) json_dict = json.loads(value) json_dict['status'] = input_value['params']['status'] value = json.dumps(json_dict) self.kv_helper.set("workers", worker_id, value) - response['error']['code'] = WorkerError.SUCCESS - response['error']['message'] = "Successfully Set Status" + response = utility.create_error_response( + WorkerError.SUCCESS, jrpc_id, + "Successfully Set Status") else: - response['error']['code'] = WorkerError.INVALID_PARAMETER_FORMAT_OR_VALUE - response['error']['message'] = "Worker Id not found in the database. Hence invalid parameter" + response = utility.create_error_response( + WorkerError.INVALID_PARAMETER_FORMAT_OR_VALUE, + jrpc_id, + "Worker Id not found in the database. \ + Hence invalid parameter") return response # ------------------------------------------------------------------------------------------------ @@ -177,12 +188,12 @@ def __lookup_basic(self, lookup_bool, input_json_str, response): work_orders = self.kv_helper.lookup("workers") alter_items = [] - alter_items = list_diff(self.worker_pool, work_orders) + alter_items = utility.list_difference(self.worker_pool, work_orders) for item in alter_items: self.worker_pool.remove(item) - alter_items = list_diff(work_orders, self.worker_pool) + alter_items = utility.list_difference(work_orders, self.worker_pool) for item in alter_items: self.worker_pool.append(item) @@ -275,9 +286,11 @@ def __process_worker_retrieve(self, worker_id, response): response["result"]["details"] = json_dict["details"] response["result"]["status"] = json_dict["status"] else : - response['error'] = {} - response['error']['code'] = WorkerError.INVALID_PARAMETER_FORMAT_OR_VALUE - response['error']['message'] = "Worker Id not found in the database. Hence invalid parameter" + jrpc_id = json.loads(response)["id"] + response = utility.create_error_response( + WorkerError.INVALID_PARAMETER_FORMAT_OR_VALUE, + jrpc_id, + "Worker Id not found in the database. Hence invalid parameter") return response # ------------------------------------------------------------------------------------------------ @@ -290,10 +303,11 @@ def __process_worker_update(self, worker_id, input_json_str, response): - response is the response object to be returned to client. """ + jrpc_id = json.loads(input_json_str)["id"] + # value retrieved is 'result' field as per Spec 5.3.8 Worker Retrieve Response Payload value = self.kv_helper.get("workers", worker_id) - response['error'] = {} - + if value is not None: json_dict = json.loads(value) input_value = json.loads(input_json_str) @@ -303,11 +317,14 @@ def __process_worker_update(self, worker_id, input_json_str, response): value = json.dumps(json_dict) self.kv_helper.set("workers", worker_id, value) - response['error']['code'] = WorkerError.SUCCESS - response['error']['message'] = "Successfully Updated" + response = utility.create_error_response( + WorkerError.SUCCESS, jrpc_id, + "Successfully Updated") else : - - response['error']['code'] = WorkerError.INVALID_PARAMETER_FORMAT_OR_VALUE - response['error']['message'] = "Worker Id not found in the database. Hence invalid parameter" + response = utility.create_error_response( + WorkerError.INVALID_PARAMETER_FORMAT_OR_VALUE, + jrpc_id, + "Worker Id not found in the database. \ + Hence invalid parameter") return response # ------------------------------------------------------------------------------------------------ diff --git a/tcs/tcs_listener/tcs_workorder_receipt_handler.py b/examples/common/python/connectors/direct/tcs_listener/tcs_workorder_receipt_handler.py similarity index 75% rename from tcs/tcs_listener/tcs_workorder_receipt_handler.py rename to examples/common/python/connectors/direct/tcs_listener/tcs_workorder_receipt_handler.py index da40c2e36..8408d0c81 100644 --- a/tcs/tcs_listener/tcs_workorder_receipt_handler.py +++ b/examples/common/python/connectors/direct/tcs_listener/tcs_workorder_receipt_handler.py @@ -16,7 +16,7 @@ import logging from error_code.error_status import ReceiptCreateStatus from error_code.error_status import WorkorderError -from utils.utility import list_difference as list_diff +import utility.utility as utility from itertools import cycle from shared_kv.shared_kv_interface import KvStorage @@ -51,12 +51,14 @@ def __process_store_workorder_receipt(self, wo_id, input_json_str, response): """ Function to process work order request Parameters: - - wo_id is workorder id - - input_json_str is create workorder receipt json as per TCF API 7.2.2 Receipt Create Request Payload + - wo_id is work order id + - input_json_str is create work order receipt json + as per TCF API 7.2.2 Receipt Create Request Payload - response is the response object to be returned to client """ input_value_json = json.loads(input_json_str) + jrpc_id = input_value_json["id"] input_value = {} input_value['result'] = input_value_json['params'] input_value['result']['receiptCurrentStatus'] = ReceiptCreateStatus.PENDING @@ -64,19 +66,21 @@ def __process_store_workorder_receipt(self, wo_id, input_json_str, response): input_value['result']['updater'] = {} input_json_str = json.dumps(input_value) - response['error'] = {} if(self.kv_helper.get("wo-receipts",wo_id) is None): value = self.kv_helper.get("wo-requests", wo_id) if value: self.kv_helper.set("wo-receipts",wo_id,input_json_str) - response['error']['code'] = WorkorderError.SUCCESS - response['error']['message'] = 'Receipt created successfully' + response = utility.create_error_response( + WorkorderError.SUCCESS, jrpc_id, + "Receipt created successfully") else: - response['error']['code'] = WorkorderError.INVALID_PARAMETER_FORMAT_OR_VALUE - response['error']['message'] = 'Workorder does not exists. Hence invalid parameter' + response = utility.create_error_response( + WorkorderError.INVALID_PARAMETER_FORMAT_OR_VALUE, jrpc_id, + "Work order does not exists. Hence invalid parameter") else: - response['error']['code'] = WorkorderError.INVALID_PARAMETER_FORMAT_OR_VALUE - response['error']['message'] = 'WorkorderReceipt already exist in the database. Hence invalid parameter' + response = utility.create_error_response( + WorkorderError.INVALID_PARAMETER_FORMAT_OR_VALUE, jrpc_id, + "Work order receipt already exist in the database. Hence invalid parameter") return response # ------------------------------------------------------------------------------------------------ @@ -85,17 +89,20 @@ def __process_workorder_receipt_update(self, wo_id, input_json_str, response): """ Function to process update work order request Parameters: - - wo_id is workorder id - - input_json_str is workorder receipt update json as per TCF API 7.2.6 Receipt Update Retrieve Request Payload + - wo_id is work order id + - input_json_str is work order receipt update json as per + TCF API 7.2.6 Receipt Update Retrieve Request Payload - response is the response object to be returned to client """ + input_value = json.loads(input_json_str) + jrpc_id = input_value["id"] + # value retrieved is 'result' field as per Spec 7.2.5 Receipt Retrieve Response Payload value = self.kv_helper.get("wo-receipts", wo_id) response['error'] = {} if value : - input_value = json.loads(input_json_str) updater_value = input_value['params'] # WorkorderId already a part of receipt. And will be not change for a given receipt. Hence it's not stored in updater param. del updater_value['workOrderId'] @@ -115,12 +122,15 @@ def __process_workorder_receipt_update(self, wo_id, input_json_str, response): value = json.dumps(json_dict) self.kv_helper.set("wo-receipts", wo_id, value) - response['error']['code'] = WorkorderError.SUCCESS - response['error']['message'] = 'Receipt Successfully Updated' + response = utility.create_error_response( + WorkorderError.SUCCESS, jrpc_id, + "Receipt Successfully Updated") else: - response['error']['code'] = WorkorderError.INVALID_PARAMETER_FORMAT_OR_VALUE - response['error']['message'] = 'Workorder Id not found in the database. Hence invalid parameter' - + response = utility.create_error_response( + WorkorderError.INVALID_PARAMETER_FORMAT_OR_VALUE, + jrpc_id, + "Work order id not found in the database. \ + Hence invalid parameter") return response # ------------------------------------------------------------------------------------------------ @@ -129,11 +139,11 @@ def __lookup_basics(self, lookup_bool, input_json_str, response): work_orders = self.kv_helper.lookup("wo-receipts") alter_items = [] - alter_items = list_diff(self.receipt_pool, work_orders) + alter_items = utility.list_difference(self.receipt_pool, work_orders) for item in alter_items: self.receipt_pool.remove(item) - alter_items = list_diff(work_orders, self.receipt_pool) + alter_items = utility.list_difference(work_orders, self.receipt_pool) for item in alter_items: self.receipt_pool.append(item) @@ -191,9 +201,10 @@ def __lookup_basics(self, lookup_bool, input_json_str, response): def __process_workorder_receipt_lookup(self,input_json_str, response): """ - Function to look the set of _workorder receipt available + Function to look the set of work order receipts available Parameters: - - input_json_str is a workorder receipt lookup request json as per TCF API 7.2.8 Receipt Lookup Request Payload + - input_json_str is a work order receipt lookup request json + as per TCF API 7.2.8 Receipt Lookup Request Payload - response is the response object to be returned to client. """ @@ -203,9 +214,10 @@ def __process_workorder_receipt_lookup(self,input_json_str, response): def __process_workorder_receipt_lookup_next(self, input_json_str, response): """ - Function to look the set of workorder receipt newly added + Function to look the set of work order receipt newly added Parameters: - - input_json_str is the workorder receipt lookup next json as per TCF API 7.2.10 Receipt Lookup Next Request Payload + - input_json_str is the work order receipt lookup next json + as per TCF API 7.2.10 Receipt Lookup Next Request Payload - response is the response object to be returned to client. """ @@ -213,12 +225,14 @@ def __process_workorder_receipt_lookup_next(self, input_json_str, response): return response # ------------------------------------------------------------------------------------------------ - def __process_workorder_receipt_retrieve(self,wo_id, response): + def __process_workorder_receipt_retrieve(self,wo_id, jrpc_id, response): """ Function to retrieve the details of worker Parameters: - - worker_id is the worker id specified in worker request json as per TCF API 7.2.4 Receipt Retrieve Request Payload - - response is the response object to be returned to client. + - worker_id is the worker id specified in worker request json + as per TCF API 7.2.4 Receipt Retrieve Request Payload + - response is the response object to be returned to client + - jrpc_id is the jrpc id of response object to be returned to client """ # value retrieved is 'result' field as per Spec 7.2.5 Receipt Retrieve Response Payload @@ -233,9 +247,11 @@ def __process_workorder_receipt_retrieve(self,wo_id, response): #Need to revisit code when actual receipts are created response['result'] = input_value['error'] else : - response['error'] = {} - response['error']['code'] = WorkorderError.INVALID_PARAMETER_FORMAT_OR_VALUE - response['error']['message'] = "Workorder Id not found in the database. Hence invalid parameter" + response = utility.create_error_response( + WorkorderError.INVALID_PARAMETER_FORMAT_OR_VALUE, + jrpc_id, + "Work order id not found in the database. \ + Hence invalid parameter") return response return response @@ -243,20 +259,21 @@ def __process_workorder_receipt_retrieve(self,wo_id, response): def __process_workorder_receipt_update_retrieve(self,wo_id, input_json_str, response): """ - Function to process workorder receipt update retrieve + Function to process work order receipt update retrieve Parameters: - - wo_id is workorder id - - input_json_str is workorder receipt update json as per TCF API 7.2.6 Receipt Update Retrieve Request Payload + - wo_id is work order id + - input_json_str is work order receipt update json + as per TCF API 7.2.6 Receipt Update Retrieve Request Payload - response is the response object to be returned to client """ + input_value = json.loads(input_json_str) + jrpc_id = input_value["id"] # value retrieved is 'result' field as per Spec 7.2.5 Receipt Retrieve Response Payload value = self.kv_helper.get("wo-receipts",wo_id) - response['error'] = {} if value : - input_value = json.loads(input_json_str) updater_id = input_value["params"]['updaterId'] update_index = input_value["params"]['updateIndex'] @@ -279,24 +296,28 @@ def __process_workorder_receipt_update_retrieve(self,wo_id, input_json_str, resp response['result']['updateCount'] = update_count else: - response['error']['code'] = WorkorderError.INVALID_PARAMETER_FORMAT_OR_VALUE - response['error']['message'] = 'Workorder Id not found in the database. Hence invalid parameter' + response = utility.create_error_response( + WorkorderError.INVALID_PARAMETER_FORMAT_OR_VALUE, + jrpc_id, + "Work order id not found in the database. \ + Hence invalid parameter") return response # ------------------------------------------------------------------------------------------------ def workorder_receipt_handler(self, input_json_str): """ - Function to process workorder receipt request + Function to process work order receipt request Parameters: - - input_json_str is a workorder receipt request json as per TCF API 7.2 Direct Model Receipt Handling + - input_json_str is a work order receipt request json + as per TCF API 7.2 Direct Model Receipt Handling """ input_json = json.loads(input_json_str) response = {} response['jsonrpc'] = input_json['jsonrpc'] response['id'] = input_json['id'] - logger.info("Received Workorder Receipt request : %s",input_json['method']) + logger.info("Received Work order Receipt request : %s",input_json['method']) if(input_json['method'] == "WorkOrderReceiptLookUp") : return self.__process_workorder_receipt_lookup(input_json_str, response) elif(input_json['method'] == "WorkOrderReceiptLookUpNext") : @@ -305,17 +326,20 @@ def workorder_receipt_handler(self, input_json_str): if 'workOrderId' in input_json_str: wo_id = str(input_json['params']['workOrderId']) else : - response['error'] = {} - response['error']['code'] = WorkorderError.INVALID_PARAMETER_FORMAT_OR_VALUE - response['error']['message'] = 'Workorder Id not found in the database. Hence invalid parameter' + response = utility.create_error_response( + WorkorderError.INVALID_PARAMETER_FORMAT_OR_VALUE, + input_json['id'], + "Work order id not found in the database. \ + Hence invalid parameter") return response + jrpc_id = input_json['id'] if(input_json['method'] == "WorkOrderReceiptCreate") : return self.__process_store_workorder_receipt(wo_id, input_json_str, response) elif(input_json['method'] == "WorkOrderReceiptUpdate") : return self.__process_workorder_receipt_update(wo_id, input_json_str, response) elif(input_json['method'] == "WorkOrderReceiptRetrieve") : - return self.__process_workorder_receipt_retrieve(wo_id, response) + return self.__process_workorder_receipt_retrieve(wo_id, jrpc_id, response) elif(input_json['method'] == "WorkOrderReceiptUpdateRetrieve") : return self.__process_workorder_receipt_update_retrieve(wo_id,input_json_str, response) # ------------------------------------------------------------------------------------------------ diff --git a/examples/common/python/connectors/direct/unit_tests/test_work_order_encryption_key_jrpc_impl.py b/examples/common/python/connectors/direct/unit_tests/test_work_order_encryption_key_jrpc_impl.py new file mode 100644 index 000000000..dccf3e723 --- /dev/null +++ b/examples/common/python/connectors/direct/unit_tests/test_work_order_encryption_key_jrpc_impl.py @@ -0,0 +1,94 @@ +# Copyright 2019 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 logging +from encodings.hex_codec import hex_encode +import base64 +import unittest +from os import path, environ +import errno +import toml +import secrets + + +from connectors.direct.work_order_encryption_key_jrpc_impl import WorkOrderEncryptionKeyJrpcImpl + +logging.basicConfig(format="%(asctime)s - %(levelname)s - %(message)s", level=logging.INFO) + +class TestWorkOrderEncryptionKeyJRPCImpl(unittest.TestCase): + def __init__(self, config_file): + super(TestWorkOrderEncryptionKeyJRPCImpl, self).__init__() + if not path.isfile(config_file): + raise FileNotFoundError("File not found at path: {0}".format(path.realpath(config_file))) + try: + with open(config_file) as fd: + self.__config = toml.load(fd) + except IOError as e: + if e.errno != errno.ENOENT: + raise Exception('Could not open config file: %s',e) + self.__wo_enc_updater = WorkOrderEncryptionKeyJrpcImpl(self.__config) + + + def test_encryption_key_get(self): + req_id = 31 + self.__workerId = secrets.token_hex(32) + self.__last_used_key_nonce = secrets.token_hex(32) + self.__tag = secrets.token_hex(32) + self.__requester_id = secrets.token_hex(32) + self.__signature_nonce = secrets.token_hex(32) + self.__signature = secrets.token_hex(32) + + logging.info("Calling encryption_key_get with workerId %s\n lastUsedKeyNonce %s\n \ + tag %s\n requesterId %s\n signatureNonce %s\n, signature %s\n", + self.__workerId, self.__last_used_key_nonce, self.__tag, + self.__requester_id, self.__signature_nonce, self.__signature) + res = self.__wo_enc_updater.encryption_key_get(self.__workerId, + self.__last_used_key_nonce, + self.__tag, self.__requester_id, + self.__signature_nonce, + self.__signature, + req_id + ) + logging.info("Result: %s\n", res) + self.assertEqual(res['id'], req_id, "work_order_get_result Response id doesn't match") + + def test_encryption_key_set(self): + req_id = 32 + workerId = "0x1234" + logging.info("Calling encryption_key_set with workerId %s\n encryptionKey %s\n \ + encryptionKeyNonce %s\n tag %s\n signatureNonce %s\n signature %s\n", + self.__workerId, self.__last_used_key_nonce, self.__tag, self.__requester_id, + self.__signature_nonce, self.__signature) + + res = self.__wo_enc_updater.encryption_key_set(self.__workerId, + self.__last_used_key_nonce, + self.__tag, self.__requester_id, + self.__signature_nonce, + self.__signature, + req_id + ) + logging.info("Result: %s\n", res) + self.assertEqual(res['id'], req_id, "encryption_key_set Response id doesn't match") + +def main(): + logging.info("Running test cases...\n") + tcf_home = environ.get("TCF_HOME", "../../") + test = TestWorkOrderEncryptionKeyJRPCImpl(tcf_home + "/examples/common/python/connectors/" + "tcf_connector.toml") + test.test_encryption_key_get() + test.test_encryption_key_set() + + +if __name__ == "__main__": + main() + diff --git a/common/tcf_connector/unit_tests/test_work_order_jrpc_impl.py b/examples/common/python/connectors/direct/unit_tests/test_work_order_jrpc_impl.py similarity index 81% rename from common/tcf_connector/unit_tests/test_work_order_jrpc_impl.py rename to examples/common/python/connectors/direct/unit_tests/test_work_order_jrpc_impl.py index 8be850165..322379966 100644 --- a/common/tcf_connector/unit_tests/test_work_order_jrpc_impl.py +++ b/examples/common/python/connectors/direct/unit_tests/test_work_order_jrpc_impl.py @@ -1,3 +1,17 @@ +# Copyright 2019 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 logging from encodings.hex_codec import hex_encode import unittest @@ -7,12 +21,12 @@ import secrets import time import base64 +import json -from tcf_connector.work_order_jrpc_impl import WorkOrderJRPCImpl +from connectors.direct.work_order_jrpc_impl import WorkOrderJRPCImpl logging.basicConfig(format="%(asctime)s - %(levelname)s - %(message)s", level=logging.INFO) - class TestWorkOrderJRPCImpl(unittest.TestCase): def __init__(self, config_file): super(TestWorkOrderJRPCImpl, self).__init__() @@ -34,7 +48,7 @@ def __init__(self, config_file): "notifyUri": "http://notify-uri:8080", "workOrderId": self.__work_order_id, "workerId": "", - "workloadId": secrets.token_hex(32), + "workloadId": "heart-disease-eval".encode("utf-8").hex(), "requesterId": secrets.token_hex(32), "workerEncryptionKey": secrets.token_hex(32), "dataEncryptionAlgorithm": "AES-GCM-256", @@ -81,8 +95,10 @@ def __init__(self, config_file): def test_work_order_submit(self): req_id = 21 - logging.info("Calling work_order_submit with params %s\n in_data %s\n out_data %s\n", - self.__work_order_submit_request, self.__in_data, self.__out_data) + logging.info("Calling work_order_submit with params %s\nin_data %s\nout_data %s\n", + json.dumps(self.__work_order_submit_request, indent=4), + json.dumps(self.__in_data, indent=4), + json.dumps(self.__out_data, indent=4)) res = self.__work_order_wrapper.work_order_submit(self.__work_order_submit_request, self.__in_data, self.__out_data, req_id) logging.info("Result: %s\n", res) self.assertEqual(res['id'], req_id, "work_order_submit Response id doesn't match") @@ -98,13 +114,10 @@ def test_work_order_get_result(self): self.assertEqual(res['id'], req_id, "work_order_get_result Response id doesn't match") - - - def main(): logging.info("Running test cases...\n") tcf_home = environ.get("TCF_HOME", "../../") - test = TestWorkOrderJRPCImpl(tcf_home + "/common/tcf_connector/" + "tcf_connector.toml") + test = TestWorkOrderJRPCImpl(tcf_home + "/examples/common/python/connectors/" + "tcf_connector.toml") test.test_work_order_submit() test.test_work_order_get_result() """ @@ -114,4 +127,3 @@ def main(): if __name__ == "__main__": main() - diff --git a/common/tcf_connector/unit_tests/test_worker_registry_jrpc_impl.py b/examples/common/python/connectors/direct/unit_tests/test_worker_registry_jrpc_impl.py similarity index 83% rename from common/tcf_connector/unit_tests/test_worker_registry_jrpc_impl.py rename to examples/common/python/connectors/direct/unit_tests/test_worker_registry_jrpc_impl.py index df7a209ff..18d032880 100644 --- a/common/tcf_connector/unit_tests/test_worker_registry_jrpc_impl.py +++ b/examples/common/python/connectors/direct/unit_tests/test_worker_registry_jrpc_impl.py @@ -1,4 +1,17 @@ -from tcf_connector.worker_registry_jrpc_impl import WorkerRegistryJRPCImpl +# Copyright 2019 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 logging import unittest import toml @@ -7,11 +20,11 @@ import secrets import json -from utils.tcf_types import WorkerType, WorkerStatus +from connectors.direct.worker_registry_jrpc_impl import WorkerRegistryJRPCImpl +from utility.tcf_types import WorkerType, WorkerStatus logging.basicConfig(format='%(asctime)s - %(levelname)s - %(message)s', level=logging.INFO) - class TestWorkerRegistryJRPCImpl(unittest.TestCase): def __init__(self, config_file): super(TestWorkerRegistryJRPCImpl, self).__init__() @@ -49,7 +62,7 @@ def test_worker_update(self): "workOrderSyncUri": "http://worker-order:8008".encode("utf-8").hex(), "workOrderNotifyUri": "http://worker-notify:8008".encode("utf-8").hex() }) - logging.info('Calling testworker_update with\n worker_id %s\n details %s\n', + logging.info('Calling test_worker_update with\n worker_id %s\n details %s\n', self.__worker_id, self.__details) res = self.__worker_registry_wrapper.worker_update(self.__worker_id, self.__details, req_id) logging.info('Result: %s\n', res) @@ -60,7 +73,7 @@ def test_worker_update(self): def test_worker_set_status(self): req_id = 14 self.__status = WorkerStatus.OFF_LINE - logging.info('Calling testworker_set_status with\n worker_id %s\n status %d\n', + logging.info('Calling test_worker_set_status with\n worker_id %s\n status %d\n', self.__worker_id, self.__status.value) res = self.__worker_registry_wrapper.worker_set_status(self.__worker_id, self.__status, req_id) logging.info('Result: %s\n', res) @@ -70,7 +83,7 @@ def test_worker_set_status(self): def test_worker_retrieve(self): req_id = 15 - logging.info('Calling testworker_retrieve with\n worker_id %s\n', + logging.info('Calling test_worker_retrieve with\n worker_id %s\n', self.__worker_id) res = self.__worker_registry_wrapper.worker_retrieve(self.__worker_id, req_id) logging.info('Result: %s\n', res) @@ -79,7 +92,7 @@ def test_worker_retrieve(self): self.assertEqual(res['result']['organizationId'], self.__org_id, "worker_retrieve Response result organizationId doesn't match") self.assertEqual(res['result']['applicationTypeId'][0], self.__app_ids[0], "worker_retrieve Response result applicationTypeId[0] doesn't match") self.assertEqual(res['result']['applicationTypeId'][1], self.__app_ids[1], "worker_retrieve Response result applicationTypeId[1] doesn't match") - self.assertEqual(res['result']['details'], self.__details, "worker_retrieve Response result details doesn't match") + self.assertEqual(res['result']['details'], json.loads(self.__details), "worker_retrieve Response result details doesn't match") self.assertEqual(res['result']['status'], self.__status.value, "worker_retrieve Response result status doesn't match") @@ -99,7 +112,7 @@ def test_worker_lookup_next(self): req_id = 17 logging.info('Calling worker_lookup_next with\n worker type %d\n org_id %s\n app_ids %s\n lookUpTag %s\n', self.__worker_type.value,self.__org_id, self.__app_ids, "sample tag") - res = self.__worker_registry_wrapper.worker_lookup_next(self.__worker_type, self.__org_id, self.__app_ids, "sample tag", req_id) + res = self.__worker_registry_wrapper.worker_lookup_next("sample tag", self.__worker_type, self.__org_id, self.__app_ids, req_id) logging.info('Result: %s\n', res) self.assertEqual(res['id'], req_id, "worker_lookup_next Response id doesn't match") """ @@ -108,13 +121,10 @@ def test_worker_lookup_next(self): self.assertEqual(res['result']['ids'][0], '0x0000a3', "worker_lookup_next Response worker id doesn't match") """ - - - def main(): logging.info("Running test cases...\n") tcf_home = environ.get("TCF_HOME", "../../") - test = TestWorkerRegistryJRPCImpl(tcf_home + "/common/tcf_connector/" + "tcf_connector.toml") + test = TestWorkerRegistryJRPCImpl(tcf_home + "/examples/common/python/connectors/" + "tcf_connector.toml") test.test_worker_register() test.test_worker_update() test.test_worker_set_status() @@ -124,4 +134,3 @@ def main(): if __name__ == '__main__': main() - diff --git a/common/tcf_connector/work_order_encryption_key_jrpc_impl.py b/examples/common/python/connectors/direct/work_order_encryption_key_jrpc_impl.py similarity index 84% rename from common/tcf_connector/work_order_encryption_key_jrpc_impl.py rename to examples/common/python/connectors/direct/work_order_encryption_key_jrpc_impl.py index 8fa26582a..d5f9f19e1 100644 --- a/common/tcf_connector/work_order_encryption_key_jrpc_impl.py +++ b/examples/common/python/connectors/direct/work_order_encryption_key_jrpc_impl.py @@ -1,17 +1,32 @@ +# Copyright 2019 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 json import logging from eth_utils.hexadecimal import is_hex import base64 from service_client.generic import GenericServiceClient -from tcf_connector.work_order_encryption_key_interface import WorkOrderEncryptionKeyInterface -from tcf.connector.utils import create_jrpc_response -from tcf_connector.tcf_types import JsonRpcErrorCode +from connectors.interfaces.work_order_encryption_key_interface import WorkOrderEncryptionKeyInterface +from connectors.utils import create_jrpc_response +from utility.tcf_types import JsonRpcErrorCode + logging.basicConfig(format="%(asctime)s - %(levelname)s - %(message)s", level=logging.INFO) class WorkOrderEncryptionKeyJrpcImpl(WorkOrderEncryptionKeyInterface): def __init__(self, config): - self.__uri_client = GenericServiceClient(config["json_rpc_uri"]) + self.__uri_client = GenericServiceClient(config["tcf"]["json_rpc_uri"]) def encryption_key_get(self, worker_id, last_used_key_nonce, tag, requester_id, signature_nonce, signature, id=None): @@ -104,4 +119,3 @@ def encryption_key_set(self, worker_id, encryption_key, encryption_key_nonce, ta } response = self.__uri_client._postmsg(json.dumps(json_rpc_request)) return response - diff --git a/common/tcf_connector/work_order_jrpc_impl.py b/examples/common/python/connectors/direct/work_order_jrpc_impl.py similarity index 57% rename from common/tcf_connector/work_order_jrpc_impl.py rename to examples/common/python/connectors/direct/work_order_jrpc_impl.py index cd8219549..ae916a213 100644 --- a/common/tcf_connector/work_order_jrpc_impl.py +++ b/examples/common/python/connectors/direct/work_order_jrpc_impl.py @@ -1,11 +1,25 @@ +# Copyright 2019 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 json import logging from eth_utils.hexadecimal import is_hex import base64 from service_client.generic import GenericServiceClient -from tcf_connector.work_order_interface import WorkOrderInterface -from tcf_connector.utils import create_jrpc_response -from utils.tcf_types import JsonRpcErrorCode +from connectors.interfaces.work_order_interface import WorkOrderInterface +from connectors.utils import create_jrpc_response +from utility.tcf_types import JsonRpcErrorCode logging.basicConfig(format="%(asctime)s - %(levelname)s - %(message)s", level=logging.INFO) @@ -44,18 +58,23 @@ def __init__(self, config): } def __validate_parameters(self, params, in_data, out_data): - """Validate parameter dictionary for existence of fields and mandatory fields """ + """ + Validate parameter dictionary for existence of + fields and mandatory fields + Returns False and string with error message on failure and + True and empty string on success + """ key_list = [] for key in params.keys(): if not key in self.__param_key_map.keys(): logging.error("Invalid parameter %s",key) - return "Invalid parameter {}".format(key) + return False, "Invalid parameter {}".format(key) else: key_list.append(key) for k, v in self.__param_key_map.items(): if v == True and not k in key_list: logging.error("Missing parameter %s", k) - return "Missing parameter {}".format(k) + return False, "Missing parameter {}".format(k) """Validate in_data and out_data dictionary for existence of fields and mandatory fields """ @@ -64,90 +83,114 @@ def __validate_parameters(self, params, in_data, out_data): for key in data.keys(): if not key in self.__data_key_map.keys(): logging.error("Invalid in data parameter %s",key) - return "Invalid in data parameter {}".format(key) + return False, "Invalid in data parameter {}".format(key) else: in_data_keys.append(key) for k, v in self.__data_key_map.items(): if v == True and not k in in_data_keys: logging.error("Missing in data parameter %s", k) - return "Missing in data parameter {}".format(k) + return False, "Missing in data parameter {}".format(k) for data in out_data: out_data_keys = [] for key in data.keys(): if not key in self.__data_key_map.keys(): logging.error("Invalid out data parameter %s",key) - return "Invalid out data parameter {}".format(key) + return False, "Invalid out data parameter {}".format(key) else: out_data_keys.append(key) for k, v in self.__data_key_map.items(): if v == True and not k in out_data_keys: logging.error("Missing out data parameter %s", k) - return "Missing out data parameter {}".format(k) + return False, "Missing out data parameter {}".format(k) - return None + return True, "" - def work_order_submit(self, params, in_data, out_data, id=None): - is_valid = self.__validate_parameters(params, in_data, out_data) - if is_valid is not None: - return create_jrpc_response(id, JsonRpcErrorCode.INVALID_PARAMETER, - is_valid) + def __validate_data_format(self, params, in_data, out_data): + """ + Validate data format of the params, in_data and out_data fields + Returns False and string with error message on failure and + True and empty string on success + """ if not is_hex(params["workOrderId"]): logging.error("Invalid work order id") - return create_jrpc_response(id, JsonRpcErrorCode.INVALID_PARAMETER, - "Invalid work order id") + return False, "Invalid work order id" if not is_hex(params["workloadId"]): logging.error("Invalid work load id") - return create_jrpc_response(id, JsonRpcErrorCode.INVALID_PARAMETER, - "Invalid work load id") + return False, "Invalid work load id" if not is_hex(params["requesterId"]): logging.error("Invalid requester id id") - return create_jrpc_response(id, JsonRpcErrorCode.INVALID_PARAMETER, - "Invalid requester id id") + return False, "Invalid requester id id" if not is_hex(params["workerEncryptionKey"]): logging.error("Invalid worker encryption key") - return create_jrpc_response(id, JsonRpcErrorCode.INVALID_PARAMETER, - "Invalid worker encryption key") + return False, "Invalid worker encryption key" for data in in_data: - if not is_hex(data["dataHash"]): - logging.error("Invalid data hash of in data") - return create_jrpc_response(id, JsonRpcErrorCode.INVALID_PARAMETER, - "Invalid data hash of in data") - if not is_hex(data["encryptedDataEncryptionKey"]): - logging.error("Invalid Encryption key of in data") - return create_jrpc_response(id, JsonRpcErrorCode.INVALID_PARAMETER, - "Invalid Encryption key of in data") - if not is_hex(data["iv"]): + if "dataHash" in in_data: + data_hash = data["dataHash"] + if not is_hex(data_hash) and data_hash != "": + logging.error("Invalid data hash of in data") + return False, "Invalid data hash of in data" + if "encryptedDataEncryptionKey" in in_data: + enc_key = data["encryptedDataEncryptionKey"] + if enc_key != "-" and \ + enc_key != "" and \ + enc_key != "null" and \ + not is_hex(enc_key): + logging.error("Invalid Encryption key of in data") + return False, \ + "Invalid Encryption key of in data" + if data["iv"] != "" and \ + data["iv"] != "0" and not is_hex(data["iv"]): logging.error("Invalid initialization vector of in data") - return create_jrpc_response(id, JsonRpcErrorCode.INVALID_PARAMETER, - "Invalid initialization vector of in data") + return False, \ + "Invalid initialization vector of in data" try: base64.b64decode(data["data"]) except Exception as e: logging.error("Invalid base64 format of in data") - return create_jrpc_response(id, JsonRpcErrorCode.INVALID_PARAMETER, - "Invalid base64 format of in data") + return False, \ + "Invalid base64 format of in data" for data in out_data: - if not is_hex(data["dataHash"]): - logging.error("Invalid data hash of out data") - return create_jrpc_response(id, JsonRpcErrorCode.INVALID_PARAMETER, - "Invalid data hash of out data") - if not is_hex(data["encryptedDataEncryptionKey"]): - logging.error("Invalid Encryption key of out data") - return create_jrpc_response(id, JsonRpcErrorCode.INVALID_PARAMETER, - "Invalid Encryption key of out data") - if not is_hex(data["iv"]): + if "dataHash" in out_data: + data_hash = data["dataHash"] + if not is_hex(data_hash) and data_hash != "": + logging.error("Invalid data hash of out data") + return False, \ + "Invalid data hash of out data" + if "encryptedDataEncryptionKey" in in_data: + enc_key = data["encryptedDataEncryptionKey"] + if enc_key != "-" and \ + enc_key != "" and \ + enc_key != "null" and \ + not is_hex(enc_key): + logging.error("Invalid Encryption key of in data") + return False, \ + "Invalid Encryption key of in data" + if data["iv"] != "" and \ + data["iv"] != "0" and not is_hex(data["iv"]): logging.error("Invalid initialization vector of out data") - return create_jrpc_response(id, JsonRpcErrorCode.INVALID_PARAMETER, - "Invalid initialization vector of out data") + return False, \ + "Invalid initialization vector of out data" try: base64.b64decode(data["data"]) except Exception as e: logging.error("Invalid base64 format of out data") - return create_jrpc_response(id, JsonRpcErrorCode.INVALID_PARAMETER, - "Invalid base64 format of out data") + return False, \ + "Invalid base64 format of out data" + return True, "" + + def work_order_submit(self, params, in_data, out_data, id=None): + valid, err = self.__validate_parameters(params, in_data, out_data) + if not valid: + return create_jrpc_response(id, JsonRpcErrorCode.INVALID_PARAMETER, + err) + valid, err = self.__validate_data_format(params, in_data, out_data) + if not valid: + return create_jrpc_response(id, JsonRpcErrorCode.INVALID_PARAMETER, + err) + json_rpc_request = { "jsonrpc": "2.0", "method": "WorkOrderSubmit", @@ -169,6 +212,7 @@ def work_order_submit(self, params, in_data, out_data, id=None): "requesterNonce": params["requesterNonce"], "encryptedRequestHash": params["encryptedRequestHash"], "requesterSignature": params["requesterSignature"], + "verifyingKey": params["verifyingKey"], "inData": in_data, "outData": out_data } @@ -178,9 +222,9 @@ def work_order_submit(self, params, in_data, out_data, id=None): def work_order_get_result(self, work_order_id, id=None): if not is_hex(work_order_id): - logging.error("Invalid workOrder Id") + logging.error("Invalid work order Id") return create_jrpc_response(id, JsonRpcErrorCode.INVALID_PARAMETER, - "Invalid workOrder Id") + "Invalid work order Id") json_rpc_request = { "jsonrpc": "2.0", @@ -192,4 +236,3 @@ def work_order_get_result(self, work_order_id, id=None): } response = self.__uri_client._postmsg(json.dumps(json_rpc_request)) return response - diff --git a/common/tcf_connector/work_order_receipt_jrpc_impl.py b/examples/common/python/connectors/direct/work_order_receipt_jrpc_impl.py similarity index 61% rename from common/tcf_connector/work_order_receipt_jrpc_impl.py rename to examples/common/python/connectors/direct/work_order_receipt_jrpc_impl.py index 035fd277c..770256adf 100644 --- a/common/tcf_connector/work_order_receipt_jrpc_impl.py +++ b/examples/common/python/connectors/direct/work_order_receipt_jrpc_impl.py @@ -1,15 +1,34 @@ +# Copyright 2019 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 json import logging from eth_utils.hexadecimal import is_hex -from tcc_connector.work_order_receipt_interface import WorkOrderReceiptInterface -from utils.tcf_types import ReceiptCreateStatus -from tcf_connector.utils import create_jrpc_response,validate_details + +from service_client.generic import GenericServiceClient +from connectors.interfaces.work_order_receipt_interface import WorkOrderReceiptInterface +from utility.tcf_types import ReceiptCreateStatus +from connectors.utils import create_jrpc_response,validate_details logging.basicConfig(format="%(asctime)s - %(levelname)s - %(message)s", level=logging.INFO) class WorkOrderReceiptJRPCImpl(WorkOrderReceiptInterface): """ WorkOrderReceiptJRPCImpl is an implementation of WorkOrderReceiptInterface """ + def __init__(self, config): + self.__uri_client = GenericServiceClient(config["tcf"]["json_rpc_uri"]) + def work_order_receipt_create(self, work_order_id, worker_id, worker_service_id, @@ -161,88 +180,106 @@ def work_order_receipt_update_retrieve(self, work_order_id, response = self.__uri_client._postmsg(json.dumps(json_rpc_request)) return response - def work_order_receipt_lookup(self, worker_service_id, - worker_id, - requester_id, - receipt_status, id=None): + def work_order_receipt_lookup(self, worker_service_id=None, + worker_id=None, requester_id=None, receipt_status=None, id=None): """ Work Order Receipt Lookup """ - if worker_id is None or not is_hex(worker_id): - logging.error("Worker id is empty or Invalid") - return create_jrpc_response(id, JsonRpcErrorCode.INVALID_PARAMETER, - "Worker id is empty or Invalid") - - if worker_service_id is None or not is_hex(worker_service_id): - logging.error("Worker service id is empty or Invalid") - return create_jrpc_response(id, JsonRpcErrorCode.INVALID_PARAMETER, - "Worker service id is empty or Invalid") - - if requester_id is None or not is_hex(requester_id): - logging.error("requester id is empty or Invalid") - return create_jrpc_response(id, JsonRpcErrorCode.INVALID_PARAMETER, - "requester id is empty or Invalid") - - if not isinstance(receipt_status, ReceiptCreateStatus): - logging.error("Invalid receipt status") - return create_jrpc_response(id, JsonRpcErrorCode.INVALID_PARAMETER, - "Invalid receipt status") - json_rpc_request = { "jsonrpc": "2.0", - "method": "WorkOrderReceiptLookUp", + "method": "WorkerLookUp", "id": id, "params": { - "workerServiceId": worker_service_id, - "workerId": worker_id, - "requesterId": requester_id, - "updateIndex": receipt_status } } + + if worker_service_id is not None: + if not is_hex(worker_service_id): + logging.error("Worker service id is Invalid") + return create_jrpc_response( + id, JsonRpcErrorCode.INVALID_PARAMETER, + "Worker service id is Invalid") + json_rpc_request["params"]["workerServiceId"] = worker_service_id + + if worker_id is not None: + if not is_hex(worker_id): + logging.error("Worker id is Invalid") + return create_jrpc_response( + id, JsonRpcErrorCode.INVALID_PARAMETER, + "Worker id is Invalid") + json_rpc_request["params"]["workerId"] = worker_id + + if requester_id is not None: + if not is_hex(requester_id): + logging.error("Requester id is Invalid") + return create_jrpc_response( + id, JsonRpcErrorCode.INVALID_PARAMETER, + "Requester id is Invalid") + json_rpc_request["params"]["requesterId"] = requester_id + + if receipt_status is not None: + if not isinstance(receipt_status, ReceiptCreateStatus): + logging.error("Receipt status is Invalid") + return create_jrpc_response( + id, JsonRpcErrorCode.INVALID_PARAMETER, + "Receipt status is Invalid") + json_rpc_request["params"]["receiptStatus"] = receipt_status + response = self.__uri_client._postmsg(json.dumps(json_rpc_request)) return response - def work_order_receipt_lookup_next(self, worker_service_id, - worker_id, - requester_id, - receipt_status, - last_lookup_tag, id=None): + def work_order_receipt_lookup_next(self, last_lookup_tag, + worker_service_id=None, worker_id=None, requester_id=None, + receipt_status=None, id=None): """ Work Order Receipt Lookup Next """ - if worker_id is None or not is_hex(worker_id): - logging.error("Worker id is empty or Invalid") - return create_jrpc_response(id, JsonRpcErrorCode.INVALID_PARAMETER, - "Worker id is empty or Invalid") - - if worker_service_id is None or not is_hex(worker_service_id): - logging.error("Worker service id is empty or Invalid") - return create_jrpc_response(id, JsonRpcErrorCode.INVALID_PARAMETER, - "Worker service id is empty or Invalid") - - if requester_id is None or not is_hex(requester_id): - logging.error("requester id is empty or Invalid") - return create_jrpc_response(id, JsonRpcErrorCode.INVALID_PARAMETER, - "requester id is empty or Invalid") - - if not isinstance(receipt_status, ReceiptCreateStatus): - logging.error("Invalid receipt status") - return create_jrpc_response(id, JsonRpcErrorCode.INVALID_PARAMETER, - "Invalid receipt status") - json_rpc_request = { "jsonrpc": "2.0", "method": "WorkOrderReceiptLookUpNext", "id": id, "params": { - "workerServiceId": worker_service_id, - "workerId": worker_id, - "requesterId": requester_id, - "updateIndex": receipt_status, "lastLookUpTag": last_lookup_tag } } - response = self.__uri_client._postmsg(json.dumps(json_rpc_request)) - return response + if worker_service_id is not None: + if not is_hex(worker_service_id): + logging.error("Worker service id is Invalid") + return create_jrpc_response( + id, JsonRpcErrorCode.INVALID_PARAMETER, + "Worker service id is Invalid") + json_rpc_request["params"]["workerServiceId"] = worker_service_id + + if worker_id is not None: + if not is_hex(worker_id): + logging.error("Worker id is Invalid") + return create_jrpc_response( + id, JsonRpcErrorCode.INVALID_PARAMETER, + "Worker id is Invalid") + json_rpc_request["params"]["workerId"] = worker_id + + if requester_id is not None: + if not is_hex(requester_id): + logging.error("Requester id is Invalid") + return create_jrpc_response( + id, JsonRpcErrorCode.INVALID_PARAMETER, + "Requester id is Invalid") + json_rpc_request["params"]["requesterId"] = requester_id + + if receipt_status is not None: + if not isinstance(receipt_status, ReceiptCreateStatus): + logging.error("Invalid receipt status") + return create_jrpc_response( + id, JsonRpcErrorCode.INVALID_PARAMETER, + "Invalid receipt status") + json_rpc_request["params"]["receiptStatus"] = receipt_status + if last_lookup_tag is None or not is_hex(last_lookup_tag): + logging.error("Last lookup tag is empty or Invalid") + return create_jrpc_response( + id, JsonRpcErrorCode.INVALID_PARAMETER, + "Last lookup tag is empty or Invalid") + + response = self.__uri_client._postmsg(json.dumps(json_rpc_request)) + return response diff --git a/common/tcf_connector/worker_registry_jrpc_impl.py b/examples/common/python/connectors/direct/worker_registry_jrpc_impl.py similarity index 60% rename from common/tcf_connector/worker_registry_jrpc_impl.py rename to examples/common/python/connectors/direct/worker_registry_jrpc_impl.py index 79b3e6b88..ab1ea099c 100644 --- a/common/tcf_connector/worker_registry_jrpc_impl.py +++ b/examples/common/python/connectors/direct/worker_registry_jrpc_impl.py @@ -1,10 +1,24 @@ +# Copyright 2019 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 json import logging from eth_utils.hexadecimal import is_hex from service_client.generic import GenericServiceClient -from tcf_connector.worker_registry_interface import WorkerRegistryInterface -from utils.tcf_types import WorkerType, JsonRpcErrorCode -from tcf_connector.utils import create_jrpc_response,validate_details +from connectors.interfaces.worker_registry_interface import WorkerRegistryInterface +from utility.tcf_types import WorkerType, JsonRpcErrorCode +from connectors.utils import create_jrpc_response,validate_details logging.basicConfig(format="%(asctime)s - %(levelname)s - %(message)s", level=logging.INFO) class WorkerRegistryJRPCImpl(WorkerRegistryInterface): @@ -27,10 +41,11 @@ def worker_register(self, worker_id, worker_type, org_id, application_type_ids, return create_jrpc_response(id, JsonRpcErrorCode.INVALID_PARAMETER, "Invalid organization id") if application_type_ids is not None: - for appId in application_type_ids: - if not is_hex(appId): + for app_id in application_type_ids: + if not is_hex(app_id): logging.error("Invalid application type id") - return create_jrpc_response(id, JsonRpcErrorCode.INVALID_PARAMETER, + return create_jrpc_response( + id, JsonRpcErrorCode.INVALID_PARAMETER, "Invalid application type id") break if details is not None: @@ -48,7 +63,7 @@ def worker_register(self, worker_id, worker_type, org_id, application_type_ids, "workerType": worker_type.value, "organizationId": org_id, "applicationTypeId": application_type_ids, - "details": details + "details": json.loads(details) } } response = self.__uri_client._postmsg(json.dumps(json_rpc_request)) @@ -114,71 +129,85 @@ def worker_retrieve(self, worker_id, id=None): return response - def worker_lookup(self, worker_type, organization_id, application_type_id, + def worker_lookup(self, worker_type=None, organization_id=None, + application_type_id=None, id=None): - """ Worker lookup based on worker type, organization id and application id""" - if not isinstance(worker_type, WorkerType): - logging.error("Worker type is invalid") - return create_jrpc_response(id, JsonRpcErrorCode.INVALID_PARAMETER, - "Worker type is invalid") - if organization_id is None or not is_hex(organization_id): - logging.error("Invalid Organization id") - return create_jrpc_response(id, JsonRpcErrorCode.INVALID_PARAMETER, - "Invalid Organization id") - if application_type_id is not None: - for appId in application_type_id: - if not is_hex(appId): - logging.error("Invalid application type id") - return create_jrpc_response(id, JsonRpcErrorCode.INVALID_PARAMETER, - "Invalid application type id") - break - - + """ Worker lookup based on worker type, organization id + and application id""" json_rpc_request = { "jsonrpc": "2.0", "method": "WorkerLookUp", "id": id, "params": { - "workerType": worker_type.value, - "organizationId": organization_id, - "applicationTypeId": application_type_id } } + + if worker_type is not None: + if not isinstance(worker_type, WorkerType): + logging.error("Invalid worker type") + return create_jrpc_response( + id, JsonRpcErrorCode.INVALID_PARAMETER, + "Invalid worker type") + json_rpc_request["params"]["workerType"] = worker_type.value + + if organization_id is not None: + if not is_hex(organization_id): + logging.error("Invalid organization id") + return create_jrpc_response( + id, JsonRpcErrorCode.INVALID_PARAMETER, + "Invalid organization id") + json_rpc_request["params"]["organizationId"] = organization_id + + if application_type_id is not None: + for app_id in application_type_id: + if not is_hex(app_id): + logging.error("Invalid application type id") + return create_jrpc_response( + id, JsonRpcErrorCode.INVALID_PARAMETER, + "Invalid application type id") + json_rpc_request["params"]["applicationTypeId"] = application_type_id + response = self.__uri_client._postmsg(json.dumps(json_rpc_request)) return response - def worker_lookup_next(self, worker_type, organization_id, - application_type_id, lookup_tag, id=None): + def worker_lookup_next(self, lookup_tag, worker_type=None, + organization_id=None, application_type_id=None, id=None): """ Similar to workerLookUp with additional parameter lookup_tag """ - if not isinstance(worker_type, WorkerType): - logging.error("Worker type is invalid") - return create_jrpc_response(id, JsonRpcErrorCode.INVALID_PARAMETER, - "Worker type is invalid") - if organization_id is None or not is_hex(organization_id): - logging.error("Invalid organization id") - return create_jrpc_response(id, JsonRpcErrorCode.INVALID_PARAMETER, - "Invalid organization id") - if application_type_id is not None: - for appId in application_type_id: - if not is_hex(appId): - logging.error("Invalid application id") - return create_jrpc_response(id, JsonRpcErrorCode.INVALID_PARAMETER, - "Invalid application id") - break - json_rpc_request = { "jsonrpc": "2.0", "method": "WorkerLookUpNext", "id": id, "params": { - "workerType": worker_type.value, - "organizationId": organization_id, - "applicationTypeId": application_type_id, "lookUpTag": lookup_tag } } + + if worker_type is not None: + if not isinstance(worker_type, WorkerType): + logging.error("Invalid worker type2") + return create_jrpc_response( + id, JsonRpcErrorCode.INVALID_PARAMETER, + "Invalid worker type") + json_rpc_request["params"]["workerType"] = worker_type.value + + if organization_id is not None: + if not is_hex(organization_id): + logging.error("Invalid organization id") + return create_jrpc_response( + id, JsonRpcErrorCode.INVALID_PARAMETER, + "Invalid organization id") + json_rpc_request["params"]["organizationId"] = organization_id + + if application_type_id is not None: + for app_id in application_type_id: + if not is_hex(app_id): + logging.error("Invalid application type id") + return create_jrpc_response( + id, JsonRpcErrorCode.INVALID_PARAMETER, + "Invalid application type id") + json_rpc_request["params"]["applicationTypeId"] = application_type_id + response = self.__uri_client._postmsg(json.dumps(json_rpc_request)) return response - diff --git a/tcs/tcs_listener/__init__.py b/examples/common/python/connectors/ethereum/__init__.py similarity index 97% rename from tcs/tcs_listener/__init__.py rename to examples/common/python/connectors/ethereum/__init__.py index 96314f2df..f34c4f48c 100644 --- a/tcs/tcs_listener/__init__.py +++ b/examples/common/python/connectors/ethereum/__init__.py @@ -12,3 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. +__all__ = [] diff --git a/common/tcf_connector/ethereum/contracts/WorkerRegistry.sol b/examples/common/python/connectors/ethereum/contracts/WorkerRegistry.sol similarity index 100% rename from common/tcf_connector/ethereum/contracts/WorkerRegistry.sol rename to examples/common/python/connectors/ethereum/contracts/WorkerRegistry.sol diff --git a/common/tcf_connector/ethereum/contracts/WorkerRegistryList.sol b/examples/common/python/connectors/ethereum/contracts/WorkerRegistryList.sol similarity index 100% rename from common/tcf_connector/ethereum/contracts/WorkerRegistryList.sol rename to examples/common/python/connectors/ethereum/contracts/WorkerRegistryList.sol diff --git a/tcs/tcs_blockchain_connector/direct_registry_bridge.py b/examples/common/python/connectors/ethereum/direct_registry_bridge.py similarity index 98% rename from tcs/tcs_blockchain_connector/direct_registry_bridge.py rename to examples/common/python/connectors/ethereum/direct_registry_bridge.py index 94092f027..2f9711c4a 100644 --- a/tcs/tcs_blockchain_connector/direct_registry_bridge.py +++ b/examples/common/python/connectors/ethereum/direct_registry_bridge.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python3 - # Copyright 2019 Intel Corporation # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -141,7 +139,7 @@ def main(args=None): # TODO: Add mechanism to read the address from config file. eth_direct_registry = registry.EthereumDirectRegistry("0x8c99670a15047248403a3E5A38eb8FBE7a12533e", \ - '../tcf_connector/DirectRegistry.sol') + '../connectors/contracts/WorkerRegistryList.sol') kv_storage = KvStorage() kv_storage.open("kv_storage") diff --git a/common/tcf_connector/ethereum/eth_cli.py b/examples/common/python/connectors/ethereum/eth_cli.py similarity index 79% rename from common/tcf_connector/ethereum/eth_cli.py rename to examples/common/python/connectors/ethereum/eth_cli.py index 96cd40de6..a532fa063 100644 --- a/common/tcf_connector/ethereum/eth_cli.py +++ b/examples/common/python/connectors/ethereum/eth_cli.py @@ -11,7 +11,6 @@ # 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 toml import errno @@ -20,9 +19,7 @@ import os,time from os.path import exists, realpath -from solc import compile_source -from web3 import HTTPProvider, Web3 -from tcf_connector.ethereum.ethereum_wrapper import ethereum_wrapper +from connectors.ethereum.ethereum_wrapper import EthereumWrapper as ethereum_wrapper logging.basicConfig(format='%(asctime)s - %(levelname)s - %(message)s', level=logging.INFO) @@ -44,24 +41,25 @@ def __init__(self, config_file): self.__eth_client = ethereum_wrapper(self.__config) def deploy_contracts(self): - self.deploy_solidity_contract(self.__config['ethereum']['direct_registry_contract_file']) - self.deploy_solidity_contract(self.__config['ethereum']['worker_registry_contract_file']) + tcf_home = os.environ.get("TCF_HOME", "../../") + self.deploy_solidity_contract(tcf_home + "/" + + self.__config['ethereum']['direct_registry_contract_file']) + self.deploy_solidity_contract(tcf_home + "/" + + self.__config['ethereum']['worker_registry_contract_file']) def deploy_solidity_contract(self, contract_file): if not exists(contract_file): raise FileNotFoundError("File not found at path: {0}".format(realpath(contract_file))) compiled_sol = self.__eth_client.compile_source_file(contract_file) contract_id, contract_interface = compiled_sol.popitem() - address = self.__eth_client.deploy_contract(self.__w3, self.__eth_account_address, - self.__eth_private_key, contract_interface, self.__chain_id) + address = self.__eth_client.deploy_contract(contract_interface) logging.info("Deployed %s to: %s\n", contract_id, address) return {"status":"success"} def main(): tcf_home = os.environ.get("TCF_HOME", "../../") - eth = eth_cli(tcf_home + "/common/tcf_connector/" + "tcf_connector.toml") + eth = eth_cli(tcf_home + "/examples/common/python/connectors/" + "tcf_connector.toml") eth.deploy_contracts(); if __name__ == '__main__': main() - diff --git a/common/tcf_connector/ethereum/ethereum_worker_registry_impl.py b/examples/common/python/connectors/ethereum/ethereum_worker_registry_impl.py similarity index 96% rename from common/tcf_connector/ethereum/ethereum_worker_registry_impl.py rename to examples/common/python/connectors/ethereum/ethereum_worker_registry_impl.py index 6235b60cb..429383b63 100644 --- a/common/tcf_connector/ethereum/ethereum_worker_registry_impl.py +++ b/examples/common/python/connectors/ethereum/ethereum_worker_registry_impl.py @@ -20,10 +20,10 @@ from eth_utils.hexadecimal import is_hex -from utils.tcf_types import WorkerStatus, WorkerType -from tcf_connector.ethereum.ethereum_wrapper import EthereumWrapper -from tcf_connector.worker_registry_interface import WorkerRegistryInterface -from tcf_connector.utils import construct_message, validate_details +from utility.tcf_types import WorkerStatus, WorkerType +from connectors.ethereum.ethereum_wrapper import EthereumWrapper +from connectors.interfaces.worker_registry_interface import WorkerRegistryInterface +from connectors.utils import construct_message, validate_details logging.basicConfig(format="%(asctime)s - %(levelname)s - %(message)s", level=logging.INFO) @@ -206,10 +206,9 @@ def __initialize(self, config): """ self.__eth_client = EthereumWrapper(config) tcf_home = environ.get("TCF_HOME", "../../../") - contract_file_name = tcf_home + "/common/tcf_connector/ethereum/contracts/" + \ + contract_file_name = tcf_home + "/" + \ config["ethereum"]["worker_registry_contract_file"] contract_address = config["ethereum"]["worker_registry_contract_address"] self.__contract_instance = self.__eth_client.get_contract_instance( contract_file_name, contract_address ) - diff --git a/common/tcf_connector/ethereum/ethereum_worker_registry_list_impl.py b/examples/common/python/connectors/ethereum/ethereum_worker_registry_list_impl.py similarity index 96% rename from common/tcf_connector/ethereum/ethereum_worker_registry_list_impl.py rename to examples/common/python/connectors/ethereum/ethereum_worker_registry_list_impl.py index b07c3dea2..4b4600bae 100644 --- a/common/tcf_connector/ethereum/ethereum_worker_registry_list_impl.py +++ b/examples/common/python/connectors/ethereum/ethereum_worker_registry_list_impl.py @@ -18,10 +18,9 @@ import binascii from os import environ -from tcf_connector.worker_registry_list_interface import WorkerRegistryListInterface -from tcf_connector.ethereum.ethereum_wrapper import EthereumWrapper -from utils.tcf_types import RegistryStatus - +from connectors.interfaces.worker_registry_list_interface import WorkerRegistryListInterface +from connectors.ethereum.ethereum_wrapper import EthereumWrapper +from utility.tcf_types import RegistryStatus logging.basicConfig(format="%(asctime)s - %(levelname)s - %(message)s", level=logging.INFO) @@ -182,11 +181,9 @@ def __initialize(self, config): """ self.__eth_client = EthereumWrapper(config) tcf_home = environ.get("TCF_HOME", "../../../") - contract_file_name = tcf_home + "/common/tcf_connector/ethereum/contracts/" + \ + contract_file_name = tcf_home + "/" + \ config["ethereum"]["direct_registry_contract_file"] contract_address = config["ethereum"]["direct_registry_contract_address"] self.__contract_instance = self.__eth_client.get_contract_instance( contract_file_name, contract_address ) - - diff --git a/common/tcf_connector/ethereum/ethereum_wrapper.py b/examples/common/python/connectors/ethereum/ethereum_wrapper.py similarity index 87% rename from common/tcf_connector/ethereum/ethereum_wrapper.py rename to examples/common/python/connectors/ethereum/ethereum_wrapper.py index 3ca0c4ac1..8c4ae459f 100644 --- a/common/tcf_connector/ethereum/ethereum_wrapper.py +++ b/examples/common/python/connectors/ethereum/ethereum_wrapper.py @@ -1,3 +1,17 @@ +# Copyright 2019 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 logging import os,sys from os.path import exists, realpath @@ -79,10 +93,10 @@ def deploy_contract(self, contract_interface): 'from': acct.address, 'chainId': self.__channel_id, 'gas': self.__gas_limit, - 'gasPrice': self.__gas_price, + 'gasPrice': self.get_gas_price(), 'nonce': nonce }) - address = execute_transaction(tx_hash)['txn_receipt']['contractAddress'] + address = self.execute_transaction(tx_hash)['txn_receipt']['contractAddress'] return address def execute_transaction(self, tx_dict): @@ -115,4 +129,3 @@ def get_contract_instance(self, contract_file_name, contract_address): def get_txn_nonce(self): return self.__w3.eth.getTransactionCount(self.__eth_account_address) - diff --git a/tcs/tcs_blockchain_connector/test_direct_registry_bridge.py b/examples/common/python/connectors/ethereum/unit_tests/test_direct_registry_bridge.py similarity index 91% rename from tcs/tcs_blockchain_connector/test_direct_registry_bridge.py rename to examples/common/python/connectors/ethereum/unit_tests/test_direct_registry_bridge.py index e96a305ae..ff468a1d2 100644 --- a/tcs/tcs_blockchain_connector/test_direct_registry_bridge.py +++ b/examples/common/python/connectors/ethereum/unit_tests/test_direct_registry_bridge.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python3 - # Copyright 2019 Intel Corporation # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -22,10 +20,11 @@ import logging from shared_kv.shared_kv_interface import KvStorage -import direct_registry_bridge as registry_helper +import connectors.ethereum.direct_registry_bridge as registry_helper -sys.path.insert(0, abspath(join(dirname(__file__), '..')) + '/tcf_connector/') -import EthereumDirectRegistry as dir_registry +sys.path.insert(0, abspath(join(dirname(__file__), '../..')) + '/connectors/') +from connectors.ethereum.ethereum_worker_registry_list_impl \ + import EthereumWorkerRegistryListImpl as dir_registry logger = logging.getLogger(__name__) @@ -96,7 +95,7 @@ def main(): logger.info("Testing Direct registry bridge functionality.") eth_direct_registry = dir_registry.EthereumDirectRegistry("0x8c99670a15047248403a3E5A38eb8FBE7a12533e", - '../tcf_connector/DirectRegistry.sol') + '../contracts/WorkerRegistryList.sol') kv_storage = KvStorage() kv_storage.open("kv_storage") diff --git a/common/tcf_connector/ethereum/TestEthConnectorAdaptor.py b/examples/common/python/connectors/ethereum/unit_tests/test_eth_connector_adaptor.py similarity index 88% rename from common/tcf_connector/ethereum/TestEthConnectorAdaptor.py rename to examples/common/python/connectors/ethereum/unit_tests/test_eth_connector_adaptor.py index 8ad485138..f58fc8c35 100644 --- a/common/tcf_connector/ethereum/TestEthConnectorAdaptor.py +++ b/examples/common/python/connectors/ethereum/unit_tests/test_eth_connector_adaptor.py @@ -11,12 +11,11 @@ # 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. -# from os import urandom import logging -from tcs_core.tcf_connector.BCAdaptorFactory import BCAdaptorFactory +from connectors.blockchain_adaptor_factory import BlockchainAdaptorFactoryImpl as BCAdaptorFactory logging.basicConfig(format='%(asctime)s - %(levelname)s - %(message)s', level=logging.INFO) @@ -24,7 +23,7 @@ class TestEthConnectorAdaptor(): def __init__(self): self.__eth_adaptor = BCAdaptorFactory('tcf_connector.toml') - def testDirectRegistryAdaptor(self): + def test_direct_registry_adaptor(self): orgId = urandom(32) uri = "http://worker1:8008" scAddr = urandom(20) @@ -36,9 +35,7 @@ def testDirectRegistryAdaptor(self): def main(): logging.info("Running test cases...") test = TestEthConnectorAdaptor() - test.testDirectRegistryAdaptor() + test.test_direct_registry_adaptor() - if __name__ == '__main__': main() - diff --git a/common/tcf_connector/ethereum/unit_tests/test_ethereum_worker_registry_impl.py b/examples/common/python/connectors/ethereum/unit_tests/test_ethereum_worker_registry_impl.py similarity index 70% rename from common/tcf_connector/ethereum/unit_tests/test_ethereum_worker_registry_impl.py rename to examples/common/python/connectors/ethereum/unit_tests/test_ethereum_worker_registry_impl.py index 63002aa24..2f606b764 100644 --- a/common/tcf_connector/ethereum/unit_tests/test_ethereum_worker_registry_impl.py +++ b/examples/common/python/connectors/ethereum/unit_tests/test_ethereum_worker_registry_impl.py @@ -19,9 +19,11 @@ import binascii import json import unittest +from web3 import Web3 -from tcf_connector.ethereum.ethereum_worker_registry_impl import EthereumWorkerRegistryImpl -from utils.tcf_types import WorkerType, WorkerStatus +from connectors.ethereum.ethereum_worker_registry_impl import EthereumWorkerRegistryImpl +from utility.tcf_types import WorkerType, WorkerStatus +from utility.hex_utils import hex_to_utf, pretty_ids logging.basicConfig(format="%(asctime)s - %(levelname)s - %(message)s", level=logging.INFO) @@ -48,20 +50,24 @@ def test_worker_register(self): self.__org_id = urandom(32) self.__application_ids = [urandom(32), urandom(32)] logging.info("Calling worker_register contract..\n worker_id: %s\n worker_type: %d\n \ - orgId: %s applicationIds %s details %s", - binascii.hexlify(self.__worker_id), self.__worker_type.value, - binascii.hexlify(self.__org_id),self.__application_ids, self.__details) +orgId: %s\n applicationIds %s\n details %s", + hex_to_utf(self.__worker_id), self.__worker_type.value, + hex_to_utf(self.__org_id), pretty_ids(self.__application_ids), self.__details) result = self.__eth_conn.worker_register(self.__worker_id, self.__worker_type, self.__org_id, self.__application_ids, self.__details) - logging.info("worker_register status %s", result) + logging.info("worker_register status \n{'status': %s', \n'txn_receipt': %s}", + result["status"], + json.dumps(json.loads(Web3.toJSON(result["txn_receipt"])), indent=4)) self.assertEqual(result["status"], "added", "worker register response not matched") def test_worker_set_status(self): self.__status = WorkerStatus.DECOMMISSIONED - logging.info("Calling worker_set_status..\n worker_id: %s\n status: %d", - binascii.hexlify(self.__worker_id), self.__status.value) + logging.info("Calling worker_set_status..\n worker_id: %s\n status: %d", + hex_to_utf(self.__worker_id), self.__status.value) result = self.__eth_conn.worker_set_status(self.__worker_id, self.__status) - logging.info("worker_set_status status %s", result) + logging.info("worker_set_status status \n{'status': %s', \n'txn_receipt': %s}", + result["status"], + json.dumps(json.loads(Web3.toJSON(result["txn_receipt"])), indent=4)) self.assertEqual(result["status"], "added", "worker set status response not matched") def test_worker_update(self): @@ -69,30 +75,33 @@ def test_worker_update(self): "workOrderSyncUri":"http://worker-order:8008".encode("utf-8").hex(), "workOrderNotifyUri":"http://worker-order-notify:9909".encode("utf-8").hex() }) - logging.info("Calling worker_update..\n worker_id: %s\n details: %s", - binascii.hexlify(self.__worker_id), self.__new_details) + logging.info("Calling worker_update..\n worker_id: %s\n details: %s", + hex_to_utf(self.__worker_id), self.__new_details) result = self.__eth_conn.worker_update(self.__worker_id, self.__new_details) - logging.info("worker_update status %s", result) + logging.info("worker_update status \n{'status': %s', \n'txn_receipt': %s}", + result["status"], + json.dumps(json.loads(Web3.toJSON(result["txn_receipt"])), indent=4)) self.assertEqual(result["status"], "added", "worker update response not matched") def test_worker_lookup(self): - logging.info("Calling worker_lookup..\n worker_type: %d\n orgId: %s applicationId: %s", + logging.info("Calling worker_lookup..\n worker_type: %d\n orgId: %s\n applicationId: %s", self.__worker_type.value, - binascii.hexlify(self.__org_id), - binascii.hexlify(self.__application_ids[0])) + hex_to_utf(self.__org_id), + hex_to_utf(self.__application_ids[0])) result = self.__eth_conn.worker_lookup(self.__worker_type, self.__org_id, self.__application_ids[0]) - logging.info("worker_lookup status %s", result) + logging.info("worker_lookup status [%d, %s, %s]", + result[0], result[1], pretty_ids(result[2])) match = self.__worker_id in result[2] self.assertEqual(result[0], 1, "Worker lookup response count doesn't match") self.assertTrue(match, "Worker lookup response worker id doesn't match") - def test_worker_retrieve(self): - logging.info("Calling worker_retrieve..\n worker_id: %s\n", - binascii.hexlify(self.__worker_id)) + logging.info("Calling worker_retrieve..\n worker_id: %s", + hex_to_utf(self.__worker_id)) result = self.__eth_conn.worker_retrieve(self.__worker_id) - logging.info("worker_retrieve status %s", result) + logging.info("worker_retrieve status [%d, %s, %s, %s, %d]", result[0], + hex_to_utf(result[1]), pretty_ids(result[2]), result[3], result[4]) self.assertEqual(result[0], self.__worker_type.value, "Worker retrieve response worker type doesn't match") self.assertEqual(result[1], self.__org_id, @@ -108,20 +117,20 @@ def test_worker_retrieve(self): def test_worker_lookup_next(self): lookUpTag = "" - logging.info("Calling worker_lookup_next..\n worker_type: %d\n \ - orgId: %s applicationId:%s lookUpTag: %s", - self.__worker_type.value, binascii.hexlify(self.__org_id), - binascii.hexlify(self.__application_ids[0]), lookUpTag) + logging.info("Calling worker_lookup_next..\n worker_type: %d\n \ +orgId: %s\n applicationId:%s\n lookUpTag: %s", + self.__worker_type.value, hex_to_utf(self.__org_id), + hex_to_utf(self.__application_ids[0]), lookUpTag) result = self.__eth_conn.worker_lookup_next(self.__worker_type, self.__org_id, self.__application_ids[0], lookUpTag) - logging.info("worker_lookup_next status %s", result) + logging.info("worker_lookup_next status [%d, %s, %s]", + result[0], result[1], pretty_ids(result[2])) self.assertEqual(result[0], 0, "worker_lookup_next response count doesn't match") - def main(): logging.info("Running test cases...") tcf_home = environ.get("TCF_HOME", "../../") - test = TestEthereumWorkerRegistryImpl(tcf_home + "/common/tcf_connector/" + "tcf_connector.toml") + test = TestEthereumWorkerRegistryImpl(tcf_home + "/examples/common/python/connectors/" + "tcf_connector.toml") test.test_worker_register() test.test_worker_update() test.test_worker_set_status() diff --git a/common/tcf_connector/ethereum/unit_tests/test_ethereum_worker_registry_list_impl.py b/examples/common/python/connectors/ethereum/unit_tests/test_ethereum_worker_registry_list_impl.py similarity index 67% rename from common/tcf_connector/ethereum/unit_tests/test_ethereum_worker_registry_list_impl.py rename to examples/common/python/connectors/ethereum/unit_tests/test_ethereum_worker_registry_list_impl.py index b6d8e4630..2f197b3fd 100644 --- a/common/tcf_connector/ethereum/unit_tests/test_ethereum_worker_registry_list_impl.py +++ b/examples/common/python/connectors/ethereum/unit_tests/test_ethereum_worker_registry_list_impl.py @@ -17,12 +17,14 @@ import logging from os import path, urandom, environ import unittest - +import json import toml +from web3 import Web3 -from tcf_connector.ethereum.ethereum_worker_registry_list_impl import \ +from connectors.ethereum.ethereum_worker_registry_list_impl import \ EthereumWorkerRegistryListImpl -from utils.tcf_types import RegistryStatus +from utility.tcf_types import RegistryStatus +from utility.hex_utils import hex_to_utf, pretty_ids logging.basicConfig(format='%(asctime)s - %(levelname)s - %(message)s', level=logging.INFO) @@ -46,50 +48,57 @@ def test_registry_add(self): self.__sc_addr = urandom(32) self.__app_type_ids = [urandom(32), urandom(32)] logging.info('Calling registry_add contract..\n org_id: %s\n uri: %s\n \ - sc_addr: %s application_ids: %s', binascii.hexlify(self.__org_id), - self.__uri,binascii.hexlify(self.__sc_addr),self.__app_type_ids) - result = self.__eth_conn.registry_add(self.__org_id, self.__uri, self.__sc_addr, +sc_addr: %s\n application_ids: %s', hex_to_utf(self.__org_id), + self.__uri, hex_to_utf(self.__sc_addr), pretty_ids(self.__app_type_ids)) + result = self.__eth_conn.registry_add(self.__org_id, self.__uri, self.__sc_addr, self.__app_type_ids) - logging.info('registry_add contract status %s', result) + logging.info("registry_add contract status \n{'status': %s', \n'txn_receipt': %s}", + result["status"], + json.dumps(json.loads(Web3.toJSON(result["txn_receipt"])), indent=4)) self.assertEqual(result['status'], 'added', "Registry add response not matched") def test_registry_update(self): self.__new_app_id = [urandom(32)] self.__new_uri = 'http://worker2:8008' logging.info('Calling registry_update contract..\n org_id: %s\n uri: %s\n \ - sc_addr: %s application_ids: %s',binascii.hexlify(self.__org_id), - self.__new_uri,binascii.hexlify(self.__sc_addr),self.__new_app_id) +sc_addr: %s\n application_ids: %s', hex_to_utf(self.__org_id), + self.__new_uri, hex_to_utf(self.__sc_addr), pretty_ids(self.__new_app_id)) result = self.__eth_conn.registry_update(self.__org_id, self.__new_uri, self.__sc_addr, self.__new_app_id) - logging.info('registry_update contract status %s', result) + logging.info("registry_update contract status \n{'status': %s', \n'txn_receipt': %s}", + result["status"], + json.dumps(json.loads(Web3.toJSON(result["txn_receipt"])), indent=4)) self.assertEqual(result['status'], 'added', "Registry update response not matched") def test_registry_set_status(self): self.__new_status = RegistryStatus.OFF_LINE logging.info('Calling registry_set_status contract..\n org_id: %s\n status: %d', - binascii.hexlify(self.__org_id), self.__new_status.value) + hex_to_utf(self.__org_id), self.__new_status.value) result = self.__eth_conn.registry_set_status(self.__org_id, self.__new_status) - logging.info('registry_set_status contract status %s', result) + logging.info("registry_set_status contract status \n{'status': %s', \n'txn_receipt': %s}", + result["status"], + json.dumps(json.loads(Web3.toJSON(result["txn_receipt"])), indent=4)) self.assertEqual(result['status'], 'added', "Registry set status response not matched") def test_registry_lookup(self): logging.info('Calling registry_lookup..\n application_id: %s', - binascii.hexlify(self.__app_type_ids[0])) + hex_to_utf(self.__app_type_ids[0])) result = self.__eth_conn.registry_lookup(self.__app_type_ids[0]) - logging.info('registry_lookup contract status %s', result) + logging.info('registry_lookup contract status [%d, %s, %s]', + result[0], result[1], pretty_ids(result[2])) self.assertEqual(result[0], 1, "Registry lookup response total count not matched") self.assertEqual(result[2][0], self.__org_id, "Registry lookup response not matched for org id") - def test_registry_retrieve(self): - logging.info('Calling registry_retrieve..\n org_id: %s\n', binascii.hexlify(self.__org_id)) + logging.info('Calling registry_retrieve..\n org_id: %s', hex_to_utf(self.__org_id)) result = self.__eth_conn.registry_retrieve(self.__org_id) - logging.info('registry_retrieve contract status %s', result) + logging.info('registry_retrieve contract status [%s, %s, %s, %d]', + result[0], hex_to_utf(result[1]), pretty_ids(result[2]), result[3]) self.assertEqual(result[0], self.__new_uri, "Registry retrieve response not matched for uri") - self.assertEqual(binascii.hexlify(result[1]).decode("utf8"), - binascii.hexlify(self.__sc_addr).decode("utf8"), + self.assertEqual(hex_to_utf(result[1]), + hex_to_utf(self.__sc_addr), "Registry retrieve response not matched for smart contract address") self.assertEqual(result[2][0], self.__app_type_ids[0], "Registry retrieve response not matched for app id type list index 0") @@ -102,17 +111,16 @@ def test_registry_retrieve(self): def test_registry_lookup_next(self): lookup_tag = "test" - logging.info('Calling registry_lookup_next..\n application_id: %s lookup_tag: %s', - binascii.hexlify(self.__app_type_ids[0]), lookup_tag) + logging.info('Calling registry_lookup_next..\n application_id: %s\n lookup_tag: %s', + hex_to_utf(self.__app_type_ids[0]), lookup_tag) result = self.__eth_conn.registry_lookup_next(self.__app_type_ids[0], lookup_tag) - logging.info('registry_lookup_next contract status %s', result) - - + logging.info('registry_lookup_next contract status [%d, %s, %s]', + result[0], result[1], pretty_ids(result[2])) def main(): logging.info("Running test cases...") tcf_home = environ.get("TCF_HOME", "../../") - test = TestEthereumWorkerRegistryListImpl(tcf_home + "/common/tcf_connector/" + "tcf_connector.toml") + test = TestEthereumWorkerRegistryListImpl(tcf_home + "/examples/common/python/connectors/" + "tcf_connector.toml") test.test_registry_add() test.test_registry_update() test.test_registry_set_status() diff --git a/tcs/tcs_blockchain_connector/__init__.py b/examples/common/python/connectors/interfaces/__init__.py similarity index 86% rename from tcs/tcs_blockchain_connector/__init__.py rename to examples/common/python/connectors/interfaces/__init__.py index 2c9db214a..f34c4f48c 100644 --- a/tcs/tcs_blockchain_connector/__init__.py +++ b/examples/common/python/connectors/interfaces/__init__.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python3 - # Copyright 2019 Intel Corporation # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__all__ = [ "direct_registry_bridge", "test_direct_registry_bridge" ] +__all__ = [] diff --git a/common/tcf_connector/connector_adaptor_factory_interface.py b/examples/common/python/connectors/interfaces/connector_adaptor_factory_interface.py similarity index 99% rename from common/tcf_connector/connector_adaptor_factory_interface.py rename to examples/common/python/connectors/interfaces/connector_adaptor_factory_interface.py index 7e95bff6c..a845d3ec7 100644 --- a/common/tcf_connector/connector_adaptor_factory_interface.py +++ b/examples/common/python/connectors/interfaces/connector_adaptor_factory_interface.py @@ -11,7 +11,6 @@ # 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. -# from abc import ABC,abstractmethod diff --git a/common/tcf_connector/work_order_encryption_key_interface.py b/examples/common/python/connectors/interfaces/work_order_encryption_key_interface.py similarity index 81% rename from common/tcf_connector/work_order_encryption_key_interface.py rename to examples/common/python/connectors/interfaces/work_order_encryption_key_interface.py index 4964310c7..6b3f0a2be 100644 --- a/common/tcf_connector/work_order_encryption_key_interface.py +++ b/examples/common/python/connectors/interfaces/work_order_encryption_key_interface.py @@ -1,3 +1,17 @@ +# Copyright 2019 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. + from abc import ABC,abstractmethod class WorkOrderEncryptionKeyInterface(ABC): @@ -51,4 +65,3 @@ def encryption_key_get(self, worker_id, encryption_key, encryption_key_nonce, """ pass - diff --git a/common/tcf_connector/work_order_interface.py b/examples/common/python/connectors/interfaces/work_order_interface.py similarity index 93% rename from common/tcf_connector/work_order_interface.py rename to examples/common/python/connectors/interfaces/work_order_interface.py index 7dd1951ae..71add2c89 100644 --- a/common/tcf_connector/work_order_interface.py +++ b/examples/common/python/connectors/interfaces/work_order_interface.py @@ -1,3 +1,17 @@ +# Copyright 2019 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. + from abc import ABC,abstractmethod class WorkOrderInterface(ABC): diff --git a/common/tcf_connector/work_order_receipt_interface.py b/examples/common/python/connectors/interfaces/work_order_receipt_interface.py similarity index 93% rename from common/tcf_connector/work_order_receipt_interface.py rename to examples/common/python/connectors/interfaces/work_order_receipt_interface.py index 8685cbb3a..da75d0169 100644 --- a/common/tcf_connector/work_order_receipt_interface.py +++ b/examples/common/python/connectors/interfaces/work_order_receipt_interface.py @@ -1,3 +1,17 @@ +# Copyright 2019 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. + from abc import ABC,abstractmethod class WorkOrderReceiptInterface(ABC): @@ -171,6 +185,3 @@ def work_order_receipt_lookup_next(self, worker_service_id, corresponding call to work_order_receipt_lookup(). """ pass - - - diff --git a/common/tcf_connector/worker_registry_interface.py b/examples/common/python/connectors/interfaces/worker_registry_interface.py similarity index 99% rename from common/tcf_connector/worker_registry_interface.py rename to examples/common/python/connectors/interfaces/worker_registry_interface.py index 8489e6107..cc18a35f0 100644 --- a/common/tcf_connector/worker_registry_interface.py +++ b/examples/common/python/connectors/interfaces/worker_registry_interface.py @@ -14,8 +14,6 @@ from abc import ABC,abstractmethod - - class WorkerRegistryInterface(ABC): """ WorkerRegistryInterface is an abstract base class containing abstract APIs @@ -142,6 +140,3 @@ def worker_lookup_next(self, worker_type, organization_id, application_type_id, 3. ids is an array of the Worker ids that match the input parameters. """ pass - - - diff --git a/common/tcf_connector/worker_registry_list_interface.py b/examples/common/python/connectors/interfaces/worker_registry_list_interface.py similarity index 100% rename from common/tcf_connector/worker_registry_list_interface.py rename to examples/common/python/connectors/interfaces/worker_registry_list_interface.py diff --git a/common/tcf_connector/tcf_connector.toml b/examples/common/python/connectors/tcf_connector.toml similarity index 77% rename from common/tcf_connector/tcf_connector.toml rename to examples/common/python/connectors/tcf_connector.toml index adf1728b0..54e237713 100644 --- a/common/tcf_connector/tcf_connector.toml +++ b/examples/common/python/connectors/tcf_connector.toml @@ -11,7 +11,6 @@ # 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. -# title = "TCF Connector configuration" @@ -29,17 +28,17 @@ type = "Ethereum" [ethereum] #Direct registry contract file -direct_registry_contract_file = "WorkerRegistryList.sol" +direct_registry_contract_file = "examples/common/python/connectors/ethereum/contracts/WorkerRegistryList.sol" #Worker registry contract file -worker_registry_contract_file = "WorkerRegistry.sol" +worker_registry_contract_file = "examples/common/python/connectors/ethereum/contracts/WorkerRegistry.sol" #Deployed contract address of direct registry contract address. #Initial deploy the contract using eth_cli.py to get the this address -direct_registry_contract_address = "0xB033aFeb6205Bcc322aa93a713db65511a447DF3" +direct_registry_contract_address = "0x9Be28B132aeE1b2c5A1C50529a636cEd807842cd" #Deployed contract address of worker registry contract address. -worker_registry_contract_address = "0xf652A128606Af90C5B80961E8e29aeE8f1299038" +worker_registry_contract_address = "0xC5cC1624d450AAcb37B2bc859f7d8632133dB041" #Ethereum account details -eth_account = "0xDcB780ea30C1041abfcCCE4233c275B9F313eAf4" +eth_account = "0xb03874AE05dCe37B162dd234d794d0e22FCdEec5" #Ethereum account private key should be set in environment variable WALLET_PRIVATE_KEY #Http provider for ropsten test network. eth_http_provider = "https://ropsten.infura.io/" @@ -52,5 +51,3 @@ eth_http_provider = "https://ropsten.infura.io/" chain_id = 3 gas_limit = 3000000 gas_price = "50" - - diff --git a/common/tcf_connector/utils.py b/examples/common/python/connectors/utils.py similarity index 99% rename from common/tcf_connector/utils.py rename to examples/common/python/connectors/utils.py index 6df8afdaf..9c2181704 100644 --- a/common/tcf_connector/utils.py +++ b/examples/common/python/connectors/utils.py @@ -18,6 +18,8 @@ import json from eth_utils.hexadecimal import is_hex +from utility.tcf_types import JsonRpcErrorCode + logging.basicConfig(format='%(asctime)s - %(levelname)s - %(message)s', level=logging.INFO) def create_jrpc_response(id, code, message, data=None): diff --git a/tcs/core/common/python/config/__init__.py b/examples/common/python/crypto/__init__.py similarity index 100% rename from tcs/core/common/python/config/__init__.py rename to examples/common/python/crypto/__init__.py diff --git a/tcs/core/common/python/crypto/crypto.i b/examples/common/python/crypto/crypto.i similarity index 100% rename from tcs/core/common/python/crypto/crypto.i rename to examples/common/python/crypto/crypto.i diff --git a/common/error_code/__init__.py b/examples/common/python/error_code/__init__.py similarity index 100% rename from common/error_code/__init__.py rename to examples/common/python/error_code/__init__.py diff --git a/common/error_code/error_status.py b/examples/common/python/error_code/error_status.py similarity index 100% rename from common/error_code/error_status.py rename to examples/common/python/error_code/error_status.py diff --git a/examples/common/python/json_rpc_request/__init__.py b/examples/common/python/json_rpc_request/__init__.py new file mode 100644 index 000000000..f34c4f48c --- /dev/null +++ b/examples/common/python/json_rpc_request/__init__.py @@ -0,0 +1,15 @@ +# Copyright 2019 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. + +__all__ = [] diff --git a/examples/common/python/json_rpc_request/json_rpc_request.py b/examples/common/python/json_rpc_request/json_rpc_request.py new file mode 100644 index 000000000..f92b0d6d6 --- /dev/null +++ b/examples/common/python/json_rpc_request/json_rpc_request.py @@ -0,0 +1,222 @@ +# Copyright 2019 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 json +import random +import sys +from utility.tcf_types import WorkerType + +class JsonRpcRequest: + def __init__(self, id, method): + self.json_obj = json.loads( + '{"jsonrpc":"2.0","method":"","id":"","params":{ } }') + self.set_id(id) + self.set_method(method) + + def set_method(self, method): + self.json_obj["method"] = method + + def get_id(self): + return self.json_obj["id"] + + def set_id(self, id): + self.json_obj["id"] = id + + def get_json_str(self): + return json.dumps(self.json_obj) + + def get_json_str_indent(self): + return json.dumps(self.json_obj, indent=4) + + def load_from_str(self, json_str): + self.json_obj = json.loads(json_str) + +class WorkerLookupJson(JsonRpcRequest): + def __init__(self, id, worker_type=None, organization_id=None, + application_type_id=None): + super().__init__(id, "WorkerLookUp") + if worker_type: + self.set_worker_type(worker_type) + if organization_id: + self.set_organization_id(organization_id) + if application_type_id: + self.set_application_type_id(application_type_id) + + def set_worker_type(self, worker_type): + self.json_obj["params"]["workerType"] = worker_type + + def get_worker_type(self): + if "workerType" in self.json_obj["params"]: + return WorkerType(self.json_obj["params"]["workerType"]) + else: + return None + + def set_organization_id(self, organization_id): + self.json_obj["params"]["organizationId"] = organization_id + + def get_organization_id(self): + if "organizationId" in self.json_obj["params"]: + return self.json_obj["params"]["organizationId"] + else: + return None + + def set_application_type_id(self, application_type_id): + self.json_obj["params"]["applicationTypeId"] = application_type_id + + def get_application_type_id(self): + if "applicationTypeId" in self.json_obj["params"]: + return self.json_obj["params"]["applicationTypeId"] + else: + return None + +class WorkerRetrieveJson(JsonRpcRequest): + def __init__(self, id, worker_id): + super().__init__(id, "WorkerRetrieve") + self.set_worker_id(worker_id) + + def get_worker_id(self): + return self.json_obj["params"]["workerId"] + + def set_worker_id(self, worker_id): + self.json_obj["params"]["workerId"] = worker_id + +class WorkOrderJson(JsonRpcRequest): + def __init__(self, id, method, work_order_id): + super().__init__(id, method) + self.set_work_order_id(work_order_id) + + def set_work_order_id(self, work_order_id): + self.json_obj["params"]["workOrderId"] = work_order_id + + def get_work_order_id(self): + return self.json_obj["params"]["workOrderId"] + +class WorkOrderSubmitJson(WorkOrderJson): + def __init__(self, id, response_timeout_msecs, payload_format, + worker_id, workload_id, requester_id, + result_uri=None, notify_uri=None, worker_encryption_key=None, + data_encryption_algorithm=None): + super().__init__(id, "WorkOrderSubmit", + hex(random.randint(1, 2**64 - 1))) + self.set_response_timeout_msecs(response_timeout_msecs) + self.set_payload_format(payload_format) + if result_uri: + self.set_result_uri(result_uri) + else: + self.set_result_uri("") + if notify_uri: + self.set_notify_uri(notify_uri) + else: + self.set_notify_uri("") + self.set_worker_id(worker_id) + self.set_workload_id(workload_id) + self.set_requester_id(requester_id) + if worker_encryption_key: + self.set_worker_encryption_key(worker_encryption_key) + else: + self.set_worker_encryption_key("") + if data_encryption_algorithm: + self.set_data_encryption_algorithm(data_encryption_algorithm) + else: + self.set_data_encryption_algorithm("") + self.json_obj["params"]["encryptedSessionKey"] = "" + self.json_obj["params"]["sessionKeyIv"] = "" + self.json_obj["params"]["requesterNonce"] = "" + self.json_obj["params"]["encryptedRequestHash"] = "" + self.json_obj["params"]["requesterSignature"] = "" + self.json_obj["params"]["inData"] = [] + self.json_obj["params"]["outData"] = [] + self.json_obj["params"]["verifyingKey"] = "" + + def set_response_timeout_msecs(self, response_timeout_msecs): + self.json_obj["params"]["responseTimeoutMSecs"] = \ + response_timeout_msecs + + def set_payload_format(self, payload_format): + self.json_obj["params"]["payloadFormat"] = payload_format + + def set_result_uri(self, result_uri): + self.json_obj["params"]["resultUri"] = result_uri + + def set_notify_uri(self, notify_uri): + self.json_obj["params"]["notifyUri"] = notify_uri + + def set_worker_id(self, worker_id): + self.json_obj["params"]["workerId"] = worker_id + + def set_workload_id(self, workload_id): + self.json_obj["params"]["workloadId"] = workload_id + + def set_requester_id(self, requester_id): + self.json_obj["params"]["requesterId"] = requester_id + + def set_worker_encryption_key(self, worker_encryption_key): + self.json_obj["params"]["workerEncryptionKey"] = worker_encryption_key + + def set_data_encryption_algorithm(self, data_encryption_algorithm): + self.json_obj["params"]["dataEncryptionAlgorithm"] = \ + data_encryption_algorithm + + def add_in_data(self, data, data_hash=None, encrypted_data_encryption_key=None): + in_data_copy = self.json_obj["params"]["inData"] + index = len(in_data_copy) + in_data_copy.append({}) + in_data_copy[index]["index"] = index + in_data_copy[index]["data"] = data + if data_hash: + in_data_copy[index]["dataHash"] = data_hash + if encrypted_data_encryption_key: + in_data_copy[index]["encryptedDataEncryptionKey"] = \ + encrypted_data_encryption_key + else: + in_data_copy[index]["encryptedDataEncryptionKey"] = "" + in_data_copy[index]["iv"] = "" + self.json_obj["params"]["inData"] = in_data_copy + + def add_out_data(self, data_hash=None, encrypted_data_encryption_key=None): + out_data_copy = self.json_obj["params"]["outData"] + index = len(out_data_copy) + out_data_copy.append({}) + out_data_copy[index]["index"] = index + out_data_copy[index]["data"] = "" + if data_hash: + out_data_copy[index]["dataHash"] = data_hash + if encrypted_data_encryption_key: + out_data_copy[index]["encryptedDataEncryptionKey"] = \ + encrypted_data_encryption_key + else: + out_data_copy[index]["encryptedDataEncryptionKey"] = "" + out_data_copy[index]["iv"] = "" + self.json_obj["params"]["outData"] = out_data_copy + + # Use these if you want to pass json to WorkOrderJRPCImpl + def get_params(self): + params_copy = self.json_obj["params"].copy() + params_copy.pop("inData") + params_copy.pop("outData") + return params_copy + + def get_in_data(self): + return self.json_obj["params"]["inData"] + + def get_out_data(self): + return self.json_obj["params"]["outData"] + +class WorkOrderGetResultJson(WorkOrderJson): + def __init__(self, id, work_order_id): + super().__init__(id, "WorkOrderGetResult", work_order_id) + +class WorkOrderReceiptRetrieveJson(WorkOrderJson): + def __init__(self, id, work_order_id): + super().__init__(id, "WorkOrderReceiptRetrieve", work_order_id) diff --git a/common/service_client/__init__.py b/examples/common/python/service_client/__init__.py similarity index 100% rename from common/service_client/__init__.py rename to examples/common/python/service_client/__init__.py diff --git a/examples/common/python/service_client/generic.py b/examples/common/python/service_client/generic.py new file mode 100644 index 000000000..4a40379e2 --- /dev/null +++ b/examples/common/python/service_client/generic.py @@ -0,0 +1,140 @@ +# Copyright 2019 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 json +import urllib.request +import urllib.error + +import logging +logger = logging.getLogger(__name__) + +class MessageException(Exception) : + """ + A class to capture communication exceptions when communicating with + services + """ + pass + +class GenericServiceClient(object) : + + def __init__(self, url) : + self.ServiceURL = url + self.ProxyHandler = urllib.request.ProxyHandler({}) + + def _postmsg(self, request) : + """ + Post a request JSON listener and return the response. + """ + + data = json.dumps(request).encode('utf8') + datalen = len(data) + + url = self.ServiceURL + + logger.debug('post request to %s with DATALEN=%d, DATA=<%s>', + url, datalen, data) + + try : + request = urllib.request.Request(url, data, + {'Content-Type': 'application/json', 'Content-Length': datalen}) + opener = urllib.request.build_opener(self.ProxyHandler) + response = opener.open(request, timeout=10) + + except urllib.error.HTTPError as err : + logger.warn('operation failed with response: %s', err.code) + raise MessageException( + 'operation failed with response: {0}'.format(err.code)) + + except urllib.error.URLError as err : + logger.warn('operation failed: %s', err.reason) + raise MessageException('operation failed: {0}'.format(err.reason)) + + except : + logger.exception('no response from server') + raise MessageException('no response from server') + + content = response.read() + headers = response.info() + response.close() + + encoding = headers.get('Content-Type') + if encoding != 'application/json' : + logger.info('server responds with message %s of type %s', + content, encoding) + return None + + # Attempt to decode the content if it is not already a string + try: + content = content.decode('utf-8') + except AttributeError: + pass + value = json.loads(content) + return value + +""" +Class similar to GenericServiceClient that handles UTF8 text instead +of JSONs +""" +class TextServiceClient(object): + + def __init__(self, url) : + self.ServiceURL = url + self.ProxyHandler = urllib.request.ProxyHandler({}) + + def _postmsg(self, request) : + """ + Post a request UTF8 text listener and return the response. + """ + + data = request.encode('utf-8') + datalen = len(data) + + url = self.ServiceURL + + logger.debug('post request to %s with DATALEN=%d, DATA=<%s>', + url, datalen, data) + + try : + request = urllib.request.Request(url, data, + {'Content-Type': 'text/plain; charset=utf-8', + 'Content-Length': datalen}) + opener = urllib.request.build_opener(self.ProxyHandler) + response = opener.open(request, timeout=10) + + except urllib.error.HTTPError as err : + logger.warn('operation failed with response: %s', err.code) + raise MessageException( + 'operation failed with response: {0}'.format(err.code)) + + except urllib.error.URLError as err : + logger.warn('operation failed: %s', err.reason) + raise MessageException('operation failed: {0}'.format(err.reason)) + + except : + logger.exception('no response from server') + raise MessageException('no response from server') + + content = response.read() + headers = response.info() + response.close() + + encoding = headers.get('Content-Type') + if encoding != 'text/plain; charset=utf-8' : + logger.info('server responds with message %s of type %s', + content, encoding) + return None + + return content diff --git a/examples/common/python/setup.py b/examples/common/python/setup.py new file mode 100644 index 000000000..2f374606c --- /dev/null +++ b/examples/common/python/setup.py @@ -0,0 +1,103 @@ +# Copyright 2019 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 re + +# 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, Extension + +tcf_root_dir = os.environ.get('TCF_HOME', '../../..') + +version = subprocess.check_output( + os.path.join(tcf_root_dir, 'bin/get_version')).decode('ascii').strip() + +openssl_cflags = subprocess.check_output(['pkg-config', 'openssl', '--cflags']).decode('ascii').strip().split() +openssl_include_dirs = list( + filter(None, re.split('\s*-I', subprocess.check_output(['pkg-config', 'openssl', '--cflags-only-I']).decode('ascii').strip()))) +openssl_libs = list( + filter(None, re.split('\s*-l', subprocess.check_output(['pkg-config', 'openssl', '--libs-only-l']).decode('ascii').strip()))) +openssl_lib_dirs = list( + filter(None, re.split('\s*-L', subprocess.check_output(['pkg-config', 'openssl', '--libs-only-L']).decode('ascii').strip()))) + +debug_flag = os.environ.get('TCF_DEBUG_BUILD',0) + +compile_args = [ + '-std=c++11', + '-Wno-switch', + '-Wno-unused-function', + '-Wno-unused-variable', +] + +# by default the extension class adds '-O2' to the compile +# flags, this lets us override since these are appended to +# the compilation switches +if debug_flag : + compile_args += ['-g'] + +include_dirs = [ + os.path.join(tcf_root_dir, 'tc/sgx/common/crypto'), + os.path.join(tcf_root_dir, 'tc/sgx/common'), + os.path.join(os.environ['SGX_SDK'],"include"), +] + openssl_include_dirs + +library_dirs = [ + os.path.join(tcf_root_dir, "tc/sgx/common/build"), + os.path.join(os.environ['SGX_SDK'], 'lib64'), + os.path.join(os.environ['SGX_SSL'], 'lib64'), + os.path.join(os.environ['SGX_SSL'], 'lib64', 'release') +] + openssl_lib_dirs + +libraries = [ + 'utcf-common' +] + openssl_libs + + +libraries.append('sgx_usgxssl') +libraries = libraries + openssl_libs + +crypto_modulefiles = [ + "crypto/crypto.i" +] + +crypto_module = Extension( + 'crypto._crypto', + crypto_modulefiles, + swig_opts=['-c++'] + openssl_cflags + ['-I%s' % i for i in include_dirs], + extra_compile_args=compile_args, + include_dirs=include_dirs, + library_dirs=library_dirs, + libraries=libraries) + +## ----------------------------------------------------------------- +setup( + name = 'tcf_examples_common', + version = version, + description = 'Common library', + author = 'Intel', + url = 'http://www.intel.com', + packages = find_packages(), + install_requires = [], + ext_modules=[crypto_module], + data_files=[], + entry_points = {}) + diff --git a/tcs/core/common/python/shared_kv/__init__.py b/examples/common/python/shared_kv/__init__.py similarity index 100% rename from tcs/core/common/python/shared_kv/__init__.py rename to examples/common/python/shared_kv/__init__.py diff --git a/examples/common/python/shared_kv/remote_lmdb/lmdb_helper_proxy.py b/examples/common/python/shared_kv/remote_lmdb/lmdb_helper_proxy.py new file mode 100644 index 000000000..d981dbb6d --- /dev/null +++ b/examples/common/python/shared_kv/remote_lmdb/lmdb_helper_proxy.py @@ -0,0 +1,159 @@ +# Copyright 2019 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. + +from service_client.generic import TextServiceClient +from string_escape import escape, unescape +import logging + +logger = logging.getLogger(__name__) +#------------------------------------------------------------------------------ +class LMDBHelperProxy: + """ + LMDBHelperProxy passes commands serialized as strings + to the LMDB remote listener. + """ + + def __init__(self, uri): + self.set_remote_uri(uri) + + def set_remote_uri(self, uri): + self.__uri_client = TextServiceClient(uri) + +#------------------------------------------------------------------------------ + # Requests are serialized as: \n\n... + + def set(self, table, key, value): + """ + Function to set a key-value pair in a lmdb table + Parameters: + - table is the name of lmdb table in which + the key-value pair needs to be inserted. + - key is the primary key of the table. + - value is the value that needs to be inserted in the table. + """ + # Set, table, key, value + request = "S\n" + escape(table) + "\n" + escape(key) + \ + "\n" + escape(value) + response = self.__uri_client._postmsg(request).decode("utf-8") + args = response.split("\n") + # Set successful (returned True) + if args[0] == "t" and len(args) == 1: + return True + # Set unsuccessful (returned False) + elif args[0] == "f" and len(args) == 1: + return False + # Error + elif args[0] == "e": + if len(args) != 2: + logger.error("Unknown error format") + else: + logger.error("Request error: %s", args[1]) + else: + logger.error("Unknown response format") + +#------------------------------------------------------------------------------ + def get(self, table, key): + """ + Function to get the value for a key in a lmdb table + Parameters: + - table is the name of lmdb table from which + the key-value pair needs to be retrieved. + - key is the primary key of the table. + """ + # Get, table, key + request = "G\n" + escape(table) + "\n" + escape(key) + response = self.__uri_client._postmsg(request).decode("utf-8") + args = response.split("\n") + # Value found + if args[0] == "v" and len(args) == 2: + return unescape(args[1]) + # Value not found + elif args[0] == "n" and len(args) == 1: + return None + # Error + elif args[0] == "e": + if len(args) != 2: + logger.error("Unknown error format") + else: + logger.error("Request error: %s", args[1]) + else: + logger.error("Unknown response format") + +#------------------------------------------------------------------------------ + def remove(self, table, key, value=None): + """ + Function to remove the value for a key in a lmdb table + Parameters: + - table is the name of lmdb table in which + the key-value pair need to be removed. + - key is the primary key of the table. + - value is data to be removed, If the database does not support + sorted duplicate data items (MDB_DUPSORT) the data parameter + is ignored. If the database supports sorted duplicates and + the data parameter is NULL, all of the duplicate data items + for the key will be deleted. Otherwise, if the data parameter is + non-NULL only the matching data item will be deleted. + """ + # Remove, table, key + request = "R\n" + escape(table) + "\n" + escape(key) + if value is not None: + request = "\n" + request + value.replace("\n", "\\n") + response = self.__uri_client._postmsg(request).decode("utf-8") + args = response.split("\n") + # Remove successful (returned True) + if args[0] == "t" and len(args) == 1: + return True + # Remove unsuccessful (returned False) + elif args[0] == "f" and len(args) == 1: + return False + # Error + elif args[0] == "e": + if len(args) != 2: + logger.error("Unknown error format") + else: + logger.error("Request error: %s", args[1]) + else: + logger.error("Unknown response format") + +#------------------------------------------------------------------------------ + def lookup(self, table): + """ + Function to get all the keys in a lmdb table + Parameters: + - table is the name of the lmdb table. + """ + result = [] + # Lookup, table + request = "L\n" + escape(table) + response = self.__uri_client._postmsg(request).decode("utf-8") + args = response.split("\n") + # Lookup result found + if args[0] == "l": + if len(args) == 2: + # Result is a list of keys separated by commas + result = unescape(args[1]).split(",") + else: + logger.error("Unknown response format") + # Lookup result not found + elif args[0] == "n" and len(args) == 1: + return result + # Error + elif args[0] == "e": + if len(args) != 2: + logger.error("Unknown error format") + else: + logger.error("Request error: %s", args[1]) + else: + logger.error("Unknown response format") + return result diff --git a/examples/common/python/shared_kv/remote_lmdb/lmdb_listener.py b/examples/common/python/shared_kv/remote_lmdb/lmdb_listener.py new file mode 100644 index 000000000..33c11c411 --- /dev/null +++ b/examples/common/python/shared_kv/remote_lmdb/lmdb_listener.py @@ -0,0 +1,118 @@ +# Copyright 2019 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 argparse +import json +from twisted.web import server +from twisted.internet import reactor + +from lmdb_request_handler import LMDBRequestHandler + +import logging +logger = logging.getLogger(__name__) + +TCFHOME = os.environ.get("TCF_HOME", "../../../../") + +# ----------------------------------------------------------------- +def local_main(config): + + root = LMDBRequestHandler(config) + site = server.Site(root) + reactor.listenTCP(int(bind_port), site) + + logger.info('LMDB Listener started on port %s', bind_port) + + try : + reactor.run() + except ReactorNotRunning: + logger.warn('shutdown') + except : + logger.warn('shutdown') + + exit(0) + +# ----------------------------------------------------------------- +def parse_command_line(config, args) : + + global bind_port + + parser = argparse.ArgumentParser() + + parser.add_argument('--logfile', + help='Name of the log file, __screen__ for standard output', + type=str) + parser.add_argument('--loglevel', + help='Logging level', + type=str) + parser.add_argument('bind_port', + help='Port to listen for requests', + type=str) + + options = parser.parse_args(args) + + if config.get('Logging') is None : + config['Logging'] = { + 'LogFile' : '__screen__', + 'LogLevel' : 'INFO' + } + if options.logfile : + config['Logging']['LogFile'] = options.logfile + if options.loglevel : + config['Logging']['LogLevel'] = options.loglevel.upper() + if options.bind_port : + bind_port = options.bind_port + +# ----------------------------------------------------------------- +def main(args=None) : + import config.config as pconfig + import utility.logger as plogger + + # Parse out the configuration file first + conffiles = [ 'tcs_config.toml' ] + confpaths = [ ".", TCFHOME + "/config"] + + parser = argparse.ArgumentParser() + parser.add_argument('--config', + help='configuration file', + nargs = '+') + parser.add_argument('--config-dir', + help='configuration folder', + nargs = '+') + (options, remainder) = parser.parse_known_args(args) + + if options.config : + conffiles = options.config + + if options.config_dir : + confpaths = options.config_dir + + try : + config = pconfig.parse_configuration_files(conffiles, confpaths) + config_json_str = json.dumps(config, indent=4) + except pconfig.ConfigurationException as e : + logger.error(str(e)) + sys.exit(-1) + + plogger.setup_loggers(config.get('Logging', {})) + sys.stdout = plogger.stream_to_logger( + logging.getLogger('STDOUT'), logging.DEBUG) + sys.stderr = plogger.stream_to_logger( + logging.getLogger('STDERR'), logging.WARN) + + parse_command_line(config, remainder) + local_main(config) + +main() diff --git a/examples/common/python/shared_kv/remote_lmdb/lmdb_request_handler.py b/examples/common/python/shared_kv/remote_lmdb/lmdb_request_handler.py new file mode 100644 index 000000000..af32c52fe --- /dev/null +++ b/examples/common/python/shared_kv/remote_lmdb/lmdb_request_handler.py @@ -0,0 +1,183 @@ +# Copyright 2019 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 urllib.request +import urllib.error +from twisted.web import resource, http +from twisted.web.error import Error +import tcf_enclave_manager.tcf_enclave as db_store +from error_code.error_status import WorkorderError +from string_escape import escape, unescape +from shared_kv.shared_kv_interface import KvStorage + +import logging +logger = logging.getLogger(__name__) + +TCFHOME = os.environ.get("TCF_HOME", "../../../../") +lookup_flag = False + +class LMDBRequestHandler(resource.Resource): + """ + LMDBRequestHandler is comprised of HTTP interface which + listens for calls to LMDB + """ + # The isLeaf instance variable describes whether or not + # a resource will have children and only leaf resources get rendered. + # LMDBRequestHandler is the most derived class hence isLeaf is required. + + isLeaf = True + + ## ----------------------------------------------------------------- + def __init__(self, config): + + if config.get('KvStorage') is None: + logger.error("Kv Storage path is missing") + sys.exit(-1) + + self.kv_helper = KvStorage() + + storage_path = TCFHOME + '/' + config['KvStorage']['StoragePath'] + if not self.kv_helper.open(storage_path): + logger.error("Failed to open KV Storage DB") + sys.exit(-1) + + def __del__(self): + self.kv_helper.close() + + def _process_request(self, request): + response = "" + logger.info(request.encode('utf-8')) + args = request.split('\n') + for i in range(len(args)): + args[i] = unescape(args[i]) + logger.info(args) + cmd = args[0] + + # Lookup + if (cmd=="L"): + if len(args) == 2: + result_list = self.kv_helper.lookup(args[1]) + result = "" + for key in result_list: + if result == "": + result = key + else: + result = result + "," + key + # Lookup result found + if result != "": + response = "l\n" + escape(result) + # No result found + else: + response = "n" + # Error + else: + logger.error("Invalid args for cmd Lookup") + response = "e\nInvalid args for cmd Lookup" + + # Get + elif (cmd=="G"): + if len(args) == 3: + result = self.kv_helper.get(args[1], args[2]) + # Value found + if result is not None: + response = "v\n" + escape(result) + # Value not found + else: + response = "n" + # Error + else: + logger.error("Invalid args for cmd Get") + response = "e\nInvalid args for cmd Get" + + # Set + elif (cmd=="S"): + if len(args) == 4: + result = self.kv_helper.set(args[1], args[2], args[3]) + # Set successful (returned True) + if result: + response = "t" + # Set unsuccessful (returned False) + else: + response = "f" + # Error + else: + logger.error("Invalid args for cmd Set") + response = "e\nInvalid args for cmd Set" + + # Remove + elif (cmd=="R"): + if len(args) == 3 or len(args) == 4: + if len(args) == 3: + result = self.kv_helper.remove(args[1], args[2]) + else: + result = self.kv_helper.remove(args[1], args[2], value=args[3]) + # Remove successful (returned True) + if result: + response = "t" + # Remove unsuccessful (returned False) + else: + response = "f" + # Error + else: + logger.error("Invalid args for cmd Remove") + response = "e\nInvalid args for cmd Remove" + # Error + else: + logger.error("Unknown cmd") + response = "e\nUnknown cmd" + return response + + def render_GET(self, request): + response = 'Only POST request is supported' + logger.error("GET request is not supported." + \ + " Only POST request is supported") + + return response + + def render_POST(self, request): + response = "" + + logger.info('Received a new request from the client') + + try : + # Process the message encoding + encoding = request.getHeader('Content-Type') + data = request.content.read().decode('utf-8') + + if encoding == 'text/plain; charset=utf-8' : + response = self._process_request(data) + else : + response = 'UNKNOWN_ERROR: unknown message encoding' + return response + + except : + logger.exception('exception while decoding http request %s', + request.path) + response = 'UNKNOWN_ERROR: unable to decode incoming request ' + return response + + # Send back the results + try : + logger.info('response[%s]: %s', encoding, response.encode('utf-8')) + request.setHeader('content-type', encoding) + request.setResponseCode(http.OK) + return response.encode('utf-8') + + except : + logger.exception('unknown exception while processing request %s', + request.path) + response = 'UNKNOWN_ERROR: unknown exception processing ' + \ + 'http request {0}'.format(request.path) + return response diff --git a/examples/common/python/shared_kv/remote_lmdb/string_escape.py b/examples/common/python/shared_kv/remote_lmdb/string_escape.py new file mode 100644 index 000000000..1c5cf40cf --- /dev/null +++ b/examples/common/python/shared_kv/remote_lmdb/string_escape.py @@ -0,0 +1,21 @@ +# Copyright 2019 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 unicode string with special characters escaped +def escape(string): + return string.encode("unicode_escape").decode("utf-8") + +# Return unicode string with escaped characters unescaped +def unescape(string): + return string.encode("utf-8").decode("unicode_escape") diff --git a/examples/common/python/shared_kv/remote_lmdb/test_lmdb_app.py b/examples/common/python/shared_kv/remote_lmdb/test_lmdb_app.py new file mode 100644 index 000000000..83ea77e87 --- /dev/null +++ b/examples/common/python/shared_kv/remote_lmdb/test_lmdb_app.py @@ -0,0 +1,180 @@ +# Copyright 2019 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 argparse +import json +import unittest +import time + +from lmdb_helper_proxy import LMDBHelperProxy + +import logging +logger = logging.getLogger(__name__) + +TCFHOME = os.environ.get("TCF_HOME", "../../../../") +# ----------------------------------------------------------------- +class TestRemoteLMDB(unittest.TestCase): + def __init__(self): + super(TestRemoteLMDB, self).__init__() + self.proxy = LMDBHelperProxy(bind_uri) + self.table = "\\ndtable" + self.key = "\ndk\\y" + self.value = "d\\\nvalue\n" + self.key2 = "dke\\\\y2" + self.value2 = "dvalue2" + + def test_set(self): + set_result = self.proxy.set(self.table, self.key, self.value) + logger.info(set_result) + self.assertTrue(set_result, "set Failed") + + def test_set2(self): + set_result2 = self.proxy.set(self.table, self.key2, self.value2) + logger.info(set_result2) + self.assertTrue(set_result2, "set Failed") + + def test_lookup(self): + lookup_result = self.proxy.lookup(self.table) + logger.info(lookup_result) + self.assertEqual(lookup_result, [self.key, self.key2], + "lookup Returned wrong keys") + + def test_get_value(self): + get_value_result = self.proxy.get(self.table, self.key) + logger.info(get_value_result) + self.assertEqual(get_value_result, self.value, + "get_value Retrieved incorrect value") + + def test_get_value2(self): + get_value_result2 = self.proxy.get(self.table, self.key2) + logger.info(get_value_result2) + self.assertEqual(get_value_result2, self.value2, + "get_value Retrieved incorrect value") + + def test_remove(self): + remove_result = self.proxy.remove(self.table, self.key) + logger.info(remove_result) + self.assertTrue(remove_result, "remove Failed") + + def test_get_none(self): + get_none_result = self.proxy.get(self.table, self.key) + logger.info(get_none_result) + self.assertIsNone(get_none_result, + "get_none Did not return None for empty value") + + def test_remove2(self): + remove_result2 = self.proxy.remove(self.table, self.key2) + logger.info(remove_result2) + self.assertTrue(remove_result2, "remove Failed") + + def test_lookup_none(self): + lookup_none_result = self.proxy.lookup(self.table) + logger.info(lookup_none_result) + self.assertEqual(lookup_none_result, [], + "lookup_none Did not return empty array") + +# ----------------------------------------------------------------- +def local_main(): + result = unittest.TestResult() + result.startTestRun() + test = TestRemoteLMDB() + test.test_set() + test.test_set2() + test.test_lookup() + test.test_get_value() + test.test_get_value2() + test.test_remove() + test.test_get_none() + test.test_remove2() + test.test_lookup_none() + result.stopTestRun() + if result.wasSuccessful(): + logger.info("All tests passed!") + else: + logger.info("Some tests failed.") + exit(0) + +# ----------------------------------------------------------------- +def parse_command_line(config, args) : + + global bind_uri + + parser = argparse.ArgumentParser() + + parser.add_argument('--logfile', + help='Name of the log file, __screen__ for standard output', + type=str) + parser.add_argument('--loglevel', + help='Logging level', + type=str) + parser.add_argument('bind_uri', + help='URI to send requests to', + type=str) + + options = parser.parse_args(args) + + if config.get('Logging') is None : + config['Logging'] = { + 'LogFile' : '__screen__', + 'LogLevel' : 'INFO' + } + if options.logfile : + config['Logging']['LogFile'] = options.logfile + if options.loglevel : + config['Logging']['LogLevel'] = options.loglevel.upper() + if options.bind_uri : + bind_uri = options.bind_uri + +# ----------------------------------------------------------------- +# ----------------------------------------------------------------- +def main(args=None) : + import config.config as pconfig + import utility.logger as plogger + + # Parse out the configuration file first + conffiles = [ 'tcs_config.toml' ] + confpaths = [ ".", TCFHOME + "/config"] + + parser = argparse.ArgumentParser() + parser.add_argument('--config', help='configuration file', + nargs = '+') + parser.add_argument('--config-dir', help='configuration folder', + nargs = '+') + (options, remainder) = parser.parse_known_args(args) + + if options.config : + conffiles = options.config + + if options.config_dir : + confpaths = options.config_dir + + try : + config = pconfig.parse_configuration_files(conffiles, confpaths) + config_json_str = json.dumps(config, indent=4) + except pconfig.ConfigurationException as e : + logger.error(str(e)) + sys.exit(-1) + + plogger.setup_loggers(config.get('Logging', {})) + sys.stdout = plogger.stream_to_logger( + logging.getLogger('STDOUT'), logging.DEBUG) + sys.stderr = plogger.stream_to_logger( + logging.getLogger('STDERR'), logging.WARN) + + parse_command_line(config, remainder) + local_main() + +main() diff --git a/tcs/core/common/python/shared_kv/shared_kv_interface.py b/examples/common/python/shared_kv/shared_kv_interface.py similarity index 82% rename from tcs/core/common/python/shared_kv/shared_kv_interface.py rename to examples/common/python/shared_kv/shared_kv_interface.py index d5a0444b1..8a6c99a87 100644 --- a/tcs/core/common/python/shared_kv/shared_kv_interface.py +++ b/examples/common/python/shared_kv/shared_kv_interface.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python3 - # Copyright 2019 Intel Corporation # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -22,7 +20,7 @@ ''' import json -import tcs.core.tcs_trusted_worker_manager.enclave_wrapper.tcf_enclave_internal as db_store +import tcf_enclave_manager.tcf_enclave as db_store import logging logger = logging.getLogger(__name__) @@ -87,14 +85,26 @@ def get(self, table, key): return value #--------------------------------------------------------------------------------------------------- - def remove(self, table, key): + def remove(self, table, key, value=None): """ - Function to remove the value for a key in a lmdb table + Function to remove the key/value from a lmdb table Parameters: - table is the name of lmdb table in which key-value pair need to be removed. - key is the primary key of the table. + - value is data to be removed, If the database does not support sorted duplicate + data items (MDB_DUPSORT) the data parameter is ignored. If the database supports + sorted duplicates and the data parameter is NULL, all of the duplicate data items + for the key will be deleted. Otherwise, if the data parameter is non-NULL only the + matching data item will be deleted """ - return self.set(table, key, "") + try: + if value is None: + db_store.db_store_del(table, key, "") + else: + db_store.db_store_del(table, key, value) + return True + except: + return False #--------------------------------------------------------------------------------------------------- def lookup(self, table): @@ -102,7 +112,6 @@ def lookup(self, table): Function to get all the keys in a lmdb table Parameters: - table is the name of lmdb table. - - key is the primary key of the table. """ result = [] try: diff --git a/tcs/core/common/python/crypto/__init__.py b/examples/common/python/utility/__init__.py similarity index 100% rename from tcs/core/common/python/crypto/__init__.py rename to examples/common/python/utility/__init__.py diff --git a/tcs/core/common/python/utility/file_utils.py b/examples/common/python/utility/file_utils.py similarity index 95% rename from tcs/core/common/python/utility/file_utils.py rename to examples/common/python/utility/file_utils.py index 2b0e1d23d..33d27fc1f 100644 --- a/tcs/core/common/python/utility/file_utils.py +++ b/examples/common/python/utility/file_utils.py @@ -30,14 +30,14 @@ # ----------------------------------------------------------------- # ----------------------------------------------------------------- def find_file_in_path(filename, search_path) : - """general utility to search for a file name in a path + """General utility to search for a file name in a path :param str filename: name of the file to locate, absolute path ignores search_path :param list(str) search_path: list of directories where the files may be located """ # os.path.abspath only works for full paths, not relative paths - # this check should catch './abc' + # This check should catch './abc' if os.path.split(filename)[0] : if os.path.isfile(filename) : return filename diff --git a/examples/common/python/utility/hex_utils.py b/examples/common/python/utility/hex_utils.py new file mode 100644 index 000000000..d6d4fc41e --- /dev/null +++ b/examples/common/python/utility/hex_utils.py @@ -0,0 +1,26 @@ +# Copyright 2019 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 binascii + +# Return list of binary hex ids as list of UTF strings +def pretty_ids(ids): + pretty_list = [] + for id in ids: + pretty_list.append(hex_to_utf(id)) + return pretty_list + +# Return binary hex as UTF string +def hex_to_utf(binary): + return binascii.hexlify(binary).decode("UTF-8") diff --git a/tcs/core/common/python/utility/ias_client.py b/examples/common/python/utility/ias_client.py similarity index 97% rename from tcs/core/common/python/utility/ias_client.py rename to examples/common/python/utility/ias_client.py index 9c4ebfd4d..b648f1235 100644 --- a/tcs/core/common/python/utility/ias_client.py +++ b/examples/common/python/utility/ias_client.py @@ -79,7 +79,7 @@ def get_signature_revocation_lists(self, def post_verify_attestation(self, quote, manifest=None, nonce=None): """ @param quote: base64 encoded quote attestation - @return: dictionary of the response from ias. + @return: Dictionary of the response from ias. """ path = '/attestation/v3/report' @@ -144,19 +144,19 @@ def verify_report_fields(self, original_quote, received_report): logger.error('AVR does not contain a nonce') return False - #leave the status check for last + # Leave the status check for last if isv_enclave_quote_status.upper() != 'OK': self._last_verification_error = isv_enclave_quote_status.upper() logger.debug("enclave quote status error: " + self._last_verification_error) return False - #all checks passed + # All checks passed return True def last_verification_error(self): """ Errno-like procedure to provide details about where the verification failed. - Mostly used for GROUP_OUT_OF_DATE verification report failure + Mostly used for GROUP_OUT_OF_DATE verification report failure. """ return self._last_verification_error diff --git a/tcs/core/common/python/utility/keys.py b/examples/common/python/utility/keys.py similarity index 98% rename from tcs/core/common/python/utility/keys.py rename to examples/common/python/utility/keys.py index d1ca40952..9557a93a4 100644 --- a/tcs/core/common/python/utility/keys.py +++ b/examples/common/python/utility/keys.py @@ -60,7 +60,7 @@ class EnclaveKeys(object) : # ------------------------------------------------------- def __init__(self, verifying_key, encryption_key) : """ - initialize the object + Initialize the object :param verifying_key: PEM encoded ECDSA verifying key :param encryption_key: PEM encoded RSA encryption key diff --git a/tcs/core/common/python/utility/logger.py b/examples/common/python/utility/logger.py similarity index 99% rename from tcs/core/common/python/utility/logger.py rename to examples/common/python/utility/logger.py index 782275979..984104c7b 100644 --- a/tcs/core/common/python/utility/logger.py +++ b/examples/common/python/utility/logger.py @@ -82,7 +82,7 @@ def setup_loggers(config) : clog.setFormatter(formatter) logger.addHandler(clog) - # process all overrides + # Process all overrides logoverride = config.get("LogOverride", {}) for modname, modlevel in logoverride.items() : modlogger = logging.getLogger(modname) diff --git a/common/utils/signature.py b/examples/common/python/utility/signature.py similarity index 99% rename from common/utils/signature.py rename to examples/common/python/utility/signature.py index ba09a6b2f..01088eeb7 100644 --- a/common/utils/signature.py +++ b/examples/common/python/utility/signature.py @@ -29,7 +29,7 @@ import logging import crypto.crypto as crypto import utility.file_utils as putils -import utils.utility as utility +import utility.utility as utility import worker.worker_details as worker from error_code.error_status import SignatureStatus diff --git a/common/utils/tcf_types.py b/examples/common/python/utility/tcf_types.py similarity index 97% rename from common/utils/tcf_types.py rename to examples/common/python/utility/tcf_types.py index 8d6062999..cf8088842 100644 --- a/common/utils/tcf_types.py +++ b/examples/common/python/utility/tcf_types.py @@ -1,4 +1,4 @@ -# Copyright 2018 Intel Corporation +# Copyright 2019 Intel Corporation # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/common/utils/utility.py b/examples/common/python/utility/utility.py similarity index 79% rename from common/utils/utility.py rename to examples/common/python/utility/utility.py index dbc5bae88..e5635f435 100644 --- a/common/utils/utility.py +++ b/examples/common/python/utility/utility.py @@ -27,7 +27,7 @@ logger = logging.getLogger(__name__) TCFHOME = os.environ.get("TCF_HOME", "../../") -#No of bytes of encrypted session key to encrypt data +# No of bytes of encrypted session key to encrypt data NO_OF_BYTES = 16 def read_toml_file(input_file, config_name = None, confpaths = [".", TCFHOME + "/" + "config"]): @@ -82,10 +82,27 @@ def write_json_file(file_name,input_data, data_dir ='./') : with open(filename, "w") as file : json.dump(result_info, file) +#--------------------------------------------------------------------------------------------- +def create_error_response(code, jrpc_id, message): + """ + Function to create error response + Parameters: + - code: error code enum which corresponds to error response + - jrpc_id: JRPC id of the error response + - message: error message which corresponds to error response + """ + error_response = {} + error_response["jsonrpc"] = "2.0" + error_response["id"] = jrpc_id + error_response["error"] = {} + error_response["error"]["code"] = code + error_response["error"]["message"] = message + return error_response + #--------------------------------------------------------------------------------------------- def strip_begin_end_key(key) : """ - strips off newline chars, BEGIN PUBLIC KEY and END PUBLIC KEY. + Strips off newline chars, BEGIN PUBLIC KEY and END PUBLIC KEY. """ return key.replace("\n", "")\ .replace("-----BEGIN PUBLIC KEY-----", "").replace("-----END PUBLIC KEY-----", "") @@ -113,8 +130,10 @@ def generate_encrypted_session_key(session_iv, worker_encryption_key): """ Function to generate session key for the client Parameters: - - worker_encryption_key is a one-time encryption key generated by the participant submitting the work order. - - session_iv is an initialization vector if required by the data encryption algorithm (encryptedSessionKey). The default is all zeros. + - worker_encryption_key is a one-time encryption key generated by the participant + submitting the work order. + - session_iv is an initialization vector if required by the data encryption algorithm + (encryptedSessionKey). The default is all zeros. """ session_key = crypto.SKENC_GenerateKey() @@ -134,9 +153,12 @@ def encrypt_data(data, encryption_key, iv): """ Function to encrypt data based on encryption key and iv Parameters: - - data is each item in inData or outData part of workorder request as per TCF API 6.1.7 Work Order Data Formats + - data is each item in inData or outData part of workorder request + as per TCF API 6.1.7 Work Order Data Formats - encryption_key is the key used to encrypt the data - - iv is an initialization vector if required by the data encryption algorithm. The default is all zeros.iv must be a unique random number for every encryption operation. + - iv is an initialization vector if required by the data encryption algorithm. + The default is all zeros.iv must be a unique random number for every + encryption operation. """ logger.debug("encrypted_session_key: %s", encryption_key) return crypto.SKENC_EncryptMessage(encryption_key, iv, data) @@ -146,27 +168,34 @@ def decrypt_data(encryption_key, iv, data): Function to decrypt the outData in the result Parameters: - encryption_key is the key used to decrypt the encrypted data of response. - - iv is an initialization vector if required by the data encryption algorithm. The default is all zeros. - - data is the parameter data in outData part of workorder request as per TCF API 6.1.7 Work Order Data Formats + - iv is an initialization vector if required by the data encryption algorithm. + The default is all zeros. + - data is the parameter data in outData part of workorder request as per + TCF API 6.1.7 Work Order Data Formats + Returns decrypted data as a string """ if not data: logger.debug("Outdata is empty, nothing to decrypt") - return + return data data_byte = crypto.base64_to_byte_array(data) logger.debug("encrypted_session_key: %s", encryption_key) - decrypt_result = crypto.SKENC_DecryptMessage(encryption_key, crypto.hex_to_byte_array(iv), data_byte) - result = base64.b64decode(crypto.byte_array_to_base64(decrypt_result)) + decrypt_result = crypto.SKENC_DecryptMessage(encryption_key, + crypto.hex_to_byte_array(iv), data_byte) + result = crypto.byte_array_to_string(decrypt_result) logger.info("Decryption Result at Client - %s ", result) + return result #--------------------------------------------------------------------------------------------- def decrypted_response(input_json_str, encrypted_session_key): """ - Function to calculate a hash value of the array concatenating dataHash, data, - encryptedDataEncryptionKey, iv for each item in the inData/outData array + Function iterate through the out data items and decrypt the data using + encryptedDataEncryptionKey and returns json object. Parameters: - - input_json_params is a collection of parameters as per TCF APi 6.1.2 Work Order Response Payload + - input_json_params is a collection of parameters as per TCF API 6.1.2 + Work Order Response Payload - encryption_session_key is the key used to decrypt the encrypted data of response. + Returns response json object after decrypting output data """ input_json = json.loads(input_json_str) input_json_params = input_json['result'] @@ -181,15 +210,18 @@ def decrypted_response(input_json_str, encrypted_session_key): elif e_key == "-".encode('UTF-8'): do_decrypt = False else: - encryption_key_byte = crypto.base64_to_byte_array(e_key) + encryption_key_byte = e_key iv = item['iv'].encode('UTF-8') if not do_decrypt: input_json_params['outData'][i]['data'] = data - logger.info("Work order response data not encrypted, data in plain is %s", base64.b64decode(data)) + logger.info("Work order response data not encrypted, data in plain is %s", + base64.b64decode(data)) else: # Decrypt output data logger.debug("encrypted_session_key: %s", encryption_key_byte) - input_json_params['outData'][i]['data'] = decrypt_data(encryption_key_byte, item['iv'], item['data']) + input_json_params['outData'][i]['data'] = decrypt_data( + encryption_key_byte, item['iv'], item['data']) i = i + 1 + return input_json_params #--------------------------------------------------------------------------------------------- diff --git a/tcs/core/common/python/utility/__init__.py b/examples/common/python/worker/__init__.py similarity index 100% rename from tcs/core/common/python/utility/__init__.py rename to examples/common/python/worker/__init__.py diff --git a/common/worker/worker_details.py b/examples/common/python/worker/worker_details.py similarity index 88% rename from common/worker/worker_details.py rename to examples/common/python/worker/worker_details.py index 79ef43060..d02b959bd 100644 --- a/common/worker/worker_details.py +++ b/examples/common/python/worker/worker_details.py @@ -18,7 +18,7 @@ """ import logging -import utils.utility as utility +import utility.utility as utility logger = logging.getLogger(__name__) @@ -51,8 +51,11 @@ def load_worker(self,input_str): self.data_encryption_algorithm = worker_data['dataEncryptionAlgorithm'] self.worker_typedata_verification_key = worker_data['workerTypeData']['verificationKey'] self.worker_encryption_key = worker_data['workerTypeData']['encryptionKey'] - # worker_id - newline, BEGIN PUB KEY and END PUB KEY are removed from worker's verification key - self.worker_id = utility.strip_begin_end_key(worker_data['workerTypeData']['verificationKey']) + + ''' worker_id - newline, BEGIN PUB KEY and END PUB KEY are removed + from worker's verification key and converted to hex ''' + self.worker_id = utility.strip_begin_end_key( + worker_data['workerTypeData']['verificationKey']).encode("UTF-8").hex() logger.info("Hashing Algorithm : %s", self.hashing_algorithm) logger.info("Signing Algorithm : %s", self.signing_algorithm) diff --git a/tcs/core/common/python/workorder_request/__init__.py b/examples/common/python/workorder_request/__init__.py similarity index 100% rename from tcs/core/common/python/workorder_request/__init__.py rename to examples/common/python/workorder_request/__init__.py diff --git a/tcs/core/common/python/workorder_request/sgx_workorder_request.py b/examples/common/python/workorder_request/sgx_workorder_request.py similarity index 100% rename from tcs/core/common/python/workorder_request/sgx_workorder_request.py rename to examples/common/python/workorder_request/sgx_workorder_request.py diff --git a/tcs/core/common/python/Makefile b/examples/enclave_manager/Makefile similarity index 59% rename from tcs/core/common/python/Makefile rename to examples/enclave_manager/Makefile index 44102099b..6fbe10b37 100644 --- a/tcs/core/common/python/Makefile +++ b/examples/enclave_manager/Makefile @@ -13,32 +13,25 @@ # limitations under the License. PY_VERSION=${shell python3 --version | sed 's/Python \(3\.[0-9]\).*/\1/'} -MOD_VERSION=${shell ../../../../bin/get_version} +MOD_VERSION=${shell ../../bin/get_version} ifndef SGX_MODE $(error Incomplete configuration, SGX_MODE is not defined) endif -EGG_FILE=dist/tcf_eservice-${MOD_VERSION}-py${PY_VERSION}-linux-x86_64.egg +EGG_FILE=dist/tcf_enclave_manager-${MOD_VERSION}-py${PY_VERSION}-linux-x86_64.egg SOURCE_DIR=$(shell pwd) -ENCLAVE_LIB=$(SOURCE_DIR)/../../tcs_trusted_worker_manager/enclave/deps/bin/libtcf-enclave.signed.so -EDL_PATH=$(SOURCE_DIR)/../../tcs_trusted_worker_manager/enclave -ENCLAVE_WRAPPER=$(SOURCE_DIR)/../../tcs_trusted_worker_manager/enclave_wrapper +EDL_PATH=$(SOURCE_DIR)/../../tc/sgx/trusted_worker_manager/enclave +ENCLAVE_WRAPPER=$(SOURCE_DIR)/../../tc/sgx/trusted_worker_manager/enclave_wrapper -SWIG_FILES = \ - $(ENCLAVE_WRAPPER)/tcf_enclave_internal.i \ - crypto/crypto.i - -SWIG_TARGET = $(ENCLAVE_WRAPPER)/tcf_enclave_internal.py all : $(EGG_FILE) -$(EGG_FILE) : $(SWIG_TARGET) +$(EGG_FILE) : build_ext @echo Build Distribution python3 setup.py bdist_egg -$(SWIG_TARGET) : $(SWIG_FILES) $(ENCLAVE_LIB) - +build_ext : $(SGX_SDK)/bin/x64/sgx_edger8r --untrusted $(EDL_PATH)/enclave.edl --search-path $(SGX_SDK)/include --search-path $(SGX_SSL)/include/ --search-path $(EDL_PATH) @echo Moving generated edge files @@ -50,19 +43,14 @@ $(SWIG_TARGET) : $(SWIG_FILES) $(ENCLAVE_LIB) build : mkdir $@ - cd $@ ; cmake .. -G "Unix Makefiles" -install: $(EGG_FILE) +install: @echo INSTALLING EGG FILE ================= - easy_install $< - -test: install - (cd tests; python3 test-secrets.py) - (cd tests; python3 test-request.py) + easy_install $(EGG_FILE) clean: - rm -f $(addprefix $(ENCLAVE_WRAPPER), /tcf_enclave_internal.py /tcf_enclave_internal_wrap.cpp /enclave_u.c /enclave_u.h) - rm -f common/crypto.py common/crypto_wrap.cpp + rm -f $(addprefix $(ENCLAVE_WRAPPER), /enclave_u.c /enclave_u.h) + rm -f tcf_enclave_manager/tcf_enclave.py tcf_enclave_manager/tcf_enclave_wrap.cpp rm -rf build deps dist *.egg-info find . -iname '*.pyc' -delete find . -iname '__pycache__' -delete @@ -72,8 +60,4 @@ print_enclave_files: .phony : all .phony : clean -.phony : enclave .phone : install -.phony : test -.phony : print_enclave_files -.phony : info diff --git a/tcs/core/common/python/setup.py b/examples/enclave_manager/setup.py similarity index 55% rename from tcs/core/common/python/setup.py rename to examples/enclave_manager/setup.py index d3d3ec5e4..448ce07b9 100644 --- a/tcs/core/common/python/setup.py +++ b/examples/enclave_manager/setup.py @@ -19,7 +19,7 @@ import subprocess import re -# this should only be run with python3 +# This should only be run with python3 import sys if sys.version_info[0] < 3: print('ERROR: must run with python3') @@ -28,20 +28,9 @@ from setuptools import setup, find_packages, Extension tcf_root_dir = os.environ.get('TCF_HOME', '../../../../') -script_dir = os.path.dirname(os.path.realpath(__file__)) -enclave_dir = os.path.realpath(os.path.join(tcf_root_dir, 'tcs/core/tcs_trusted_worker_manager/enclave')) +enclave_dir = os.path.realpath(os.path.join(tcf_root_dir, 'tc/sgx/trusted_worker_manager/enclave')) -log_dir = os.path.join(tcf_root_dir, "logs") - -openssl_cflags = subprocess.check_output(['pkg-config', 'openssl', '--cflags']).decode('ascii').strip().split() -openssl_include_dirs = list( - filter(None, re.split('\s*-I', subprocess.check_output(['pkg-config', 'openssl', '--cflags-only-I']).decode('ascii').strip()))) -openssl_libs = list( - filter(None, re.split('\s*-l', subprocess.check_output(['pkg-config', 'openssl', '--libs-only-l']).decode('ascii').strip()))) -openssl_lib_dirs = list( - filter(None, re.split('\s*-L', subprocess.check_output(['pkg-config', 'openssl', '--libs-only-L']).decode('ascii').strip()))) - -module_path = 'tcs/core/tcs_trusted_worker_manager/enclave_wrapper' +module_path = 'tc/sgx/trusted_worker_manager/enclave_wrapper' module_src_path = os.path.join(tcf_root_dir, module_path) sgx_mode_env = os.environ.get('SGX_MODE', None) @@ -49,18 +38,9 @@ print("error: SGX_MODE value must be HW or SIM, current value is: ", sgx_mode_env) sys.exit(2) -data_files = [ - (log_dir, []), - ("tcs/core/tcs_trusted_worker_manager/enclave_wrapper", [module_src_path + "/tcf_enclave_internal.py"]), - ('lib', [ os.path.join(enclave_dir, 'deps/bin/libtcf-enclave.signed.so')]), -] - -ext_deps = [ - ('lib', [ os.path.join(script_dir, '../../core/enclave/deps/bin/libtcf-enclave.signed.so')]) -] ## ----------------------------------------------------------------- -## set up the enclave +## Set up the enclave ## ----------------------------------------------------------------- debug_flag = os.environ.get('TCF_DEBUG_BUILD',0) @@ -72,36 +52,34 @@ ] -# by default the extension class adds '-O2' to the compile +# By default the extension class adds '-O2' to the compile # flags, this lets us override since these are appended to -# the compilation switches +# the compilation switches. if debug_flag : compile_args += ['-g'] include_dirs = [ module_src_path, - os.path.join(tcf_root_dir, 'tcs/core/common/crypto'), - os.path.join(tcf_root_dir, 'tcs/core/common'), + os.path.join(tcf_root_dir, 'tc/sgx/common'), + os.path.join(tcf_root_dir, 'tc/sgx/common/crypto'), os.path.join(module_src_path, 'build'), os.path.join(os.environ['SGX_SDK'],"include"), - os.path.join(tcf_root_dir, 'tcs/core/common/packages/db_store'), - os.path.join(tcf_root_dir, 'tcs/core/common/packages/base64') -] + openssl_include_dirs + os.path.join(tcf_root_dir, 'tc/sgx/common/packages/db_store'), + os.path.join(tcf_root_dir, 'tc/sgx/common/packages/base64') +] library_dirs = [ - os.path.join(tcf_root_dir, "tcs/core/tcs_trusted_worker_manager/enclave/build/lib"), - os.path.join(tcf_root_dir, "tcs/core/common/build"), + os.path.join(tcf_root_dir, "tc/sgx/common/build"), os.path.join(os.environ['SGX_SDK'], 'lib64'), os.path.join(os.environ['SGX_SSL'], 'lib64'), os.path.join(os.environ['SGX_SSL'], 'lib64', 'release') -] + openssl_lib_dirs +] libraries = [ 'utcf-common', - 'tcf-enclave', 'utcf-lmdb-store', 'lmdb' -] + openssl_libs +] if sgx_mode_env == "HW": libraries.append('sgx_urts') @@ -112,17 +90,16 @@ libraries.append('sgx_uae_service_sim') SGX_SIMULATOR_value = '1' +# This library is needed as it's used by enclave_u.c libraries.append('sgx_usgxssl') -libraries = libraries + openssl_libs module_files = [ - os.path.join(module_src_path, 'tcf_enclave_internal.i'), + "tcf_enclave_manager/tcf_enclave.i", os.path.join(module_src_path, 'swig_utils.cpp'), os.path.join(module_src_path, 'ocall.cpp'), os.path.join(module_src_path, 'base.cpp'), os.path.join(module_src_path, 'enclave_u.c'), os.path.join(module_src_path, 'log.cpp'), - os.path.join(module_src_path, 'work_order.cpp'), os.path.join(module_src_path, 'work_order_wrap.cpp'), os.path.join(module_src_path, 'signup.cpp'), @@ -130,28 +107,13 @@ os.path.join(module_src_path, 'enclave.cpp'), os.path.join(module_src_path, 'enclave_info.cpp'), os.path.join(module_src_path, 'signup_info.cpp'), - os.path.join(module_src_path, 'db_store.cpp'), - os.path.join(tcf_root_dir, 'tcs/core/common/packages/db_store/lmdb_store.cpp') + os.path.join(module_src_path, 'db_store.cpp') ] -crypto_modulefiles = [ - "crypto/crypto.i" -] - -crypto_module = Extension( - 'crypto._crypto', - crypto_modulefiles, - swig_opts=['-c++'] + openssl_cflags + ['-I%s' % i for i in include_dirs], - extra_compile_args=compile_args, - include_dirs=include_dirs, - library_dirs=library_dirs, - libraries=libraries) - - enclave_module = Extension( - 'tcs.core.tcs_trusted_worker_manager.enclave_wrapper._tcf_enclave_internal', + 'tcf_enclave_manager._tcf_enclave', module_files, - swig_opts = ['-c++', '-threads'], + swig_opts = ['-c++', '-threads'] + ['-I%s' % i for i in include_dirs], extra_compile_args = compile_args, libraries = libraries, include_dirs = include_dirs, @@ -164,27 +126,14 @@ undef_macros = ['NDEBUG', 'EDEBUG'] ) -## ----------------------------------------------------------------- ## ----------------------------------------------------------------- version = subprocess.check_output( os.path.join(tcf_root_dir, 'bin/get_version')).decode('ascii').strip() -setup(name='tcf_crypto_library', - version=version, - description='Common library for Trusted Compute Framework', - author='Intel Labs', - packages=find_packages(), - install_requires=[], - data_files=[], - #namespace_packages=[''], - ext_modules=[crypto_module], - entry_points={} - ) - -setup(name='tcf_eservice', +setup(name='tcf_enclave_manager', version = version, - description = 'Trusted Compute Framework SGX Worker', - author = 'Hyperledger', + description = 'Trusted Compute Framework SGX Enclave Manager', + author = 'Intel', url = 'http://www.intel.com', packages = find_packages(), #namespace_packages=[''], @@ -197,6 +146,6 @@ ext_modules = [ enclave_module ], - data_files = data_files, + data_files = [], entry_points = {} ) diff --git a/tcs/core/tcs_trusted_worker_manager/tcs_enclave_manager/__init__.py b/examples/enclave_manager/tcf_enclave_manager/__init__.py similarity index 100% rename from tcs/core/tcs_trusted_worker_manager/tcs_enclave_manager/__init__.py rename to examples/enclave_manager/tcf_enclave_manager/__init__.py diff --git a/tcs/core/tcs_trusted_worker_manager/tcs_enclave_manager/tcs_enclave_manager.py b/examples/enclave_manager/tcf_enclave_manager/enclave_manager.py similarity index 98% rename from tcs/core/tcs_trusted_worker_manager/tcs_enclave_manager/tcs_enclave_manager.py rename to examples/enclave_manager/tcf_enclave_manager/enclave_manager.py index 0231eb843..00022dce1 100644 --- a/tcs/core/tcs_trusted_worker_manager/tcs_enclave_manager/tcs_enclave_manager.py +++ b/examples/enclave_manager/tcf_enclave_manager/enclave_manager.py @@ -20,12 +20,12 @@ import argparse import json -import utility.tcf_enclave_helper as enclave_helper +import tcf_enclave_helper as enclave_helper from error_code.error_status import WorkOrderStatus from shared_kv.shared_kv_interface import KvStorage import workorder_request.sgx_workorder_request as workorder_request -from utils.tcf_types import WorkerStatus, WorkerType -import utils.utility as utils +from utility.tcf_types import WorkerStatus, WorkerType +import utility.utility as utils import logging @@ -77,7 +77,7 @@ def manager_on_boot(self, kv_helper): worker_info = create_json_worker(self, self.config) logger.info("Adding enclave workers to workers table") - worker_id = utils.strip_begin_end_key(self.enclave_id) + worker_id = utils.strip_begin_end_key(self.enclave_id).encode("UTF-8").hex() kv_helper.set("workers", worker_id, worker_info) # Cleanup wo-processing" table diff --git a/tcs/core/tcs_trusted_worker_manager/enclave_wrapper/tcf_enclave_internal.i b/examples/enclave_manager/tcf_enclave_manager/tcf_enclave.i similarity index 98% rename from tcs/core/tcs_trusted_worker_manager/enclave_wrapper/tcf_enclave_internal.i rename to examples/enclave_manager/tcf_enclave_manager/tcf_enclave.i index 299e79d6f..4b3d5cd69 100644 --- a/tcs/core/tcs_trusted_worker_manager/enclave_wrapper/tcf_enclave_internal.i +++ b/examples/enclave_manager/tcf_enclave_manager/tcf_enclave.i @@ -13,7 +13,7 @@ * limitations under the License. */ -%module tcf_enclave_internal +%module tcf_enclave %include %include diff --git a/tcs/core/common/python/utility/tcf_enclave_bridge.py b/examples/enclave_manager/tcf_enclave_manager/tcf_enclave_bridge.py similarity index 94% rename from tcs/core/common/python/utility/tcf_enclave_bridge.py rename to examples/enclave_manager/tcf_enclave_manager/tcf_enclave_bridge.py index 0d052c6b9..d959f5185 100644 --- a/tcs/core/common/python/utility/tcf_enclave_bridge.py +++ b/examples/enclave_manager/tcf_enclave_manager/tcf_enclave_bridge.py @@ -20,7 +20,7 @@ from requests.exceptions import Timeout from requests.exceptions import HTTPError import utility.ias_client as ias_client -import tcs.core.tcs_trusted_worker_manager.enclave_wrapper.tcf_enclave_internal as enclave +import tcf_enclave_manager.tcf_enclave as enclave import logging logger = logging.getLogger(__name__) @@ -47,7 +47,7 @@ def __find_enclave_library(config) : Find enclave library file from the parsed config """ enclave_file_name = config.get('enclave_library'); - enclave_file_path = config.get('enclave_library_path') + enclave_file_path = TCFHOME + "/" + config.get('enclave_library_path') logger.info("Enclave Lib: %s", enclave_file_name) if enclave_file_path : @@ -60,11 +60,7 @@ def __find_enclave_library(config) : logger.info("Script directory - %s", script_directory) 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')) ] for path in search_path : @@ -179,7 +175,7 @@ def get_enclave_basename(): # ----------------------------------------------------------------- def create_signup_info(originator_public_key_hash, nonce): """ - create enclave signup data + Create enclave signup data """ # Part of what is returned with the signup data is an enclave quote, we # want to update the revocation list first. @@ -233,7 +229,7 @@ def create_signup_info(originator_public_key_hash, nonce): signup_info['enclave_persistent_id'] = verification_report_dict.get('epidPseudonym') # Now we can finally serialize the signup info and create a corresponding - # signup info object. Because we don't want the sealed signup data in the + # signup info object. Because we don't want the sealed signup data in the # serialized version, we set it separately. signup_info_obj = enclave.deserialize_signup_info(json.dumps(signup_info)) diff --git a/tcs/core/common/python/utility/tcf_enclave_helper.py b/examples/enclave_manager/tcf_enclave_manager/tcf_enclave_helper.py similarity index 90% rename from tcs/core/common/python/utility/tcf_enclave_helper.py rename to examples/enclave_manager/tcf_enclave_manager/tcf_enclave_helper.py index 8de355875..f08afdb93 100644 --- a/tcs/core/common/python/utility/tcf_enclave_helper.py +++ b/examples/enclave_manager/tcf_enclave_manager/tcf_enclave_helper.py @@ -22,14 +22,14 @@ import random import logging -import utility.tcf_enclave_bridge as tcf_enclave +import tcf_enclave_bridge as tcf_enclave import utility.keys as keys logger = logging.getLogger(__name__) # ----------------------------------------------------------------- def initialize_enclave(enclave_config) : - """initialize_enclave -- call the initialization function on the + """initialize_enclave -- Call the initialization function on the enclave module """ return tcf_enclave.initialize_with_configuration(enclave_config) @@ -43,9 +43,9 @@ class EnclaveHelper(object) : # ------------------------------------------------------- @classmethod def create_enclave_signup_data(cls, tcf_instance_keys = None) : - """create_enclave_signup_data -- create enclave signup data + """create_enclave_signup_data -- Create enclave signup data - :param tcf_instance_keys: object of type TransactionKeys + :param tcf_instance_keys: Object of type TransactionKeys """ if tcf_instance_keys is None : @@ -74,7 +74,7 @@ def create_enclave_signup_data(cls, tcf_instance_keys = None) : # ------------------------------------------------------- def __init__(self, enclave_info, tcf_instance_keys) : - # initialize the keys that can be used later to + # Initialize the keys that can be used later to # register the enclave self.tcf_instance_keys = tcf_instance_keys @@ -93,7 +93,7 @@ def __init__(self, enclave_info, tcf_instance_keys) : # ------------------------------------------------------- def send_to_sgx_worker(self, encrypted_request) : """ - Submit workorder request to the SGX Worker enclave + Submit workorder request to the SGX Worker enclave :param encrypted_request: base64 encoded encrypted workorder request """ @@ -104,6 +104,6 @@ def send_to_sgx_worker(self, encrypted_request) : # ------------------------------------------------------- def get_enclave_public_info(self) : """ - return information about the enclave + Return information about the enclave """ return tcf_enclave.get_enclave_public_info(self.sealed_data) diff --git a/scripts/tcs_startup.sh b/scripts/tcs_startup.sh index b049dd8f7..ebd257b85 100755 --- a/scripts/tcs_startup.sh +++ b/scripts/tcs_startup.sh @@ -14,8 +14,8 @@ # See the License for the specific language governing permissions and # limitations under the License. -enclave_manager="${TCF_HOME}/tcs/core/tcs_trusted_worker_manager/tcs_enclave_manager/tcs_enclave_manager.py" -listener="${TCF_HOME}/tcs/tcs_listener/tcs_listener.py" +enclave_manager="${TCF_HOME}/examples/enclave_manager/tcf_enclave_manager/enclave_manager.py" +listener="${TCF_HOME}/examples/common/python/connectors/direct/tcs_listener/tcs_listener.py" # Read Listener port from config file listener_port=`grep listener_port ${TCF_HOME}/config/tcs_config.toml | awk {'print $3'}` diff --git a/tcs/core/common/BUILD.md b/tc/sgx/common/BUILD.md similarity index 100% rename from tcs/core/common/BUILD.md rename to tc/sgx/common/BUILD.md diff --git a/tcs/core/common/CMakeLists.txt b/tc/sgx/common/CMakeLists.txt similarity index 98% rename from tcs/core/common/CMakeLists.txt rename to tc/sgx/common/CMakeLists.txt index a1a5220be..d032aad5d 100644 --- a/tcs/core/common/CMakeLists.txt +++ b/tc/sgx/common/CMakeLists.txt @@ -23,8 +23,8 @@ INCLUDE(CMakeVariables.txt) # Common components for both trusted and untrusted common libraries ################################################################################ -FILE(GLOB PROJECT_HEADERS *.h crypto/*.h packages/base64/*.h packages/parson/*.h state/*.h) -FILE(GLOB PROJECT_SOURCES *.cpp crypto/*.cpp packages/base64/*.cpp packages/parson/*.cpp state/*.cpp) +FILE(GLOB PROJECT_HEADERS *.h crypto/*.h packages/base64/*.h packages/parson/*.h) +FILE(GLOB PROJECT_SOURCES *.cpp crypto/*.cpp packages/base64/*.cpp packages/parson/*.cpp) SET(COMMON_PRIVATE_INCLUDE_DIRS "." "tests" "crypto" "packages/base64" "packages/parson" "state") SET(COMMON_CXX_FLAGS ${DEBUG_FLAGS} "-m64" "-fvisibility=hidden" "-fpie" "-fPIC" "-fstack-protector" "-std=c++11" "-Wall") diff --git a/tcs/core/common/CMakeVariables.txt b/tc/sgx/common/CMakeVariables.txt similarity index 100% rename from tcs/core/common/CMakeVariables.txt rename to tc/sgx/common/CMakeVariables.txt diff --git a/tcs/core/common/README.md b/tc/sgx/common/README.md similarity index 100% rename from tcs/core/common/README.md rename to tc/sgx/common/README.md diff --git a/tcs/core/common/c11_support.cpp b/tc/sgx/common/c11_support.cpp similarity index 100% rename from tcs/core/common/c11_support.cpp rename to tc/sgx/common/c11_support.cpp diff --git a/tcs/core/common/c11_support.h b/tc/sgx/common/c11_support.h similarity index 100% rename from tcs/core/common/c11_support.h rename to tc/sgx/common/c11_support.h diff --git a/tcs/core/common/crypto/crypto.h b/tc/sgx/common/crypto/crypto.h similarity index 100% rename from tcs/core/common/crypto/crypto.h rename to tc/sgx/common/crypto/crypto.h diff --git a/tcs/core/common/crypto/crypto_shared.h b/tc/sgx/common/crypto/crypto_shared.h similarity index 100% rename from tcs/core/common/crypto/crypto_shared.h rename to tc/sgx/common/crypto/crypto_shared.h diff --git a/tcs/core/common/crypto/crypto_utils.cpp b/tc/sgx/common/crypto/crypto_utils.cpp similarity index 100% rename from tcs/core/common/crypto/crypto_utils.cpp rename to tc/sgx/common/crypto/crypto_utils.cpp diff --git a/tcs/core/common/crypto/crypto_utils.h b/tc/sgx/common/crypto/crypto_utils.h similarity index 100% rename from tcs/core/common/crypto/crypto_utils.h rename to tc/sgx/common/crypto/crypto_utils.h diff --git a/tcs/core/common/crypto/pkenc.h b/tc/sgx/common/crypto/pkenc.h similarity index 100% rename from tcs/core/common/crypto/pkenc.h rename to tc/sgx/common/crypto/pkenc.h diff --git a/tcs/core/common/crypto/pkenc_private_key.cpp b/tc/sgx/common/crypto/pkenc_private_key.cpp similarity index 99% rename from tcs/core/common/crypto/pkenc_private_key.cpp rename to tc/sgx/common/crypto/pkenc_private_key.cpp index 4f7c00344..c0ef6e2c2 100644 --- a/tcs/core/common/crypto/pkenc_private_key.cpp +++ b/tc/sgx/common/crypto/pkenc_private_key.cpp @@ -12,6 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + #include "pkenc_private_key.h" #include #include @@ -106,7 +107,7 @@ pcrypto::pkenc::PrivateKey::~PrivateKey() { } // pcrypto::pkenc::Private::~PrivateKey // XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -// assignment operator overload +// Assignment operator overload // throws RuntimeError pcrypto::pkenc::PrivateKey& pcrypto::pkenc::PrivateKey::operator=( const pcrypto::pkenc::PrivateKey& privateKey) { diff --git a/tcs/core/common/crypto/pkenc_private_key.h b/tc/sgx/common/crypto/pkenc_private_key.h similarity index 100% rename from tcs/core/common/crypto/pkenc_private_key.h rename to tc/sgx/common/crypto/pkenc_private_key.h diff --git a/tcs/core/common/crypto/pkenc_public_key.cpp b/tc/sgx/common/crypto/pkenc_public_key.cpp similarity index 100% rename from tcs/core/common/crypto/pkenc_public_key.cpp rename to tc/sgx/common/crypto/pkenc_public_key.cpp diff --git a/tcs/core/common/crypto/pkenc_public_key.h b/tc/sgx/common/crypto/pkenc_public_key.h similarity index 100% rename from tcs/core/common/crypto/pkenc_public_key.h rename to tc/sgx/common/crypto/pkenc_public_key.h diff --git a/tcs/core/common/crypto/sig.h b/tc/sgx/common/crypto/sig.h similarity index 100% rename from tcs/core/common/crypto/sig.h rename to tc/sgx/common/crypto/sig.h diff --git a/tcs/core/common/crypto/sig_private_key.cpp b/tc/sgx/common/crypto/sig_private_key.cpp similarity index 100% rename from tcs/core/common/crypto/sig_private_key.cpp rename to tc/sgx/common/crypto/sig_private_key.cpp diff --git a/tcs/core/common/crypto/sig_private_key.h b/tc/sgx/common/crypto/sig_private_key.h similarity index 100% rename from tcs/core/common/crypto/sig_private_key.h rename to tc/sgx/common/crypto/sig_private_key.h diff --git a/tcs/core/common/crypto/sig_public_key.cpp b/tc/sgx/common/crypto/sig_public_key.cpp similarity index 100% rename from tcs/core/common/crypto/sig_public_key.cpp rename to tc/sgx/common/crypto/sig_public_key.cpp diff --git a/tcs/core/common/crypto/sig_public_key.h b/tc/sgx/common/crypto/sig_public_key.h similarity index 100% rename from tcs/core/common/crypto/sig_public_key.h rename to tc/sgx/common/crypto/sig_public_key.h diff --git a/tcs/core/common/crypto/skenc.cpp b/tc/sgx/common/crypto/skenc.cpp similarity index 100% rename from tcs/core/common/crypto/skenc.cpp rename to tc/sgx/common/crypto/skenc.cpp diff --git a/tcs/core/common/crypto/skenc.h b/tc/sgx/common/crypto/skenc.h similarity index 100% rename from tcs/core/common/crypto/skenc.h rename to tc/sgx/common/crypto/skenc.h diff --git a/tcs/core/common/docs/crypto.md b/tc/sgx/common/docs/crypto.md similarity index 100% rename from tcs/core/common/docs/crypto.md rename to tc/sgx/common/docs/crypto.md diff --git a/tcs/core/common/error.cpp b/tc/sgx/common/error.cpp similarity index 100% rename from tcs/core/common/error.cpp rename to tc/sgx/common/error.cpp diff --git a/tcs/core/common/error.h b/tc/sgx/common/error.h similarity index 100% rename from tcs/core/common/error.h rename to tc/sgx/common/error.h diff --git a/tcs/core/common/hex_string.cpp b/tc/sgx/common/hex_string.cpp similarity index 100% rename from tcs/core/common/hex_string.cpp rename to tc/sgx/common/hex_string.cpp diff --git a/tcs/core/common/hex_string.h b/tc/sgx/common/hex_string.h similarity index 100% rename from tcs/core/common/hex_string.h rename to tc/sgx/common/hex_string.h diff --git a/tcs/core/common/json_utils.cpp b/tc/sgx/common/json_utils.cpp similarity index 100% rename from tcs/core/common/json_utils.cpp rename to tc/sgx/common/json_utils.cpp diff --git a/tcs/core/common/json_utils.h b/tc/sgx/common/json_utils.h similarity index 100% rename from tcs/core/common/json_utils.h rename to tc/sgx/common/json_utils.h diff --git a/tcs/core/common/jsonvalue.h b/tc/sgx/common/jsonvalue.h similarity index 100% rename from tcs/core/common/jsonvalue.h rename to tc/sgx/common/jsonvalue.h diff --git a/tcs/core/common/packages/base64/base64.cpp b/tc/sgx/common/packages/base64/base64.cpp similarity index 100% rename from tcs/core/common/packages/base64/base64.cpp rename to tc/sgx/common/packages/base64/base64.cpp diff --git a/tcs/core/common/packages/base64/base64.h b/tc/sgx/common/packages/base64/base64.h similarity index 100% rename from tcs/core/common/packages/base64/base64.h rename to tc/sgx/common/packages/base64/base64.h diff --git a/tcs/core/common/packages/db_store/db_store.h b/tc/sgx/common/packages/db_store/db_store.h similarity index 80% rename from tcs/core/common/packages/db_store/db_store.h rename to tc/sgx/common/packages/db_store/db_store.h index 50356a00f..1f100f4cc 100644 --- a/tcs/core/common/packages/db_store/db_store.h +++ b/tc/sgx/common/packages/db_store/db_store.h @@ -109,6 +109,29 @@ namespace tcf { const uint8_t* inValue, const size_t inValueSize); + // XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + /** + * Deletes a key/value from the database store + * Primary expected use: ocall + * + * @param table table name + * @param inId pointer to id byte array + * @param inIdSize length of inId + * @param inValue pointer to value byte array + * @param inValueSize length of inValue + * + * @return + * TCF_SUCCESS id->value stored + * else failed, database store unchanged + */ + tcf_err_t db_store_del( + const std::string& table, + const uint8_t* inId, + const size_t inIdSize, + const uint8_t* inValue, + const size_t inValueSize); + + // XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX /** * Gets the size of a value in the database store @@ -166,6 +189,24 @@ namespace tcf { const ByteArray& inId, const ByteArray& inValue); - } /* namespace db_strore */ + // XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + /** + * Deletes a key/value from the database store + * Primary expected use: python / untrusted side + * + * @param table table name + * @param inId id byte array + * @param inValue data to be written + * + * @return + * TCF_SUCCESS id->value deleted + * else failed, d store unchanged + */ + tcf_err_t db_store_del( + const std::string& table, + const ByteArray& inId, + const ByteArray& inValue); + + } /* namespace db_store */ } /* namespace tcf */ diff --git a/tcs/core/common/packages/db_store/lmdb_store.cpp b/tc/sgx/common/packages/db_store/lmdb_store.cpp similarity index 88% rename from tcs/core/common/packages/db_store/lmdb_store.cpp rename to tc/sgx/common/packages/db_store/lmdb_store.cpp index 768fec27e..c1dd35324 100644 --- a/tcs/core/common/packages/db_store/lmdb_store.cpp +++ b/tc/sgx/common/packages/db_store/lmdb_store.cpp @@ -288,6 +288,52 @@ tcf_err_t tcf::db_store::db_store_put( return TCF_SUCCESS; } +// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +tcf_err_t tcf::db_store::db_store_del( + const std::string& table, + const uint8_t* inId, + const size_t inIdSize, + const uint8_t* inValue, + const size_t inValueSize) { + MDB_dbi dbi; + MDB_val lmdb_id; + MDB_val lmdb_data; + int ret; + +#if DB_STORE_DEBUG + { + std::string idStr = BinaryToHexString(inId, inIdSize); + // SAFE_LOG(TCF_LOG_DEBUG, "db store Del: %zu bytes '%s' -> %zu bytes '%s'", inIdSize, + // idStr.c_str(), inValueSize, valueStr.c_str()); + } +#endif + + SafeThreadLock slock; + SafeTransaction stxn(0); + + if (stxn.txn == NULL) + return TCF_ERR_SYSTEM; + + ret = mdb_dbi_open(stxn.txn, table.c_str(), MDB_CREATE, &dbi); + if (ret != 0) { + // SAFE_LOG(TCF_LOG_ERROR, "Failed to open LMDB transaction : %d", ret); + return TCF_ERR_SYSTEM; + } + + lmdb_id.mv_size = inIdSize; + lmdb_id.mv_data = (void*)inId; + lmdb_data.mv_size = inValueSize; + lmdb_data.mv_data = (void*)inValue; + + ret = mdb_del(stxn.txn, dbi, &lmdb_id, &lmdb_data); + if (ret != 0) { + // SAFE_LOG(TCF_LOG_ERROR, "Failed to delete from LMDB database : %d", ret); + return TCF_ERR_SYSTEM; + } + + return TCF_SUCCESS; +} + // XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX tcf_err_t tcf::db_store::db_store_get_value_size( const std::string& table, @@ -349,6 +395,14 @@ tcf_err_t tcf::db_store::db_store_put( return db_store_put(table, inId.data(), inId.size(), inValue.data(), inValue.size()); } +// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +tcf_err_t tcf::db_store::db_store_del( + const std::string& table, + const ByteArray& inId, + const ByteArray& inValue) { + return db_store_del(table, inId.data(), inId.size(), inValue.data(), inValue.size()); +} + // XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX std::string tcf::db_store::db_store_get_all( const std::string& table, diff --git a/tcs/core/common/packages/db_store/lmdb_store.h b/tc/sgx/common/packages/db_store/lmdb_store.h similarity index 100% rename from tcs/core/common/packages/db_store/lmdb_store.h rename to tc/sgx/common/packages/db_store/lmdb_store.h diff --git a/tcs/core/common/packages/parson/parson.cpp b/tc/sgx/common/packages/parson/parson.cpp similarity index 100% rename from tcs/core/common/packages/parson/parson.cpp rename to tc/sgx/common/packages/parson/parson.cpp diff --git a/tcs/core/common/packages/parson/parson.h b/tc/sgx/common/packages/parson/parson.h similarity index 100% rename from tcs/core/common/packages/parson/parson.h rename to tc/sgx/common/packages/parson/parson.h diff --git a/tcs/core/common/sgx_support.h b/tc/sgx/common/sgx_support.h similarity index 100% rename from tcs/core/common/sgx_support.h rename to tc/sgx/common/sgx_support.h diff --git a/tcs/core/common/tcf_error.h b/tc/sgx/common/tcf_error.h similarity index 100% rename from tcs/core/common/tcf_error.h rename to tc/sgx/common/tcf_error.h diff --git a/tcs/core/common/tests/CMakeLists.txt b/tc/sgx/common/tests/CMakeLists.txt similarity index 100% rename from tcs/core/common/tests/CMakeLists.txt rename to tc/sgx/common/tests/CMakeLists.txt diff --git a/tcs/core/common/tests/testCrypto.cpp b/tc/sgx/common/tests/testCrypto.cpp similarity index 100% rename from tcs/core/common/tests/testCrypto.cpp rename to tc/sgx/common/tests/testCrypto.cpp diff --git a/tcs/core/common/tests/testCrypto.h b/tc/sgx/common/tests/testCrypto.h similarity index 100% rename from tcs/core/common/tests/testCrypto.h rename to tc/sgx/common/tests/testCrypto.h diff --git a/tcs/core/common/tests/test_cryptoWrapper.py b/tc/sgx/common/tests/test_cryptoWrapper.py similarity index 100% rename from tcs/core/common/tests/test_cryptoWrapper.py rename to tc/sgx/common/tests/test_cryptoWrapper.py diff --git a/tcs/core/common/tests/trusted/app/TestApp.cpp b/tc/sgx/common/tests/trusted/app/TestApp.cpp similarity index 100% rename from tcs/core/common/tests/trusted/app/TestApp.cpp rename to tc/sgx/common/tests/trusted/app/TestApp.cpp diff --git a/tcs/core/common/tests/trusted/app/TestApp.h b/tc/sgx/common/tests/trusted/app/TestApp.h similarity index 100% rename from tcs/core/common/tests/trusted/app/TestApp.h rename to tc/sgx/common/tests/trusted/app/TestApp.h diff --git a/tcs/core/common/tests/trusted/enclave/CMakeLists.txt b/tc/sgx/common/tests/trusted/enclave/CMakeLists.txt similarity index 100% rename from tcs/core/common/tests/trusted/enclave/CMakeLists.txt rename to tc/sgx/common/tests/trusted/enclave/CMakeLists.txt diff --git a/tcs/core/common/tests/trusted/enclave/TestEnclave.config.xml b/tc/sgx/common/tests/trusted/enclave/TestEnclave.config.xml similarity index 100% rename from tcs/core/common/tests/trusted/enclave/TestEnclave.config.xml rename to tc/sgx/common/tests/trusted/enclave/TestEnclave.config.xml diff --git a/tcs/core/common/tests/trusted/enclave/TestEnclave.cpp b/tc/sgx/common/tests/trusted/enclave/TestEnclave.cpp similarity index 100% rename from tcs/core/common/tests/trusted/enclave/TestEnclave.cpp rename to tc/sgx/common/tests/trusted/enclave/TestEnclave.cpp diff --git a/tcs/core/common/tests/trusted/enclave/TestEnclave.edl b/tc/sgx/common/tests/trusted/enclave/TestEnclave.edl similarity index 100% rename from tcs/core/common/tests/trusted/enclave/TestEnclave.edl rename to tc/sgx/common/tests/trusted/enclave/TestEnclave.edl diff --git a/tcs/core/common/tests/trusted/enclave/TestEnclave.h b/tc/sgx/common/tests/trusted/enclave/TestEnclave.h similarity index 100% rename from tcs/core/common/tests/trusted/enclave/TestEnclave.h rename to tc/sgx/common/tests/trusted/enclave/TestEnclave.h diff --git a/tcs/core/common/tests/trusted/enclave/TestEnclave.lds b/tc/sgx/common/tests/trusted/enclave/TestEnclave.lds similarity index 100% rename from tcs/core/common/tests/trusted/enclave/TestEnclave.lds rename to tc/sgx/common/tests/trusted/enclave/TestEnclave.lds diff --git a/tcs/core/common/tests/trusted/enclave/TestEnclave_private.pem b/tc/sgx/common/tests/trusted/enclave/TestEnclave_private.pem similarity index 100% rename from tcs/core/common/tests/trusted/enclave/TestEnclave_private.pem rename to tc/sgx/common/tests/trusted/enclave/TestEnclave_private.pem diff --git a/tcs/core/common/tests/untrusted/TestUntrusted.cpp b/tc/sgx/common/tests/untrusted/TestUntrusted.cpp similarity index 100% rename from tcs/core/common/tests/untrusted/TestUntrusted.cpp rename to tc/sgx/common/tests/untrusted/TestUntrusted.cpp diff --git a/tcs/core/common/timer.h b/tc/sgx/common/timer.h similarity index 100% rename from tcs/core/common/timer.h rename to tc/sgx/common/timer.h diff --git a/tcs/core/common/types.cpp b/tc/sgx/common/types.cpp similarity index 100% rename from tcs/core/common/types.cpp rename to tc/sgx/common/types.cpp diff --git a/tcs/core/common/types.h b/tc/sgx/common/types.h similarity index 100% rename from tcs/core/common/types.h rename to tc/sgx/common/types.h diff --git a/tcs/core/common/utils.cpp b/tc/sgx/common/utils.cpp similarity index 100% rename from tcs/core/common/utils.cpp rename to tc/sgx/common/utils.cpp diff --git a/tcs/core/common/utils.h b/tc/sgx/common/utils.h similarity index 100% rename from tcs/core/common/utils.h rename to tc/sgx/common/utils.h diff --git a/tcs/core/common/work_order_interface/CMakeLists.txt b/tc/sgx/common/work_order_interface/CMakeLists.txt similarity index 100% rename from tcs/core/common/work_order_interface/CMakeLists.txt rename to tc/sgx/common/work_order_interface/CMakeLists.txt diff --git a/tcs/core/common/work_order_interface/work_order_data.cpp b/tc/sgx/common/work_order_interface/work_order_data.cpp similarity index 100% rename from tcs/core/common/work_order_interface/work_order_data.cpp rename to tc/sgx/common/work_order_interface/work_order_data.cpp diff --git a/tcs/core/common/work_order_interface/work_order_data.h b/tc/sgx/common/work_order_interface/work_order_data.h similarity index 100% rename from tcs/core/common/work_order_interface/work_order_data.h rename to tc/sgx/common/work_order_interface/work_order_data.h diff --git a/tcs/core/common/work_order_interface/work_order_processor_interface.h b/tc/sgx/common/work_order_interface/work_order_processor_interface.h similarity index 97% rename from tcs/core/common/work_order_interface/work_order_processor_interface.h rename to tc/sgx/common/work_order_interface/work_order_processor_interface.h index 12a56bd91..d48b314e3 100644 --- a/tcs/core/common/work_order_interface/work_order_processor_interface.h +++ b/tc/sgx/common/work_order_interface/work_order_processor_interface.h @@ -25,7 +25,7 @@ namespace tcf { class WorkOrderProcessorInterface { public: virtual void ProcessWorkOrder( - std::string code_id, + std::string workload_id, const ByteArray& participant_address, const ByteArray& enclave_id, const ByteArray& work_order_id, diff --git a/tcs/core/common/zero.h b/tc/sgx/common/zero.h similarity index 100% rename from tcs/core/common/zero.h rename to tc/sgx/common/zero.h diff --git a/tcs/core/tcs_trusted_worker_manager/enclave/CMakeLists.txt b/tc/sgx/trusted_worker_manager/enclave/CMakeLists.txt similarity index 94% rename from tcs/core/tcs_trusted_worker_manager/enclave/CMakeLists.txt rename to tc/sgx/trusted_worker_manager/enclave/CMakeLists.txt index 6820e49d1..934f4fb9d 100644 --- a/tcs/core/tcs_trusted_worker_manager/enclave/CMakeLists.txt +++ b/tc/sgx/trusted_worker_manager/enclave/CMakeLists.txt @@ -124,8 +124,8 @@ ENDFUNCTION() # XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -FILE(GLOB PROJECT_HEADERS *.h state/*.h ${TCF_CORE_DIR}/common/*.h) -FILE(GLOB PROJECT_SOURCES *.cpp *.c state/*.cpp) +FILE(GLOB PROJECT_HEADERS *.h ${TCF_CORE_DIR}/common/*.h) +FILE(GLOB PROJECT_SOURCES *.cpp *.c) FILE(GLOB PROJECT_EDL enclave.edl) FILE(GLOB PROJECT_CONFIG *.xml) SOURCE_GROUP("Source" FILES ${PROJECT_HEADERS} ${PROJECT_SOURCES} ${PROJECT_EDL}) @@ -141,7 +141,7 @@ INCLUDE_DIRECTORIES(${TCF_CORE_DIR}/common/work_order_interface) INCLUDE_DIRECTORIES(${TCF_CORE_DIR}/common/packages/db_store) INCLUDE_DIRECTORIES(${TCF_CORE_DIR}/common/packages/base64) INCLUDE_DIRECTORIES(${TCF_CORE_DIR}/common/packages/parson) -INCLUDE_DIRECTORIES(${TCF_TOP_DIR}/workloads) +INCLUDE_DIRECTORIES(${TCF_TOP_DIR}/common/sgx_workload) LINK_DIRECTORIES() SGX_EDGE_TRUSTED(${PROJECT_EDL} PROJECT_EDGE_SOURCES) @@ -195,9 +195,9 @@ SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-L,$ENV{SGX_SDK} SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-L,$ENV{SGX_SSL}/lib64") SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-L,$ENV{SGX_SSL}/lib64/release") SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-L,${TCF_CORE_DIR}/common/build") -SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-L,${TCF_TOP_DIR}/workloads/build") -SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-L,${TCF_TOP_DIR}/workloads/build/echo_work_order") -SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-L,${TCF_TOP_DIR}/workloads/build/heart_disease_eval") +SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-L,${TCF_TOP_DIR}/common/sgx_workload/build") +SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-L,${TCF_TOP_DIR}/examples/apps/build/echo/workload") +SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-L,${TCF_TOP_DIR}/examples/apps/build/heart_disease_eval/workload") SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-L,$ENV{SGX_SSL}/lib64") # Remove all the default windows libraries (kernel32, etc) SET(CMAKE_C_STANDARD_LIBRARIES_INIT "") @@ -220,10 +220,10 @@ SGX_SIGN_ENCLAVE(${PROJECT_NAME} ${TCF_ENCLAVE_CODE_SIGN_PEM} ${PROJECT_CONFIG}) TARGET_LINK_LIBRARIES(${PROJECT_NAME} -Wl,--whole-archive -lsgx_tsgxssl -Wl,--no-whole-archive) TARGET_LINK_LIBRARIES(${PROJECT_NAME} -Wl,--whole-archive -l${TRTS_LIBRARY_NAME} -Wl,--no-whole-archive) -TARGET_LINK_LIBRARIES(${PROJECT_NAME} -Wl,--start-group -lttcf-common -ltcf_work_order_interface -lworkloads -lecho_wo -lheart_disease_eval -lsgx_tsgxssl_crypto -lsgx_tstdc -lsgx_tcxx -lsgx_tcrypto -l${SERVICE_LIBRARY_NAME} -Wl,--end-group) +TARGET_LINK_LIBRARIES(${PROJECT_NAME} -Wl,--start-group -lttcf-common -ltcf_work_order_interface -lsgx_workload -lecho_wo -lheart_disease_eval -lsgx_tsgxssl_crypto -lsgx_tstdc -lsgx_tcxx -lsgx_tcrypto -l${SERVICE_LIBRARY_NAME} -Wl,--end-group) TARGET_INCLUDE_DIRECTORIES( ${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${SGX_ENCLAVE_INCLUDE} ${SGX_INCLUDE}) -TARGET_INCLUDE_DIRECTORIES(${PROJECT_NAME} PRIVATE ${TCF_CORE_DIR}/common/packages/db_store ${TCF_TOP_DIR}/workloads) +TARGET_INCLUDE_DIRECTORIES(${PROJECT_NAME} PRIVATE ${TCF_CORE_DIR}/common/packages/db_store ${TCF_TOP_DIR}/examples/apps) ADD_CUSTOM_COMMAND( TARGET ${PROJECT_NAME} diff --git a/tcs/core/tcs_trusted_worker_manager/enclave/auto_handle.h b/tc/sgx/trusted_worker_manager/enclave/auto_handle.h similarity index 100% rename from tcs/core/tcs_trusted_worker_manager/enclave/auto_handle.h rename to tc/sgx/trusted_worker_manager/enclave/auto_handle.h diff --git a/tcs/core/tcs_trusted_worker_manager/enclave/auto_handle_sgx.h b/tc/sgx/trusted_worker_manager/enclave/auto_handle_sgx.h similarity index 100% rename from tcs/core/tcs_trusted_worker_manager/enclave/auto_handle_sgx.h rename to tc/sgx/trusted_worker_manager/enclave/auto_handle_sgx.h diff --git a/tcs/core/tcs_trusted_worker_manager/enclave/base.edl b/tc/sgx/trusted_worker_manager/enclave/base.edl similarity index 100% rename from tcs/core/tcs_trusted_worker_manager/enclave/base.edl rename to tc/sgx/trusted_worker_manager/enclave/base.edl diff --git a/tcs/core/tcs_trusted_worker_manager/enclave/base_enclave.cpp b/tc/sgx/trusted_worker_manager/enclave/base_enclave.cpp similarity index 97% rename from tcs/core/tcs_trusted_worker_manager/enclave/base_enclave.cpp rename to tc/sgx/trusted_worker_manager/enclave/base_enclave.cpp index ec21f960c..805be52c9 100644 --- a/tcs/core/tcs_trusted_worker_manager/enclave/base_enclave.cpp +++ b/tc/sgx/trusted_worker_manager/enclave/base_enclave.cpp @@ -43,8 +43,8 @@ tcf_err_t ecall_Initialize() { tcf_err_t result = TCF_SUCCESS; - // we need to make sure we print a warning if the logging is turned on - // since it can break confidentiality of workorder execution + // We need to make sure we print a warning if the logging is turned on + // since it can break confidentiality of workorder execution. SAFE_LOG(TCF_LOG_CRITICAL, "enclave initialized with debugging turned on"); return result; diff --git a/tcs/core/tcs_trusted_worker_manager/enclave/base_enclave.h b/tc/sgx/trusted_worker_manager/enclave/base_enclave.h similarity index 100% rename from tcs/core/tcs_trusted_worker_manager/enclave/base_enclave.h rename to tc/sgx/trusted_worker_manager/enclave/base_enclave.h diff --git a/tcs/core/tcs_trusted_worker_manager/enclave/db_store.cpp b/tc/sgx/trusted_worker_manager/enclave/db_store.cpp similarity index 100% rename from tcs/core/tcs_trusted_worker_manager/enclave/db_store.cpp rename to tc/sgx/trusted_worker_manager/enclave/db_store.cpp diff --git a/tcs/core/tcs_trusted_worker_manager/enclave/db_store.edl b/tc/sgx/trusted_worker_manager/enclave/db_store.edl similarity index 100% rename from tcs/core/tcs_trusted_worker_manager/enclave/db_store.edl rename to tc/sgx/trusted_worker_manager/enclave/db_store.edl diff --git a/tcs/core/tcs_trusted_worker_manager/enclave/enclave.edl b/tc/sgx/trusted_worker_manager/enclave/enclave.edl similarity index 100% rename from tcs/core/tcs_trusted_worker_manager/enclave/enclave.edl rename to tc/sgx/trusted_worker_manager/enclave/enclave.edl diff --git a/tcs/core/tcs_trusted_worker_manager/enclave/enclave_data.cpp b/tc/sgx/trusted_worker_manager/enclave/enclave_data.cpp similarity index 94% rename from tcs/core/tcs_trusted_worker_manager/enclave/enclave_data.cpp rename to tc/sgx/trusted_worker_manager/enclave/enclave_data.cpp index c4e8a153b..0ef9dc1b6 100644 --- a/tcs/core/tcs_trusted_worker_manager/enclave/enclave_data.cpp +++ b/tc/sgx/trusted_worker_manager/enclave/enclave_data.cpp @@ -1,4 +1,4 @@ -/* Copyright 2018 Intel Corporation +/* Copyright 2019 Intel Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,19 +33,19 @@ // XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX // XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX EnclaveData::EnclaveData(void) { - // do not attempt to catch errors here... let the calling procedure + // Do not attempt to catch errors here... let the calling procedure // handle the constructor errors - // generate private signing key + // Generate private signing key private_signing_key_.Generate(); - // create the public verifying key + // Create the public verifying key public_signing_key_ = private_signing_key_.GetPublicKey(); - // generate private encryption key + // Generate private encryption key private_encryption_key_.Generate(); - // create the public encryption key + // Create the public encryption key public_encryption_key_ = private_encryption_key_.GetPublicKey(); SerializePrivateData(); @@ -60,7 +60,7 @@ EnclaveData::EnclaveData(const uint8_t* inSealedData) { uint32_t decrypted_size = sgx_get_encrypt_txt_len(reinterpret_cast(inSealedData)); - // need to check for error + // Need to check for error std::vector decrypted_data; decrypted_data.resize(decrypted_size); @@ -90,7 +90,7 @@ void EnclaveData::DeserializeSealedData(const std::string& inSerializedEnclaveDa JSON_Object* keystore_object = json_value_get_object(parsed); tcf::error::ThrowIfNull(keystore_object, "Failed to parse the key store object"); - // public signing key + // Public signing key pvalue = json_object_dotget_string(keystore_object, "SigningKey.PublicKey"); tcf::error::ThrowIf( !pvalue, "Failed to retrieve public signing key from the key store"); @@ -98,7 +98,7 @@ void EnclaveData::DeserializeSealedData(const std::string& inSerializedEnclaveDa svalue.assign(pvalue); public_signing_key_.Deserialize(svalue); - // private signing key + // Private signing key pvalue = json_object_dotget_string(keystore_object, "SigningKey.PrivateKey"); tcf::error::ThrowIf( !pvalue, "Failed to retrieve private signing key from the key store"); @@ -106,7 +106,7 @@ void EnclaveData::DeserializeSealedData(const std::string& inSerializedEnclaveDa svalue.assign(pvalue); private_signing_key_.Deserialize(svalue); - // public encryption key + // Public encryption key pvalue = json_object_dotget_string(keystore_object, "EncryptionKey.PublicKey"); tcf::error::ThrowIf( !pvalue, "Failed to retrieve public encryption key from the key store"); @@ -114,7 +114,7 @@ void EnclaveData::DeserializeSealedData(const std::string& inSerializedEnclaveDa svalue.assign(pvalue); public_encryption_key_.Deserialize(svalue); - // private encryption key + // Private encryption key pvalue = json_object_dotget_string(keystore_object, "EncryptionKey.PrivateKey"); tcf::error::ThrowIf( !pvalue, "Failed to retrieve private encryption key from the key store"); @@ -136,7 +136,7 @@ void EnclaveData::SerializePrivateData(void) { JSON_Object* dataObject = json_value_get_object(dataValue); tcf::error::ThrowIfNull(dataObject, "Failed to retrieve serialization object"); - // private signing key + // Private signing key std::string b64_private_signing_key = private_signing_key_.Serialize(); tcf::error::ThrowIf( b64_private_signing_key.empty(), "failed to serialize the private signing key"); @@ -146,7 +146,7 @@ void EnclaveData::SerializePrivateData(void) { tcf::error::ThrowIf( jret != JSONSuccess, "enclave data serialization failed on private signing key"); - // public signing key + // Public signing key std::string b64_public_signing_key = public_signing_key_.Serialize(); tcf::error::ThrowIf( b64_public_signing_key.empty(), "failed to serialize the public signing key"); @@ -156,7 +156,7 @@ void EnclaveData::SerializePrivateData(void) { tcf::error::ThrowIf( jret != JSONSuccess, "enclave data serialization failed on public signing key"); - // private encryption key + // Private encryption key std::string b64_private_encryption_key = private_encryption_key_.Serialize(); tcf::error::ThrowIf( b64_private_encryption_key.empty(), "failed to serialize the private encryption key"); @@ -166,7 +166,7 @@ void EnclaveData::SerializePrivateData(void) { tcf::error::ThrowIf( jret != JSONSuccess, "enclave data serialization failed on private encryption key"); - // public encryption key + // Public encryption key std::string b64_public_encryption_key = public_encryption_key_.Serialize(); tcf::error::ThrowIf( b64_public_encryption_key.empty(), "failed to serialize the public encryption key"); @@ -201,7 +201,7 @@ void EnclaveData::SerializePublicData(void) { JSON_Object* dataObject = json_value_get_object(dataValue); tcf::error::ThrowIfNull(dataObject, "Failed to retrieve serialization object"); - // public signing key + // Public signing key std::string b64_public_signing_key = public_signing_key_.Serialize(); tcf::error::ThrowIf( b64_public_signing_key.empty(), "failed to serialize the public signing key"); @@ -210,7 +210,7 @@ void EnclaveData::SerializePublicData(void) { tcf::error::ThrowIf( jret != JSONSuccess, "enclave data serialization failed on public signing key"); - // public encryption key + // Public encryption key std::string b64_public_encryption_key = public_encryption_key_.Serialize(); tcf::error::ThrowIf( b64_public_encryption_key.empty(), "failed to serialize the public encryption key"); diff --git a/tcs/core/tcs_trusted_worker_manager/enclave/enclave_data.h b/tc/sgx/trusted_worker_manager/enclave/enclave_data.h similarity index 96% rename from tcs/core/tcs_trusted_worker_manager/enclave/enclave_data.h rename to tc/sgx/trusted_worker_manager/enclave/enclave_data.h index f4463cccd..5af6e815c 100644 --- a/tcs/core/tcs_trusted_worker_manager/enclave/enclave_data.h +++ b/tc/sgx/trusted_worker_manager/enclave/enclave_data.h @@ -61,9 +61,9 @@ class EnclaveData { std::string serialized_public_data_; public: - // we need some way to compute the required size so the client can + // We need some way to compute the required size so the client can // allocated storage for the sealed data. There are a number of ways - // to do this; for now, the constant will be good enough + // to do this; for now, the constant will be good enough. static const size_t cMaxSealedDataSize = 8192; static const size_t cMaxPublicDataSize = 4096; diff --git a/tcs/core/tcs_trusted_worker_manager/enclave/enclave_utils.cpp b/tc/sgx/trusted_worker_manager/enclave/enclave_utils.cpp similarity index 100% rename from tcs/core/tcs_trusted_worker_manager/enclave/enclave_utils.cpp rename to tc/sgx/trusted_worker_manager/enclave/enclave_utils.cpp diff --git a/tcs/core/tcs_trusted_worker_manager/enclave/enclave_utils.h b/tc/sgx/trusted_worker_manager/enclave/enclave_utils.h similarity index 100% rename from tcs/core/tcs_trusted_worker_manager/enclave/enclave_utils.h rename to tc/sgx/trusted_worker_manager/enclave/enclave_utils.h diff --git a/tcs/core/tcs_trusted_worker_manager/enclave/signup.edl b/tc/sgx/trusted_worker_manager/enclave/signup.edl similarity index 100% rename from tcs/core/tcs_trusted_worker_manager/enclave/signup.edl rename to tc/sgx/trusted_worker_manager/enclave/signup.edl diff --git a/tcs/core/tcs_trusted_worker_manager/enclave/signup_enclave.cpp b/tc/sgx/trusted_worker_manager/enclave/signup_enclave.cpp similarity index 99% rename from tcs/core/tcs_trusted_worker_manager/enclave/signup_enclave.cpp rename to tc/sgx/trusted_worker_manager/enclave/signup_enclave.cpp index d327dbe39..fa6a386cf 100644 --- a/tcs/core/tcs_trusted_worker_manager/enclave/signup_enclave.cpp +++ b/tc/sgx/trusted_worker_manager/enclave/signup_enclave.cpp @@ -136,7 +136,7 @@ tcf_err_t ecall_CreateEnclaveData(const sgx_target_info_t* inTargetInfo, inAllocatedSealedEnclaveDataSize < enclaveData.get_sealed_data_size(), "Sealed enclave data buffer size is too small"); - // pass back the actual size of the enclave data + // Pass back the actual size of the enclave data (*outPublicEnclaveDataSize) = enclaveData.get_public_data_size(); (*outSealedEnclaveDataSize) = enclaveData.get_sealed_data_size(); diff --git a/tcs/core/tcs_trusted_worker_manager/enclave/signup_enclave.h b/tc/sgx/trusted_worker_manager/enclave/signup_enclave.h similarity index 100% rename from tcs/core/tcs_trusted_worker_manager/enclave/signup_enclave.h rename to tc/sgx/trusted_worker_manager/enclave/signup_enclave.h diff --git a/tcs/core/tcs_trusted_worker_manager/enclave/tcf_enclave.config.xml b/tc/sgx/trusted_worker_manager/enclave/tcf_enclave.config.xml similarity index 100% rename from tcs/core/tcs_trusted_worker_manager/enclave/tcf_enclave.config.xml rename to tc/sgx/trusted_worker_manager/enclave/tcf_enclave.config.xml diff --git a/tcs/core/tcs_trusted_worker_manager/enclave/tcf_enclave.lds b/tc/sgx/trusted_worker_manager/enclave/tcf_enclave.lds similarity index 100% rename from tcs/core/tcs_trusted_worker_manager/enclave/tcf_enclave.lds rename to tc/sgx/trusted_worker_manager/enclave/tcf_enclave.lds diff --git a/tcs/core/tcs_trusted_worker_manager/enclave/work_order_data_handler.cpp b/tc/sgx/trusted_worker_manager/enclave/work_order_data_handler.cpp similarity index 99% rename from tcs/core/tcs_trusted_worker_manager/enclave/work_order_data_handler.cpp rename to tc/sgx/trusted_worker_manager/enclave/work_order_data_handler.cpp index 86e199b88..9a731e2de 100644 --- a/tcs/core/tcs_trusted_worker_manager/enclave/work_order_data_handler.cpp +++ b/tc/sgx/trusted_worker_manager/enclave/work_order_data_handler.cpp @@ -134,7 +134,7 @@ namespace tcf { } void WorkOrderDataHandler::VerifyInputHash(ByteArray input_data, ByteArray input_hash) { - // do nothing at the phase 1 + // Do nothing at the phase 1 } void WorkOrderDataHandler::DecryptInputData(ByteArray encrypted_input_data, std::string iv_str) { diff --git a/tcs/core/tcs_trusted_worker_manager/enclave/work_order_data_handler.h b/tc/sgx/trusted_worker_manager/enclave/work_order_data_handler.h similarity index 100% rename from tcs/core/tcs_trusted_worker_manager/enclave/work_order_data_handler.h rename to tc/sgx/trusted_worker_manager/enclave/work_order_data_handler.h diff --git a/tcs/core/tcs_trusted_worker_manager/enclave/work_order_enclave.cpp b/tc/sgx/trusted_worker_manager/enclave/work_order_enclave.cpp similarity index 98% rename from tcs/core/tcs_trusted_worker_manager/enclave/work_order_enclave.cpp rename to tc/sgx/trusted_worker_manager/enclave/work_order_enclave.cpp index a67cecd16..9475cb600 100644 --- a/tcs/core/tcs_trusted_worker_manager/enclave/work_order_enclave.cpp +++ b/tc/sgx/trusted_worker_manager/enclave/work_order_enclave.cpp @@ -69,7 +69,7 @@ tcf_err_t ecall_HandleWorkOrderRequest(const uint8_t* inSealedSignupData, std::string wo_string(request.begin(), request.end()); last_result = wo_processor.Process(enclaveData, wo_string); - // save the response and return the size of the buffer required for it + // Save the response and return the size of the buffer required for it (*outSerializedResponseSize) = last_result.size(); } catch (tcf::error::Error& e) { SAFE_LOG(TCF_LOG_ERROR, diff --git a/tcs/core/tcs_trusted_worker_manager/enclave/work_order_enclave.h b/tc/sgx/trusted_worker_manager/enclave/work_order_enclave.h similarity index 100% rename from tcs/core/tcs_trusted_worker_manager/enclave/work_order_enclave.h rename to tc/sgx/trusted_worker_manager/enclave/work_order_enclave.h diff --git a/tcs/core/tcs_trusted_worker_manager/enclave/work_order_processor.cpp b/tc/sgx/trusted_worker_manager/enclave/work_order_processor.cpp similarity index 90% rename from tcs/core/tcs_trusted_worker_manager/enclave/work_order_processor.cpp rename to tc/sgx/trusted_worker_manager/enclave/work_order_processor.cpp index ce3bd3b53..7244ab309 100644 --- a/tcs/core/tcs_trusted_worker_manager/enclave/work_order_processor.cpp +++ b/tc/sgx/trusted_worker_manager/enclave/work_order_processor.cpp @@ -87,7 +87,7 @@ namespace tcf { "workerId", "invalid request; failed to retrieve worker id"); - work_load_id = GetJsonStr( + workload_id = GetJsonStr( params_object, "workloadId", "invalid request; failed to retrieve work load id"); @@ -125,7 +125,7 @@ namespace tcf { encrypted_request_hash = GetJsonStr( params_object, "encryptedRequestHash", - "invalid request; failed to retrieve requester nonce"); + "invalid request; failed to retrieve encrypted request hash"); requester_signature = GetJsonStr( params_object, @@ -177,12 +177,18 @@ namespace tcf { JSON_Object* result = json_object_get_object(resp, "result"); tcf::error::ThrowIfNull(result, "failed to serialize the result"); - JsonSetStr(result, "workOrderId", work_order_id.c_str(), "failed to serialize work order id"); - JsonSetStr(result, "workloadId", work_load_id.c_str(), "failed to serialize workload id"); - JsonSetStr(result, "workerId", worker_id.c_str(), "failed to serialize worker id"); - JsonSetStr(result, "requesterId", requester_id.c_str(), "failed to serialize requester id"); - JsonSetStr(result, "workerNonce", worker_nonce.c_str(), "failed to serialize worker nonce"); - JsonSetStr(result, "workerSignature", worker_signature.c_str(), "failed to serialize worker signature"); + JsonSetStr(result, "workOrderId", work_order_id.c_str(), + "failed to serialize work order id"); + JsonSetStr(result, "workloadId", workload_id.c_str(), + "failed to serialize workload id"); + JsonSetStr(result, "workerId", worker_id.c_str(), + "failed to serialize worker id"); + JsonSetStr(result, "requesterId", requester_id.c_str(), + "failed to serialize requester id"); + JsonSetStr(result, "workerNonce", worker_nonce.c_str(), + "failed to serialize worker nonce"); + JsonSetStr(result, "workerSignature", worker_signature.c_str(), + "failed to serialize worker signature"); jret = json_object_set_value(result, "outData", json_value_init_array()); tcf::error::ThrowIf( @@ -194,7 +200,7 @@ namespace tcf { for (auto out_data : data_items_out) out_data.Pack(data_array); - // serialize the resulting json + // Serialize the resulting json size_t serializedSize = json_serialization_size(resp_value); ByteArray serialized_response; serialized_response.resize(serializedSize); @@ -213,37 +219,37 @@ namespace tcf { if (data_items_in.size() > 0) { // data_items_in vector is sorted based out of index - // data at index 0 is the identifier of the workorder - WorkOrderDataHandler& code_data_item = data_items_in.at(0); - // Vector is sorted the first object should have index 0 - if (code_data_item.workorder_data.index == 0) { - for (auto d : data_items_in) { - in_wo_data.emplace_back(d.workorder_data.index, d.workorder_data.decrypted_data); - } - - for (auto d : data_items_out) { - out_wo_data.emplace_back(d.workorder_data.index, d.workorder_data.decrypted_data); - } - - WorkloadProcessor processor; - std::string workload_type = ByteArrayToStr(code_data_item.workorder_data.decrypted_data); - processor.ProcessWorkOrder( + for (auto d : data_items_in) { + in_wo_data.emplace_back(d.workorder_data.index, + d.workorder_data.decrypted_data); + } + + for (auto d : data_items_out) { + out_wo_data.emplace_back(d.workorder_data.index, + d.workorder_data.decrypted_data); + } + + WorkloadProcessor processor; + // Convert workload_id from hex string to string + ByteArray workload_bytes = HexStringToBinary(workload_id); + std::string workload_type(workload_bytes.begin(), workload_bytes.end()); + processor.ProcessWorkOrder( workload_type, StrToByteArray(requester_id), StrToByteArray(worker_id), StrToByteArray(work_order_id), in_wo_data, out_wo_data); - return out_wo_data; - } + return out_wo_data; } - tcf::error::RuntimeError("Work Order inData not Found\n"); + tcf::error::RuntimeError("Work order inData not found\n"); return out_wo_data; } ByteArray WorkOrderProcessor::ComputeRequestHash() { ByteArray concat_hashes; - std::string concat_string = requester_nonce + work_order_id + worker_id + work_load_id + requester_id; + std::string concat_string = requester_nonce + work_order_id + + worker_id + workload_id + requester_id; ByteArray hash_1 = tcf::crypto::ComputeMessageHash(StrToByteArray(concat_string)); ByteArray hash_data; @@ -330,7 +336,8 @@ namespace tcf { ByteArray concat_hashes; ByteArray nonce = tcf::crypto::RandomBitString(16); worker_nonce = base64_encode(tcf::crypto::ComputeMessageHash(nonce)); - std::string concat_string = worker_nonce + work_order_id + worker_id + work_load_id + requester_id; + std::string concat_string = worker_nonce + work_order_id + + worker_id + workload_id + requester_id; std::string hash_1 = base64_encode(tcf::crypto::ComputeMessageHash(StrToByteArray(concat_string))); @@ -402,7 +409,7 @@ namespace tcf { JsonSetNumber(error, "code", err_code, "failed to serialize error code"); JsonSetStr(error, "message", err_message, "failed to serialize error message"); - // serialize the resulting json + // Serialize the resulting json size_t serializedSize = json_serialization_size(resp_value); ByteArray serialized_response; serialized_response.resize(serializedSize); diff --git a/tcs/core/tcs_trusted_worker_manager/enclave/work_order_processor.h b/tc/sgx/trusted_worker_manager/enclave/work_order_processor.h similarity index 98% rename from tcs/core/tcs_trusted_worker_manager/enclave/work_order_processor.h rename to tc/sgx/trusted_worker_manager/enclave/work_order_processor.h index 28e81405f..6545a294d 100644 --- a/tcs/core/tcs_trusted_worker_manager/enclave/work_order_processor.h +++ b/tc/sgx/trusted_worker_manager/enclave/work_order_processor.h @@ -55,7 +55,7 @@ namespace tcf { std::string notify_uri; std::string work_order_id; std::string worker_id; - std::string work_load_id; + std::string workload_id; std::string requester_id; std::string worker_encryption_key; std::string data_encryption_algorithm; diff --git a/tcs/core/tcs_trusted_worker_manager/enclave/worker.cpp b/tc/sgx/trusted_worker_manager/enclave/worker.cpp similarity index 100% rename from tcs/core/tcs_trusted_worker_manager/enclave/worker.cpp rename to tc/sgx/trusted_worker_manager/enclave/worker.cpp diff --git a/tcs/core/tcs_trusted_worker_manager/enclave/worker.h b/tc/sgx/trusted_worker_manager/enclave/worker.h similarity index 100% rename from tcs/core/tcs_trusted_worker_manager/enclave/worker.h rename to tc/sgx/trusted_worker_manager/enclave/worker.h diff --git a/tcs/core/tcs_trusted_worker_manager/enclave/workload.edl b/tc/sgx/trusted_worker_manager/enclave/workload.edl similarity index 95% rename from tcs/core/tcs_trusted_worker_manager/enclave/workload.edl rename to tc/sgx/trusted_worker_manager/enclave/workload.edl index 4ff616ec2..1b05725fc 100644 --- a/tcs/core/tcs_trusted_worker_manager/enclave/workload.edl +++ b/tc/sgx/trusted_worker_manager/enclave/workload.edl @@ -19,7 +19,7 @@ enclave { include "sgx_tcrypto.h" trusted { - // inSerializedRequest is binary encoding of the encrypted request + // inSerializedRequest is a binary encoding of the encrypted request // outSerializedResponseSize is the computed size of the response public tcf_err_t ecall_HandleWorkOrderRequest( [in, size=inSealedSignupDataSize] const uint8_t* inSealedSignupData, diff --git a/tcs/core/tcs_trusted_worker_manager/enclave_wrapper/base.cpp b/tc/sgx/trusted_worker_manager/enclave_wrapper/base.cpp similarity index 98% rename from tcs/core/tcs_trusted_worker_manager/enclave_wrapper/base.cpp rename to tc/sgx/trusted_worker_manager/enclave_wrapper/base.cpp index 49d90ce6f..cf999e7bb 100644 --- a/tcs/core/tcs_trusted_worker_manager/enclave_wrapper/base.cpp +++ b/tc/sgx/trusted_worker_manager/enclave_wrapper/base.cpp @@ -138,9 +138,9 @@ size_t tcf::enclave_api::base::GetEnclaveQuoteSize() { // XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX size_t tcf::enclave_api::base::GetSignatureSize() { - // this is the size of the byte array required for the signature - // fixed constant for now until there is one we can get from the - // crypto library + // This is the size of the byte array required for the signature. + // Fixed constant for now until there is one we can get from the + // crypto library. return tcf::crypto::constants::MAX_SIG_SIZE; } diff --git a/tcs/core/tcs_trusted_worker_manager/enclave_wrapper/base.h b/tc/sgx/trusted_worker_manager/enclave_wrapper/base.h similarity index 96% rename from tcs/core/tcs_trusted_worker_manager/enclave_wrapper/base.h rename to tc/sgx/trusted_worker_manager/enclave_wrapper/base.h index df990d52a..c57c2e71a 100644 --- a/tcs/core/tcs_trusted_worker_manager/enclave_wrapper/base.h +++ b/tc/sgx/trusted_worker_manager/enclave_wrapper/base.h @@ -93,7 +93,7 @@ namespace tcf { outEnclaveBasename - A pointer to a buffer that upon return will contain the hex encoded enclave basename. inEnclaveBasenameLength - The size of the buffer pointed to by - outEnclaveBasename. The value to provide for this parameter may + outEnclaveBasename. The value to provide for this parameter may be obtained by calling GetEnclaveBasenameSize(). */ tcf_err_t GetEnclaveCharacteristics( @@ -101,7 +101,7 @@ namespace tcf { HexEncodedString& outEnclaveBasename); /* - takes in the results from the IAS server and + Takes in the results from the IAS server and stores the revocation list for future processing inSignatureRevocationList - A string containing the signature diff --git a/tcs/core/tcs_trusted_worker_manager/enclave_wrapper/db_store.cpp b/tc/sgx/trusted_worker_manager/enclave_wrapper/db_store.cpp similarity index 86% rename from tcs/core/tcs_trusted_worker_manager/enclave_wrapper/db_store.cpp rename to tc/sgx/trusted_worker_manager/enclave_wrapper/db_store.cpp index a096a7149..368376758 100644 --- a/tcs/core/tcs_trusted_worker_manager/enclave_wrapper/db_store.cpp +++ b/tc/sgx/trusted_worker_manager/enclave_wrapper/db_store.cpp @@ -86,4 +86,13 @@ void db_store_put( ThrowTCFError(presult); } // XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX - +void db_store_del( + const std::string& table_b64, + const std::string& key_b64, + const std::string& value_b64) { + ByteArray raw_key(key_b64.begin(), key_b64.end()); + ByteArray raw_value(value_b64.begin(), value_b64.end()); + tcf_err_t presult = tcf::db_store::db_store_del(table_b64, raw_key, raw_value); + ThrowTCFError(presult); +} +// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX diff --git a/tcs/core/tcs_trusted_worker_manager/enclave_wrapper/db_store.h b/tc/sgx/trusted_worker_manager/enclave_wrapper/db_store.h similarity index 83% rename from tcs/core/tcs_trusted_worker_manager/enclave_wrapper/db_store.h rename to tc/sgx/trusted_worker_manager/enclave_wrapper/db_store.h index 0f74b7fa4..8b3bf63b2 100644 --- a/tcs/core/tcs_trusted_worker_manager/enclave_wrapper/db_store.h +++ b/tc/sgx/trusted_worker_manager/enclave_wrapper/db_store.h @@ -76,4 +76,21 @@ void db_store_put( const std::string& table_b64, const std::string& key_b64, const std::string& value_b64); + +// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +/** + * Deletes a key->value pair from the database store + * + * @param table_b64 base64 encode table name + * @param key_b64 base64 encoded key string + * @param value_b64 base64 encoded value string + * + * @return + * Success: void/no return + * Failure: throws exception + */ +void db_store_del( + const std::string& table_b64, + const std::string& key_b64, + const std::string& value_b64); // XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX diff --git a/tcs/core/tcs_trusted_worker_manager/enclave_wrapper/enclave.cpp b/tc/sgx/trusted_worker_manager/enclave_wrapper/enclave.cpp similarity index 98% rename from tcs/core/tcs_trusted_worker_manager/enclave_wrapper/enclave.cpp rename to tc/sgx/trusted_worker_manager/enclave_wrapper/enclave.cpp index 7e470b231..27d0185fe 100644 --- a/tcs/core/tcs_trusted_worker_manager/enclave_wrapper/enclave.cpp +++ b/tc/sgx/trusted_worker_manager/enclave_wrapper/enclave.cpp @@ -70,7 +70,7 @@ namespace tcf { tcf::error::ThrowSgxError(ret, "Failed to get SGX quote size."); this->quoteSize = size; - // initialize the targetinfo and epid variables + // Initialize the targetinfo and epid variables ret = g_Enclave[0].CallSgx([this] () { return sgx_init_quote(&this->reportTargetInfo, &this->epidGroupId); }); @@ -110,8 +110,8 @@ namespace tcf { // XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX void Enclave::Unload() { if (this->enclaveId) { - // no power or busy retries here.... - // we don't want to reinitialize just to shutdown. + // No power or busy retries here.... + // We don't want to reinitialize just to shutdown. sgx_destroy_enclave(this->enclaveId); this->enclaveId = 0; } @@ -121,13 +121,13 @@ namespace tcf { void Enclave::GetEpidGroup( sgx_epid_group_id_t* outEpidGroup) { sgx_status_t ret; - // retrieve epid by calling init quote + // Retrieve epid by calling init quote ret = g_Enclave[0].CallSgx([this] () { return sgx_init_quote(&this->reportTargetInfo, &this->epidGroupId); }); tcf::error::ThrowSgxError(ret, "Failed to get epid group id from init_quote"); - // copy epid group into output parameter + // Copy epid group into output parameter memcpy_s( outEpidGroup, sizeof(sgx_epid_group_id_t), @@ -188,7 +188,7 @@ namespace tcf { this->ThrowTCFError(tcfRet); // Properly size a buffer to receive an enclave quote and then - // retrieve it. The enclave quote contains the basename. + // retrieve it. The enclave quote contains the basename. ByteArray enclaveQuoteBuffer(this->quoteSize); sgx_quote_t* enclaveQuote = reinterpret_cast(&enclaveQuoteBuffer[0]); diff --git a/tcs/core/tcs_trusted_worker_manager/enclave_wrapper/enclave.h b/tc/sgx/trusted_worker_manager/enclave_wrapper/enclave.h similarity index 100% rename from tcs/core/tcs_trusted_worker_manager/enclave_wrapper/enclave.h rename to tc/sgx/trusted_worker_manager/enclave_wrapper/enclave.h diff --git a/tcs/core/tcs_trusted_worker_manager/enclave_wrapper/enclave_info.cpp b/tc/sgx/trusted_worker_manager/enclave_wrapper/enclave_info.cpp similarity index 100% rename from tcs/core/tcs_trusted_worker_manager/enclave_wrapper/enclave_info.cpp rename to tc/sgx/trusted_worker_manager/enclave_wrapper/enclave_info.cpp diff --git a/tcs/core/tcs_trusted_worker_manager/enclave_wrapper/enclave_info.h b/tc/sgx/trusted_worker_manager/enclave_wrapper/enclave_info.h similarity index 100% rename from tcs/core/tcs_trusted_worker_manager/enclave_wrapper/enclave_info.h rename to tc/sgx/trusted_worker_manager/enclave_wrapper/enclave_info.h diff --git a/tcs/core/tcs_trusted_worker_manager/enclave_wrapper/enclave_queue.cpp b/tc/sgx/trusted_worker_manager/enclave_wrapper/enclave_queue.cpp similarity index 100% rename from tcs/core/tcs_trusted_worker_manager/enclave_wrapper/enclave_queue.cpp rename to tc/sgx/trusted_worker_manager/enclave_wrapper/enclave_queue.cpp diff --git a/tcs/core/tcs_trusted_worker_manager/enclave_wrapper/enclave_queue.h b/tc/sgx/trusted_worker_manager/enclave_wrapper/enclave_queue.h similarity index 100% rename from tcs/core/tcs_trusted_worker_manager/enclave_wrapper/enclave_queue.h rename to tc/sgx/trusted_worker_manager/enclave_wrapper/enclave_queue.h diff --git a/tcs/core/tcs_trusted_worker_manager/enclave_wrapper/log.cpp b/tc/sgx/trusted_worker_manager/enclave_wrapper/log.cpp similarity index 100% rename from tcs/core/tcs_trusted_worker_manager/enclave_wrapper/log.cpp rename to tc/sgx/trusted_worker_manager/enclave_wrapper/log.cpp diff --git a/tcs/core/tcs_trusted_worker_manager/enclave_wrapper/log.h b/tc/sgx/trusted_worker_manager/enclave_wrapper/log.h similarity index 100% rename from tcs/core/tcs_trusted_worker_manager/enclave_wrapper/log.h rename to tc/sgx/trusted_worker_manager/enclave_wrapper/log.h diff --git a/tcs/core/tcs_trusted_worker_manager/enclave_wrapper/ocall.cpp b/tc/sgx/trusted_worker_manager/enclave_wrapper/ocall.cpp similarity index 100% rename from tcs/core/tcs_trusted_worker_manager/enclave_wrapper/ocall.cpp rename to tc/sgx/trusted_worker_manager/enclave_wrapper/ocall.cpp diff --git a/tcs/core/tcs_trusted_worker_manager/enclave_wrapper/signup.cpp b/tc/sgx/trusted_worker_manager/enclave_wrapper/signup.cpp similarity index 96% rename from tcs/core/tcs_trusted_worker_manager/enclave_wrapper/signup.cpp rename to tc/sgx/trusted_worker_manager/enclave_wrapper/signup.cpp index 19e3379c6..e2848ddae 100644 --- a/tcs/core/tcs_trusted_worker_manager/enclave_wrapper/signup.cpp +++ b/tc/sgx/trusted_worker_manager/enclave_wrapper/signup.cpp @@ -39,7 +39,7 @@ static size_t CalculateSealedEnclaveDataSize(void) { tcf_err_t presult = TCF_SUCCESS; sgx_status_t sresult; - // get the enclave id for passing into the ecall + // Get the enclave id for passing into the ecall sgx_enclave_id_t enclaveid = g_Enclave[0].GetEnclaveId(); sresult = @@ -68,7 +68,7 @@ static size_t CalculatePublicEnclaveDataSize(void) { tcf_err_t presult = TCF_SUCCESS; sgx_status_t sresult; - // get the enclave id for passing into the ecall + // Get the enclave id for passing into the ecall sgx_enclave_id_t enclaveid = g_Enclave[0].GetEnclaveId(); sresult = @@ -106,7 +106,7 @@ tcf_err_t tcf::enclave_api::enclave_data::CreateEnclaveData( ByteArray sealed_enclave_data_buffer(CalculateSealedEnclaveDataSize()); - // get the enclave id for passing into the ecall + // Get the enclave id for passing into the ecall sgx_enclave_id_t enclaveid = g_Enclave[0].GetEnclaveId(); // We need target info in order to create signup data report @@ -155,14 +155,14 @@ tcf_err_t tcf::enclave_api::enclave_data::CreateEnclaveData( tcf::error::ThrowSgxError(sresult, "SGX enclave call failed (ecall_CreateSignupData), failed to create signup data"); g_Enclave[0].ThrowTCFError(presult); - // reset the size of the public data + // Reset the size of the public data outPublicEnclaveData.resize(computed_public_enclave_data_size); - // reset the size of the enclave data and encode it + // Reset the size of the enclave data and encode it sealed_enclave_data_buffer.resize(computed_sealed_enclave_data_size); outSealedEnclaveData = ByteArrayToBase64EncodedString(sealed_enclave_data_buffer); - // take the report generated and create a quote for it, encode it + // Take the report generated and create a quote for it, encode it size_t quote_size = tcf::enclave_api::base::GetEnclaveQuoteSize(); ByteArray enclave_quote_buffer(quote_size); g_Enclave[0].CreateQuoteFromReport(&enclave_report, enclave_quote_buffer); diff --git a/tcs/core/tcs_trusted_worker_manager/enclave_wrapper/signup.h b/tc/sgx/trusted_worker_manager/enclave_wrapper/signup.h similarity index 100% rename from tcs/core/tcs_trusted_worker_manager/enclave_wrapper/signup.h rename to tc/sgx/trusted_worker_manager/enclave_wrapper/signup.h diff --git a/tcs/core/tcs_trusted_worker_manager/enclave_wrapper/signup_info.cpp b/tc/sgx/trusted_worker_manager/enclave_wrapper/signup_info.cpp similarity index 97% rename from tcs/core/tcs_trusted_worker_manager/enclave_wrapper/signup_info.cpp rename to tc/sgx/trusted_worker_manager/enclave_wrapper/signup_info.cpp index b346b5fcb..e7bde8856 100644 --- a/tcs/core/tcs_trusted_worker_manager/enclave_wrapper/signup_info.cpp +++ b/tc/sgx/trusted_worker_manager/enclave_wrapper/signup_info.cpp @@ -159,7 +159,7 @@ std::map CreateEnclaveData( // PyLog(TCF_LOG_DEBUG, public_enclave_data.str().c_str()); - // parse the json and save the verifying and encryption keys + // Parse the json and save the verifying and encryption keys std::string verifying_key; std::string encryption_key; @@ -169,7 +169,7 @@ std::map CreateEnclaveData( encryption_key); ThrowTCFError(presult); - // save the information + // Save the information std::map result; result["verifying_key"] = verifying_key; result["encryption_key"] = encryption_key; @@ -190,7 +190,7 @@ std::map UnsealEnclaveData( public_enclave_data); ThrowTCFError(presult); - // parse the json and save the verifying and encryption keys + // Parse the json and save the verifying and encryption keys std::string verifying_key; std::string encryption_key; diff --git a/tcs/core/tcs_trusted_worker_manager/enclave_wrapper/signup_info.h b/tc/sgx/trusted_worker_manager/enclave_wrapper/signup_info.h similarity index 100% rename from tcs/core/tcs_trusted_worker_manager/enclave_wrapper/signup_info.h rename to tc/sgx/trusted_worker_manager/enclave_wrapper/signup_info.h diff --git a/tcs/core/tcs_trusted_worker_manager/enclave_wrapper/swig_utils.cpp b/tc/sgx/trusted_worker_manager/enclave_wrapper/swig_utils.cpp similarity index 100% rename from tcs/core/tcs_trusted_worker_manager/enclave_wrapper/swig_utils.cpp rename to tc/sgx/trusted_worker_manager/enclave_wrapper/swig_utils.cpp diff --git a/tcs/core/tcs_trusted_worker_manager/enclave_wrapper/swig_utils.h b/tc/sgx/trusted_worker_manager/enclave_wrapper/swig_utils.h similarity index 100% rename from tcs/core/tcs_trusted_worker_manager/enclave_wrapper/swig_utils.h rename to tc/sgx/trusted_worker_manager/enclave_wrapper/swig_utils.h diff --git a/tcs/core/tcs_trusted_worker_manager/enclave_wrapper/tcf_enclave.h b/tc/sgx/trusted_worker_manager/enclave_wrapper/tcf_enclave.h similarity index 100% rename from tcs/core/tcs_trusted_worker_manager/enclave_wrapper/tcf_enclave.h rename to tc/sgx/trusted_worker_manager/enclave_wrapper/tcf_enclave.h diff --git a/tcs/core/tcs_trusted_worker_manager/enclave_wrapper/work_order.cpp b/tc/sgx/trusted_worker_manager/enclave_wrapper/work_order.cpp similarity index 96% rename from tcs/core/tcs_trusted_worker_manager/enclave_wrapper/work_order.cpp rename to tc/sgx/trusted_worker_manager/enclave_wrapper/work_order.cpp index 110920f77..94bd38262 100644 --- a/tcs/core/tcs_trusted_worker_manager/enclave_wrapper/work_order.cpp +++ b/tc/sgx/trusted_worker_manager/enclave_wrapper/work_order.cpp @@ -40,9 +40,9 @@ tcf_err_t tcf::enclave_api::workorder::HandleWorkOrderRequest( ByteArray sealed_enclave_data = Base64EncodedStringToByteArray(inSealedEnclaveData); ByteArray serialized_request = Base64EncodedStringToByteArray(inSerializedRequest); - // xxxxx call the enclave + // xxxxx Call the enclave - /// get the enclave id for passing into the ecall + // Get the enclave id for passing into the ecall sgx_enclave_id_t enclaveid = g_Enclave[enclaveIndex].GetEnclaveId(); tcf_err_t presult = TCF_SUCCESS; @@ -98,9 +98,9 @@ tcf_err_t tcf::enclave_api::workorder::GetSerializedResponse( ByteArray serialized_response(inSerializedResponseSize); ByteArray sealed_enclave_data = Base64EncodedStringToByteArray(inSealedEnclaveData); - // xxxxx call the enclave + // xxxxx Call the enclave - /// get the enclave id for passing into the ecall + // Get the enclave id for passing into the ecall sgx_enclave_id_t enclaveid = g_Enclave[enclaveIndex].GetEnclaveId(); // tcf::logger::LogV(TCF_LOG_DEBUG, "GetSerializedResponse[%ld] %u ", (long)enclaveid, enclaveIndex); diff --git a/tcs/core/tcs_trusted_worker_manager/enclave_wrapper/work_order.h b/tc/sgx/trusted_worker_manager/enclave_wrapper/work_order.h similarity index 100% rename from tcs/core/tcs_trusted_worker_manager/enclave_wrapper/work_order.h rename to tc/sgx/trusted_worker_manager/enclave_wrapper/work_order.h diff --git a/tcs/core/tcs_trusted_worker_manager/enclave_wrapper/work_order_wrap.cpp b/tc/sgx/trusted_worker_manager/enclave_wrapper/work_order_wrap.cpp similarity index 100% rename from tcs/core/tcs_trusted_worker_manager/enclave_wrapper/work_order_wrap.cpp rename to tc/sgx/trusted_worker_manager/enclave_wrapper/work_order_wrap.cpp diff --git a/tcs/core/tcs_trusted_worker_manager/enclave_wrapper/work_order_wrap.h b/tc/sgx/trusted_worker_manager/enclave_wrapper/work_order_wrap.h similarity index 100% rename from tcs/core/tcs_trusted_worker_manager/enclave_wrapper/work_order_wrap.h rename to tc/sgx/trusted_worker_manager/enclave_wrapper/work_order_wrap.h diff --git a/tests/Demo.py b/tests/Demo.py index 97db0bb37..4333eaffe 100644 --- a/tests/Demo.py +++ b/tests/Demo.py @@ -1,4 +1,4 @@ -# Copyright 2018 Intel Corporation +# Copyright 2019 Intel Corporation # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -22,10 +22,10 @@ from service_client.generic import GenericServiceClient import crypto.crypto as crypto -import utils.signature as signature +import utility.signature as signature import worker.worker_details as worker from shared_kv.shared_kv_interface import KvStorage -import utils.utility as enclave_helper +import utility.utility as enclave_helper import utility.file_utils as futils logger = logging.getLogger(__name__) @@ -62,11 +62,15 @@ def LocalMain(config) : #If Client request is WorkOrderSubmit,a requester payload's signature with the requester private signing key is generated. if "WorkOrderSubmit" in input_json_str1 : - # Update workorder ID and workerId + # Update workOrderId , workerId and workloadId input_json_obj = json.loads(input_json_str1) wo_id = hex(random.randint(1, 2**64 - 1)) input_json_obj["params"]["workOrderId"] = wo_id input_json_obj["params"]["workerId"] = worker_obj.worker_id + # Convert workloadId to a hex string and update the request + workload_id = input_json_obj["params"]["workloadId"] + workload_id_hex = workload_id.encode("UTF-8").hex() + input_json_obj["params"]["workloadId"] = workload_id_hex input_json_str1 = json.dumps(input_json_obj) #Generate session iv an encrypted session key @@ -85,7 +89,8 @@ def LocalMain(config) : #Retrieving the worker id from the "WorkerRetrieve" response and update the worker id information for the further json requests if "result" in response and "ids" in response["result"].keys(): input_json_final = json.loads(input_json_str1) - input_json_final["params"]["workerId"] = enclave_helper.strip_begin_end_key(response["result"]["ids"][0]) + worker_id = response["result"]["ids"][0] + input_json_final["params"]["workerId"] = worker_id input_json_str1 = json.dumps(input_json_final) logger.info("**********Worker details Updated with Worker ID*********\n%s\n", input_json_str1) #----------------------------------------------------------------------------------- @@ -120,16 +125,18 @@ def LocalMain(config) : try: if sig_bool > 0: logger.info("Signature Verified") + enclave_helper.decrypted_response(json.dumps(response), encrypted_session_key) else : logger.info("Signature Failed") + exit(1) except: logger.error("ERROR: Failed to analyze Signature Verification") + exit(1) - enclave_helper.decrypted_response(json.dumps(response), encrypted_session_key) #---------------------------------------------------------------------------------- else : logger.info("Input Request %s", input_json_str) - response = uri_client._postmsg(input_json_str_1) + response = uri_client._postmsg(input_json_str) logger.info("Received Response : %s , \n \n ", response); exit(0) diff --git a/tests/__init__.py b/tests/__init__.py index 98ca26c9f..b37589b08 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2018 Intel Corporation +# Copyright 2019 Intel Corporation # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/tests/clients/echo_client.py b/tests/clients/echo_client.py new file mode 100644 index 000000000..0e9eee2a4 --- /dev/null +++ b/tests/clients/echo_client.py @@ -0,0 +1,189 @@ +# Copyright 2019 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 random +import json +import argparse +import logging + +import config.config as pconfig +import utility.logger as plogger +from service_client.generic import GenericServiceClient +import utility.utility as enclave_helper +import worker.worker_details as worker +import json_rpc_request as jrpc_request +from direct_adaptor_factory_wrapper import DirectAdaptorFactoryWrapper + +# Remove duplicate loggers +for handler in logging.root.handlers[:]: + logging.root.removeHandler(handler) +logger = logging.getLogger(__name__) +TCFHOME = os.environ.get("TCF_HOME", "../../") + +def ParseCommandLine(args) : + + global worker_obj + global worker_id + global message + global config + global off_chain + + parser = argparse.ArgumentParser() + use_service = parser.add_mutually_exclusive_group() + parser.add_argument("-c", "--config", + help="the config file containing the Ethereum contract information", + type=str) + use_service.add_argument("-r", "--registry-list", + help="the Ethereum address of the registry list", + type=str) + use_service.add_argument("-s", "--service-uri", + help="skip URI lookup and send to specified URI", + type=str) + use_service.add_argument("-o", "--off-chain", + help="skip URI lookup and use the registry in the config file", + action="store_true") + parser.add_argument("-w", "--worker-id", + help="skip worker lookup and retrieve specified worker", + type=str) + parser.add_argument("-m", "--message", + help='text message to be included in the JSON request payload', + type=str) + + options = parser.parse_args(args) + + if options.config: + conffiles = [options.config] + else: + conffiles = [ TCFHOME + "/common/tcf_connector/tcf_connector.toml" ] + confpaths = [ "." ] + try : + config = pconfig.parse_configuration_files(conffiles, confpaths) + config_json_str = json.dumps(config) + except pconfig.ConfigurationException as e : + logger.error(str(e)) + sys.exit(-1) + + global direct_wrapper + direct_wrapper = DirectAdaptorFactoryWrapper(conffiles[0]) + + # Whether or not to connect to the registry list on the blockchain + off_chain = False + + if options.registry_list: + config["ethereum"]["direct_registry_contract_address"] = \ + options.registry_list + + if options.service_uri: + config["tcf"]["json_rpc_uri"] = options.service_uri + off_chain = True + + if options.off_chain: + off_chain = True + + worker_id = options.worker_id + message = options.message + if options.message == None or options.message == "": + message = "Test Message" + + # Initializing Worker Object + worker_obj = worker.WorkerDetails() + +def Main(args=None): + ParseCommandLine(args) + + config["Logging"] = { + "LogFile" : "__screen__", + "LogLevel" : "INFO" + } + + plogger.setup_loggers(config.get("Logging", {})) + sys.stdout = plogger.stream_to_logger( + logging.getLogger("STDOUT"), logging.DEBUG) + sys.stderr = plogger.stream_to_logger( + logging.getLogger("STDERR"), logging.WARN) + + logger.info("***************** INTEL TRUSTED COMPUTE FRAMEWORK (TCF)" + \ + " *****************") + + # Connect to registry list and retrieve registry + if not off_chain: + direct_wrapper.init_worker_registry_list(config) + registry_lookup_result = direct_wrapper.registry_lookup() + if (registry_lookup_result[0] == 0): + logger.warn("No registries found") + sys.exit(1) + registry_retrieve_result = direct_wrapper.registry_retrieve( + registry_lookup_result[2][0]) + config["tcf"]["json_rpc_uri"] = registry_retrieve_result[0] + + # Prepare worker + direct_wrapper.init_worker_registry(config) + + global worker_id + if not worker_id: + worker_lookup_json = jrpc_request.WorkerLookupJson(1, worker_type=1) + worker_lookup_result = direct_wrapper.worker_lookup(worker_lookup_json) + if "result" in worker_lookup_result and \ + "ids" in worker_lookup_result["result"].keys(): + if worker_lookup_result["result"]["totalCount"] != 0: + worker_id = worker_lookup_result["result"]["ids"][0] + else: + logger.error("ERROR: No workers found") + sys.exit(1) + else: + logger.error("ERROR: Failed to lookup worker") + sys.exit(1) + + worker_retrieve_json = jrpc_request.WorkerRetrieveJson(2, worker_id) + worker_obj.load_worker( + direct_wrapper.worker_retrieve(worker_retrieve_json)) + + logger.info("**********Worker details Updated with Worker ID" + \ + "*********\n%s\n", worker_id) + + # Create, sign, and submit workorder + # Convert workloadId to hex + workload_id = "echo-result" + workload_id = workload_id.encode("UTF-8").hex() + wo_submit_json = jrpc_request.WorkOrderSubmitJson(3, 6000, "pformat", + worker_id, workload_id, "0x2345", + worker_encryption_key=worker_obj.worker_encryption_key, + data_encryption_algorithm="AES-GCM-256") + wo_id = wo_submit_json.get_work_order_id() + wo_submit_json.add_in_data("bcde1111", message) + + private_key = enclave_helper.generate_signing_keys() + session_iv = enclave_helper.generate_sessioniv() + encrypted_session_key = enclave_helper.generate_encrypted_session_key( + session_iv, worker_obj.worker_encryption_key) + + direct_wrapper.init_work_order(config) + direct_wrapper.work_order_submit(wo_submit_json, encrypted_session_key, + worker_obj, private_key, session_iv) + + # Retrieve result + wo_get_result_json = jrpc_request.WorkOrderGetResultJson(4, wo_id) + direct_wrapper.work_order_get_result( + wo_get_result_json, encrypted_session_key) + + # Retrieve receipt + wo_receipt_retrieve_json = \ + jrpc_request.WorkOrderReceiptRetrieveJson(5, wo_id) + direct_wrapper.init_work_order_receipt(config) + direct_wrapper.work_order_receipt_retrieve(wo_receipt_retrieve_json) + +#------------------------------------------------------------------------------ +Main() diff --git a/tests/json_requests/json_03.json b/tests/json_requests/json_03.json index 5ed18b635..3d379ee5e 100644 --- a/tests/json_requests/json_03.json +++ b/tests/json_requests/json_03.json @@ -9,9 +9,9 @@ "notifyUri": "notifyuri", "workOrderId": "0x11ABCD", "workerId":"", - "workloadId": "0x2345", + "workloadId": "heart-disease-eval", "requesterId": "0x3456", - "workerEncryptionKey": "0x6789", + "workerEncryptionKey": "", "dataEncryptionAlgorithm": "AES-GCM-256", "encryptedSessionKey": "sessionkey", "sessionKeyIv": "Iv", @@ -20,33 +20,18 @@ "requesterSignature": "", "inData": [ {"index": 2, - "dataHash": "12ab34cd", + "dataHash": "", "data": "Heart disease evaluation data: 25 10 1 67 102 125 1 95 5 10 1 11 36 1", "encryptedDataEncryptionKey": "", "iv": "" }, {"index": 1, - "dataHash": "dcba4444", + "dataHash": "", "data": "Heart disease evaluation data: 32 1 1 156 132 125 1 95 1 0 1 1 3 1", "encryptedDataEncryptionKey": "", "iv": "" - }, - {"index": 0, - "dataHash": "abcd5555", - "data": "heart-disease-eval:", - "encryptedDataEncryptionKey": "", - "iv": "" - } - ], - "outData": [ - {"index": 0, - "dataHash": "aabbccdd", - "data": "", - "encryptedDataEncryptionKey": "", - "iv": "" } - ], - "verifyingKey": "" + ] } } diff --git a/tests/json_requests/json_06.json b/tests/json_requests/json_06.json index dcb44e535..f4ed62ff5 100644 --- a/tests/json_requests/json_06.json +++ b/tests/json_requests/json_06.json @@ -9,9 +9,9 @@ "notifyUri": "notifyuri", "workOrderId": "0x11ABCE", "workerId":"", - "workloadId": "0x2345", + "workloadId": "echo-result", "requesterId": "0x3456", - "workerEncryptionKey": "0x6789", + "workerEncryptionKey": "", "dataEncryptionAlgorithm": "AES-GCM-256", "encryptedSessionKey": "sessionkey", "sessionKeyIv": "Iv", @@ -20,30 +20,10 @@ "requesterSignature": "", "inData": [ {"index": 1, - "dataHash": "12ab34cd", + "dataHash": "", "data": "Hello world", "encryptedDataEncryptionKey": "", "iv": "" - }, - {"index": 0, - "dataHash": "dcba4321", - "data": "echo-result:", - "encryptedDataEncryptionKey": "", - "iv": "" - } - ], - "outData": [ - {"index": 1, - "dataHash": "12ab34cd", - "data": "", - "encryptedDataEncryptionKey": "", - "iv": "" - }, - {"index": 0, - "dataHash": "dcba4321", - "data": "", - "encryptedDataEncryptionKey": "", - "iv": "" } ], "verifyingKey": "" diff --git a/tests/json_requests/json_08.json b/tests/json_requests/json_08.json index 9b4eeb4ba..8a88baa47 100644 --- a/tests/json_requests/json_08.json +++ b/tests/json_requests/json_08.json @@ -9,9 +9,9 @@ "notifyUri": "notifyuri", "workOrderId": "0x23", "workerId":"", - "workloadId": "0x2345", + "workloadId": "echo-result", "requesterId": "0x3456", - "workerEncryptionKey": "0x6789", + "workerEncryptionKey": "", "dataEncryptionAlgorithm": "AES-GCM-256", "encryptedSessionKey": "sessionkey", "sessionKeyIv": "Iv", @@ -20,16 +20,10 @@ "requesterSignature": "", "inData": [ {"index": 1, - "dataHash": "12ab34cd", + "dataHash": "", "data": "Hello world", "encryptedDataEncryptionKey": "", "iv": "" - }, - {"index": 0, - "dataHash": "dcba4321", - "data": "echo-result:", - "encryptedDataEncryptionKey": "", - "iv": "" } ], "verifyingKey": "" diff --git a/tests/json_requests/json_10.json b/tests/json_requests/json_10.json index d9333b9d3..974576628 100644 --- a/tests/json_requests/json_10.json +++ b/tests/json_requests/json_10.json @@ -9,9 +9,9 @@ "notifyUri": "notifyuri", "workOrderId": "0x1234ABCD", "workerId":"", - "workloadId": "0x2345", + "workloadId": "heart-disease-eval", "requesterId": "0x3456", - "workerEncryptionKey": "0x6789", + "workerEncryptionKey": "", "dataEncryptionAlgorithm": "AES-GCM-256", "encryptedSessionKey": "sessionkey", "sessionKeyIv": "Iv", @@ -20,24 +20,10 @@ "requesterSignature": "", "inData": [ {"index": 1, - "dataHash": "dcba4444", + "dataHash": "", "data": "Heart disease evaluation data: 32 1 1 156 132 125 1 95 1 0 1 1 3 1", "encryptedDataEncryptionKey": "-", "iv": "" - }, - {"index": 0, - "dataHash": "abcd5555", - "data": "heart-disease-eval:", - "encryptedDataEncryptionKey": "-", - "iv": "" - } - ], - "outData": [ - {"index": 0, - "dataHash": "aabbccdd", - "data": "", - "encryptedDataEncryptionKey": "-", - "iv": "" } ], "verifyingKey": "" diff --git a/tests/json_requests/json_12.json b/tests/json_requests/json_12.json index 2de0f7eaf..3541fcce3 100644 --- a/tests/json_requests/json_12.json +++ b/tests/json_requests/json_12.json @@ -9,9 +9,9 @@ "notifyUri": "notifyuri", "workOrderId": "0x1234FFFF", "workerId":"", - "workloadId": "0x2345", + "workloadId": "heart-disease-eval", "requesterId": "0x3456", - "workerEncryptionKey": "0x6789", + "workerEncryptionKey": "", "dataEncryptionAlgorithm": "AES-GCM-256", "encryptedSessionKey": "sessionkey", "sessionKeyIv": "Iv", @@ -20,24 +20,10 @@ "requesterSignature": "", "inData": [ {"index": 1, - "dataHash": "dcba4444", + "dataHash": "", "data": "Heart disease evaluation data: 32 1 1 156 132 125 1 95 1 0 1 1 3 1", "encryptedDataEncryptionKey": "null", "iv": "" - }, - {"index": 0, - "dataHash": "abcd5555", - "data": "heart-disease-eval:", - "encryptedDataEncryptionKey": "null", - "iv": "" - } - ], - "outData": [ - {"index": 0, - "dataHash": "aabbccdd", - "data": "", - "encryptedDataEncryptionKey": "null", - "iv": "" } ], "verifyingKey": "" diff --git a/tests/signature/wo_request_03.json b/tests/signature/wo_request_03.json index f2f9a4283..e2bafb52a 100644 --- a/tests/signature/wo_request_03.json +++ b/tests/signature/wo_request_03.json @@ -9,9 +9,9 @@ "notifyUri": "notifyuri", "workOrderId": "0x22ABCD", "workerId":"", - "workloadId": "0x2345", + "workloadId": "heart-disease-eval", "requesterId": "0x3456", - "workerEncryptionKey": "0x6789", + "workerEncryptionKey": "", "dataEncryptionAlgorithm": "AES-GCM-256", "encryptedSessionKey": "sessionkey", "sessionKeyIv": "Iv", @@ -20,30 +20,10 @@ "requesterSignature": "", "inData": [ {"index": 1, - "dataHash": "mhash444", + "dataHash": "", "data": "Heart disease evaluation data: 32 1 1 156 132 125 1 95 1 0 1 1 3 1", "encryptedDataEncryptionKey": "", "iv": "" - }, - {"index": 0, - "dataHash": "mhash555", - "data": "heart-disease-eval:", - "encryptedDataEncryptionKey": "", - "iv": "" - } - ], - "outData": [ - {"index": 1, - "dataHash": "mhash444", - "data": "", - "encryptedDataEncryptionKey": "", - "iv": "" - }, - {"index": 0, - "dataHash": "mhash555", - "data": "", - "encryptedDataEncryptionKey": "", - "iv": "" } ], "verifyingKey": "" diff --git a/tests/test_encryption.py b/tests/test_encryption.py index 967dfe01c..5a5f239cb 100644 --- a/tests/test_encryption.py +++ b/tests/test_encryption.py @@ -1,6 +1,4 @@ -#!/usr/bin/env python - -# Copyright 2018 Intel Corporation +# Copyright 2019 Intel Corporation # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -14,51 +12,48 @@ # See the License for the specific language governing permissions and # limitations under the License. - -import crypto.crypto as crypto import logging -import utils.signature as signature +import crypto.crypto as crypto +import utility.utility as utility logging.basicConfig(format='%(asctime)s - %(levelname)s - %(message)s', level=logging.INFO) -def test_encrypt_session_key(client, iv): +def test_encrypt_session_key(iv): worker_enc_key = "MIIBCgKCAQEAwocGo" - enc_sess_key = client.generate_encrypted_session_key(iv, worker_enc_key) + enc_sess_key = utility.generate_encrypted_session_key(iv, worker_enc_key) if enc_sess_key: logging.info("Test case: test_encrypt_session_key PASS...") else: logging.info("Test case: test_encrypt_session_key FAIL...") return enc_sess_key -def test_encrypt_data(client, iv, enc_sess_key, data): +def test_encrypt_data(iv, enc_sess_key, data): data_bytes = bytes(data, 'ascii') - enc_req_hash = client.encrypt_data(data_bytes, enc_sess_key, iv) + enc_req_hash = utility.encrypt_data(data_bytes, enc_sess_key, iv) if enc_req_hash: logging.info("Test case: test_encrypt_data PASS...") else: logging.info("Test case: test_encrypt_data FAIL...") return enc_req_hash -def test_decrypt_data(client, iv, enc_sess_key, plain_data, enc_data): - dec_data = client.decrypt_data(enc_sess_key, iv, enc_data) - if dec_data.decode() == plain_data: +def test_decrypt_data(iv, enc_sess_key, plain_data, enc_data): + dec_data = utility.decrypt_data(enc_sess_key, iv, enc_data) + if dec_data == plain_data: logging.info("Test case: test_decrypt_data PASS..") else: logging.info("Test case: test_decrypt_data FAIL..") def main(): logging.info("Executing Unit test cases for encryption at client") - client = signature.ClientSignature() msg = "This is client request" - iv = client.generate_sessioniv() - enc_sess_key = test_encrypt_session_key(client, iv) + iv = utility.generate_sessioniv() + enc_sess_key = test_encrypt_session_key(iv) if enc_sess_key: - enc_data = test_encrypt_data(client, iv, enc_sess_key[:16], msg) + enc_data = test_encrypt_data(iv, enc_sess_key[:16], msg) if enc_data: b64_enc_data = crypto.byte_array_to_base64(enc_data) - b64_enc_sess_key = crypto.byte_array_to_base64(enc_sess_key[:16]) iv_hex = crypto.byte_array_to_hex(iv) - test_decrypt_data(client, iv_hex, b64_enc_sess_key, msg, b64_enc_data) + test_decrypt_data(iv_hex, enc_sess_key[:16], msg, b64_enc_data) logging.info("Unit test case execution for encryption/decryption complete.") if __name__ == "__main__": diff --git a/tests/test_request.py b/tests/test_request.py index 3dccb0016..13371bb83 100644 --- a/tests/test_request.py +++ b/tests/test_request.py @@ -1,4 +1,4 @@ -# Copyright 2018 Intel Corporation +# Copyright 2019 Intel Corporation # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -22,8 +22,8 @@ from service_client.generic import GenericServiceClient import crypto.crypto as crypto -import utils.utility as helper -import utils.signature as signature +import utility.utility as helper +import utility.signature as signature import worker.worker_details as worker from shared_kv.shared_kv_interface import KvStorage import logging diff --git a/tests/test_work_order_cornercases.py b/tests/test_work_order_cornercases.py index 5aa6ffd8f..e3ab16021 100644 --- a/tests/test_work_order_cornercases.py +++ b/tests/test_work_order_cornercases.py @@ -1,6 +1,4 @@ -#!/usr/bin/env python - -# Copyright 2018 Intel Corporation +# Copyright 2019 Intel Corporation # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -24,7 +22,7 @@ from service_client.generic import GenericServiceClient import crypto.crypto as crypto -import utils.signature as signature +import utility.signature as signature import worker.worker as worker from shared_kv.shared_kv_interface import KvStorage import logging diff --git a/tests/test_work_order_handler.py b/tests/test_work_order_handler.py index a10d1b00b..af536eb1c 100644 --- a/tests/test_work_order_handler.py +++ b/tests/test_work_order_handler.py @@ -1,6 +1,4 @@ -#!/usr/bin/env python - -# Copyright 2018 Intel Corporation +# Copyright 2019 Intel Corporation # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/tests/work_orders/02_work_order_encruptionkey_get.json b/tests/work_orders/02_work_order_encryptionkey_get.json similarity index 100% rename from tests/work_orders/02_work_order_encruptionkey_get.json rename to tests/work_orders/02_work_order_encryptionkey_get.json diff --git a/tests/work_orders/04_work_order_submit.json b/tests/work_orders/04_work_order_submit.json index 9c9096ccc..e877d6c20 100644 --- a/tests/work_orders/04_work_order_submit.json +++ b/tests/work_orders/04_work_order_submit.json @@ -9,9 +9,9 @@ "notifyUri": "notifyuri", "workOrderId": "0x11", "workerId":"", - "workloadId": "0x2345", + "workloadId": "heart-disease-eval", "requesterId": "0x3456", - "workerEncryptionKey": "0x6789", + "workerEncryptionKey": "", "dataEncryptionAlgorithm": "AES-GCM-256", "encryptedSessionKey": "sessionkey", "sessionKeyIv": "Iv", @@ -20,30 +20,10 @@ "requesterSignature": "", "inData": [ {"index": 1, - "dataHash": "mhash444", + "dataHash": "", "data": "Heart disease evaluation data: 32 1 1 156 132 125 1 95 1 0 1 1 3 1", "encryptedDataEncryptionKey": "", "iv": "" - }, - {"index": 0, - "dataHash": "mhash555", - "data": "heart-disease-eval:", - "encryptedDataEncryptionKey": "", - "iv": "" - } - ], - "outData": [ - {"index": 1, - "dataHash": "mhash444", - "data": "", - "encryptedDataEncryptionKey": "", - "iv": "" - }, - {"index": 0, - "dataHash": "mhash555", - "data": "", - "encryptedDataEncryptionKey": "", - "iv": "" } ], "verifyingKey": "" diff --git a/__tools__/build/Makefile b/tools/build/Makefile similarity index 100% rename from __tools__/build/Makefile rename to tools/build/Makefile diff --git a/__tools__/clean.sh b/tools/clean.sh similarity index 78% rename from __tools__/clean.sh rename to tools/clean.sh index d34ec7e29..c423a5c20 100755 --- a/__tools__/clean.sh +++ b/tools/clean.sh @@ -30,22 +30,22 @@ rm -f $SRCDIR/enclave.pem echo "******** DELETE LMDB FILES **************" rm -f $SRCDIR/config/Kv_Shared* -# --------------- TCS CORE COMMON --------------- -cd $SRCDIR/tcs/core/common/python +# --------------- EXAMPLES COMMON --------------- +cd $SRCDIR/examples/common/python make clean -# --------------- TCF COMMON --------------- -cd $SRCDIR/common -make clean +# --------------- TOP COMMON --------------- +#cd $SRCDIR/common +#make clean -# --------------- CORE --------------- -cd $SRCDIR/tcs/core/tcs_trusted_worker_manager/enclave +# --------------- ENCLAVE --------------- +cd $SRCDIR/tc/sgx/trusted_worker_manager/enclave rm -rf build deps -cd $SRCDIR/tcs/core/common +cd $SRCDIR/tc/sgx/common rm -rf build # --------------- WORKLOADS ------------- -cd $SRCDIR/workloads +cd $SRCDIR/examples/apps rm -rf build diff --git a/__tools__/rebuild.sh b/tools/rebuild.sh similarity index 87% rename from __tools__/rebuild.sh rename to tools/rebuild.sh index 0cb198896..80a9c3ee9 100755 --- a/__tools__/rebuild.sh +++ b/tools/rebuild.sh @@ -63,11 +63,11 @@ yell --------------- CONFIG AND ENVIRONMENT CHECK --------------- # Set proxy for Intel Architectural Enclave Service Manager if [[ ${SGX_MODE} && "${SGX_MODE}" == "HW" ]]; then - #Add proxy settings + # Add proxy settings echo "proxy type = manual" >> /etc/aesmd.conf echo "aesm proxy = $http_proxy" >> /etc/aesmd.conf - #starting aesm service + # Starting aesm service echo "Starting aesm service" /opt/intel/libsgx-enclave-common/aesm/aesm_service & else @@ -127,36 +127,44 @@ NUM_CORES=1 # ----------------------------------------------------------------- # BUILD # ----------------------------------------------------------------- -yell --------------- WORKLOADS --------------- -cd $SRCDIR/workloads +yell --------------- COMMON SGX WORKLOAD --------------- +cd $SRCDIR/common/sgx_workload mkdir -p build cd build try cmake .. try make "-j$NUM_CORES" -yell --------------- TCS CORE COMMON --------------- -cd $SRCDIR/tcs/core/common +yell --------------- EXAMPLE WORKLOADS --------------- +cd $SRCDIR/examples/apps mkdir -p build cd build try cmake .. try make "-j$NUM_CORES" -yell --------------- CORE --------------- -cd $SRCDIR/tcs/core/tcs_trusted_worker_manager/enclave +yell --------------- TC SGX COMMON --------------- +cd $SRCDIR/tc/sgx/common mkdir -p build cd build try cmake .. try make "-j$NUM_CORES" -yell --------------- TCS CORE COMMON PYTHON --------------- -cd $SRCDIR/tcs/core/common/python +yell --------------- ENCLAVE --------------- +cd $SRCDIR/tc/sgx/trusted_worker_manager/enclave + +mkdir -p build +cd build +try cmake .. +try make "-j$NUM_CORES" + +yell --------------- EXAMPLES COMMON PYTHON --------------- +cd $SRCDIR/examples/common/python try make "-j$NUM_CORES" try make install -yell --------------- TCF COMMON PYTHON --------------- -cd $SRCDIR/common +yell --------------- ENCLAVE MANAGER --------------- +cd $SRCDIR/examples/enclave_manager try make "-j$NUM_CORES" try make install diff --git a/__tools__/run-tests.sh b/tools/run_tests.sh similarity index 84% rename from __tools__/run-tests.sh rename to tools/run_tests.sh index 3092c3a27..3779749df 100755 --- a/__tools__/run-tests.sh +++ b/tools/run_tests.sh @@ -23,6 +23,8 @@ fi SCRIPTDIR="$(dirname $(readlink --canonicalize ${BASH_SOURCE}))" SRCDIR="$(realpath ${SCRIPTDIR}/..)" +# Read Listener port from config file +listener_port=`grep listener_port ${TCF_HOME}/config/tcs_config.toml | awk {'print $3'}` yell() { echo "$0: $*" >&2; @@ -38,7 +40,7 @@ try() { } SAVE_FILE=$(mktemp /tmp/tcf-test.XXXXXXXXX) -INPUT_FOLDERS=(workorder_receipt json_requests worker work_orders signature) +INPUT_FOLDERS=(json_requests worker work_orders signature) function cleanup { yell "Clearing enclave files and database files" @@ -58,12 +60,13 @@ for folder in "${INPUT_FOLDERS[@]}" do yell "Start testing folder:: $folder ............" yell "#------------------------------------------------------------------------------------------------" - # 5seconds delay is introduced for user readability + # Delay is introduced for user readability sleep 5s - try python3 ${TCF_HOME}/tests/test_request.py \ + try python3 ${TCF_HOME}/tests/Demo.py \ --logfile __screen__ --loglevel warn \ - --input_dir ${TCF_HOME}/tests/$folder/ \ - --connect_uri "http://localhost:1947" work_orders/output.json > /dev/null + --input_dir ${TCF_HOME}/tests/$folder/ \ + --connect_uri "http://localhost:$listener_port" work_orders/output.json > /dev/null + yell "#------------------------------------------------------------------------------------------------" yell "#------------------------------------------------------------------------------------------------" done diff --git a/workloads/CMakeVariables.txt b/workloads/CMakeVariables.txt deleted file mode 100644 index 28b318bfa..000000000 --- a/workloads/CMakeVariables.txt +++ /dev/null @@ -1,71 +0,0 @@ -# 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. - - -################################################################################ -# Configure Environment -################################################################################ - -SET(TCF_TOP_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../") - -if("$ENV{DEBUG} " STREQUAL " ") - SET(DEBUG_FLAGS "-O2") - message(STATUS "Compiling with optimizations (-O2). To use debug flags, set the DEBUG environment variable.") -else() - SET(DEBUG_FLAGS "-Og" "-g" "-DDEBUG") - message(STATUS "Compiling in debug mode without optimizations (-Og -g)") -endif() - -SET(TCF_ENCLAVE_CODE_SIGN_PEM "$ENV{TCF_ENCLAVE_CODE_SIGN_PEM}") -if("${TCF_ENCLAVE_CODE_SIGN_PEM} " STREQUAL " ") - message(FATAL_ERROR "TCF_ENCLAVE_CODE_SIGN_PEM environment variable not defined!") -endif() - -SET(SGX_MODE "$ENV{SGX_MODE}") -if("${SGX_MODE} " STREQUAL " ") - message(FATAL_ERROR "SGX_MODE environment variable not defined!") -endif() -IF("${SGX_MODE}" STREQUAL "SIM") - SET(TRTS_LIBRARY_NAME "sgx_trts_sim") - SET(URTS_LIBRARY_NAME "sgx_urts_sim") - SET(SERVICE_LIBRARY_NAME "sgx_tservice_sim") - SET(IAS_CA_CERT_REQUIRED_FLAGS "") -ELSE() - SET(TRTS_LIBRARY_NAME "sgx_trts") - SET(URTS_LIBRARY_NAME "sgx_urts") - SET(SERVICE_LIBRARY_NAME "sgx_tservice") - SET(IAS_CA_CERT_REQUIRED_FLAGS "-DIAS_CA_CERT_REQUIRED") -ENDIF() - -SET(SGX_SDK "$ENV{SGX_SDK}") -if("${SGX_SDK} " STREQUAL " ") - message(FATAL_ERROR "SGX_SDK environment variable not defined!") -endif() -SET(SGX_SSL "$ENV{SGX_SSL}") -if("${SGX_SSL} " STREQUAL " ") - message(FATAL_ERROR "SGX_SSL environment variable not defined!") -endif() - -SET(SGX_EDGER "${SGX_SDK}/bin/x64/sgx_edger8r") -SET(SGX_SIGN "${SGX_SDK}/bin/x64/sgx_sign") - -SET(SGX_SEARCH_PATH "${SGX_SDK}/include:${SGX_SSL}/include") -SET(SGX_ENCLAVE_INCLUDE "${SGX_SDK}/include" - "${SGX_SDK}/include/tlibc" - "${SGX_SDK}/include/libcxx") - -SET(GENERIC_PRIVATE_INCLUDE_DIRS "." ".." "../crypto" "../crypto/verify_ias_report" "../packages/base64") -SET(GENERIC_PUBLIC_INCLUDE_DIRS "${SGX_SDK}/include") - -enable_testing()