def _start_kme_listener(self): """ This function reads the host_name and port for the listener to bind. It instantiates the KMEListener and starts it. This listener runs indefinitely processing requests received from WPEs. It terminates only when an exception occurs within start method os the listener instance. """ host_name, port = parse_bind_url( self._config["KMEListener"].get("bind")) rpc_methods = [ self.GetUniqueVerificationKey, self.RegisterWorkOrderProcessor, self.PreProcessWorkOrder ] self._kme_listener = KMEListener(rpc_methods) self._kme_listener.start(host_name, port)
class KeyManagementEnclaveManager(EnclaveManager): """ Class to manage key management enclave in a worker pool setup for processing work orders """ def __init__(self, config): super().__init__(config) self.proof_data_type = config.get("WorkerConfig")["ProofDataType"] # ------------------------------------------------------------------------- def _create_signup_data(self): """ Create KME signup data. Returns : signup_data - Relevant signup data to be used for requests to the enclave """ return enclave_info.\ KeyManagementEnclaveInfo(self._config, self._worker_id, EnclaveType.KME) # ------------------------------------------------------------------------- def _manager_on_boot(self): """ Executes Boot flow of enclave manager """ logger.info("Executing boot time procedure") # Cleanup all stale work orders for this worker which # used old worker keys self._wo_kv_delegate.cleanup_work_orders() # Clear all WPEs mapped to this worker_id (pool). WPEs will have # to register afresh to get into the pool now. self._worker_kv_delegate.cleanup_pool(self._worker_id) # Add a new worker worker_info = EnclaveManager.create_json_worker(self, self._config) # Hex string read from config which is 64 characters long self._worker_kv_delegate.add_new_worker(self._worker_id, worker_info) # ------------------------------------------------------------------------- def _execute_work_order(self, input_json_str, ext_data=""): """ Submits request to KME and retrieves the response Parameters : @param input_json_str - A JSON formatted str of the request @param ext_data - Extended data to pass to trusted code Returns : @returns json_response - A JSON formatted str of the response received from the enclave """ try: logger.info("Request sent to enclave %s", input_json_str) wo_request = work_order_request.SgxWorkOrderRequest( EnclaveType.KME, input_json_str, ext_data) wo_response = wo_request.execute() logger.info("_execute_work_order Done") try: json_response = json.dumps(wo_response, indent=4) logger.info("Response from enclave %s", json_response) except Exception as err: logger.error("ERROR: Failed to serialize JSON; %s", str(err)) except Exception as e: logger.error("failed to execute work order; %s", str(e)) wo_response = dict() wo_response["error"] = dict() wo_response["error"]["code"] = WorkOrderStatus.FAILED wo_response["error"]["message"] = str(e) json_response = json.dumps(wo_response, indent=4) return json_response # ------------------------------------------------------------------------- def start_enclave_manager(self): """ Execute boot flow and run time flow """ try: logger.info( "--------------- Starting Boot time flow ----------------") self._manager_on_boot() logger.info( "--------------- Boot time flow Complete ----------------") except Exception as err: logger.error("Failed to execute boot time flow; " + "exiting Intel SGX Enclave manager: {}".format(err)) exit(1) self._start_kme_listener() # ------------------------------------------------------------------------- def _start_kme_listener(self): """ This function reads the host_name and port for the listener to bind. It instantiates the KMEListener and starts it. This listener runs indefinitely processing requests received from WPEs. It terminates only when an exception occurs within start method os the listener instance. """ host_name, port = parse_bind_url( self._config["KMEListener"].get("bind")) rpc_methods = [ self.GetUniqueVerificationKey, self.RegisterWorkOrderProcessor, self.PreProcessWorkOrder ] self._kme_listener = KMEListener(rpc_methods) self._kme_listener.start(host_name, port) # ----------------------------------------------------------------- def GetUniqueVerificationKey(self, **params): """ RPC method registered with the KME listener to generate an unique verification key before a WPE registration. Parameters : @param params - variable-length argument list Returns : @returns response - A jrpc response """ logger.info("in kme_enclave_manager.py GetUniqueVerificationKey") try: wo_request = get_request_json("GetUniqueVerificationKey", random.randint(0, 100000)) wo_request["params"] = params wo_response = self._execute_work_order(json.dumps(wo_request), "") wo_response_json = json.loads(wo_response) data = {"workOrderId": wo_request["params"]["workOrderId"]} if "result" in wo_response_json: return wo_response_json["result"] else: logger.error("Could not get UniqueVerificationKey - %s", wo_response_json) # For all negative cases, response should have an error field. # Hence constructing JSONRPC error response with # error code and message mapped to KME enclave response err_code = wo_response_json["error"]["code"] err_msg = wo_response_json["error"]["message"] raise JSONRPCDispatchException(err_code, err_msg, data) except Exception as e: raise JSONRPCDispatchException(WorkOrderStatus.FAILED, str(e), data) # ----------------------------------------------------------------- def RegisterWorkOrderProcessor(self, **params): """ RPC method registered with the KME listener to register a WPE with a KME. Parameters : @param params - variable-length argument list Returns : @returns response - A jrpc response """ logger.info("in kme_enclave_manager.py RegisterWorkOrderProcessor") wo_request = get_request_json("RegisterWorkOrderProcessor", random.randint(0, 100000)) wo_request["params"] = params wo_response = self._execute_work_order(json.dumps(wo_request), "") wo_response_json = json.loads(wo_response) logger.info("kme_enclave_manager.py RegisterWorkOrderProcessor Done") if "result" in wo_response_json: return wo_response_json["result"] else: logger.error("Could not register WPE") return wo_response_json # ----------------------------------------------------------------- def PreProcessWorkOrder(self, **params): """ RPC method registered with the KME listener to pre-process a work order request. Parameters : @param params - variable-length argument list Returns : @returns response - A jrpc response """ wo_request = get_request_json("PreProcessWorkOrder", random.randint(0, 100000)) wo_request["params"] = params wo_response = self._execute_work_order(json.dumps(wo_request), "") wo_response_json = json.loads(wo_response) if "result" in wo_response_json: return wo_response_json["result"] else: logger.error("Could not preprocess work order at KME") # For all negative cases, response should have an error field. # Hence constructing JSONRPC error response with # error code and message mapped to KME enclave response err_code = wo_response_json["error"]["code"] err_msg = wo_response_json["error"]["message"] data = { "workOrderId": wo_response_json["error"]["data"]["workOrderId"] } raise JSONRPCDispatchException(err_code, err_msg, data)