def test_write_result_data_to_json_file(self): """Tests to verify function write_result_data_to_json_file(file_name,input_data, data_dir ='./') """ input_data = '{"result":1,"field2":2}' file_name = "write_sample.json" write_result_data_to_json_file(file_name, input_data) read_json = read_json_file("write_sample.json", ["./"]) # with extension case self.assertEqual('{"Result": 1}', read_json) try: os.remove(file_name) except OSError: pass file_name = "write_sample" write_result_data_to_json_file(file_name, input_data) read_json = read_json_file("write_sample.json", ["./"]) # positive case self.assertEqual('{"Result": 1}', read_json) try: os.remove(file_name + ".json") except OSError: pass input_data = '{"field1":1,"field2":2}' # No attribute 'result' file_name = "write_sample.json" self.assertRaises(ValueError, write_result_data_to_json_file, file_name, input_data)
def test_read_json_file(self): """Tests to verify read_json_file(input_file,data_dir) function """ input_json = read_json_file( "sample1.json", [FILE_PATH]) # positive case self.assertEqual(input_json, '{"field1": 1,"field2": 2}') input_json = read_json_file( "sample2.json", [FILE_PATH]) # positive case self.assertEqual(input_json, '{"field1":1,"field2":2}') input_json = read_json_file( "sample3.json", [FILE_PATH]) # positive case self.assertEqual(input_json, '{1:"one",2:"two",3:["one","two","three"]}')
def test_generate_client_signature(): logging.info("Testing generate_client_signature...") worker_obj = worker.SGXWorkerDetails() worker_obj.encryption_key = worker_enc_key encrypted_session_key = crypto_utility.generate_encrypted_key( session_key, worker_obj.encryption_key) encrypted_session_key_hex = \ crypto_utility.byte_array_to_hex(encrypted_session_key) read_json = read_json_file("wo_request.json", ["./"]) wo_submit_request = json.loads(read_json) wo_request = wo_submit_request["params"] wo_request["workOrderId"] = work_order_id wo_request["workerId"] = worker_id wo_request["requesterId"] = requester_id wo_request["sessionKeyIv"] = session_key_iv wo_request["encryptedSessionKey"] = encrypted_session_key_hex wo_request["requesterNonce"] = requester_nonce try: input_json_str = json.dumps(wo_submit_request) input_json_str, status = sig_obj.generate_client_signature( input_json_str, worker_obj, client_private_key, session_key, session_iv, encrypted_session_key) if status == SignatureStatus.PASSED: logging.info("PASSED: generate_client_signature") return 0 else: logging.info("FAILED: generate_client_signature") return 1 except Exception as err: return 1
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 test_work_order_complete_error(self): """ This function verifies if work order complete function succeeds when there is an error in work order execution. """ read_json = read_json_file("work_order_get_result_error.json", ["./"]) wo_id = urandom(32).hex() result = self.__eth_conn.work_order_complete(wo_id, read_json) self.assertEqual(result, 0, "Work order result submission should succeed")
def test_calculate_datahash(): read_json = read_json_file("wo_request.json", ["./"]) wo_request = json.loads(read_json)["params"]["inData"] try: result_hash = sig_obj.calculate_datahash(wo_request) logging.info("PASSED: calculate_datahash") return 0 except Exception as err: logging.info("FAILED: calculate_datahash") return 1
def test_work_order_submit_mismatch(self): read_json = read_json_file("work_order_req.json", ["./"]) wo_id = urandom(32).hex() worker_id = urandom(32).hex() requester_id = urandom(32).hex() wo_req = json.loads(read_json)["params"] wo_req["workOrderId"] = wo_id wo_req["workerId"] = urandom(32).hex() # Different workerId wo_req["requesterId"] = requester_id result = self.__eth_conn.work_order_submit(wo_id, worker_id, requester_id, json.dumps(wo_req)) self.assertEqual(result, 1, "Work order sumbissoin should fail")
def test_work_order_submit_positive(self): read_json = read_json_file("work_order_req.json", ["./"]) wo_id = urandom(32).hex() worker_id = urandom(32).hex() requester_id = urandom(32).hex() wo_req = json.loads(read_json)["params"] wo_req["workOrderId"] = wo_id wo_req["workerId"] = worker_id wo_req["requesterId"] = requester_id result = self.__eth_conn.work_order_submit(wo_id, worker_id, requester_id, json.dumps(wo_req)) self.assertEqual(result, 0, "Work order should pass")
def test_calculate_response_hash(): read_json = read_json_file( "wo_response.json", ["./"]) wo_response = json.loads(read_json)["result"] wo_response["workOrderId"] = work_order_id wo_response["workerId"] = worker_id wo_response["requesterId"] = requester_id wo_response["workerNonce"] = worker_nonce try: resp_hash = sig_obj.calculate_response_hash(wo_response) logging.info("PASSED: calculate_response_hash") return 0 except Exception as err: logging.info("FAILED: calculate_response_hash") return 1
def test_calculate_request_hash(): read_json = read_json_file("wo_request.json", ["./"]) wo_request = json.loads(read_json)["params"] wo_request["workOrderId"] = work_order_id wo_request["workerId"] = worker_id wo_request["requesterId"] = requester_id wo_request["sessionKeyIv"] = session_key_iv wo_request["requesterNonce"] = requester_nonce try: resp_hash = sig_obj.calculate_request_hash(wo_request) logging.info("PASSED: calculate_request_hash") return 0 except Exception as err: logging.info("FAILED: calculate_request_hash") return 1
def test_verify_create_receipt_signature(): read_json = read_json_file("wo_receipt_request.json", ["./"]) wo_receipt_request = json.loads(read_json) wo_receipt_req_params = wo_receipt_request["params"] wo_receipt_req_params["workOrderId"] = work_order_id wo_receipt_req_params["workerId"] = worker_id wo_receipt_req_params["requesterNonce"] = requester_nonce wo_receipt_req_params["receiptVerificationKey"] = client_public_key # generate hash wo_receipt_str = wo_receipt_req_params["workOrderId"] + \ wo_receipt_req_params["workerServiceId"] + \ wo_receipt_req_params["workerId"] + \ wo_receipt_req_params["requesterId"] + \ str(wo_receipt_req_params["receiptCreateStatus"]) + \ wo_receipt_req_params["workOrderRequestHash"] + \ wo_receipt_req_params["requesterGeneratedNonce"] wo_receipt_bytes = bytes(wo_receipt_str, "UTF-8") wo_receipt_hash = crypto_utility.compute_message_hash(wo_receipt_bytes) try: # sign hash status, wo_receipt_sign = sig_obj.generate_signature( wo_receipt_hash, client_private_key) wo_receipt_req_params["requesterSignature"] = wo_receipt_sign # test verify signature status = sig_obj.verify_create_receipt_signature(wo_receipt_request) if status == SignatureStatus.PASSED: logging.info("PASSED: verify_create_receipt_signature") return 0 else: logging.info("FAILED: verify_create_receipt_signature") return 1 except Exception as err: logging.info("FAILED: verify_create_receipt_signature") return 1
def local_main(config): 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_str1 = 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_str1: # 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 session_iv = enclave_helper.generate_iv() session_key = enclave_helper.generate_key() encrypted_session_key = enclave_helper.generate_encrypted_key( session_key, worker_obj.encryption_key) input_json_str1, status = sig_obj.generate_client_signature( input_json_str1, worker_obj, private_key, session_key, session_iv, encrypted_session_key) if status != SignatureStatus.PASSED: LOGGER.info("Generate signature failed\n") exit(1) if input_json_str1 is None: continue # ----------------------------------------------------------------- # Update the worker ID if response: if "workerId" in input_json_str1: # 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(): input_json_final = json.loads(input_json_str1) 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) # ----------------------------------------------------------------- if "WorkOrderGetResult" in input_json_str1 or \ "WorkOrderReceiptRetrieve": input_json_obj = json.loads(input_json_str1) input_json_obj["params"]["workOrderId"] = wo_id input_json_str1 = json.dumps(input_json_obj) LOGGER.info("*********Request Json********* \n%s\n", input_json_str1) response = uri_client._postmsg(input_json_str1) LOGGER.info("**********Received Response*********\n%s\n", response) # ----------------------------------------------------------------- # Worker details are loaded into Worker_Obj if "WorkerRetrieve" in input_json_str1 and "result" in response: worker_obj.load_worker(response) # ----------------------------------------------------------------- # Poll for "WorkOrderGetResult" and break when you get the result while ("WorkOrderGetResult" in input_json_str1 and "result" not in response): if response["error"]["code"] != WorkOrderStatus.PENDING: break response = uri_client._postmsg(input_json_str1) LOGGER.info("Received Response: %s, \n \n ", response) time.sleep(3) # ----------------------------------------------------------------- # Verify the signature if "WorkOrderGetResult" in input_json_str1: if "error" in response: # Response has error, hence skip Signature verification LOGGER.info("Work order response has error; " "skipping signature verification") continue sig_bool = sig_obj.verify_signature( response, worker_obj.verification_key) try: if sig_bool > 0: LOGGER.info("Signature Verified") enclave_helper.decrypted_response( response, session_key, session_iv) else: LOGGER.info("Signature verification Failed") exit(1) except Exception as e: LOGGER.error("ERROR: Failed to analyze " + "Signature Verification") 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)
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)
def LocalMain(config): 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 = GenericServiceClient(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_str1 = 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_str1: # Update workorder ID and workerId 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 input_json_str1 = json.dumps(input_json_obj) #Generate session iv an encrypted session key session_iv = enclave_helper.generate_sessioniv() encrypted_session_key = enclave_helper.generate_encrypted_session_key( session_iv, worker_obj.worker_encryption_key) input_json_str1 = sig_obj.generate_client_signature( input_json_str1, worker_obj, private_key, session_iv, encrypted_session_key) if input_json_str1 is None: continue #---------------------------------------------------------------------------------- # Update the worker ID if response: if "workerId" in input_json_str1: #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]) input_json_str1 = json.dumps(input_json_final) logger.info( "**********Worker details Updated with Worker ID*********\n%s\n", input_json_str1) #----------------------------------------------------------------------------------- if "WorkOrderGetResult" in input_json_str1 or "WorkOrderReceiptRetrieve": input_json_obj = json.loads(input_json_str1) input_json_obj["params"]["workOrderId"] = wo_id input_json_str1 = json.dumps(input_json_obj) logger.info("*********Request Json********* \n%s\n", input_json_str1) response = uri_client._postmsg(input_json_str1) logger.info("**********Received Response*********\n%s\n", response) #----------------------------------------------------------------------------------- #Worker details are loaded into Worker_Obj if "WorkerRetrieve" in input_json_str1 and "result" in response: worker_obj.load_worker(response) #---------------------------------------------------------------------------------- # Polling for the "WorkOrderGetResult" and break when you get the result while ("WorkOrderGetResult" in input_json_str1 and "result" not in response): if response["error"]["code"] == 9: break response = uri_client._postmsg(input_json_str1) logger.info("Received Response : %s, \n \n ", response) time.sleep(3) #---------------------------------------------------------------------------------- #Verify the signature if ("WorkOrderGetResult" in input_json_str1): sig_bool = sig_obj.verify_signature(json.dumps(response), worker_obj) try: if sig_bool > 0: logger.info("Signature Verified") else: logger.info("Signature Failed") except: logger.error( "ERROR: Failed to analyze Signature Verification") 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) logger.info("Received Response : %s , \n \n ", response) exit(0)
def test_verify_signature(): err_cnt = 0 read_json = read_json_file( "wo_response.json", ["./"]) wo_response = json.loads(read_json)["result"] wo_response["workOrderId"] = work_order_id wo_response["workerId"] = worker_id wo_response["requesterId"] = requester_id wo_response["workerNonce"] = worker_nonce try: # imitate worker signature SHA-256/RSA-OAEP-4096 response_hash = sig_obj.calculate_response_hash(wo_response) status, sign = sig_obj.generate_signature( response_hash, worker_signing_key) wo_response["workerSignature"] = sign # test 1 step verification status = sig_obj.verify_signature( wo_response, worker_verifying_key, requester_nonce) if status == SignatureStatus.PASSED: logging.info("PASSED: verify_signature (1 step)") else: logging.info("FAILED: verify_signature (1 step)") err_cnt += 1 except Exception as err: logging.info("FAILED: verify_signature (1 step)") err_cnt += 1 # generate extVerificationKey ext_private_key = crypto_utility.generate_signing_keys() ext_public_key = crypto_utility.get_verifying_key(ext_private_key) wo_response["extVerificationKey"] = ext_public_key # sign extVerificationKey with worker private key concat_string = wo_response["extVerificationKey"] + requester_nonce v_key_hash = crypto_utility.compute_message_hash( bytes(concat_string, 'UTF-8')) try: status, sign = \ sig_obj.generate_signature(v_key_hash, worker_signing_key) wo_response["extVerificationKeySignature"] = sign # Sign wo_response with extVerificationKey response_hash = sig_obj.calculate_response_hash(wo_response) status, sign = \ sig_obj.generate_signature(response_hash, ext_private_key) wo_response["workerSignature"] = sign # test 2 step verification status = sig_obj.verify_signature( wo_response, worker_verifying_key, requester_nonce) if status == SignatureStatus.PASSED: logging.info("PASSED: verify_signature (2 step)") else: logging.info("FAILED: verify_signature (2 step)") err_cnt += 1 except Exception as err: logging.info("FAILED: verify_signature (2 step)") err_cnt += 1 return err_cnt