def add_encrypted_request_hash(self): """ calculates request has 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.byte_array_to_base64( crypto.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.compute_message_hash(concat_hash) encrypted_request_hash = utility.encrypt_data(self.final_hash, self.session_key, self.session_iv) self.params_obj["encryptedRequestHash"] = crypto.byte_array_to_hex( encrypted_request_hash)
def calculate_request_hash(self, input_json): """ Function to create the work order reuest 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.byte_array_to_base64( crypto.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.compute_message_hash(concat_hash) final_hash_str = crypto.byte_array_to_hex(final_hash) return final_hash_str
def __init__(self, work_order_id, worker_id, workload_id, requester_id, session_key, session_iv, requester_nonce, verifying_key=None, payload_format="JSON-RPC", response_timeout_msecs=6000, result_uri=None, notify_uri=None, worker_encryption_key=None, data_encryption_algorithm=None): self.params_obj = {} self.set_work_order_id(work_order_id) self.set_response_timeout_msecs(response_timeout_msecs) self.set_payload_format(payload_format) if result_uri: self.set_result_uri(result_uri) if notify_uri: self.set_notify_uri(notify_uri) self.set_worker_id(worker_id) self.set_workload_id(workload_id) self.set_requester_id(requester_id) if worker_encryption_key: self.set_worker_encryption_key( worker_encryption_key.encode("UTF-8").hex()) if data_encryption_algorithm: self.set_data_encryption_algorithm(data_encryption_algorithm) encrypted_session_key = utility.generate_encrypted_key( session_key, worker_encryption_key) self.set_encrypted_session_key( crypto.byte_array_to_hex(encrypted_session_key)) self.session_iv = session_iv self.set_session_key_iv(crypto.byte_array_to_hex(session_iv)) self.set_requester_nonce(requester_nonce) self.params_obj["encryptedRequestHash"] = "" self.params_obj["requesterSignature"] = "" self.params_obj["inData"] = [] self.session_key = session_key
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 = utility.strip_begin_end_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 main(): logging.info("Executing Unit test cases for encryption at client") msg = "This is client request" iv = utility.generate_sessioniv() enc_sess_key = test_encrypt_session_key(iv) if enc_sess_key: enc_data = test_encrypt_data(iv, enc_sess_key[:16], msg) if enc_data: b64_enc_data = crypto.byte_array_to_base64(enc_data) iv_hex = crypto.byte_array_to_hex(iv) test_decrypt_data(iv_hex, enc_sess_key[:16], msg, b64_enc_data) logging.info( "Unit test case execution for encryption/decryption complete.")
def __validate_work_order_receipt_update_req(self, wo_receipt_req): """ Function to validate the work order receipt create request parameters Parameters: - wo_receipt_req is work order receipt request as dictionary Returns - tuple containing validation status(Boolean) and error message(string) """ valid_params = [ "workOrderId", "updaterId", "updateType", "updateData", "updateSignature", "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", "updaterId"]: if not is_valid_hex_str(wo_receipt_req[key]): return False, "invalid data parameter for " + key elif key in ["updateData", "updateSignature"]: try: base64.b64decode(wo_receipt_req[key]) except Exception: return False, "Invalid data format for " + key update_type = wo_receipt_req["params"]["updateType"] try: update_enum_value = ReceiptCreateStatus(update_type) except Exception as err: return False, "Invalid receipt update type {}: {}".format( update_enum_value, str(err)) # If update type is completed or processed, # it is a hash value of the Work Order Response if wo_receipt_req["params"]["updateType"] in [ ReceiptCreateStatus.PROCESSED.value, ReceiptCreateStatus.COMPLETED.value ]: wo_id = wo_receipt_req["params"]["workOrderId"] # Load the work order response and calculate it's hash wo_resp = self.kv_helper.get("wo-responses", wo_id) wo_resp_bytes = bytes(wo_resp, "UTF-8") wo_resp_hash = crypto.compute_message_hash(wo_resp_bytes) wo_resp_hash_str = crypto.byte_array_to_hex(wo_resp_hash) if wo_resp_hash_str != wo_receipt_req["params"]["updateData"]: return False, "Invalid Update data in the request" # If all validation is pass return True, ""
def hashed_identity(self): key_byte_array = crypto.string_to_byte_array(self.txn_public) hashed_txn_key = crypto.compute_message_hash(key_byte_array) encoded_hashed_key = crypto.byte_array_to_hex(hashed_txn_key) encoded_hashed_key = encoded_hashed_key.lower() return encoded_hashed_key