def __encrypt_data(self, data, encrypted_data_encryption_key=None, data_iv=None): """ Encrypt data and encode in base64 format. If key is None or "" or null, use session key. If key is "-" skip encryption and just encode base64. Parameters: data Data to encrypt encrypted_data_encryption_key Encryption private key. Pass "-" for no encryption. Pass "" or None to encrypt with the session key data_iv IV for data Returns: Encrypted (if requested) and base64 encoded data. """ data = data.encode("UTF-8") if encrypted_data_encryption_key is None or \ encrypted_data_encryption_key == "" or \ encrypted_data_encryption_key == "null": enc_data = crypto_utility.encrypt_data( data, self.session_key, self.session_iv ) return crypto_utility.byte_array_to_base64(enc_data) elif encrypted_data_encryption_key == "-": # Skip encryption and just encode workorder data to # base64 format. enc_data = crypto_utility.byte_array_to_base64(data) return enc_data else: enc_data = crypto_utility.encrypt_data( data, encrypted_data_encryption_key, data_iv) return crypto_utility.byte_array_to_base64(enc_data)
def __encrypt_workorder_indata(self, input_json_params, session_key, session_iv, worker_encryption_key, data_key=None, data_iv=None): """ Function to encrypt inData of workorder Parameters: - input_json_params is inData and outData elements within the work order request as per Trusted Compute EEA API 6.1.7 Work Order Data Formats. - session_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. - data_key is a one time key generated by participant used to encrypt work order indata - data_iv is an initialization vector used along with data_key. Default is all zeros. """ indata_objects = input_json_params['inData'] input_json_params['inData'] = indata_objects logger.info("Encrypting Workorder Data") i = 0 for item in indata_objects: data = item['data'].encode('UTF-8') e_key = item['encryptedDataEncryptionKey'].encode('UTF-8') if (not e_key) or (e_key == "null".encode('UTF-8')): enc_data = crypto_utility.encrypt_data(data, session_key, session_iv) input_json_params['inData'][i]['data'] = \ crypto_utility.byte_array_to_base64(enc_data) logger.debug("encrypted indata - %s", crypto_utility.byte_array_to_base64(enc_data)) elif e_key == "-".encode('UTF-8'): # Skip encryption and just encode workorder data to # base64 format. input_json_params['inData'][i]['data'] = \ crypto_utility.byte_array_to_base64(data) else: enc_data = crypto_utility.encrypt_data(data, data_key, data_iv) input_json_params['inData'][i]['data'] = \ crypto_utility.byte_array_to_base64(enc_data) logger.debug("encrypted indata - %s", crypto_utility.byte_array_to_base64(enc_data)) i = i + 1 logger.debug("Workorder InData after encryption: %s", indata_objects)
def execute(self): serialized_byte_array = crypto.string_to_byte_array(self.work_order) encrypted_request = crypto.byte_array_to_base64(serialized_byte_array) logger.info( "------------------------sgx_work_order_request1------------------------------------" ) try: encoded_encrypted_response = self.enclave.HandleWorkOrderRequest( encrypted_request, self.ext_data) logger.info( "------------------------sgx_work_order_request2------------------------------------" ) assert encoded_encrypted_response except Exception as err: logger.info( "------------------------sgx_work_order_request3------------------------------------" ) logger.exception('workorder request invocation failed: %s', str(err)) raise logger.info( "------------------------sgx_work_order_request4------------------------------------" ) try: decrypted_response = crypto.base64_to_byte_array( encoded_encrypted_response) response_string = crypto.byte_array_to_string(decrypted_response) response_parsed = json.loads(response_string[0:-1]) except Exception as err: logger.exception('workorder response is invalid: %s', str(err)) raise return response_parsed
def __calculate_hash_on_concatenated_string(self, input_json_params, nonce): """ Function to calculate a hash value of the string concatenating the following values: requesterNonce, workOrderId, workerId, workloadId, and requesterId. Parameters: - input_json_params is a collection of parameters, as per Off-Chain Trusted Compute EEA API 6.1.1 Work Order Request Payload - nonce a random string generated by the participant. """ workorder_id = (input_json_params['workOrderId']).encode('UTF-8') worker_id = (input_json_params['workerId']).encode('UTF-8') workload_id = "".encode('UTF-8') if 'workloadId' in input_json_params: workload_id = (input_json_params['workloadId']).encode('UTF-8') requester_id = (input_json_params['requesterId']).encode('UTF-8') concat_string = nonce + workorder_id + worker_id + workload_id + \ requester_id concat_hash = bytes(concat_string) # SHA-256 hashing is used hash_1 = crypto_utility.compute_message_hash(concat_hash) result_hash = crypto_utility.byte_array_to_base64(hash_1) return result_hash
def add_encrypted_request_hash(self): """ Calculates request hash based on EEA trusted-computing spec 6.1.8.1 and set encryptedRequestHash parameter in the request. """ sig_obj = signature.ClientSignature() concat_string = self.get_requester_nonce() + \ self.get_work_order_id() + \ self.get_worker_id() + \ self.get_workload_id() + \ self.get_requester_id() concat_bytes = bytes(concat_string, "UTF-8") # SHA-256 hashing is used hash_1 = crypto_utility.byte_array_to_base64( crypto_utility.compute_message_hash(concat_bytes)) hash_2 = sig_obj.calculate_datahash(self.get_in_data()) hash_3 = "" out_data = self.get_out_data() if out_data and len(out_data) > 0: hash_3 = sig_obj.calculate_datahash(out_data) concat_hash = hash_1 + hash_2 + hash_3 concat_hash = bytes(concat_hash, "UTF-8") self.final_hash = crypto_utility.compute_message_hash(concat_hash) encrypted_request_hash = crypto_utility.encrypt_data( self.final_hash, self.session_key, self.session_iv) encrypted_request_hash_hex = crypto_utility.byte_array_to_hex( encrypted_request_hash) self.params_obj["encryptedRequestHash"] = encrypted_request_hash_hex
def create_receipt(self, wo_request, receipt_create_status, signing_key, nonce=None): """ Create a work order receipt corresponding to a workorder ID. Parameters: wo_request JSON RPC work order request used to create the work order request as defined in EEA spec 6.1.1 receipt_create_status Receipt creation status signing_key Private key of the signer nonce Optional random number or monotonic counter Returns: JSON RPC request of type dictionary """ wo_request_params = wo_request["params"] wo_request_hash = \ self.sig_obj.calculate_request_hash(wo_request_params) wo_request_hash_str = \ crypto_utility.byte_array_to_base64(wo_request_hash) worker_id = wo_request_params["workerId"] requester_nonce = nonce if nonce is None: requester_nonce = str(random.randint(1, 10**10)) public_key = signing_key.get_verifying_key().to_pem().decode('ascii') wo_receipt_request = { "workOrderId": wo_request_params["workOrderId"], # TODO: workerServiceId is same as worker id, # needs to be updated with actual service id "workerServiceId": worker_id, "workerId": worker_id, "requesterId": wo_request_params["requesterId"], "receiptCreateStatus": receipt_create_status, "workOrderRequestHash": wo_request_hash_str, "requesterGeneratedNonce": requester_nonce, "signatureRules": self.HASHING_ALGORITHM + "/" + self.SIGNING_ALGORITHM, "receiptVerificationKey": public_key } wo_receipt_str = wo_receipt_request["workOrderId"] + \ wo_receipt_request["workerServiceId"] + \ wo_receipt_request["workerId"] + \ wo_receipt_request["requesterId"] + \ str(wo_receipt_request["receiptCreateStatus"]) + \ wo_receipt_request["workOrderRequestHash"] + \ wo_receipt_request["requesterGeneratedNonce"] wo_receipt_bytes = bytes(wo_receipt_str, "UTF-8") wo_receipt_hash = crypto_utility.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 generate signature is failed. wo_receipt_request["requesterSignature"] = "" raise Exception("Generate signature is failed") else: wo_receipt_request["requesterSignature"] = wo_receipt_sign return wo_receipt_request
def _encrypt_and_sign_response(self, session_key, session_key_iv, output_json): """ Encrypt outdata and compute worker signature. Parameters : session_key: Session key of the client which submitted this work order session_key_iv: iv corresponding to teh session key output_json: Pre-populated response json Returns : JSON RPC response with worker signature """ # Encrypt outData self.encrypt.encrypt_work_order_data_json( output_json["result"]["outData"], session_key, session_key_iv) # Compute worker signature res_hash = worker_hash.WorkerHash().calculate_response_hash( output_json["result"]) res_hash_sign = self.sign.sign_message(res_hash) res_hash_sign_b64 = crypto_utility.byte_array_to_base64(res_hash_sign) output_json["result"]["workerSignature"] = res_hash_sign_b64 return output_json
def _create_work_order_response(self, input_json, out_data, session_key, session_key_iv): """ Creates work order response JSON object. Parameters : input_json: JSON work order request out_data: output data dictionary which has data in plain text session_key: Session key of the client which submitted this work order session_key_iv: iv corresponding to teh session key Returns : JSON RPC response containing result. """ output_json = dict() output_json["jsonrpc"] = "2.0" output_json["id"] = input_json["id"] output_json["result"] = dict() output_json["result"]["workloadId"] = \ input_json["params"]["workloadId"] output_json["result"]["workOrderId"] = \ input_json["params"]["workOrderId"] output_json["result"]["workerId"] = \ input_json["params"]["workerId"] output_json["result"]["requesterId"] = \ input_json["params"]["requesterId"] workerNonce = ''.join(random.choices(string.ascii_uppercase + string.digits, k=16)) output_json["result"]["workerNonce"] = \ crypto_utility.byte_array_to_base64( workerNonce.encode("UTF-8")) output_json["result"]["outData"] = [out_data] return self._encrypt_and_sign_response( session_key, session_key_iv, output_json)
def calculate_request_hash(self, input_json): """ Function to create the work order request hash as defined in EEA spec 6.1.8.1 Parameters: - input_json is dictionary contains work order request payload as define EEA spec 6.1.1 Returns hash of work order request as string """ wo_request_params = input_json["params"] concat_string = wo_request_params["requesterNonce"] + \ wo_request_params["workOrderId"] + \ wo_request_params["workerId"] + \ wo_request_params["workloadId"] + \ wo_request_params["requesterId"] concat_bytes = bytes(concat_string, "UTF-8") # SHA-256 hashing is used hash_1 = crypto_utility.byte_array_to_base64( crypto_utility.compute_message_hash(concat_bytes)) hash_2 = self.calculate_datahash(wo_request_params["inData"]) hash_3 = "" if "outData" in wo_request_params and \ len(wo_request_params["outData"]) > 0: hash_3 = self.calculate_datahash(wo_request_params["outData"]) concat_hash = hash_1 + hash_2 + hash_3 concat_hash = bytes(concat_hash, "UTF-8") final_hash = crypto_utility.compute_message_hash(concat_hash) final_hash_str = crypto_utility.byte_array_to_hex(final_hash) return final_hash_str
def calculate_datahash(self, data_objects): """ Function to calculate a hash value of the array concatenating dataHash, data, encryptedDataEncryptionKey, iv for each item in the inData/outData array Parameters: - data_objects is each item in inData or outData part of workorder request as per Trusted Compute EEA API 6.1.7 Work Order Data Formats """ hash_str = "" # Sort the data items based on index field before calculating data hash data_objects.sort(key=lambda x: x['index']) for item in data_objects: datahash = "".encode('UTF-8') e_key = "".encode('UTF-8') iv = "".encode('UTF-8') if 'dataHash' in item: datahash = item['dataHash'].encode('UTF-8') data = item['data'].encode('UTF-8') if 'encryptedDataEncryptionKey' in item: e_key = item['encryptedDataEncryptionKey'].encode('UTF-8') if 'iv' in item: iv = item['iv'].encode('UTF-8') concat_string = datahash + data + e_key + iv concat_hash = bytes(concat_string) hash = crypto_utility.compute_message_hash(concat_hash) hash_str = hash_str + crypto_utility.byte_array_to_base64(hash) return hash_str
def generate_signature(self, hash, private_key): """ Function to generate signature object Parameters: - hash is the combined array of all hashes calculated on the message - private_key is Client private key Returns tuple(status, signature) """ try: self.private_key = private_key self.public_key = \ crypto_utility.get_verifying_key(private_key) signature_res = \ self.private_key.sign_digest_deterministic( bytes(hash), sigencode=sigencode_der) signature_base64 = crypto_utility.byte_array_to_base64( signature_res) except Exception as err: logger.error("Exception occurred during signature generation: %s", str(err)) return False, None return True, signature_base64
def encrypt_work_order_data_json(self, data_objects, session_key, session_iv=None): """ Function to encrypt inData/outData of workorder. Function iterate through the inData/outData items and encrypt the data using DataEncryptionKey/Session key. inData/outData data field is updated with enrypted data. Parameters: data_objects: inData/outData elements within the work order request as per Trusted Compute EEA API 6.1.7 Work Order Data Formats. session_key: one-time symmetric encryption key generated by the participant submitting the work order. session_iv: initialization vector if required by the data encryption algorithm. The default is None. """ data_objects.sort(key=lambda x: x['index']) i = 0 for item in data_objects: data = item['data'] if 'encryptedDataEncryptionKey' in item: e_key = item['encryptedDataEncryptionKey'] else: e_key = None if (not e_key) or (e_key == "null"): enc_data = self.encrypt_data(data, session_key, session_iv) item['data'] = crypto_utility.byte_array_to_base64(enc_data) elif e_key == "-": # Skip encryption and just encode workorder data to # base64 format. item['data'] = crypto_utility.byte_array_to_base64(data) else: if 'iv' in item: data_iv = item['iv'] else: data_iv = None # Decrypt data key data_key = self.decrypt_data_encryption_key( e_key, data_iv, sesssion_key) enc_data = self.encrypt_data(data, data_key, data_iv) item['data'] = crypto_utility.byte_array_to_base64(enc_data) i = i + 1
def _create_work_order_response(self, input_json, out_data, session_key, session_key_iv): """ Creates work order response JSON object. Parameters : input_json: JSON work order request out_data: output data dictionary which has data in plain text session_key: Session key of the client which submitted this work order session_key_iv: iv corresponding to teh session key Returns : JSON RPC response containing result. """ output_json = dict() output_json["jsonrpc"] = "2.0" output_json["id"] = input_json["id"] output_json["result"] = dict() output_json["result"]["workloadId"] = \ input_json["params"]["workloadId"] output_json["result"]["workOrderId"] = \ input_json["params"]["workOrderId"] output_json["result"]["workerId"] = \ input_json["params"]["workerId"] output_json["result"]["requesterId"] = \ input_json["params"]["requesterId"] workerNonce = ''.join( random.choices(string.ascii_uppercase + string.digits, k=16)) output_json["result"]["workerNonce"] = \ crypto_utility.byte_array_to_base64( workerNonce.encode("UTF-8")) output_json["result"]["outData"] = [out_data] # Encrypt outData self.encrypt.encrypt_work_order_data_json( output_json["result"]["outData"], session_key, session_key_iv) # Compute worker signature res_hash = worker_hash.WorkerHash().calculate_response_hash( output_json["result"]) res_hash_sign = self.sign.sign_message(res_hash) res_hash_sign_b64 = crypto_utility.byte_array_to_base64(res_hash_sign) output_json["result"]["workerSignature"] = res_hash_sign_b64 return output_json
def add_requester_signature(self, private_key): """ Calculate the signature of the request as defined in Off-Chain Trusted Compute EEA spec 6.1.8.3 and set the requesterSignature parameter in the request. """ signature = self.signer.sign_message(req_hash) if status is True: self.params_obj["requesterSignature"] = \ crypto_utility.byte_array_to_base64(signature) # public signing key is shared to enclave manager to # verify the signature. # It is temporary approach to share the key with the worker. verifying_key = self.signer.get_public_sign_key(private_key) self.set_verifying_key(verifying_key) return True else: logger.error("Signing request failed") return False
def EncryptionKeyGet(self, **params): """ Function to process get encryption key request. Parameters: - param is the 'param' object in the a worker request as per TCF API 6.1.10 Get Encryption Key Request Payload """ worker_id = str(params['workerId']) value = self.kv_helper.get("workers", worker_id) if value is None: raise JSONRPCDispatchException( WorkerError.INVALID_PARAMETER_FORMAT_OR_VALUE, "Worker id not found in the database. Hence invalid parameter") worker_type_data = json.loads(value).get("details").get( "workerTypeData") encryptionKey = worker_type_data["encryptionKey"] try: encryptionKeyNonce = worker_type_data["encryptionKeyNonce"] except Exception: encryptionKeyNonce = crypto.generate_random_string(NO_OF_BYTES) tag = "" # calculate signature concat_string = worker_id.encode('UTF-8') + encryptionKey.encode( 'UTF-8') + encryptionKeyNonce.encode('UTF-8') + tag.encode('UTF-8') concat_hash = bytes(concat_string) hash_1 = worker_hash.WorkerHash().compute_message_hash(concat_hash) s1 = crypto.byte_array_to_base64(hash_1) # Requires worker private key to sign. # signature = self.PrivateKey.SignMessage(hash) result = { "workerId": worker_id, "encryptionKey": encryptionKey, "encryptionKeyNonce": encryptionKeyNonce, "tag": "", "signature": s1, } return result
def calculate_wo_pre_proc_keys_hash(self, pre_proc_json): """ Computes hash on pre-processed work order keys(by KME worker) Parameters: pre_proc_json: Pre processed JSON(by KME worker) having work order keys needed in encrypted format to process client work order request Returns: Computed hash of pre-processed work order keys in bytes """ concat_hash = crypto_utility.byte_array_to_base64( self.encrypted_sym_key) + \ crypto_utility.byte_array_to_base64(self.encrypted_wo_key) + \ crypto_utility.byte_array_to_base64(self.encrypted_sig_key) hash_1 = worker_hash.WorkerHash().compute_message_hash( concat_hash.encode("utf-8")) hash_1_str = crypto_utility.byte_array_to_base64(hash_1) # Compute hash of input-data-keys in_data_key_hash_str = "" for key in pre_proc_json['input-data-keys']: in_data_key_hash_str += crypto_utility.byte_array_to_base64( worker_hash.WorkerHash().compute_message_hash( crypto_utility.base64_to_byte_array( key['encrypted-data-key']))) # Compute hash on output-data-keys out_data_key_hash_str = "" for key in pre_proc_json['output-data-keys']: out_data_key_hash_str += crypto_utility.byte_array_to_base64( worker_hash.WorkerHash().compute_message_hash( crypto_utility.base64_to_byte_array( key['encrypted-data-key']))) final_hash = hash_1_str.encode("utf-8") + \ in_data_key_hash_str.encode("utf-8") + \ out_data_key_hash_str.encode("utf-8") return worker_hash.WorkerHash().compute_message_hash(final_hash)
def __validate_work_order_receipt_create_req(self, wo_receipt_req, wo_request): """ Function to validate the work order receipt create request parameters Parameters: - wo_receipt_req is work order receipt request as dictionary - wo_request is string containing jrpc work order request Returns - tuple containing validation status(Boolean) and error message(string) """ # Valid parameters list valid_params = [ "workOrderId", "workerServiceId", "workerId", "requesterId", "receiptCreateStatus", "workOrderRequestHash", "requesterGeneratedNonce", "requesterSignature", "signatureRules", "receiptVerificationKey" ] for key in wo_receipt_req["params"]: if key not in valid_params: return False, "Missing parameter " + key + " in the request" else: if key in [ "workOrderId", "workerServiceId", "workerId", "requesterId", "requesterGeneratedNonce" ]: if not is_valid_hex_str(wo_receipt_req["params"][key]): return False, "invalid data parameter for " + key elif key in ["workOrderRequestHash", "requesterSignature"]: try: base64.b64decode(wo_receipt_req["params"][key]) except Exception as e: return False, \ "Invalid data format for " + key receipt_type = wo_receipt_req["params"]["receiptCreateStatus"] try: receipt_enum_type = ReceiptCreateStatus(receipt_type) except Exception as err: return False, "Invalid receipt status type {}: {}".format( receipt_enum_type, str(err)) # Validate signing rules signing_rules = wo_receipt_req["params"]["signatureRules"] rules = signing_rules.split("/") if len(rules) == 2 and (rules[0] != self.HASHING_ALGORITHM or rules[1] != self.SIGNING_ALGORITHM): return False, "Unsupported the signing rules" # Verify work order request is calculated properly or not. json_wo_request = json.loads(wo_request) wo_request_params = json_wo_request["params"] wo_request_hash = \ self.hasher.calculate_request_hash(wo_request_params) wo_request_hash_str = \ crypto_utility.byte_array_to_base64(wo_request_hash) expected_hash_str = wo_receipt_req["params"]["workOrderRequestHash"] if wo_request_hash_str != expected_hash_str: return False, "Work order request hash does not match" # Verify requester signature with signing key in the request status = self.signer.verify_create_receipt_signature(wo_receipt_req) if status != SignatureStatus.PASSED: return False, "Receipt create requester signature does not match" # If all parameters are verified in the request return True, ""
def local_main(config): global input_json_str if not input_json_str and not input_json_dir: LOGGER.error("JSON input file is not provided") exit(1) if not output_json_file_name: LOGGER.error("JSON output file is not provided") exit(1) if not server_uri: LOGGER.error("Server URI is not provided") exit(1) LOGGER.info("Execute work order") uri_client = HttpJrpcClient(server_uri) response = None wo_id = None if input_json_dir: directory = os.fsencode(input_json_dir) files = os.listdir(directory) for file in sorted(files): LOGGER.info("---------------- Input file name: %s -------------\n", file.decode("utf-8")) input_json_str = futils.read_json_file( (directory.decode("utf-8") + file.decode("utf-8"))) # ----------------------------------------------------------------- # If Client request is WorkOrderSubmit, a requester payload's # signature with the requester private signing key is generated. if "WorkOrderSubmit" in input_json_str: # Update workOrderId , workerId and workloadId input_json_obj = json.loads(input_json_str) wo_id = hex(random.randint(1, 2**64 - 1)) input_json_obj["params"]["workOrderId"] = wo_id input_json_obj["params"]["workerId"] = 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 encrypt = worker_encryption.WorkerEncrypt() # Generate session key, session iv and encrypted session key session_key = encrypt.generate_session_key() session_iv = encrypt.generate_iv() encrypted_session_key = encrypt.encrypt_session_key( session_key, worker_obj.encryption_key) input_json_obj["params"]["encryptedSessionKey"] = \ crypto_utility.byte_array_to_hex(encrypted_session_key) input_json_obj["params"]["sessionKeyIv"] = \ crypto_utility.byte_array_to_hex(session_iv) if "requesterNonce" in input_json_obj["params"]: if len(input_json_obj["params"]["requesterNonce"]) == 0: # [NO_OF_BYTES] 16 BYTES for nonce. # This is the recommendation by NIST to # avoid collisions by the "Birthday Paradox". requester_nonce = secrets.token_hex(NO_OF_BYTES) input_json_obj["params"]["requesterNonce"] = \ requester_nonce requester_nonce = input_json_obj["params"]["requesterNonce"] # Encode data in inData for data_obj in input_json_obj["params"]["inData"]: encoded_data = data_obj["data"].encode('UTF-8') data_obj["data"] = encoded_data # Encrypt inData encrypt.encrypt_work_order_data_json( input_json_obj["params"]["inData"], session_key, session_iv) req_hash = worker_hash.WorkerHash().calculate_request_hash( input_json_obj["params"]) encrypted_req_hash = encrypt.encrypt_data( req_hash, session_key, session_iv) input_json_obj["params"]["encryptedRequestHash"] = \ encrypted_req_hash.hex() signer = worker_signing.WorkerSign() signer.generate_signing_key() wo_req_sig = signer.sign_message(req_hash) input_json_obj["params"]["requesterSignature"] = \ crypto_utility.byte_array_to_base64(wo_req_sig) input_json_obj["params"]["verifyingKey"] = \ signer.get_public_sign_key().decode('utf-8') input_json_str = json.dumps(input_json_obj) if input_json_str is None: continue # ----------------------------------------------------------------- # Update the worker ID if response: if "workerId" in input_json_str: # Retrieve the worker id from the "WorkerRetrieve" # response and update the worker id information for # further json requests. if "result" in response and \ "ids" in response["result"].keys() and \ len(response["result"]["ids"]) > 0: input_json_final = json.loads(input_json_str) worker_id = response["result"]["ids"][0] input_json_final["params"]["workerId"] = worker_id input_json_str = json.dumps(input_json_final) LOGGER.info( "********** Worker details Updated with " "Worker ID*********\n%s\n", input_json_str) # ----------------------------------------------------------------- if "WorkOrderGetResult" in input_json_str or \ "WorkOrderReceiptRetrieve" in input_json_str: input_json_obj = json.loads(input_json_str) input_json_obj["params"]["workOrderId"] = wo_id input_json_str = json.dumps(input_json_obj) LOGGER.info("*********Request Json********* \n%s\n", input_json_str) response = uri_client._postmsg(input_json_str) LOGGER.info("**********Received Response*********\n%s\n", response) # ----------------------------------------------------------------- # Worker details are loaded into Worker_Obj if "WorkerRetrieve" in input_json_str and "result" in response: worker_obj.load_worker(response["result"]["details"]) # ----------------------------------------------------------------- # Poll for "WorkOrderGetResult" and break when you get the result while ("WorkOrderGetResult" in input_json_str and "result" not in response): if response["error"]["code"] != WorkOrderStatus.PENDING: break response = uri_client._postmsg(input_json_str) LOGGER.info("Received Response: %s, \n \n ", response) time.sleep(3) # ----------------------------------------------------------------- # Verify the signature if "WorkOrderGetResult" in input_json_str: if "error" in response: # Response has error, hence skip Signature verification LOGGER.info("Work order response has error; " "skipping signature verification") continue sig_bool = signer.verify_signature(response['result'], worker_obj.verification_key, requester_nonce) try: if sig_bool > 0: LOGGER.info("Signature Verified") encrypt.decrypt_work_order_data_json( response['result']['outData'], session_key, session_iv) else: LOGGER.info("Signature verification Failed") exit(1) except Exception as e: LOGGER.error("ERROR: Failed to verify signature of " + "work order response") exit(1) # ----------------------------------------------------------------- else: LOGGER.info("Input Request %s", input_json_str) response = uri_client._postmsg(input_json_str) LOGGER.info("Received Response: %s , \n \n ", response) exit(0)