コード例 #1
0
    def __init__(self, request, response, **kwargs):
        super().__init__(request, response, **kwargs)

        self.state_changed = True
        self.request_number = request.request_number
        self.operation = 'initialize'

        self.metadata_hash = crypto.base64_to_byte_array(
            response['MetadataHash'])
        self.signature = response['Signature']

        # save the information we will need for the transaction
        state_hash_b64 = response['StateHash']
        self.new_state_hash = crypto.base64_to_byte_array(state_hash_b64)

        message = self.serialize_for_signing()
        if not self.verify_enclave_signature(message, request.enclave_keys):
            raise InvocationException('failed to verify enclave signature')

        self.raw_state = self.enclave_service.get_block(state_hash_b64)
        self.new_state_object = ContractState(self.contract_id, self.raw_state)
        self.new_state_object.pull_state_from_eservice(self.enclave_service)

        # compute ids of blocks in the change set (used for replication)
        self.new_state_object.compute_ids_of_newblocks(
            request.contract_state.component_block_ids)
        self.replication_params = request.replication_params
コード例 #2
0
def compute_pdo_ccl_signature(private_key, enclave_id, enclave_signature,
                              channel_id, contract_id, creator_public_key_pem,
                              contract_code_hash, message_hash,
                              current_state_hash, previous_state_hash,
                              dependency_list):
    k = crypto.SIG_PrivateKey(private_key)
    message_byte_array = crypto.string_to_byte_array(enclave_id)
    message_byte_array += crypto.base64_to_byte_array(enclave_signature)
    message_byte_array += crypto.string_to_byte_array(channel_id)
    message_byte_array += crypto.string_to_byte_array(contract_id)
    message_byte_array += crypto.string_to_byte_array(creator_public_key_pem)
    message_byte_array += crypto.base64_to_byte_array(contract_code_hash)
    message_byte_array += crypto.base64_to_byte_array(message_hash)
    message_byte_array += crypto.base64_to_byte_array(current_state_hash)
    #in ccl initialize, previous state hash and dependencies are supposed to be empty
    if previous_state_hash:
        message_byte_array += crypto.base64_to_byte_array(previous_state_hash)
    for d in dependency_list:
        message_byte_array += crypto.string_to_byte_array(d.contract_id)
        message_byte_array += crypto.string_to_byte_array(d.state_hash)
    signature = k.SignMessage(message_byte_array)
    encoded_signature = crypto.byte_array_to_base64(signature)
    logger.debug("signed message string: " +
                 crypto.byte_array_to_base64(message_byte_array))
    logger.debug("signed message hash: " + crypto.byte_array_to_hex(
        crypto.compute_message_hash(message_byte_array)))
    logger.debug("signature: %s", encoded_signature)
    return encoded_signature
コード例 #3
0
    def ccl_update(self, channel_keys, contract_enclave_id, enclave_signature,
                   contract_id, message_hash, current_state_hash,
                   previous_state_hash, dependency_list, **extra_params):

        tx_method = "ccl_update"

        dependencies = []
        for dependency in dependency_list:
            temp = dict()
            temp['contract_id'] = dependency['contract_id']
            temp['state_hash'] = crypto.base64_to_byte_array(
                dependency['state_hash'])
            temp['state_hash_for_sign'] = dependency['state_hash']
            dependencies.append(temp)

        tx_params = PayloadBuilder.build_update_contract_state_transaction_from_data(
            channel_keys, contract_enclave_id,
            crypto.base64_to_byte_array(enclave_signature), contract_id,
            current_state_hash, previous_state_hash, message_hash,
            dependencies)

        try:
            response = self.ccf_client.submit_rpc(tx_method, tx_params)
            if response.result:  # result will be True for successful init transaction
                return tx_params['nonce']
            else:
                raise Exception(response.error)
        except Exception as e:
            raise
コード例 #4
0
    def ccl_initialize(
            self,
            channel_keys,
            contract_enclave_id,
            enclave_signature,
            contract_id,
            contract_code_hash,  # not used by CCF
            message_hash,
            initial_state_hash,
            contract_metadata_hash,
            **extra_params):

        tx_method = "ccl_initialize"

        tx_params = PayloadBuilder.build_initialize_contract_state_transaction_from_data(
            channel_keys, contract_enclave_id,
            crypto.base64_to_byte_array(enclave_signature), contract_id,
            message_hash, initial_state_hash, contract_metadata_hash,
            self.pdo_signer.signing_key)
        try:
            response = self.ccf_client.submit_rpc(tx_method, tx_params)
            if response.result:  # result will be True for successful init transaction
                return tx_params['nonce']
            else:
                raise Exception(response.error)
        except Exception as e:
            raise
コード例 #5
0
    def verify(self, message, encoded_signature, encoding='hex'):
        """
        verify the signature of a message from the agent

        :param message: the message for verification, no encoding
        :param signature: encoded signature
        :param encoding: the encoding used for the signature; one of raw, hex, b64
        """
        logger.debug("signature for verification: %s", encoded_signature)

        if type(message) is bytes:
            message_byte_array = message
        elif type(message) is tuple:
            message_byte_array = message
        else:
            message_byte_array = bytes(message, 'ascii')

        if encoding == 'raw':
            decoded_signature = encoded_signature
        elif encoding == 'hex':
            decoded_signature = crypto.hex_to_byte_array(encoded_signature)
        elif encoding == 'b64':
            decoded_signature = crypto.base64_to_byte_array(encoded_signature)
        else:
            raise ValueError('unknown encoding; {0}'.format(encoding))

        result = self._verifying_key.VerifySignature(message_byte_array,
                                                     decoded_signature)
        if result < 0:
            raise Error('malformed signature')

        return
コード例 #6
0
 def safe_filename(b64name):
     """the base64 encoding we use for contract_id and state_hash make
     them very poor file names; convert to hex for better behavior
     """
     decoded = crypto.base64_to_byte_array(b64name)
     encoded = crypto.byte_array_to_hex(decoded)
     return encoded[16:]
コード例 #7
0
    def __decrypt_response(self, response) :
        """
        decrypt the response using the session key

        :param response string: base64 encoded, encrypted with session key
        """
        decoded_response = crypto.base64_to_byte_array(response)
        return crypto.SKENC_DecryptMessage(self.session_key, decoded_response)
コード例 #8
0
    def __init__(self, request, response) :
        """
        Initialize a contract response object

        :param request: the ContractRequest object corresponding to the response
        :param response: diction containing the response from the enclave
        """

        self.status = response['Status']
        self.invocation_response_raw = response['InvocationResponse']
        self.invocation_response = invocation_response(response['InvocationResponse'])
        self.state_changed = response['StateChanged']
        self.new_state_object = request.contract_state
        #if the new state is same as the old state, then change set is empty
        self.new_state_object.changed_block_ids=[]
        self.request_number = request.request_number
        self.operation = request.operation

        if self.status and self.state_changed :
            self.signature = response['Signature']
            state_hash_b64 = response['StateHash']

            # we have another mismatch between the field names in the enclave
            # and the field names expected in the transaction; this needs to
            # be fixed at some point
            self.dependencies = []
            for dependency in response['Dependencies'] :
                contract_id = dependency['ContractID']
                state_hash = dependency['StateHash']
                self.dependencies.append({'contract_id' : contract_id, 'state_hash' : state_hash})

            # save the information we will need for the transaction
            self.channel_keys = request.channel_keys
            self.channel_id = request.channel_id
            self.contract_id = request.contract_id
            self.creator_id = request.creator_id
            self.code_hash = request.contract_code.compute_hash()
            self.message_hash = request.message.compute_hash()
            self.new_state_hash = crypto.base64_to_byte_array(state_hash_b64)

            self.originator_keys = request.originator_keys
            self.enclave_service = request.enclave_service

            self.old_state_hash = ()
            if request.operation != 'initialize' :
                self.old_state_hash = ContractState.compute_hash(request.contract_state.raw_state)

            if not self.__verify_enclave_signature(request.enclave_keys) :
                raise Exception('failed to verify enclave signature')

            self.raw_state = self.enclave_service.get_block(state_hash_b64)
            self.new_state_object = ContractState(self.contract_id, self.raw_state)
            self.new_state_object.pull_state_from_eservice(self.enclave_service)

            # compute ids of blocks in the change set (used for replication)
            self.new_state_object.compute_ids_of_newblocks(request.contract_state.component_block_ids)
            self.replication_params = request.replication_params
コード例 #9
0
    def verify_ledger_signature(cls, message, signature):
        """ Verify ledger signature. sign is base64 encoded. document is a string"""
        message_byte_array = bytes(message, 'ascii')
        decoded_signature = crypto.base64_to_byte_array(signature)
        result = cls.ccf_signature_verifyer.VerifySignature(message_byte_array, decoded_signature)
        if result < 0 :
            raise Exception('malformed signature');

        return result
コード例 #10
0
    def update_state(self, encrypted_state) :
        self.encrypted_state = encrypted_state
        self.component_block_ids = []

        if self.encrypted_state :
            b64_decoded_byte_array = crypto.base64_to_byte_array(self.encrypted_state)
            b64_decoded_string = crypto.byte_array_to_string(b64_decoded_byte_array).rstrip('\0')
            json_main_state_block = json.loads(b64_decoded_string)
            self.component_block_ids = json_main_state_block['BlockIds']
コード例 #11
0
    def compute_hash(encrypted_state, encoding='raw'):
        """ compute the hash of the encrypted state
        """
        state_byte_array = crypto.base64_to_byte_array(encrypted_state)
        state_hash = crypto.compute_message_hash(state_byte_array)
        if encoding == 'raw':
            return state_hash
        elif encoding == 'b64':
            return crypto.byte_array_to_base64(state_hash)
        elif encoding == 'hex':
            return crypto.byte_array_to_hex(state_hash)

        raise ValueError('unknown encoding; {}'.format(encoding))
コード例 #12
0
    def __init__(self, request, response) :
        """
        Initialize a contract response object

        :param request: the ContractRequest object corresponding to the response
        :param response: diction containing the response from the enclave
        """
        self.status = response['Status']
        self.result = response['Result']
        self.state_changed = response['StateChanged']

        if self.status and self.state_changed :
            self.signature = response['Signature']
            state_hash_b64 = response['StateHash']

            # we have another mismatch between the field names in the enclave
            # and the field names expected in the transaction; this needs to
            # be fixed at some point
            self.dependencies = []
            for dependency in response['Dependencies'] :
                contract_id = dependency['ContractID']
                state_hash = dependency['StateHash']
                self.dependencies.append({'contract_id' : contract_id, 'state_hash' : state_hash})

            # save the information we will need for the transaction
            self.channel_keys = request.channel_keys
            self.contract_id = request.contract_id
            self.creator_id = request.creator_id
            self.code_hash = request.contract_code.compute_hash()
            self.message_hash = request.message.compute_hash()
            self.new_state_hash = crypto.base64_to_byte_array(state_hash_b64)
            self.originator_keys = request.originator_keys
            self.enclave_service = request.enclave_service

            self.old_state_hash = ()
            if request.operation != 'initialize' :
                self.old_state_hash = ContractState.compute_hash(request.contract_state.encrypted_state)

            if not self.__verify_enclave_signature(request.enclave_keys) :
                raise Exception('failed to verify enclave signature')

            # Retrieve the encrypted state from the enclave's block store
            # Note that this channel is untrusted - must verify the retrieved data has the correct hash!
            # This is intentionally done after the signature verification
            encrypted_state_u_b64 = self.enclave_service.block_store_get(state_hash_b64)
            encrypted_state_u_hash_b64 = ContractState.compute_hash(encrypted_state_u_b64, encoding='b64')
            if (state_hash_b64 != encrypted_state_u_hash_b64):
                raise Exception('Encrypted state from block store has incorrect hash!')
            self.encrypted_state = encrypted_state_u_b64;
コード例 #13
0
    def __init__(self, request, response) :
        """
        Initialize a contract response object

        :param request: the ContractRequest object corresponding to the response
        :param response: diction containing the response from the enclave
        """
        self.status = response['Status']
        self.result = response['Result']
        self.state_changed = response['StateChanged']
        self.new_state_object = request.contract_state

        if self.status and self.state_changed :
            self.signature = response['Signature']
            state_hash_b64 = response['StateHash']

            # we have another mismatch between the field names in the enclave
            # and the field names expected in the transaction; this needs to
            # be fixed at some point
            self.dependencies = []
            for dependency in response['Dependencies'] :
                contract_id = dependency['ContractID']
                state_hash = dependency['StateHash']
                self.dependencies.append({'contract_id' : contract_id, 'state_hash' : state_hash})

            # save the information we will need for the transaction
            self.channel_keys = request.channel_keys
            self.contract_id = request.contract_id
            self.creator_id = request.creator_id
            self.code_hash = request.contract_code.compute_hash()
            self.message_hash = request.message.compute_hash()
            self.new_state_hash = crypto.base64_to_byte_array(state_hash_b64)
            self.originator_keys = request.originator_keys
            self.enclave_service = request.enclave_service

            self.old_state_hash = ()
            if request.operation != 'initialize' :
                self.old_state_hash = ContractState.compute_hash(request.contract_state.encrypted_state)

            if not self.__verify_enclave_signature(request.enclave_keys) :
                raise Exception('failed to verify enclave signature')

            self.encrypted_state = self.enclave_service.block_store_get(state_hash_b64)
            self.new_state_object = ContractState(self.contract_id, self.encrypted_state)
            self.new_state_object.pull_state_from_eservice(self.enclave_service)
コード例 #14
0
def serialize_for_signing(encrypted_state_key, secret_list, contract_id,
                          creator_id):
    """Create a buffer with the canonical serialization of secret list
    for verifying the signature from the enclave

    :param string encrypted_state_key: base64 encoded string
    :param array of dictionaries secret_list: dictionary defines values for pspk and encrypted_secret
    :param string contract_id: 16 character, hex encoded, sha256 hashed, registration transaction signature
    :param string creator_id: PEM encoded ECDSA verifying key
    """
    message = crypto.string_to_byte_array(contract_id)
    message += crypto.string_to_byte_array(creator_id)

    for secret in secret_list:
        message += crypto.string_to_byte_array(secret['pspk'])
        message += crypto.string_to_byte_array(secret['encrypted_secret'])

    message += crypto.base64_to_byte_array(encrypted_state_key)
    return message
コード例 #15
0
    def get_state_details(self,
        contract_id,
        state_hash):

        tx_method = "get_details_about_state"
        tx_params = PayloadBuilder.build_get_details_about_state_from_data(contract_id, \
            crypto.base64_to_byte_array(state_hash))

        state_details = self.submit_read_request_to_ccf(tx_method, tx_params)

        # verify ccf signature
        message = state_details["previous_state_hash"]
        message+= state_details["message_hash"]
        message+= state_details["transaction_id"]
        message+= state_details["dependency_list"]

        if not CCFSubmitter.verify_ledger_signature(message, state_details["signature"]):
            raise Exception("Invalid signature on Get State Details from CCF Ledger")

        return state_details
コード例 #16
0
    def __init__(self, request, response, **kwargs):
        super().__init__(request, response, **kwargs)

        self.state_changed = True
        self.request_number = request.request_number
        self.operation = 'update'

        self.signature = response['Signature']

        # we have another mismatch between the field names in the enclave
        # and the field names expected in the transaction; this needs to
        # be fixed at some point
        for dependency in response['Dependencies']:
            contract_id = dependency['ContractID']
            state_hash = dependency['StateHash']
            self.dependencies.append({
                'contract_id': contract_id,
                'state_hash': state_hash
            })

        # save the information we will need for the transaction
        state_hash_b64 = response['StateHash']
        self.new_state_hash = crypto.base64_to_byte_array(state_hash_b64)
        self.old_state_hash = ContractState.compute_hash(
            request.contract_state.raw_state)

        message = self.serialize_for_signing()
        if not self.verify_enclave_signature(message, request.enclave_keys):
            raise Exception('failed to verify enclave signature')

        self.raw_state = self.enclave_service.get_block(state_hash_b64)
        self.new_state_object = ContractState(self.contract_id, self.raw_state)
        self.new_state_object.pull_state_from_eservice(self.enclave_service)

        # compute ids of blocks in the change set (used for replication)
        self.new_state_object.compute_ids_of_newblocks(
            request.contract_state.component_block_ids)
        self.replication_params = request.replication_params
コード例 #17
0
    def ccl_initialize(self,
        channel_keys,
        contract_enclave_id,
        enclave_signature,
        contract_id,
        message_hash,
        current_state_hash,
        contract_code_hash,
        **extra_params):

        tx_method = "ccl_update"
        verb = "init"
        previous_state_hash = [];
        dependency_list = [];

        tx_params = PayloadBuilder.build_initialize_contract_state_transaction_from_data(
            verb,
            contract_enclave_id,
            crypto.base64_to_byte_array(enclave_signature),
            contract_id,
            current_state_hash,
            previous_state_hash,
            dependency_list,
            message_hash,
            contract_code_hash,
            self.pdo_signer.signing_key,
            self.pdo_signer.verifying_key,
            nonce = channel_keys
            )
        try:
            response = self.submit_rpc_to_ccf(tx_method, tx_params)
            if response.result: # result will be True for successful init transaction
                return tx_params['nonce'] # this will represent the transaction id
            else:
                raise Exception(response.error['message'])
        except Exception as e:
            raise
コード例 #18
0
 def raw_encryption_key(self) :
     return pcrypto.base64_to_byte_array(self.encryption_key)
コード例 #19
0
 def __decrypt_response(self, response):
     decoded_response = crypto.base64_to_byte_array(response)
     return crypto.SKENC_DecryptMessage(self.session_key, decoded_response)
コード例 #20
0
def KeyValueGetBlock(hash_identity) :
    raw_hash_identity = pcrypto.base64_to_byte_array(hash_identity)
    return kvs.block_store_get(raw_hash_identity)
コード例 #21
0
            "Symmetric decryption (random IV) invalid key detection test successful!"
        )
    else:
        logger.error(
            "ERROR: Symmetric decryption (random IV) invalid key detection test failed: ",
            exc)
        sys.exit(-1)
try:
    iv = crypto.SKENC_GenerateIV("A message")
except Exception as exc:
    logger.error(
        "ERROR: Symmetric encryption deterministic iv generation test failed: ",
        exc)
    sys.exit(-1)
logger.debug(
    "Symmetric encryption deterministic iv generation test successful!")
try:
    rand = crypto.random_bit_string(16)
except Exception as exc:
    logger.error("ERROR: Random number generation failed: ", exc)
    sys.exit(-1)
logger.debug("Random number generation successful!")

hash = crypto.compute_message_hash(rand)
bhash = bytearray(hash)
b64hash = crypto.byte_array_to_base64(bhash)
logger.debug("Hash computed!")
crypto.base64_to_byte_array(b64hash)
logger.debug("SWIG CRYPTO_WRAPPER TEST SUCCESSFUL!")
sys.exit(0)
コード例 #22
0
 def raw_hash_identity(self) :
     if self.hash_identity is None :
         return None
     return pcrypto.base64_to_byte_array(self.hash_identity)