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 = utility.strip_begin_end_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 test_strip_begin_end_key(self): """Tests to verify strip_begin_end_key(key) function """ expected = "123456aghdfgasdasdkommkf" # Positive case self.assertEquals(expected, strip_begin_end_key( "-----BEGIN PUBLIC KEY-----123456aghdfgas\n" "dasdkommkf-----END PUBLIC KEY-----")) expected = "123456aghdfgasdasdkommkf" # Interspersed with '\n' self.assertEquals(expected, strip_begin_end_key( "\n-----BEGIN PUBLIC KEY\n" "-----123456aghdfgas\n" "dasdkommkf\n" "-----END PUBLIC KEY-----\n")) expected = "123456+/aghdfgasdasdkommkf===" # Other base64 characters self.assertEquals(expected, strip_begin_end_key( "-----BEGIN PUBLIC KEY-----123456+/aghdfgasdasdkommkf===" "-----END PUBLIC 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 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'] self.worker_id = utility.strip_begin_end_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 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 = utils.strip_begin_end_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 is None: # create receipt logger.info("Creating receipt in boot flow") wo_receipt = create_receipt(wo, wo_json_resp) logger.info("Receipt created for workorder %s during boot", wo_receipt) kv_helper.set("wo-receipts", wo, wo_receipt) 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)