def execute(self):
        serialized_byte_array = crypto.string_to_byte_array(self.work_order)
        encrypted_request = crypto.byte_array_to_base64(serialized_byte_array)

        try:
            encoded_encrypted_response = \
                self.enclave_service.send_to_sgx_worker(encrypted_request)
            assert encoded_encrypted_response
        except Exception as err:
            logger.exception('workorder request invocation failed: %s',
                             str(err))
            raise

        try:
            decrypted_response = crypto.base64_to_byte_array(
                encoded_encrypted_response)
            response_string = crypto.byte_array_to_string(decrypted_response)
            response_parsed = json.loads(response_string[0:-1])
        except Exception as err:
            logger.exception('workorder response is invalid: %s', str(err))
            raise

        return response_parsed
Esempio n. 2
0
    def generate_client_signature(
            self, input_json_str, worker, private_key, session_key,
            session_iv, encrypted_session_key, data_key=None, data_iv=None):
        """
        Function to generate client signature
        Parameters:
            - input_json_str is requester Work Order Request payload in a
              JSON-RPC based format defined 6.1.1 Work Order Request Payload
            - worker is a worker object to store all the common details of
              worker as per Trusted Compute EEA API 8.1
              Common Data for All Worker Types
            - private_key is Client private key
            - session_key is one time session key generated by the participant
              submitting the work order.
            - session_iv is an initialization vector if required by the
              data encryption algorithm (encryptedSessionKey).
              The default is all zeros.
            - data_key is a one time key generated by participant used to
              encrypt work order indata
            - data_iv is an initialization vector used along with data_key.
              Default is all zeros.
            - encrypted_session_key is a encrypted version of session_key.
        Returns a tuple containing signature and status
        """

        if (self.__payload_json_check(input_json_str) is False):
            logger.error("ERROR: Signing the request failed")
            return None

        if (self.tcs_worker['HashingAlgorithm'] != worker.hashing_algorithm):
            logger.error(
                "ERROR: Signing the request failed. Hashing " +
                "algorithm is not supported for %s", worker.hashing_algorithm)
            return None

        if (self.tcs_worker['SigningAlgorithm'] != worker.signing_algorithm):
            logger.error(
                "ERROR: Signing the request failed. Signing " +
                "algorithm is not supported for %s", worker.signing_algorithm)
            return None

        input_json = json.loads(input_json_str)
        input_json_params = input_json['params']
        input_json_params["sessionKeyIv"] = byte_array_to_hex_str(session_iv)

        encrypted_session_key_str = byte_array_to_hex_str(
            encrypted_session_key)
        self.__encrypt_workorder_indata(
            input_json_params, session_key,
            session_iv, worker.encryption_key, data_key, data_iv)

        if input_json_params["requesterNonce"] and \
                is_valid_hex_str(input_json_params["requesterNonce"]):
            nonce = crypto.string_to_byte_array(
                input_json_params["requesterNonce"])
        else:
            # [NO_OF_BYTES] 16 BYTES for nonce.
            # This is the recommendation by NIST to
            # avoid collisions by the "Birthday Paradox".
            nonce = crypto.random_bit_string(NO_OF_BYTES)

        request_nonce_hash = crypto.compute_message_hash(nonce)
        nonce_hash = (crypto.byte_array_to_base64(request_nonce_hash)).encode(
            'UTF-8')
        hash_string_1 = self.__calculate_hash_on_concatenated_string(
            input_json_params, nonce_hash)
        data_objects = input_json_params['inData']
        hash_string_2 = self.calculate_datahash(data_objects)

        hash_string_3 = ""
        if 'outData' in input_json_params:
            data_objects = input_json_params['outData']
            data_objects.sort(key=lambda x: x['index'])
            hash_string_3 = self.calculate_datahash(data_objects)

        concat_string = hash_string_1 + hash_string_2 + hash_string_3
        concat_hash = bytes(concat_string, 'UTF-8')
        final_hash = crypto.compute_message_hash(concat_hash)

        encrypted_request_hash = crypto_utility.encrypt_data(
            final_hash, session_key, session_iv)
        encrypted_request_hash_str = \
            byte_array_to_hex_str(encrypted_request_hash)
        logger.debug("encrypted request hash: \n%s",
                     encrypted_request_hash_str)

        # Update the input json params
        input_json_params["encryptedRequestHash"] = encrypted_request_hash_str
        status, signature = self.generate_signature(final_hash, private_key)
        if status is False:
            return SignatureStatus.FAILED
        input_json_params['requesterSignature'] = signature
        input_json_params["encryptedSessionKey"] = encrypted_session_key_str
        # Temporary mechanism to share client's public key. Not a part of Spec
        input_json_params['verifyingKey'] = self.public_key
        input_json_params['requesterNonce'] = crypto.byte_array_to_base64(
            request_nonce_hash)
        input_json['params'] = input_json_params
        input_json_str = json.dumps(input_json)
        logger.info("Request Json successfully Signed")

        return input_json_str, SignatureStatus.PASSED
Esempio n. 3
0
 def hashed_identity(self):
     key_byte_array = crypto.string_to_byte_array(self.txn_public)
     hashed_txn_key = crypto.compute_message_hash(key_byte_array)
     encoded_hashed_key = crypto.byte_array_to_hex(hashed_txn_key)
     encoded_hashed_key = encoded_hashed_key.lower()
     return encoded_hashed_key