def _construct_wo_req(self, in_data, workload_id, encryption_key, session_key, session_iv): """ Construct the parameters for a standard work order request Parameters : @param in_data - List of data to be passed to workload processor @param workload_id - Id of the target workload @encryption_key - Worker encryption key @session_key - Session key to be embedded in request @session_iv - Session key iv for encryption algorithm Returns : @returns A json request prepared using parameters passed """ # Create work order # Convert workloadId to hex workload_id_hex = workload_id.encode("UTF-8").hex() work_order_id = secrets.token_hex(32) requester_id = secrets.token_hex(32) requester_nonce = secrets.token_hex(16) # worker id is not known here. Hence passing a random string worker_id = secrets.token_hex(32) # Create work order params wo_params = WorkOrderParams() wo_params.create_request(work_order_id, worker_id, workload_id_hex, requester_id, session_key, session_iv, requester_nonce, result_uri=" ", notify_uri=" ", worker_encryption_key=encryption_key, data_encryption_algorithm="AES-GCM-256") for value in in_data: wo_params.add_in_data(value) # Encrypt work order request hash wo_params.add_encrypted_request_hash() return { "jsonrpc": "2.0", "id": random.randint(0, 100000), "params": json.loads(wo_params.to_string()), "method": self._jrpc_methods[workload_id] }
def create_work_order_params(self, worker_id, workload_id, in_data, worker_encrypt_key, session_key, session_iv, enc_data_enc_key): """ Create work order request params """ logging.info("worker_encrypt_key {}".format(worker_encrypt_key)) work_load_id = workload_id.encode("UTF-8").hex() self._work_order_id = secrets.token_hex(32) self._session_key = session_key self._session_iv = session_iv requester_id = secrets.token_hex(32) requester_nonce = secrets.token_hex(16) # Create work order params try: wo_params = WorkOrderParams() error = wo_params.create_request( self._work_order_id, worker_id, work_load_id, requester_id, self._session_key, self._session_iv, requester_nonce, worker_encryption_key=worker_encrypt_key, data_encryption_algorithm="AES-GCM-256") if error is not None: return False, error except Exception as err: logging.error("Exception occurred while " "creating work order request {}".format(err)) return False, None # Add worker input data for value in in_data: error = wo_params.add_in_data( value, encrypted_data_encryption_key=enc_data_enc_key) if error is not None: return False, error # Encrypt work order request hash error = wo_params.add_encrypted_request_hash() if error is not None: logging.error("Creating encrypted request hash failed") return False, error return True, wo_params
def evaluate(self, message): """Create and submit workorder and wait for result.""" self.result_text.set("Waiting for evaluation result...") self.update() # Create, sign, and submit workorder. # Convert workloadId to hex. workload_id = "heart-disease-eval" workload_id = workload_id.encode("UTF-8").hex() session_iv = utility.generate_iv() session_key = utility.generate_key() requester_nonce = secrets.token_hex(16) work_order_id = secrets.token_hex(32) requester_id = secrets.token_hex(32) wo_params = WorkOrderParams() wo_params.create_request( work_order_id, worker_id, workload_id, requester_id, session_key, session_iv, requester_nonce, result_uri=" ", notify_uri=" ", worker_encryption_key=worker_obj.encryption_key, data_encryption_algorithm="AES-GCM-256") wo_params.add_in_data(message) wo_params.add_encrypted_request_hash() private_key = utility.generate_signing_keys() if requester_signature: # Add requester signature and requester verifying_key if wo_params.add_requester_signature(private_key) is False: logger.info("Work order request signing failed") exit(1) # Set text for JSON sidebar req_id = 51 self.request_json = wo_params.to_jrpc_string(req_id) work_order_instance = direct_jrpc.get_work_order_instance() response = work_order_instance.work_order_submit( wo_params.get_work_order_id(), wo_params.get_worker_id(), wo_params.get_requester_id(), wo_params.to_string(), id=req_id) logger.info("Work order submit response : {}\n ".format( json.dumps(response, indent=4))) if "error" in response and response["error"]["code"] != \ WorkOrderStatus.PENDING: sys.exit(1) # Create work order receipt req_id += 1 wo_receipt_instance = direct_jrpc.get_work_order_receipt_instance() wo_request = json.loads(self.request_json) wo_receipt_obj = WorkOrderReceiptRequest() wo_create_receipt = wo_receipt_obj.create_receipt( wo_request, ReceiptCreateStatus.PENDING.value, private_key) logger.info("Work order create receipt request : {} \n \n ".format( json.dumps(wo_create_receipt, indent=4))) # Submit work order create receipt jrpc request wo_receipt_resp = wo_receipt_instance.work_order_receipt_create( wo_create_receipt["workOrderId"], wo_create_receipt["workerServiceId"], wo_create_receipt["workerId"], wo_create_receipt["requesterId"], wo_create_receipt["receiptCreateStatus"], wo_create_receipt["workOrderRequestHash"], wo_create_receipt["requesterGeneratedNonce"], wo_create_receipt["requesterSignature"], wo_create_receipt["signatureRules"], wo_create_receipt["receiptVerificationKey"], req_id) logger.info("Work order create receipt response : {} \n \n ".format( wo_receipt_resp)) # Retrieve result and set GUI result text res = work_order_instance.work_order_get_result(work_order_id, req_id) self.result_json = json.dumps(res, indent=4) if "result" in res: sig_obj = signature.ClientSignature() status = sig_obj.verify_signature(res['result'], worker_obj.verification_key, wo_params.get_requester_nonce()) try: if status == SignatureStatus.PASSED: logger.info("Signature verification Successful") decrypted_res = utility. \ decrypted_response( res['result'], session_key, session_iv) logger.info( "\n" + "Decrypted response:\n {}".format(decrypted_res)) else: logger.info("Signature verification Failed") sys.exit(1) except Exception as err: logger.info("ERROR: Failed to decrypt response: %s", str(err)) sys.exit(1) else: logger.info("\n Work order get result failed {}\n".format(res)) sys.exit(1) # Set text for JSON sidebar self.result_text.set(decrypted_res[0]["data"]) # Retrieve receipt # Set text for JSON sidebar req_id += 1 self.receipt_json = json.dumps( wo_receipt_instance.work_order_receipt_retrieve( work_order_id, req_id), indent=4)
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("***************** AVALON *****************") # Connect to registry list and retrieve registry if not off_chain: registry_list_instance = direct_jrpc.get_worker_registry_list_instance( ) # Lookup returns tuple, first element is number of registries and # second is element is lookup tag and # third is list of organization ids. registry_count, lookup_tag, registry_list = \ registry_list_instance.registry_lookup() logger.info("\n Registry lookup response: registry count: {} " + "lookup tag: {} registry list: {}\n".format( registry_count, lookup_tag, registry_list)) if (registry_count == 0): logger.warn("No registries found") sys.exit(1) # Retrieve the first registry details. registry_retrieve_result = registry_list_instance.registry_retrieve( registry_list[0]) logger.info("\n Registry retrieve response: {}\n".format( registry_retrieve_result)) config["tcf"]["json_rpc_uri"] = registry_retrieve_result[0] # Prepare worker req_id = 31 global worker_id worker_registry_instance = direct_jrpc.get_worker_registry_instance() if not worker_id: worker_lookup_result = worker_registry_instance.worker_lookup( worker_type=WorkerType.TEE_SGX, id=req_id) logger.info("\n Worker lookup response: {}\n".format( json.dumps(worker_lookup_result, indent=4))) 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) req_id += 1 worker_retrieve_result = worker_registry_instance.worker_retrieve( worker_id, req_id) logger.info("\n Worker retrieve response: {}\n".format( json.dumps(worker_retrieve_result, indent=4))) worker_obj.load_worker(worker_retrieve_result["result"]["details"]) logger.info( "**********Worker details Updated with Worker ID" + "*********\n%s\n", worker_id) # Convert workloadId to hex workload_id = "echo-result".encode("UTF-8").hex() work_order_id = secrets.token_hex(32) requester_id = secrets.token_hex(32) session_iv = utility.generate_iv() session_key = utility.generate_key() requester_nonce = secrets.token_hex(16) # Create work order request wo_params = WorkOrderParams() wo_params.create_request(work_order_id, worker_id, workload_id, requester_id, session_key, session_iv, requester_nonce, result_uri=" ", notify_uri=" ", worker_encryption_key=worker_obj.encryption_key, data_encryption_algorithm="AES-GCM-256") # Add worker input data if input_data_hash: # Compute data hash for data params inData data_hash = utility.compute_data_hash(message) # Convert data_hash to hex data_hash = hex_utils.byte_array_to_hex_str(data_hash) wo_params.add_in_data(message, data_hash) else: wo_params.add_in_data(message) # Encrypt work order request hash wo_params.add_encrypted_request_hash() private_key = utility.generate_signing_keys() if requester_signature: # Add requester signature and requester verifying_key if wo_params.add_requester_signature(private_key) is False: logger.info("Work order request signing failed") exit(1) # Submit work order logger.info("Work order submit request : %s, \n \n ", wo_params.to_jrpc_string(req_id)) work_order_instance = direct_jrpc.get_work_order_instance() req_id += 1 response = work_order_instance.work_order_submit( wo_params.get_work_order_id(), wo_params.get_worker_id(), wo_params.get_requester_id(), wo_params.to_string(), id=req_id) logger.info("Work order submit response : {}\n ".format( json.dumps(response, indent=4))) if "error" in response and response["error"]["code"] != \ WorkOrderStatus.PENDING: sys.exit(1) # Create receipt wo_receipt_instance = direct_jrpc.get_work_order_receipt_instance() req_id += 1 # Create work order receipt object using WorkOrderReceiptRequest class wo_request = json.loads(wo_params.to_jrpc_string(req_id)) wo_receipt_obj = WorkOrderReceiptRequest() wo_create_receipt = wo_receipt_obj.create_receipt( wo_request, ReceiptCreateStatus.PENDING.value, private_key) logger.info("Work order create receipt request : {} \n \n ".format( json.dumps(wo_create_receipt, indent=4))) # Submit work order create receipt jrpc request wo_receipt_resp = wo_receipt_instance.work_order_receipt_create( wo_create_receipt["workOrderId"], wo_create_receipt["workerServiceId"], wo_create_receipt["workerId"], wo_create_receipt["requesterId"], wo_create_receipt["receiptCreateStatus"], wo_create_receipt["workOrderRequestHash"], wo_create_receipt["requesterGeneratedNonce"], wo_create_receipt["requesterSignature"], wo_create_receipt["signatureRules"], wo_create_receipt["receiptVerificationKey"], req_id) logger.info("Work order create receipt response : {} \n \n ".format( wo_receipt_resp)) # Retrieve result req_id += 1 res = work_order_instance.work_order_get_result(work_order_id, req_id) logger.info("Work order get result : {}\n ".format( json.dumps(res, indent=4))) sig_obj = signature.ClientSignature() if "result" in res: status = sig_obj.verify_signature(res['result'], worker_obj.verification_key, wo_params.get_requester_nonce()) try: if status == SignatureStatus.PASSED: logger.info( "Work order response signature verification Successful") decrypted_res = utility.decrypted_response( res['result'], session_key, session_iv) logger.info("\nDecrypted response:\n {}".format(decrypted_res)) if input_data_hash: decrypted_data = decrypted_res[0]["data"] data_hash_in_resp = (decrypted_res[0]["dataHash"]).upper() # Verify data hash in response if utility.verify_data_hash(decrypted_data, data_hash_in_resp) is False: sys.exit(1) else: logger.info("Signature verification Failed") sys.exit(1) except Exception as err: logger.error("ERROR: Failed to decrypt response: %s", str(err)) sys.exit(1) else: logger.info("\n Work order get result failed {}\n".format(res)) sys.exit(1) # Retrieve receipt receipt_res = wo_receipt_instance.work_order_receipt_retrieve( work_order_id, id=req_id) logger.info("\n Retrieve receipt response:\n {}".format( json.dumps(receipt_res, indent=4))) # Retrieve last update to receipt by passing 0xFFFFFFFF req_id += 1 receipt_update_retrieve = \ wo_receipt_instance.work_order_receipt_update_retrieve( work_order_id, None, 1 << 32, id=req_id) logger.info("\n Last update to receipt receipt is:\n {}".format( json.dumps(receipt_update_retrieve, indent=4))) if "result" in receipt_update_retrieve: status = sig_obj.verify_update_receipt_signature( receipt_update_retrieve['result']) if status == SignatureStatus.PASSED: logger.info("Work order receipt retrieve signature" + " verification Successful") else: logger.info("Work order receipt retrieve signature" + " verification failed!!") sys.exit(1) else: logger.info("Work order receipt update failed") # Receipt lookup based on requesterId req_id += 1 receipt_lookup_res = wo_receipt_instance.work_order_receipt_lookup( requester_id=requester_id, id=req_id) logger.info("\n Work order receipt lookup response :\n {}".format( json.dumps(receipt_lookup_res, indent=4)))