def load_worker(self, input_str): """ Function to load the member variables of this class based on worker retrieved details. """ worker_data = input_str['result']['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 signup 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 worker_lookup_retrieve(config, worker_obj, uri_client): """ Function for computing worker lookup and retrieve once per session. """ if not uri_client: logger.error("Server URI is not provided") exit(1) # logger.info("Execute work order") response = None err_cd = 0 # create worker lookup request output_json_file_name = 'worker_lookup' lookup_obj = WorkerLookUp() lookup_obj.set_worker_type(WorkerType.TEE_SGX.value) input_worker_look_up = json.loads(lookup_obj.to_string()) # input_json_str = input_worker_look_up logger.info("------------------Testing WorkerLookUp------------------") # submit worker lookup request and retrieve response logger.info("********Received Request*******\n%s\n", input_worker_look_up) response = submit_request(uri_client, input_worker_look_up, output_json_file_name) logger.info("**********Received Response*********\n%s\n", response) # check worker lookup response if "result" in response and "totalCount" in response["result"].keys(): if response["result"]["totalCount"] == 0: err_cd = 1 logger.info('ERROR: Failed at WorkerLookUp - \ No Workers exist to submit workorder.') if err_cd == 0: retrieve_obj = WorkerRetrieve() logger.info("-----Testing WorkerRetrieve-----") # Retrieving the worker id from the "WorkerLookUp" response and # update the worker id information for the further json requests if "result" in response and "ids" in response["result"].keys(): retrieve_obj.set_worker_id(crypto_utils.strip_begin_end_public_key (response["result"]["ids"][0])) input_worker_retrieve = json.loads(retrieve_obj.to_string()) logger.info('*****Worker details Updated with Worker ID***** \ \n%s\n', input_worker_retrieve) else: logger.info('ERROR: Failed at WorkerLookUp - \ No Worker ids in WorkerLookUp response.') err_cd = 1 if err_cd == 0: # submit worker retrieve request and load to worker object response = submit_request(uri_client, input_worker_retrieve, output_json_file_name) worker_obj.load_worker(response) return worker_obj, err_cd
def update_receipt(self, work_order_id, update_type, update_data, signing_key): """ Update the existing work order receipt with update_type, update_data. Parameters: - work_order_id is work order id whose receipt needs to be updated. - update_type is integer, these values corresponds to receipt status as defined in 7.1.1 - update_data is update-specific data that depend on the workOrderStatus Returns jrpc 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 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").hex() 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.nonce = crypto.string_to_byte_array( input_json_temp["params"]["requesterNonce"]) self.nonce_hash = (crypto.byte_array_to_base64( crypto.compute_message_hash(self.nonce))).encode('UTF-8') self.set_requester_nonce( crypto.byte_array_to_base64( crypto.compute_message_hash(self.nonce))) else: self.nonce = crypto.random_bit_string(NO_OF_BYTES) self.nonce_hash = (crypto.byte_array_to_base64( crypto.compute_message_hash(self.nonce))).encode('UTF-8') self.set_requester_nonce( crypto.byte_array_to_base64( crypto.compute_message_hash(self.nonce))) 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)