Beispiel #1
0
def _handle_ethereum_event(event, *kargs, **kwargs):
    """
    The function retrieves pertinent information from the event received
    """
    response = event["args"]
    if "result" not in response["workOrderResponse"]:
        logger.error(
            "Work order execution failed")
        sys.exit(1)
    show_decrypted_output = kargs[0]
    verification_key = kargs[1]
    session_key = kargs[2]
    session_iv = kargs[3]

    response_json = response["workOrderResponse"]["result"]
    if _verify_wo_res_signature(response_json, verification_key) is False:
        logger.error(
            "Work order response signature verification Failed")
        sys.exit(1)
    # Decrypt work order response
    if show_decrypted_output:
        decrypted_res = crypto_utility.decrypted_response(
            response_json, session_key, session_iv)
        logger.info("\nDecrypted response:\n {}"
                    .format(decrypted_res))
    sys.exit(1)
Beispiel #2
0
def _verify_work_order_response(res):
    # Verify work order response signature
    sig_obj = signature.ClientSignature()
    status = sig_obj.verify_signature(res, verification_key)
    if status == SignatureStatus.PASSED:
        logger.info("Signature verification Successful")
    else:
        logger.error("Signature verification Failed")
    decrypted_res = crypto_utility.decrypted_response(res, s_key, s_iv)
    logger.info("\nDecrypted response:\n {}".format(decrypted_res))
 def decrypt_wo_response(self, wo_res):
     """
     Decrypt work order response
     """
     try:
         decrypted_res = crypto_utility.decrypted_response(
             wo_res, self._session_key, self._session_iv)
     except Exception as ex:
         logging.error("Error in decrypting response {}".format(ex))
         return None
     return decrypted_res
Beispiel #4
0
    def register_wo_processor(self, unique_verification_id, encryption_key,
                              proof_data, mr_enclave):
        """
        Request to register this WPE with the KME

        Parameters :
            @param unique_verification_id - Unique verifying key received from
            KME.
            @param encryption_key - encryption key of WPE
            @param proof_data - The IAS attestation report/DCAP quote
            @param mr_enclave - MRENCLAVE for this WPE
        Returns :
            @returns status - The status of the registration.
                              True, for success. None, in case of errors.
        """
        workload_id = "kme-reg"
        registration_params = {
            "unique_id": unique_verification_id,
            "proof_data": proof_data,
            "wpe_encryption_key": encryption_key,
            "mr_enclave": mr_enclave
        }
        in_data = [json.dumps(registration_params)]

        # Create session key and iv to sign work order request
        session_key = crypto_utils.generate_key()
        session_iv = crypto_utils.generate_iv()

        wo_req = self._construct_wo_req(in_data, workload_id,
                                        self._worker.encryption_key,
                                        session_key, session_iv)

        response = self._post_and_get_result(wo_req)

        if "result" in response:
            wo_response_json = response["result"]
            if "error" not in wo_response_json and self._verify_res_signature(
                    wo_response_json, self._worker.verification_key,
                    wo_req["params"]["requesterNonce"]):
                decrypted_res = crypto_utils.decrypted_response(
                    wo_response_json, session_key, session_iv)
                # Response contains an array of results. In this case, the
                # array has single element and the data field is of interest.
                # It is integer with status of registration.
                return decrypted_res[0]['data']
            return None
        else:
            logger.error(
                "Could not register this WPE with the KME : {}".format(
                    response))
            return None
Beispiel #5
0
def decrypt_work_order_response(response, session_key, session_iv):
    decrypted_data = ""
    try:
        decrypted_data = enclave_helper.decrypted_response(
            response, session_key, session_iv)
        err_cd = 0
        logger.info('Success: Work Order Response Decrypted.\n\n')
    except Exception:
        err_cd = 1
        logger.info(
            'ERROR: Decryption failed %s \
                           where expected. \n', decrypted_data)
        logger.info('ERROR: Work Order Response Decryption Failed')

    return err_cd, decrypted_data
Beispiel #6
0
    def get_unique_verification_key(self, verification_key_nonce):
        """
        Request wrapper to get a unique id from the KME

        Parameters :
            @param verification_key_nonce - Random nonce generated by this WPE
        Returns :
            @returns result - Result received from the KME which includes the
                              public verification key which is supposed to be
                              included in REPORTDATA by the WPE. None, in case
                              of failure.
        """
        workload_id = "kme-uid"
        in_data = [verification_key_nonce]

        # Create session key and iv to sign work order request
        session_key = crypto_utils.generate_key()
        session_iv = crypto_utils.generate_iv()

        wo_req = self._construct_wo_req(in_data, workload_id,
                                        self._worker.encryption_key,
                                        session_key, session_iv)

        response = self._post_and_get_result(wo_req)

        if "result" in response:
            wo_response_json = response["result"]
            if self._verify_res_signature(wo_response_json,
                                          self._worker.verification_key,
                                          wo_req["params"]["requesterNonce"]):
                decrypted_res = crypto_utils.decrypted_response(
                    wo_response_json, session_key, session_iv)
                # Response contains an array of results. In this case, the
                # array has single element and the data field is of interest.
                # The data contains result,verification_key and
                # verification_key_signature delimited by ' '.
                # @TODO : Update to use multiple out_data fields.
                return decrypted_res[0]['data']
            return None
        else:
            logger.error(
                "Could not get a unique id from the KME : {}".format(response))
            return None
Beispiel #7
0
    def preprocess_work_order(self, wo_request, encryption_key):
        """
        Request to preprocess a work order

        Parameters :
            @param wo_request - The original work order request as str
            @param encryption_key - WPE's public encryption key
        Returns :
            @returns result - Result from KME that includes the workorder
                              key info. error response, in case of failure.
        """
        workload_id = "kme-preprocess"
        in_data = [wo_request, encryption_key]

        # Create session key and iv to sign work order request
        session_key = crypto_utils.generate_key()
        session_iv = crypto_utils.generate_iv()

        wo_req = self._construct_wo_req(in_data, workload_id,
                                        self._worker.encryption_key,
                                        session_key, session_iv)

        response = self._post_and_get_result(wo_req)

        if "result" in response:
            wo_response_json = response["result"]
            if self._verify_res_signature(wo_response_json,
                                          self._worker.verification_key,
                                          wo_req["params"]["requesterNonce"]):
                decrypted_res = crypto_utils.decrypted_response(
                    wo_response_json, session_key, session_iv)
                # Response contains an array of results. In this case, the
                # array has single element and the data field is of interest.
                return decrypted_res[0]['data']
            return None
        else:
            logger.error(
                "Could not preprocess work order at KME : {}".format(response))
            return response
def Main(args=None):
    options = _parse_command_line(args)

    config = _parse_config_file(options.config)
    if config is None:
        logger.error("\n Error in parsing config file: {}\n".format(
            options.config))
        sys.exit(-1)

    # mode should be one of listing or registry (default)
    mode = options.mode

    # Http JSON RPC listener uri
    uri = options.uri
    if uri:
        config["tcf"]["json_rpc_uri"] = uri
    # Setting blockchain type
    # if blockchain parameter is not passed, set to None
    # and None implies direct mode.
    blockchain = options.blockchain
    if blockchain:
        config['blockchain']['type'] = blockchain

    # Address of smart contract
    address = options.address
    if address:
        if mode == "listing":
            config["ethereum"]["direct_registry_contract_address"] = \
                address
        elif mode == "registry":
            logger.error(
                "\n Only Worker registry listing address is supported." +
                "Worker registry address is unsupported \n")
            sys.exit(-1)

    # worker id
    worker_id = options.worker_id
    worker_id_hex = options.worker_id_hex

    worker_id = worker_id_hex if not worker_id \
        else hex_utils.get_worker_id_from_name(worker_id)

    # work load id of worker
    workload_id = options.workload_id
    if not workload_id:
        logger.error("\nWorkload id is mandatory\n")
        sys.exit(-1)

    # work order input data
    in_data = options.in_data

    # show receipt in output
    show_receipt = options.receipt

    # show decrypted result in output
    show_decrypted_output = options.decrypted_output

    # requester signature for work order requests
    requester_signature = options.requester_signature

    # setup logging
    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("******* Hyperledger Avalon Generic client *******")

    if mode == "registry" and address:
        logger.error("\n Worker registry contract address is unsupported \n")
        sys.exit(-1)

    # Retrieve JSON RPC uri from registry list for direct mode.
    if not uri and mode == "listing":
        if not blockchain:
            uri = _retrieve_uri_from_registry_list(config)
            if uri is None:
                logger.error("\n Unable to get http JSON RPC uri \n")
                sys.exit(-1)

    # Prepare worker
    worker_registry = _create_worker_registry_instance(blockchain, config)
    worker_obj, worker_id = _get_first_active_worker(worker_registry,
                                                     worker_id, config)
    if worker_obj is None:
        logger.error("Cannot proceed without a valid worker")
        sys.exit(-1)
    # Create session key and iv to sign work order request
    session_key = crypto_utility.generate_key()
    session_iv = crypto_utility.generate_iv()

    s_key = session_key
    s_iv = session_iv
    logger.info(
        "**********Worker details Updated with Worker ID" + "*********\n%s\n",
        worker_id)

    # Create work order
    verification_key = worker_obj.verification_key
    code, wo_params = _create_work_order_params(worker_id, workload_id,
                                                in_data,
                                                worker_obj.encryption_key,
                                                session_key, session_iv)
    if not code:
        logger.error("Work order submission failed")
        exit(1)

    client_private_key = crypto_utility.generate_signing_keys()
    if requester_signature:
        # Add requester signature and requester verifying_key
        if wo_params.add_requester_signature(client_private_key) is False:
            logger.info("Work order request signing failed")
            exit(1)

    # Submit work order
    jrpc_req_id = random.randint(0, 100000)
    logger.info("Work order submit request : %s, \n \n ",
                wo_params.to_jrpc_string(jrpc_req_id))
    work_order = _create_work_order_instance(blockchain, config)
    jrpc_req_id += 1
    wo_id = wo_params.get_worker_id()
    response = work_order.work_order_submit(wo_params.get_work_order_id(),
                                            wo_params.get_worker_id(),
                                            wo_params.get_requester_id(),
                                            wo_params.to_string(),
                                            id=jrpc_req_id)
    logger.info("Work order submit response : {}\n ".format(response))

    if blockchain is None:
        if "error" in response and response["error"]["code"] != \
                WorkOrderStatus.PENDING:
            sys.exit(1)
    else:
        if response != ContractResponse.SUCCESS:
            sys.exit(1)

    # Create receipt
    wo_receipt = _create_work_order_receipt_instance(blockchain, config)
    if show_receipt and wo_receipt:
        jrpc_req_id += 1
        _create_work_order_receipt(wo_receipt, wo_params, client_private_key,
                                   jrpc_req_id)

    # Retrieve work order result
    res = _get_work_order_result(work_order, wo_params.get_work_order_id(),
                                 jrpc_req_id + 1)
    if res:
        logger.info("Work order get result : {}\n ".format(
            json.dumps(res, indent=4)))

        # Check if result field is present in work order response
        if "result" in res:
            # Verify work order response signature
            if _verify_wo_res_signature(res['result'],
                                        worker_obj.verification_key,
                                        wo_params.get_requester_nonce()) \
                    is False:
                logger.error(
                    "Work order response signature verification Failed")
                sys.exit(1)
            # Decrypt work order response
            if show_decrypted_output:
                decrypted_res = crypto_utility.decrypted_response(
                    res['result'], session_key, session_iv)
                logger.info("\nDecrypted response:\n {}".format(decrypted_res))
        else:
            logger.error("\n Work order get result failed {}\n".format(res))
            sys.exit(1)
    else:
        logger.error("\n Work order get result failed {}\n".format(res))
        sys.exit(1)

    if show_receipt and wo_receipt:
        # Retrieve receipt
        jrpc_req_id += 1
        retrieve_wo_receipt \
            = _retrieve_work_order_receipt(wo_receipt,
                                           wo_params, jrpc_req_id)
        # Verify receipt signature
        if _verify_receipt_signature(retrieve_wo_receipt) is False:
            logger.error("Receipt signature verification Failed")
            sys.exit(1)
Beispiel #9
0
def Main(args=None):
    options = _parse_command_line(args)

    config = _parse_config_file(options.config)
    if config is None:
        logger.error("\n Error in parsing config file: {}\n".format(
            options.config))
        sys.exit(-1)

    # mode should be one of listing or registry (default)
    mode = options.mode

    # Http JSON RPC listener uri
    uri = options.uri
    if uri:
        config["tcf"]["json_rpc_uri"] = uri

    # Address of smart contract
    address = options.address
    if address:
        if mode == "listing":
            config["ethereum"]["direct_registry_contract_address"] = \
                address
        elif mode == "registry":
            logger.error(
                "\n Only Worker registry listing address is supported." +
                "Worker registry address is unsupported \n")
            sys.exit(-1)

    # worker id
    worker_id = options.worker_id
    worker_id_hex = options.worker_id_hex

    worker_id = worker_id_hex if not worker_id \
        else hex_utils.get_worker_id_from_name(worker_id)

    # work load id of worker
    workload_id = options.workload_id
    if not workload_id:
        logger.error("\nWorkload id is mandatory\n")
        sys.exit(-1)

    # work order input data
    in_data = options.in_data

    # Option to send input data in plain text
    in_data_plain_text = options.in_data_plain

    # show receipt in output
    show_receipt = options.receipt

    # show decrypted result in output
    show_decrypted_output = options.decrypted_output

    # requester signature for work order requests
    requester_signature = options.requester_signature

    # setup logging
    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("******* Hyperledger Avalon Generic client *******")

    if mode == "registry" and address:
        logger.error("\n Worker registry contract address is unsupported \n")
        sys.exit(-1)

    # Retrieve JSON RPC uri from registry list
    if not uri and mode == "listing":
        uri = _retrieve_uri_from_registry_list(config)
        if uri is None:
            logger.error("\n Unable to get http JSON RPC uri \n")
            sys.exit(-1)

    # Prepare worker
    # JRPC request id. Choose any integer value
    jrpc_req_id = 31
    worker_registry = JRPCWorkerRegistryImpl(config)
    if not worker_id:
        # Get first worker from worker registry
        worker_id = _lookup_first_worker(worker_registry, jrpc_req_id)
        if worker_id is None:
            logger.error("\n Unable to get worker \n")
            sys.exit(-1)

    # Retrieve worker details
    jrpc_req_id += 1
    worker_retrieve_result = worker_registry.worker_retrieve(
        worker_id, jrpc_req_id)
    logger.info("\n Worker retrieve response: {}\n".format(
        json.dumps(worker_retrieve_result, indent=4)))

    if "error" in worker_retrieve_result:
        logger.error("Unable to retrieve worker details\n")
        sys.exit(1)

    # Create session key and iv to sign work order request
    session_key = crypto_utility.generate_key()
    session_iv = crypto_utility.generate_iv()

    # Initializing Worker Object
    worker_obj = worker_details.SGXWorkerDetails()
    worker_obj.load_worker(worker_retrieve_result['result']['details'])

    # Do worker verification
    _do_worker_verification(worker_obj)

    logger.info(
        "**********Worker details Updated with Worker ID" + "*********\n%s\n",
        worker_id)

    # Create work order
    if in_data_plain_text:
        # As per TC spec, if encryptedDataEncryptionKey is "-" then
        # input data is not encrypted
        encrypted_data_encryption_key = "-"
    else:
        # As per TC spec, if encryptedDataEncryptionKey is not
        # provided then set it to None which means
        # use default session key to encrypt input data
        encrypted_data_encryption_key = None

    wo_params = _create_work_order_params(worker_id, workload_id, in_data,
                                          worker_obj.encryption_key,
                                          session_key, session_iv,
                                          encrypted_data_encryption_key)

    client_private_key = crypto_utility.generate_signing_keys()
    if requester_signature:
        # Add requester signature and requester verifying_key
        if wo_params.add_requester_signature(client_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(jrpc_req_id))
    work_order = JRPCWorkOrderImpl(config)
    jrpc_req_id += 1
    response = work_order.work_order_submit(wo_params.get_work_order_id(),
                                            wo_params.get_worker_id(),
                                            wo_params.get_requester_id(),
                                            wo_params.to_string(),
                                            id=jrpc_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 = JRPCWorkOrderReceiptImpl(config)
    if show_receipt:
        jrpc_req_id += 1
        _create_work_order_receipt(wo_receipt, wo_params, client_private_key,
                                   jrpc_req_id)

    # Retrieve work order result
    jrpc_req_id += 1
    res = work_order.work_order_get_result(wo_params.get_work_order_id(),
                                           jrpc_req_id)

    logger.info("Work order get result : {}\n ".format(
        json.dumps(res, indent=4)))

    # Check if result field is present in work order response
    if "result" in res:
        # Verify work order response signature
        if _verify_wo_res_signature(res['result'], worker_obj.verification_key,
                                    wo_params.get_requester_nonce()) is False:
            logger.error("Work order response signature verification Failed")
            sys.exit(1)
        # Decrypt work order response
        if show_decrypted_output:
            decrypted_res = crypto_utility.decrypted_response(
                res['result'], session_key, session_iv)
            logger.info("\nDecrypted response:\n {}".format(decrypted_res))
    else:
        logger.error("\n Work order get result failed {}\n".format(res))
        sys.exit(1)

    if show_receipt:
        # Retrieve receipt
        jrpc_req_id += 1
        retrieve_wo_receipt \
            = _retrieve_work_order_receipt(wo_receipt,
                                           wo_params, jrpc_req_id)
        # Verify receipt signature
        if "result" in retrieve_wo_receipt:
            if _verify_receipt_signature(retrieve_wo_receipt) is False:
                logger.error("Receipt signature verification Failed")
                sys.exit(1)
        else:
            logger.info("Work Order receipt retrieve failed")
            sys.exit(1)
Beispiel #10
0
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
    wo_params = WorkOrderParams(
        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)))
Beispiel #11
0
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["result"]["details"])
            # -----------------------------------------------------------------

            # 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['result'], worker_obj.verification_key)
                try:
                    if sig_bool > 0:
                        LOGGER.info("Signature Verified")
                        enclave_helper.decrypted_response(
                            response['result'], 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)