Ejemplo n.º 1
0
    def __init__(self, config):

        super().__init__()

        self._config = config
        worker_id = config.get("WorkerConfig")["worker_id"]
        self._worker_id = hex_utils.get_worker_id_from_name(worker_id)
        self._kv_helper = self._connect_to_kv_store()
        self._worker_kv_delegate = WorkerKVDelegate(self._kv_helper)
        self._wo_kv_delegate = WorkOrderKVDelegate(self._kv_helper,
                                                   self._worker_id)
        signup_data, measurements = self._setup_enclave()
        self.enclave_data = signup_data
        self.sealed_data = signup_data.sealed_data
        self.verifying_key = signup_data.verifying_key
        self.encryption_key = signup_data.encryption_key

        # TODO: encryption_key_nonce is hardcoded to an empty str
        # Need to come up with a scheme to generate it for every unique
        # encryption key.
        self.encryption_key_nonce = ""
        self.encryption_key_signature = signup_data.encryption_key_signature
        self.enclave_id = signup_data.enclave_id
        self.extended_measurements = measurements
        self.proof_data = signup_data.proof_data
Ejemplo n.º 2
0
    def __init__(self, config):

        super().__init__()

        self._config = config
        worker_id = config.get("WorkerConfig")["worker_id"]
        self._worker_id = hex_utils.get_worker_id_from_name(worker_id)
Ejemplo n.º 3
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
    # 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)
Ejemplo n.º 4
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)
Ejemplo n.º 5
0
def parse_command_line(args):
    """Setup and parse command line arguments and help information."""

    global worker_obj
    global worker_id
    global verbose
    global config
    global off_chain
    global requester_signature

    parser = argparse.ArgumentParser()
    use_service = parser.add_mutually_exclusive_group()
    parser.add_argument("-c",
                        "--config",
                        help="the config file containing the" +
                        " Ethereum contract information",
                        type=str)
    use_service.add_argument("-r",
                             "--registry-list",
                             help="the Ethereum address of the registry list",
                             type=str)
    use_service.add_argument("-s",
                             "--service-uri",
                             help="skip URI lookup and send to specified URI",
                             type=str)
    use_service.add_argument(
        "-o",
        "--off-chain",
        help="skip URI lookup and use the registry in the config file",
        action="store_true")
    optional_worker_id = parser.add_mutually_exclusive_group()
    optional_worker_id.add_argument(
        "-w",
        "--worker_id",
        help="skip worker lookup and retrieve specified worker (plain text)",
        type=str)
    optional_worker_id.add_argument(
        "-wx",
        "--worker_id_hex",
        help="skip worker lookup and retrieve specified worker (hex string)",
        type=str)
    parser.add_argument("-v",
                        "--verbose",
                        help="increase output verbosity",
                        action="store_true")
    parser.add_argument(
        "-rs",
        "--requester_signature",
        help="Enable requester signature for work order requests",
        action="store_true")

    options = parser.parse_args(args)

    if options.config:
        conf_files = [options.config]
    else:
        conf_files = [TCFHOME + "/sdk/avalon_sdk/tcf_connector.toml"]
    conf_paths = ["."]

    try:
        config = pconfig.parse_configuration_files(conf_files, conf_paths)
        json.dumps(config, indent=4)
    except pconfig.ConfigurationException as e:
        logger.error(str(e))
        sys.exit(-1)

    global direct_jrpc
    direct_jrpc = AvalonDirectClient(conf_files[0])

    # Whether or not to connect to the registry list on the blockchain
    off_chain = False

    if options.registry_list:
        config["ethereum"]["direct_registry_contract_address"] = \
            options.registry_list

    if options.service_uri:
        off_chain = True

    if options.off_chain:
        off_chain = True

    requester_signature = options.requester_signature

    verbose = options.verbose
    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)

    # Initializing Worker Object
    worker_obj = SGXWorkerDetails()
Ejemplo n.º 6
0
    def __init__(self, args):
        # Parse command line arguments
        options = self._parse_command_line(args)
        # Read config params
        if options.config:
            self._config = self._parse_config_file(options.config)
        else:
            self._config = self._parse_config_file(
                TCF_HOME + "/sdk/avalon_sdk/tcf_connector.toml")
        if self._config is None:
            logging.error("\n Error in parsing config file: {}\n")
            sys.exit(-1)
        if options.blockchain:
            self._config['blockchain']['type'] = options.blockchain
            self._blockchain = options.blockchain
        else:
            self._blockchain = self._config['blockchain']['type']

        self._is_direct_mode = False
        # Mode
        self._mode = options.mode

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

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

        bc_type = self._blockchain
        if self._uri or self._address:
            self._is_direct_mode = True
        elif bc_type == 'fabric' or bc_type == 'ethereum':
            self._is_direct_mode = False

        # worker id
        self._worker_id = options.worker_id
        self._worker_id_hex = options.worker_id_hex

        self._worker_id = self._worker_id_hex if not self._worker_id \
            else hex_utils.get_worker_id_from_name(self._worker_id)

        # work load id of worker
        self._workload_id = options.workload_id
        if not self._workload_id:
            logging.error("\nWorkload id is mandatory\n")
            sys.exit(-1)
        # work order input data
        self._in_data = options.in_data

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

        # show receipt in output
        self._show_receipt = options.receipt

        # show decrypted result in output
        self._show_decrypted_output = options.decrypted_output

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

        logging.info("******* Hyperledger Avalon Generic client *******")

        # mode should be one of listing or registry (default)
        if self._mode == "registry" and self._address:
            logging.error("\n Worker registry contract"
                          " address is unsupported \n")
            sys.exit(-1)
Ejemplo n.º 7
0
def ParseCommandLine(args):
    global worker_obj
    global worker_id
    global message
    global config
    global off_chain
    global requester_signature
    global input_data_hash

    parser = argparse.ArgumentParser()
    use_service = parser.add_mutually_exclusive_group()
    parser.add_argument(
        "-c",
        "--config",
        help="the config file containing the Ethereum contract information",
        type=str)
    use_service.add_argument("-r",
                             "--registry-list",
                             help="the Ethereum address of the registry list",
                             type=str)

    use_service.add_argument("-s",
                             "--service-uri",
                             help="skip URI lookup and send to specified URI",
                             type=str)

    use_service.add_argument(
        "-o",
        "--off-chain",
        help="skip URI lookup and use the registry in the config file",
        action="store_true")

    mutually_excl_group_worker = parser.add_mutually_exclusive_group(
        required=True)
    mutually_excl_group_worker.add_argument(
        "-w",
        "--worker_id",
        help="worker id in plain text to use to submit a work order",
        type=str)
    mutually_excl_group_worker.add_argument(
        "-wx",
        "--worker_id_hex",
        help="worker id as hex string to use to submit a work order",
        type=str)

    parser.add_argument(
        "-m",
        "--message",
        help='text message to be included in the JSON request payload',
        type=str)
    parser.add_argument(
        "-rs",
        "--requester-signature",
        help="Enable requester signature for work order requests",
        action="store_true")
    parser.add_argument("-dh",
                        "--data-hash",
                        help="Enable input data hash for work order requests",
                        action="store_true")

    options = parser.parse_args(args)
    if options.config:
        conf_files = [options.config]
    else:
        conf_files = [TCFHOME + "/sdk/avalon_sdk/tcf_connector.toml"]
    confpaths = ["."]
    try:
        config = pconfig.parse_configuration_files(conf_files, confpaths)
        config_json_str = json.dumps(config)
    except pconfig.ConfigurationException as e:
        logger.error(str(e))
        sys.exit(-1)

    # Whether or not to connect to the registry list on the blockchain
    off_chain = False

    if options.registry_list:
        config["ethereum"]["direct_registry_contract_address"] = \
            options.registry_list

    if options.service_uri:
        config["tcf"]["json_rpc_uri"] = options.service_uri
        off_chain = True

    if options.off_chain:
        off_chain = True

    global direct_jrpc
    direct_jrpc = AvalonDirectClient(config=config)

    requester_signature = options.requester_signature
    input_data_hash = options.data_hash
    # 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)

    message = options.message
    if options.message is None or options.message == "":
        message = "Test Message"

    # Initializing Worker Object
    worker_obj = worker.SGXWorkerDetails()