def load_worker(self, worker_data): """ Function to load the member variables of this class based on worker retrieved details. """ logger.info("*********Updating Worker Details*********") self.hashing_algorithm = worker_data['hashingAlgorithm'] self.signing_algorithm = worker_data['signingAlgorithm'] self.key_encryption_algorithm = worker_data['keyEncryptionAlgorithm'] self.data_encryption_algorithm = worker_data['dataEncryptionAlgorithm'] self.verification_key = \ worker_data['workerTypeData']['verificationKey'] self.encryption_key = worker_data['workerTypeData']['encryptionKey'] if 'proofData' in worker_data['workerTypeData'] and \ worker_data['workerTypeData']['proofData']: # proofData will be initialized only in HW mode by the # tcf_enclave_bridge module when sign up info is obtained from # the worker. self.proof_data = json.loads( worker_data['workerTypeData']['proofData']) self.worker_id = crypto_utility.strip_begin_end_public_key( worker_data['workerTypeData']['verificationKey']) \ .encode("UTF-8").hex() ''' worker_id - newline, BEGIN PUB KEY and END PUB KEY are removed from worker's verification key and converted to hex ''' logger.info("Hashing Algorithm : %s", self.hashing_algorithm) logger.info("Signing Algorithm : %s", self.signing_algorithm)
def test_verify_update_receipt_signature(): # update the payload updater_id = crypto_utility.strip_begin_end_public_key(client_public_key) read_json = read_json_file("wo_receipt_update_response.json", ["./"]) wo_receipt_update_response = json.loads(read_json)["result"] wo_receipt_update_response["workOrderId"] = work_order_id wo_receipt_update_response["updaterId"] = updater_id wo_receipt_update_response["receiptVerificationKey"] = client_public_key wo_receipt_str = wo_receipt_update_response["workOrderId"] + \ str(wo_receipt_update_response["updateType"]) + \ wo_receipt_update_response["updateData"] wo_receipt_bytes = bytes(wo_receipt_str, "UTF-8") wo_receipt_hash = crypto_utility.compute_message_hash(wo_receipt_bytes) try: status, wo_receipt_sign = sig_obj.generate_signature( wo_receipt_hash, client_private_key) wo_receipt_update_response["updateSignature"] = wo_receipt_sign # test verify update receipt status = sig_obj.verify_update_receipt_signature( wo_receipt_update_response) if status == SignatureStatus.PASSED: logging.info("PASSED: verify_update_receipt_signature") return 0 else: logging.info("FAILED: verify_update_receipt_signature") return 1 except Exception as err: logging.info("FAILED: verify_update_receipt_signature") return 1
def load_worker(self, worker_data): """ Load member variables of this class based on worker-retrieved details. Parameters: worker_data Worker Data to load into the class """ logger.info("*********Updating Worker Details*********") self.hashing_algorithm = worker_data['hashingAlgorithm'] self.signing_algorithm = worker_data['signingAlgorithm'] self.key_encryption_algorithm = worker_data['keyEncryptionAlgorithm'] self.data_encryption_algorithm = worker_data['dataEncryptionAlgorithm'] self.verification_key = \ worker_data['workerTypeData']['verificationKey'] self.encryption_key = worker_data['workerTypeData']['encryptionKey'] if 'proofData' in worker_data['workerTypeData'] and \ worker_data['workerTypeData']['proofData']: # proofData will be initialized only in HW mode by the # tcf_enclave_bridge module when sign up info is obtained from # the worker. self.proof_data = json.loads( worker_data['workerTypeData']['proofData']) w_id = crypto_utility.strip_begin_end_public_key( worker_data['workerTypeData']['verificationKey']) \ .encode("UTF-8") # Calculate sha256 of worker id to get 32 bytes. The TC spec proxy # model contracts expect byte32. Then take a hexdigest for hex str. self.worker_id = hashlib.sha256(w_id).hexdigest() ''' worker_id - newline, BEGIN PUB KEY and END PUB KEY are removed from worker's verification key and converted to hex ''' logger.info("Hashing Algorithm : %s", self.hashing_algorithm) logger.info("Signing Algorithm : %s", self.signing_algorithm) logger.info("Worker ID : %s", self.worker_id)
def update_receipt(self, work_order_id, update_type, update_data, signing_key): """ Update the existing work order receipt with update_type and update_data. Parameters: work_order_id Work order ID whose receipt needs to be updated update_type Update type. These values correspond to receipt status as defined in EEA Spec 7.1.1 update_data Update-specific data that depends on the workOrderStatus Returns: JSON RPC work order update receipt request of type dictionary """ data = update_data if update_type in [ReceiptCreateStatus.PROCESSED.value, ReceiptCreateStatus.COMPLETED.value]: # Work Order Receipt status is set to be completed or processed, # then update_data should be work order response. wo_resp_str = json.dumps(update_data) wo_resp_bytes = bytes(wo_resp_str, "UTF-8") # Hash of work order response is update_data wo_resp_hash = crypto.compute_message_hash(wo_resp_bytes) wo_resp_hash_str = crypto.byte_array_to_hex(wo_resp_hash) data = wo_resp_hash_str public_key = signing_key.GetPublicKey().Serialize() updater_id = crypto_utility.strip_begin_end_public_key(public_key) wo_receipt_update = { "workOrderId": work_order_id, "updaterId": updater_id, "updateType": update_type, "updateData": data, "signatureRules": self.HASHING_ALGORITHM + "/" + self.SIGNING_ALGORITHM, "receiptVerificationKey": public_key } wo_receipt_str = wo_receipt_update["workOrderId"] + \ str(wo_receipt_update["updateType"]) + \ wo_receipt_update["updateData"] wo_receipt_bytes = bytes(wo_receipt_str, "UTF-8") wo_receipt_hash = crypto.compute_message_hash(wo_receipt_bytes) status, wo_receipt_sign = self.sig_obj.generate_signature( wo_receipt_hash, signing_key ) if status is False: # if generating signature failed. wo_receipt_update["updateSignature"] = "" raise Exception("Generate signature is failed") else: wo_receipt_update["updateSignature"] = wo_receipt_sign return wo_receipt_update
def configure_data(self, input_json, worker_obj, pre_test_response): # worker_obj = worker.SGXWorkerDetails() if input_json is not None: self.add_json_values(input_json, pre_test_response, self.tamper) else: self.set_worker_id( crypto_utils.strip_begin_end_public_key( pre_test_response["result"]["ids"][0])) input_worker_retrieve = json.loads(self.to_string()) logger.info( '*****Worker details Updated with Worker ID***** \ \n%s\n', input_worker_retrieve) return input_worker_retrieve
def add_json_values(self, input_json_temp, pre_test_response, tamper): if "workerId" in input_json_temp["params"].keys(): if input_json_temp["params"]["workerId"] != "": self.set_worker_id(input_json_temp["params"]["workerId"]) else: self.set_worker_id( crypto_utils.strip_begin_end_public_key( pre_test_response["result"]["ids"][0])) if "id" in input_json_temp.keys(): self.set_request_id(input_json_temp["id"]) for key in tamper["params"].keys(): param = key value = tamper["params"][key] self.set_unknown_parameter(param, value)
def manager_on_boot(self, kv_helper): """ Executes Boot flow of enclave manager """ logger.info("Executing boot time procedure") # Cleanup "workers" table workers_list = kv_helper.lookup("workers") if len(workers_list) == 0: logger.info("No worker entries available in workers table; " + "skipping cleanup") else: logger.info("Clearing entries in workers table") for worker in workers_list: kv_helper.remove("workers", worker) worker_info = create_json_worker(self, self.config) logger.info("Adding enclave workers to workers table") worker_id = crypto_utils.strip_begin_end_public_key(self.enclave_id) \ .encode("UTF-8") # Calculate sha256 of worker id to get 32 bytes. The TC spec proxy # model contracts expect byte32. Then take a hexdigest for hex str. worker_id = hashlib.sha256(worker_id).hexdigest() kv_helper.set("workers", worker_id, worker_info) # Cleanup wo-processing" table processing_list = kv_helper.lookup("wo-processing") if len(processing_list) == 0: logger.info("No workorder entries found in " + "wo-processing table, skipping Cleanup") return for wo in processing_list: logger.info("Validating workorders in wo-processing table") wo_json_resp = kv_helper.get("wo-responses", wo) wo_processed = kv_helper.get("wo-processed", wo) if wo_json_resp is not None: try: wo_resp = json.loads(wo_json_resp) except ValueError as e: logger.error( "Invalid JSON format found for the response for " + "workorder %s - %s", wo, e) if wo_processed is None: kv_helper.set("wo-processed", wo, WorkOrderStatus.FAILED.name) kv_helper.remove("wo-processing", wo) continue if "Response" in wo_resp and \ wo_resp["Response"]["Status"] == \ WorkOrderStatus.FAILED: if wo_processed is None: kv_helper.set("wo-processed", wo, WorkOrderStatus.FAILED.name) logger.error("Work order processing failed; " + "removing it from wo-processing table") kv_helper.remove("wo-processing", wo) continue wo_receipt = kv_helper.get("wo-receipts", wo) if wo_receipt: # update receipt logger.info("Updating receipt in boot flow") self.__update_receipt(kv_helper, wo, wo_json_resp) logger.info("Receipt updated for workorder %s during boot", wo) if wo_processed is None: kv_helper.set("wo-processed", wo, WorkOrderStatus.SUCCESS.name) else: logger.info( "No response found for the workorder %s; " + "hence placing the workorder request " + "back in wo-scheduled", wo) kv_helper.set("wo-scheduled", wo, WorkOrderStatus.SCHEDULED.name) logger.info( "Finally deleting workorder %s from wo-processing table", wo) kv_helper.remove("wo-processing", wo)
def add_json_values(self, input_json_temp, worker_obj, private_key, tamper): self.private_key = private_key self.worker_obj = worker_obj input_params_list = input_json_temp["params"].keys() if "responseTimeoutMSecs" in input_params_list: if input_json_temp["params"]["responseTimeoutMSecs"] != "": self.set_response_timeout_msecs( input_json_temp["params"]["responseTimeoutMSecs"]) else: self.set_response_timeout_msecs(6000) if "payloadFormat" in input_params_list: if input_json_temp["params"]["payloadFormat"] != "": self.set_payload_format( input_json_temp["params"]["payloadFormat"]) else: self.set_payload_format("JSON-RPC") if "resultUri" in input_params_list: if input_json_temp["params"]["resultUri"] != "": self.set_result_uri(input_json_temp["params"]["resultUri"]) else: self.set_result_uri("") if "notifyUri" in input_params_list: if input_json_temp["params"]["notifyUri"] != "": self.set_notify_uri(input_json_temp["params"]["notifyUri"]) else: self.set_notify_uri("") if "workOrderId" in input_params_list: if input_json_temp["params"]["workOrderId"] != "": self.set_work_order_id( input_json_temp["params"]["workOrderId"]) else: work_order_id = hex(random.randint(1, 2**64 - 1)) self.set_work_order_id(work_order_id) if "workerId" in input_params_list: if input_json_temp["params"]["workerId"] != "": self.set_worker_id(input_json_temp["params"]["workerId"]) else: self.set_worker_id(worker_obj.worker_id) if "workloadId" in input_params_list: if input_json_temp["params"]["workloadId"] != "": self.set_workload_id(input_json_temp["params"] ["workloadId"].encode('UTF-8').hex()) else: workload_id = "echo-client" self.set_workload_id(workload_id.encode('UTF-8').hex()) if "requesterId" in input_params_list: if input_json_temp["params"]["requesterId"] != "": self.set_requester_id(input_json_temp["params"]["requesterId"]) else: self.set_requester_id("0x3456") if "workerEncryptionKey" in input_params_list: if input_json_temp["params"]["workerEncryptionKey"] != "": self.set_worker_encryption_key( input_json_temp["params"]["workerEncryptionKey"].encode( "UTF-8").hex()) else: self.set_worker_encryption_key( crypto_utils.strip_begin_end_public_key( worker_obj.encryption_key).encode("UTF-8").hex()) if "dataEncryptionAlgorithm" in input_params_list: if input_json_temp["params"]["dataEncryptionAlgorithm"] != "": self.set_data_encryption_algorithm( input_json_temp["params"]["dataEncryptionAlgorithm"]) else: self.set_data_encryption_algorithm("AES-GCM-256") if "sessionKeyIv" in input_params_list: if input_json_temp["params"]["sessionKeyIv"] != "": self.set_session_key_iv( input_json_temp["params"]["sessionKeyIv"]) else: self.set_session_key_iv( self.byte_array_to_hex_str(self.session_iv)) if "encryptedSessionKey" in input_params_list: if input_json_temp["params"]["encryptedSessionKey"] != "": self.set_encrypted_session_key( input_json_temp["params"]["encryptedSessionKey"]) self.encrypted_session_key = ( input_json_temp["params"]["encryptedSessionKey"]) else: self.encrypted_session_key = (self.generate_encrypted_key( self.session_key, worker_obj.encryption_key)) self.set_encrypted_session_key( self.byte_array_to_hex_str(self.encrypted_session_key)) if "requesterNonce" in input_params_list: if input_json_temp["params"]["requesterNonce"] != "": self.set_requester_nonce( input_json_temp["params"]["requesterNonce"]) else: self.set_requester_nonce(secrets.token_hex(16)) if "inData" in input_params_list: if input_json_temp["params"]["inData"] != "": input_json_inData = input_json_temp["params"]["inData"] self.add_in_data(input_json_inData) else: self.params_obj["inData"] = "" if "outData" in input_params_list: if input_json_temp["params"]["outData"] != "": input_json_outData = input_json_temp["params"]["outData"] self.add_out_data(input_json_outData) else: self.params_obj["outData"] = "" if "encryptedRequestHash" in input_params_list: if input_json_temp["params"]["encryptedRequestHash"] != "": self.params_obj["encryptedRequestHash"] = \ input_json_temp["params"]["encryptedRequestHash"] else: self._compute_encrypted_request_hash() if "requesterSignature" in input_params_list: if input_json_temp["params"]["requesterSignature"] != "": self.params_obj["requesterSignature"] = \ input_json_temp["params"]["requesterSignature"] else: self.params_obj["requesterSignature"] = "" if "verifyingKey" in input_params_list: if input_json_temp["params"]["verifyingKey"] != "": self.params_obj["verifyingKey"] = \ input_json_temp["params"]["verifyingKey"] if "default" in tamper.keys(): if "params" in tamper["default"].keys(): for key, value in tamper["default"]["params"]: param = key value = value self.set_unknown_parameter(param, value)