コード例 #1
0
def AddEnclaveSecrets(ledger_config, contract_id, client_keys, enclaves,
                      provclients):
    secrets = {}
    encrypted_state_encryption_keys = {}
    for enclave in enclaves:

        if use_pservice:
            psecrets = []
            for provclient in provclients:
                # Get a pspk:esecret pair from the provisioning service for each enclave
                sig_payload = crypto.string_to_byte_array(enclave.enclave_id +
                                                          contract_id)
                secretinfo = provclient.get_secret(
                    enclave.enclave_id, contract_id, client_keys.verifying_key,
                    client_keys.sign(sig_payload))
                logger.debug("pservice secretinfo: %s", secretinfo)

                # Add this pspk:esecret pair to the list
                psecrets.append(secretinfo)
        else:
            psecrets = secret_helper.create_secrets_for_services(
                provclients, enclave.enclave_keys, contract_id,
                client_keys.identity)

        # Print all of the secret pairs generated for this particular enclave
        logger.debug('psecrets for enclave %s : %s', enclave.enclave_id,
                     psecrets)

        # Verify those secrets with the enclave
        esresponse = enclave.verify_secrets(contract_id,
                                            client_keys.verifying_key,
                                            psecrets)
        logger.debug("verify_secrets response: %s", esresponse)

        # Store the ESEK mapping in a dictionary key'd by the enclave's public key (ID)
        encrypted_state_encryption_keys[
            enclave.enclave_id] = esresponse['encrypted_state_encryption_key']

        # Add this spefiic enclave to the contract
        if use_ledger:
            contract_helper.add_enclave_to_contract(
                ledger_config, client_keys, contract_id, enclave.enclave_id,
                psecrets, esresponse['encrypted_state_encryption_key'],
                esresponse['signature'])

    return encrypted_state_encryption_keys
コード例 #2
0
def CreateAndRegisterContract(config, enclave, contract_creator_keys):
    global txn_dependencies

    data_dir = config['PDO']['DataPath']

    ledger_config = config.get('Sawtooth')
    contract_creator_id = contract_creator_keys.identity

    contract_name = config['contract']
    contract_code = contract_helper.ContractCode.create_from_scheme_file(
        contract_name, search_path=[".", "..", "contracts"])

    # create the provisioning servers
    if use_pservice:
        pservice_urls = config.get("pservice-urls")
        provisioning_services = list(
            map(lambda url: pservice_helper.ProvisioningServiceClient(url),
                pservice_urls))
    else:
        provisioning_services = secret_helper.create_provisioning_services(
            config['secrets'])
    provisioning_service_keys = list(
        map(lambda svc: svc.identity, provisioning_services))

    try:
        if use_ledger:
            contract_id = contract_helper.register_contract(
                ledger_config, contract_creator_keys, contract_code,
                provisioning_service_keys)
            logger.info('contract registration successful; %s', contract_id)
        else:
            contract_id = crypto.byte_array_to_base64(
                crypto.compute_message_hash(crypto.random_bit_string(256)))
            logger.info('no ledger config; skipping contract registration')
    except Exception as e:
        logger.error('failed to register the contract; %s', str(e))
        sys.exit(-1)

    contract_state = contract_helper.ContractState.create_new_state(
        contract_id)
    contract = contract_helper.Contract(contract_code, contract_state,
                                        contract_id, contract_creator_id)

    # --------------------------------------------------
    logger.info('create the provisioning secrets')
    # --------------------------------------------------
    if use_pservice:
        secret_list = []
        for pservice in provisioning_services:
            logger.debug('ask pservice %s to generate a secret for %s',
                         pservice.ServiceURL, contract_id)
            message = enclave.enclave_id + contract_id
            signature = contract_creator_keys.sign(message, encoding='hex')
            secret = pservice.get_secret(enclave.enclave_id, contract_id,
                                         contract_creator_keys.verifying_key,
                                         signature)
            if secret is None:
                logger.error('failed to create secret for %s',
                             pservice.ServiceURL)
                sys.exit(-1)
            secret_list.append(secret)
    else:
        secret_list = secret_helper.create_secrets_for_services(
            provisioning_services, enclave.enclave_keys, contract_id,
            contract_creator_id)

    logger.debug('secrets: %s', secret_list)

    try:
        secretinfo = enclave.verify_secrets(contract_id, contract_creator_id,
                                            secret_list)
        assert secretinfo

        encrypted_state_encryption_key = secretinfo[
            'encrypted_state_encryption_key']
        signature = secretinfo['signature']

    except Exception as e:
        logger.error('failed to create the state encryption key; %s', str(e))
        sys.exit(-1)

    try:
        if not secrets.verify_state_encryption_key_signature(
                encrypted_state_encryption_key, secret_list, contract_id,
                contract_creator_id, signature, enclave.enclave_keys):
            raise RuntimeError('signature verification failed')
    except Exception as e:
        logger.error('failed to verify the state encryption key; %s', str(e))
        sys.exit(-1)

    logger.info('encrypted state encryption key: %s',
                encrypted_state_encryption_key)

    # --------------------------------------------------
    logger.info('add the provisioned enclave to the contract')
    # --------------------------------------------------
    try:
        if use_ledger:
            txnid = contract_helper.add_enclave_to_contract(
                ledger_config,
                contract_creator_keys,
                contract_id,
                enclave.enclave_id,
                secret_list,
                encrypted_state_encryption_key,
                signature,
                transaction_dependency_list=txn_dependencies)
            txn_dependencies = [txnid]

            logger.info('contract state encryption key added to contract')
        else:
            logger.info(
                'no ledger config; skipping state encryption key registration')
    except Exception as e:
        logger.error('failed to add state encryption key; %s', str(e))
        sys.exit(-1)

    contract.set_state_encryption_key(enclave.enclave_id,
                                      encrypted_state_encryption_key)
    contract.save_to_file(contract_name, data_dir=data_dir)

    # --------------------------------------------------
    logger.info('create the initial contract state')
    # --------------------------------------------------
    try:
        initialize_request = contract.create_initialize_request(
            contract_creator_keys, enclave)
        initialize_response = initialize_request.evaluate()
        contract.set_state(initialize_response.encrypted_state)

    except Exception as e:
        logger.error('failed to create the initial state; %s', str(e))
        sys.exit(-1)

    logger.info('enclave created initial state')

    # --------------------------------------------------
    logger.info('save the initial state in the ledger')
    # --------------------------------------------------
    try:
        if use_ledger:
            logger.info("sending to ledger")
            # note that we will wait for commit of the transaction before
            # continuing; this is not necessary in general (if there is
            # confidence the transaction will succeed) but is useful for
            # testing
            txnid = initialize_response.submit_initialize_transaction(
                ledger_config,
                wait=30,
                transaction_dependency_list=txn_dependencies)
            txn_dependencies = [txnid]
        else:
            logger.info('no ledger config; skipping iniatialize state save')
    except Exception as e:
        logger.error('failed to save the initial state; %s', str(e))
        sys.exit(-1)

    contract.contract_state.save_to_cache(data_dir=data_dir)

    return contract
コード例 #3
0
def CreateAndRegisterContract(config, contract_info, creator_keys):
    ledger_config = config.get('Sawtooth')
    contract_config = config.get('Contract')

    contract_creator_id = creator_keys.identity

    contract_name = contract_info['Name']
    source_file = contract_info['Source']
    search_path = contract_config['SourceSearchPath']
    contract_code = ContractCode.create_from_scheme_file(
        contract_name, source_file, search_path=search_path)

    # --------------------------------------------------
    logger.info('register the contract')
    # --------------------------------------------------
    pservice_urls = contract_info.get("ProvisioningServices")
    provisioning_services = list(
        map(lambda url: ProvisioningServiceClient(url), pservice_urls))
    provisioning_service_keys = list(
        map(lambda svc: svc.identity, provisioning_services))

    contract_id = register_contract(ledger_config, creator_keys, contract_code,
                                    provisioning_service_keys)
    logger.info('registered the contract as %s', contract_id)

    contract_state = ContractState.create_new_state(contract_id)
    contract = Contract(contract_code, contract_state, contract_id,
                        contract_creator_id)

    # --------------------------------------------------
    logger.info('provision enclaves')
    # --------------------------------------------------
    eservice_urls = contract_info.get("EnclaveServices")
    enclave_services = list(
        map(lambda url: GetEnclaveServiceByURL(url), eservice_urls))

    for eservice in enclave_services:
        secret_list = []
        for pservice in provisioning_services:
            message = pcrypto.string_to_byte_array(eservice.enclave_id +
                                                   contract_id)
            signature = creator_keys.sign(message)
            secret = pservice.get_secret(eservice.enclave_id, contract_id,
                                         creator_keys.verifying_key, signature)
            secret_list.append(secret)

        secretinfo = eservice.verify_secrets(contract_id, contract_creator_id,
                                             secret_list)
        encrypted_state_encryption_key = secretinfo[
            'encrypted_state_encryption_key']
        signature = secretinfo['signature']

        txnid = add_enclave_to_contract(ledger_config, creator_keys,
                                        contract_id, eservice.enclave_id,
                                        secret_list,
                                        encrypted_state_encryption_key,
                                        signature)

        contract.set_state_encryption_key(eservice.enclave_id,
                                          encrypted_state_encryption_key)

    # --------------------------------------------------
    logger.info('create the initial contract state')
    # --------------------------------------------------
    eservice = random.choice(enclave_services)
    initialize_request = contract.create_initialize_request(
        creator_keys, eservice)
    initialize_response = initialize_request.evaluate()
    if initialize_response.status is False:
        emessage = initialize_response.result
        logger.warn('initialization for contract %s failed; %s', contract_name,
                    emessage)
        raise Exception('initialization failed; {}'.format(emessage))

    contract.set_state(initialize_response.encrypted_state)

    logger.info('initial state created')

    # --------------------------------------------------
    logger.info('save the initial state in the ledger')
    # --------------------------------------------------
    txnid = initialize_response.submit_initialize_transaction(ledger_config,
                                                              wait=30)

    return contract