Exemplo n.º 1
0
    def __encrypt_workorder_indata(self, input_json_params, encrypted_session_key, session_iv):
        """
        Function to encrypt inData of workorder
        Parameters:
            - input_json_params is inData and outData elements within work order request as per TCF API 6.1.7 Work Order Data Formats
            - encrypted_session_key is a one-time encryption 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.
        """

        indata_objects = input_json_params['inData']
        indata_objects.sort(key=lambda x: x['index'])
        input_json_params['inData'] = indata_objects
        logger.info("Encrypting Workorder Data");

        i = 0
        for item in indata_objects:
            data = item['data'].encode('UTF-8')
            e_key = item['encryptedDataEncryptionKey'].encode('UTF-8')
            if (not e_key ) or (e_key == "null".encode('UTF-8')):
                enc_data = utility.encrypt_data(data, encrypted_session_key, session_iv)
                input_json_params['inData'][i]['data'] = crypto.byte_array_to_base64(enc_data)
                input_json_params['inData'][i]['iv'] = input_json_params["sessionKeyIv"]
                logger.debug("encrypted indata - %s", crypto.byte_array_to_base64(enc_data))
            elif e_key == "-".encode('UTF-8'):
                # Skip encryption and just encode workorder data to base64 format
                input_json_params['inData'][i]['data'] = crypto.byte_array_to_base64(data)
            else:
                #TODO: Explore the necessity of session iv
                enc_data = utility.encrypt_data(data, e_key, "0")
                input_json_params['inData'][i]['data'] = crypto.byte_array_to_base64(enc_data)
                input_json_params['inData'][i]['iv'] = format("0", '02x')
                logger.debug("encrypted indata - %s", crypto.byte_array_to_base64(enc_data))
            i = i + 1

        logger.debug("Workorder InData after encryption: %s", indata_objects)
Exemplo n.º 2
0
    def __encrypt_workorder_indata(
            self, input_json_params, session_key, session_iv,
            worker_encryption_key, data_key=None, data_iv=None):
        """
        Function to encrypt inData of workorder
        Parameters:
            - input_json_params is inData and outData elements within the
              work order request as per TCF API 6.1.7 Work Order Data Formats.
            - session_key is a one-time encryption 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.
        """

        indata_objects = input_json_params['inData']
        indata_objects.sort(key=lambda x: x['index'])
        input_json_params['inData'] = indata_objects
        logger.info("Encrypting Workorder Data")

        i = 0
        for item in indata_objects:
            data = item['data'].encode('UTF-8')
            e_key = item['encryptedDataEncryptionKey'].encode('UTF-8')

            if (not e_key) or (e_key == "null".encode('UTF-8')):
                enc_data = utility.encrypt_data(data, session_key, session_iv)
                input_json_params['inData'][i]['data'] = \
                    crypto.byte_array_to_base64(enc_data)
                logger.debug(
                    "encrypted indata - %s",
                    crypto.byte_array_to_base64(enc_data))
            elif e_key == "-".encode('UTF-8'):
                # Skip encryption and just encode workorder data to
                # base64 format.
                input_json_params['inData'][i]['data'] = \
                    crypto.byte_array_to_base64(data)
            else:
                enc_data = utility.encrypt_data(data, data_key, data_iv)
                input_json_params['inData'][i]['data'] = \
                    crypto.byte_array_to_base64(enc_data)
                logger.debug("encrypted indata - %s",
                             crypto.byte_array_to_base64(enc_data))
            i = i + 1

        logger.debug("Workorder InData after encryption: %s", indata_objects)
Exemplo n.º 3
0
    def add_encrypted_request_hash(self):
        """
		calculates request has based on EEA trusted-computing spec 6.1.8.1
		and set encryptedRequestHash parameter in the request.
		"""
        sig_obj = signature.ClientSignature()
        concat_string = self.get_requester_nonce() + \
         self.get_work_order_id() + \
         self.get_worker_id() + \
         self.get_workload_id() + \
         self.get_requester_id()
        concat_bytes = bytes(concat_string, "UTF-8")
        #SHA-256 hashing is used
        hash_1 = crypto.byte_array_to_base64(
            crypto.compute_message_hash(concat_bytes))
        hash_2 = sig_obj.calculate_datahash(self.get_in_data())
        hash_3 = ""
        out_data = self.get_out_data()
        if out_data and len(out_data) > 0:
            hash_3 = sig_obj.calculate_datahash(out_data)
        concat_hash = hash_1 + hash_2 + hash_3
        concat_hash = bytes(concat_hash, "UTF-8")
        self.final_hash = crypto.compute_message_hash(concat_hash)
        encrypted_request_hash = utility.encrypt_data(self.final_hash,
                                                      self.session_key,
                                                      self.session_iv)
        self.params_obj["encryptedRequestHash"] = crypto.byte_array_to_hex(
            encrypted_request_hash)
Exemplo n.º 4
0
def test_encrypt_data(iv, enc_sess_key, data):
    data_bytes = bytes(data, 'ascii')
    enc_req_hash = utility.encrypt_data(data_bytes, enc_sess_key, iv)
    if enc_req_hash:
        logging.info("Test case: test_encrypt_data PASS...")
    else:
        logging.info("Test case: test_encrypt_data FAIL...")
    return enc_req_hash
Exemplo n.º 5
0
 def __encrypt_data(self,
                    data,
                    encrypted_data_encryption_key=None,
                    data_iv=None):
     data = data.encode("UTF-8")
     if encrypted_data_encryption_key is None or \
      encrypted_data_encryption_key == "" or \
      encrypted_data_encryption_key == "null":
         enc_data = utility.encrypt_data(data, self.session_key,
                                         self.session_iv)
         return crypto.byte_array_to_base64(enc_data)
     elif encrypted_data_encryption_key == "-".encode('UTF-8'):
         # Skip encryption and just encode workorder data to base64 format
         enc_data = crypto.byte_array_to_base64(data)
         return enc_data
     else:
         enc_data = utility.encrypt_data(data,
                                         encrypted_data_encryption_key,
                                         data_iv)
         return crypto.byte_array_to_base64(enc_data)
Exemplo n.º 6
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 TCF 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 intialization 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"] = ''.join(
            format(i, '02x') for i in session_iv)

        encrypted_session_key_str = ''.join(
            format(i, '02x') for i in 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_hex(input_json_params["requesterNonce"]):
            nonce = crypto.string_to_byte_array(
                input_json_params["requesterNonce"])
        else:
            # [NO_OF_BYTES] 16 BYTES for nonce, 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 = utility.encrypt_data(final_hash, session_key,
                                                      session_iv)
        encrypted_request_hash_str = ''.join(
            format(i, '02x') for i in 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 == 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
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:
                direct_wrapper.init_worker_registry_list(config)
                registry_lookup_result = direct_wrapper.registry_lookup()
                if (registry_lookup_result[0] == 0):
                    logger.warn("No registries found")
                    sys.exit(1)
                registry_retrieve_result = direct_wrapper.registry_retrieve(
                    registry_lookup_result[2][0])
                config["tcf"]["json_rpc_uri"] = registry_retrieve_result[0]

        # Prepare worker
        direct_wrapper.init_worker_registry(config)

        global worker_id
        if not worker_id:
                worker_lookup_json = jrpc_request.WorkerLookupJson(
                    1, worker_type=1)
                worker_lookup_result = direct_wrapper.worker_lookup(
                    worker_lookup_json)
                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)

        worker_retrieve_json = jrpc_request.WorkerRetrieveJson(2, worker_id)
        worker_obj.load_worker(
            direct_wrapper.worker_retrieve(worker_retrieve_json))

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

        # Convert workloadId to hex
        workload_id = "echo-result"
        workload_id = workload_id.encode("UTF-8").hex()
        # Create work order
        wo_submit_json = jrpc_request.WorkOrderSubmitJson(
            3, 6000, "pformat",
            worker_id, workload_id, "0x2345",
            worker_encryption_key=base64.b64decode(
                worker_obj.worker_encryption_key).hex(),
            data_encryption_algorithm="AES-GCM-256")
        wo_id = wo_submit_json.get_work_order_id()

        # Sign work order
        private_key = utility.generate_signing_keys()
        session_key = utility.generate_key()
        session_iv = utility.generate_iv()
        encrypted_session_key = utility.generate_encrypted_key(
            session_key, worker_obj.worker_encryption_key)
        # Generate one time key used for encrypting inData
        data_key = utility.generate_key()
        # Initialation vector of size 12 bytes with all zeros.
        data_iv = bytearray(12)

        encrypted_key = utility.generate_encrypted_key(
            data_key, worker_obj.worker_encryption_key)
        encrypted_data_encryption_key = utility.encrypt_data(
            encrypted_key, session_key)
        encrypted_data_encryption_key_str = ''.join(
            format(i, '02x') for i in encrypted_data_encryption_key)
        data_iv_str = ''.join(format(i, '02x') for i in data_iv)
        wo_submit_json.add_in_data(
            message, None, encrypted_data_encryption_key_str, data_iv_str)
        # Submit work order
        direct_wrapper.init_work_order(config)
        direct_wrapper.work_order_submit(
            wo_submit_json, encrypted_session_key, worker_obj, private_key,
            session_key, session_iv, data_key, data_iv)

        # Retrieve result
        wo_get_result_json = jrpc_request.WorkOrderGetResultJson(4, wo_id)
        direct_wrapper.work_order_get_result(
            wo_get_result_json, session_key, session_iv, data_key, data_iv)