Ejemplo n.º 1
0
 def add_encrypted_request_hash(self):
     """
     Calculates request hash 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 = crypto_utility.encrypt_data(
         self.final_hash, self.session_key, self.session_iv)
     self.params_obj["encryptedRequestHash"] = crypto.byte_array_to_hex(
         encrypted_request_hash)
Ejemplo n.º 2
0
 def calculate_request_hash(self, input_json):
     """
     Function to create the work order reuest hash
     as defined in EEA spec 6.1.8.1
     Parameters:
         - input_json is dictionary contains work order request payload
           as define EEA spec 6.1.1
     Returns hash of work order request as string
     """
     wo_request_params = input_json["params"]
     concat_string = wo_request_params["requesterNonce"] + \
         wo_request_params["workOrderId"] + \
         wo_request_params["workerId"] + \
         wo_request_params["workloadId"] + \
         wo_request_params["requesterId"]
     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 = self.calculate_datahash(wo_request_params["inData"])
     hash_3 = ""
     if "outData" in wo_request_params and \
             len(wo_request_params["outData"]) > 0:
         hash_3 = self.calculate_datahash(wo_request_params["outData"])
     concat_hash = hash_1 + hash_2 + hash_3
     concat_hash = bytes(concat_hash, "UTF-8")
     final_hash = crypto.compute_message_hash(concat_hash)
     final_hash_str = crypto.byte_array_to_hex(final_hash)
     return final_hash_str
Ejemplo n.º 3
0
    def update_receipt(self, work_order_id, update_type,
                       update_data, signing_key):
        """
        Update the existing work order receipt with
        update_type and update_data.

        Parameters:
        work_order_id Work order ID whose receipt
                      needs to be updated
        update_type   Update type. These values correspond to
                      receipt status as defined in EEA Spec 7.1.1
        update_data   Update-specific data that depends on
                      the workOrderStatus
        Returns:
        JSON RPC work order update receipt request of type dictionary
        """
        data = update_data
        if update_type in [ReceiptCreateStatus.PROCESSED.value,
                           ReceiptCreateStatus.COMPLETED.value]:
            # Work Order Receipt status is set to be completed or processed,
            # then update_data should be work order response.
            wo_resp_str = json.dumps(update_data)
            wo_resp_bytes = bytes(wo_resp_str, "UTF-8")
            # Hash of work order response is update_data
            wo_resp_hash = crypto.compute_message_hash(wo_resp_bytes)
            wo_resp_hash_str = crypto.byte_array_to_hex(wo_resp_hash)
            data = wo_resp_hash_str
        public_key = signing_key.GetPublicKey().Serialize()
        updater_id = crypto_utility.strip_begin_end_public_key(public_key)

        wo_receipt_update = {
            "workOrderId": work_order_id,
            "updaterId": updater_id,
            "updateType": update_type,
            "updateData": data,
            "signatureRules":
            self.HASHING_ALGORITHM + "/" + self.SIGNING_ALGORITHM,
            "receiptVerificationKey": public_key
        }
        wo_receipt_str = wo_receipt_update["workOrderId"] + \
            str(wo_receipt_update["updateType"]) + \
            wo_receipt_update["updateData"]
        wo_receipt_bytes = bytes(wo_receipt_str, "UTF-8")
        wo_receipt_hash = crypto.compute_message_hash(wo_receipt_bytes)
        status, wo_receipt_sign = self.sig_obj.generate_signature(
            wo_receipt_hash,
            signing_key
        )
        if status is False:
            # if generating signature failed.
            wo_receipt_update["updateSignature"] = ""
            raise Exception("Generate signature is failed")
        else:
            wo_receipt_update["updateSignature"] = wo_receipt_sign
        return wo_receipt_update
    def _compute_encrypted_request_hash(self):
        first_string = self.get_requester_nonce()
        worker_order_id = self.get_work_order_id()
        if worker_order_id is not None:
            first_string = first_string + worker_order_id
        else:
            first_string = first_string + ""

        worker_id = self.get_worker_id()
        if worker_id is not None:
            first_string = first_string + worker_id
        else:
            first_string = first_string + ""

        workload_id = self.get_workload_id()
        if workload_id is not None:
            first_string = first_string + workload_id
        else:
            first_string = first_string + ""

        requester_id = self.get_requester_id()
        if requester_id is not None:
            first_string = first_string + requester_id
        else:
            first_string = first_string + ""

        concat_hash = bytes(first_string, "UTF-8")
        self.hash_1 = crypto.byte_array_to_base64(
            crypto.compute_message_hash(concat_hash))

        in_data = self.get_in_data()
        out_data = self.get_out_data()

        self.hash_2 = ""
        if in_data is not None:
            self.hash_2 = self._compute_hash_string(in_data)

        self.hash_3 = ""
        if out_data is not None:
            self.hash_3 = self._compute_hash_string(out_data)

        final_string = self.hash_1 + self.hash_2 + self.hash_3
        self.final_hash = crypto.compute_message_hash(
            bytes(final_string, 'UTF-8'))

        self.encrypted_request_hash = self.byte_array_to_hex_str(
            self.encrypt_data(self.final_hash, self.session_key,
                              self.session_iv))

        self.params_obj["encryptedRequestHash"] = self.encrypted_request_hash
Ejemplo n.º 5
0
    def __calculate_hash_on_concatenated_string(
            self, input_json_params, nonce):
        """
        Function to calculate a hash value of the string concatenating the
        following values:
        requesterNonce, workOrderId, workerId, workloadId, and requesterId.
        Parameters:
            - input_json_params is a collection of parameters,
              as per Off-Chain Trusted Compute EEA API 6.1.1
              Work Order Request Payload
            - nonce a random string generated by the participant.
        """

        workorder_id = (input_json_params['workOrderId']).encode('UTF-8')
        worker_id = (input_json_params['workerId']).encode('UTF-8')
        workload_id = "".encode('UTF-8')
        if 'workloadId' in input_json_params:
            workload_id = (input_json_params['workloadId']).encode('UTF-8')
        requester_id = (input_json_params['requesterId']).encode('UTF-8')

        concat_string = nonce + workorder_id + worker_id + workload_id + \
            requester_id
        concat_hash = bytes(concat_string)
        # SHA-256 hashing is used
        hash_1 = crypto.compute_message_hash(concat_hash)
        result_hash = crypto.byte_array_to_base64(hash_1)

        return result_hash
Ejemplo n.º 6
0
    def calculate_datahash(self, data_objects):
        """
        Function to calculate a hash value of the array concatenating dataHash,
        data, encryptedDataEncryptionKey, iv for each item in the
        inData/outData array
        Parameters:
            - data_objects is each item in inData or outData part of workorder
              request as per Trusted Compute EEA API 6.1.7
              Work Order Data Formats
        """

        hash_str = ""
        # Sort the data items based on index field before calculating data hash
        data_objects.sort(key=lambda x: x['index'])
        for item in data_objects:
            datahash = "".encode('UTF-8')
            e_key = "".encode('UTF-8')
            iv = "".encode('UTF-8')
            if 'dataHash' in item:
                datahash = item['dataHash'].encode('UTF-8')
            data = item['data'].encode('UTF-8')
            if 'encryptedDataEncryptionKey' in item:
                e_key = item['encryptedDataEncryptionKey'].encode('UTF-8')
            if 'iv' in item:
                iv = item['iv'].encode('UTF-8')
            concat_string = datahash + data + e_key + iv
            concat_hash = bytes(concat_string)
            hash = crypto.compute_message_hash(concat_hash)
            hash_str = hash_str + crypto.byte_array_to_base64(hash)

        return hash_str
Ejemplo n.º 7
0
    def verify_update_receipt_signature(self, input_json):
        """
        Function to verify the signature of work order receipt update
        Parameters:
            - input_json is dictionary contains payload returned by the
              WorkOrderReceiptUpdateRetrieve API as define EEA spec 7.2.7
        Returns enum type SignatureStatus
        """
        input_json_params = input_json

        concat_string = input_json_params["workOrderId"] + \
            str(input_json_params["updateType"]) + \
            input_json_params["updateData"]
        concat_hash = bytes(concat_string, 'UTF-8')
        final_hash = crypto.compute_message_hash(concat_hash)
        signature = input_json_params["updateSignature"]
        verification_key = input_json_params["receiptVerificationKey"]

        try:
            _verifying_key = crypto.SIG_PublicKey(verification_key)
        except Exception as error:
            logger.info("Error in verification key : %s", error)
            return SignatureStatus.INVALID_VERIFICATION_KEY

        decoded_signature = crypto.base64_to_byte_array(signature)
        sig_result = _verifying_key.VerifySignature(
            final_hash, decoded_signature)

        if sig_result == 1:
            return SignatureStatus.PASSED
        elif sig_result == 0:
            return SignatureStatus.FAILED
        else:
            return SignatureStatus.INVALID_SIGNATURE_FORMAT
Ejemplo n.º 8
0
    def create_receipt(self, wo_request,
                       receipt_create_status, signing_key, nonce=None):
        """
        Create a work order receipt corresponding to a workorder ID.

        Parameters:
        wo_request            JSON RPC work order request used to create the
                              work order request as defined in EEA spec 6.1.1
        receipt_create_status Receipt creation status
        signing_key           Private key of the signer
        nonce                 Optional random number or monotonic counter

        Returns:
        JSON RPC request of type dictionary
        """
        final_hash_str = self.sig_obj.calculate_request_hash(wo_request)
        wo_request_params = wo_request["params"]
        worker_id = wo_request_params["workerId"]
        requester_nonce = nonce
        if nonce is None:
            requester_nonce = str(random.randint(1, 10**10))
        public_key = signing_key.GetPublicKey().Serialize()
        wo_receipt_request = {
            "workOrderId": wo_request_params["workOrderId"],
            # TODO: workerServiceId is same as worker id,
            # needs to be updated with actual service id
            "workerServiceId": worker_id,
            "workerId": worker_id,
            "requesterId": wo_request_params["requesterId"],
            "receiptCreateStatus": receipt_create_status,
            "workOrderRequestHash": final_hash_str,
            "requesterGeneratedNonce": requester_nonce,
            "signatureRules":
            self.HASHING_ALGORITHM + "/" + self.SIGNING_ALGORITHM,
            "receiptVerificationKey": public_key
        }
        wo_receipt_str = wo_receipt_request["workOrderId"] + \
            wo_receipt_request["workerServiceId"] + \
            wo_receipt_request["workerId"] + \
            wo_receipt_request["requesterId"] + \
            str(wo_receipt_request["receiptCreateStatus"]) + \
            wo_receipt_request["workOrderRequestHash"] + \
            wo_receipt_request["requesterGeneratedNonce"]
        wo_receipt_bytes = bytes(wo_receipt_str, "UTF-8")
        wo_receipt_hash = crypto.compute_message_hash(wo_receipt_bytes)
        status, wo_receipt_sign = self.sig_obj.generate_signature(
            wo_receipt_hash,
            signing_key
        )
        if status is False:
            # if generate signature is failed.
            wo_receipt_request["requesterSignature"] = ""
            raise Exception("Generate signature is failed")
        else:
            wo_receipt_request["requesterSignature"] = wo_receipt_sign
        return wo_receipt_request
    def __validate_work_order_receipt_update_req(self, wo_receipt_req):
        """
        Function to validate the work order receipt create request parameters
        Parameters:
                - wo_receipt_req is work order receipt request as dictionary
        Returns - tuple containing validation status(Boolean) and error
                  message(string)
        """
        valid_params = [
            "workOrderId", "updaterId", "updateType", "updateData",
            "updateSignature", "signatureRules", "receiptVerificationKey"
        ]
        for key in wo_receipt_req["params"]:
            if key not in valid_params:
                return False, "Missing parameter " + key + " in the request"
            else:
                if key in ["workOrderId", "updaterId"]:
                    if not is_valid_hex_str(wo_receipt_req[key]):
                        return False, "invalid data parameter for " + key
                elif key in ["updateData", "updateSignature"]:
                    try:
                        base64.b64decode(wo_receipt_req[key])
                    except Exception:
                        return False, "Invalid data format for " + key
        update_type = wo_receipt_req["params"]["updateType"]
        try:
            update_enum_value = ReceiptCreateStatus(update_type)
        except Exception as err:
            return False, "Invalid receipt update type {}: {}".format(
                update_enum_value, str(err))

        # If update type is completed or processed,
        # it is a hash value of the Work Order Response
        if wo_receipt_req["params"]["updateType"] in [
                ReceiptCreateStatus.PROCESSED.value,
                ReceiptCreateStatus.COMPLETED.value
        ]:
            wo_id = wo_receipt_req["params"]["workOrderId"]
            # Load the work order response and calculate it's hash
            wo_resp = self.kv_helper.get("wo-responses", wo_id)
            wo_resp_bytes = bytes(wo_resp, "UTF-8")
            wo_resp_hash = crypto.compute_message_hash(wo_resp_bytes)
            wo_resp_hash_str = crypto.byte_array_to_hex(wo_resp_hash)
            if wo_resp_hash_str != wo_receipt_req["params"]["updateData"]:
                return False, "Invalid Update data in the request"
        # If all validation is pass
        return True, ""
    def EncryptionKeyGet(self, **params):
        """
        Function to process get encryption key request.
        Parameters:
            - param is the 'param' object in the a worker request as per TCF
                API 6.1.10 Get Encryption Key Request Payload
        """

        worker_id = str(params['workerId'])
        value = self.kv_helper.get("workers", worker_id)

        if value is None:
            raise JSONRPCDispatchException(
                WorkerError.INVALID_PARAMETER_FORMAT_OR_VALUE,
                "Worker id not found in the database. Hence invalid parameter")

        worker_type_data = json.loads(value).get("details").get(
            "workerTypeData")
        encryptionKey = worker_type_data["encryptionKey"]
        try:
            encryptionKeyNonce = worker_type_data["encryptionKeyNonce"]
        except Exception:
            encryptionKeyNonce = crypto.random_bit_string(NO_OF_BYTES)

        tag = ""
        # calculate signature
        concat_string = worker_id.encode('UTF-8') + encryptionKey.encode(
            'UTF-8') + encryptionKeyNonce.encode('UTF-8') + tag.encode('UTF-8')
        concat_hash = bytes(concat_string)
        hash_1 = crypto.compute_message_hash(concat_hash)
        s1 = crypto.byte_array_to_base64(hash_1)
        # Requires worker private key to sign.
        # signature =  self.PrivateKey.SignMessage(hash)

        result = {
            "workerId": worker_id,
            "encryptionKey": encryptionKey,
            "encryptionKeyNonce": encryptionKeyNonce,
            "tag": "",
            "signature": s1,
        }

        return result
Ejemplo n.º 11
0
    def verify_signature(self, input_json, verification_key):
        """
        Function to verify the signature received from the enclave
        Parameters:
            - input_json is dictionary contains payload returned by the
              Worker Service in response to successful workorder submit request
              as per Trusted Compute EEA API 6.1.2 Work Order Result Payload
            - verification_key is ECDSA/SECP256K1 public key used to verify
              signatures created by the Enclave.
        Returns enum type SignatureStatus
        """

        input_json_params = input_json

        nonce = (input_json_params['workerNonce']).encode('UTF-8')
        signature = input_json_params['workerSignature']

        hash_string_1 = self.__calculate_hash_on_concatenated_string(
            input_json_params, nonce)
        data_objects = input_json_params['outData']
        data_objects.sort(key=lambda x: x['index'])
        hash_string_2 = self.calculate_datahash(data_objects)
        concat_string = hash_string_1 + hash_string_2
        concat_hash = bytes(concat_string, 'UTF-8')
        final_hash = crypto.compute_message_hash(concat_hash)

        try:
            _verifying_key = crypto.SIG_PublicKey(verification_key)
        except Exception as error:
            logger.info("Error in verification key : %s", error)
            return SignatureStatus.INVALID_VERIFICATION_KEY

        decoded_signature = crypto.base64_to_byte_array(signature)
        sig_result = _verifying_key.VerifySignature(final_hash,
                                                    decoded_signature)

        if sig_result == 1:
            return SignatureStatus.PASSED
        elif sig_result == 0:
            return SignatureStatus.FAILED
        else:
            return SignatureStatus.INVALID_SIGNATURE_FORMAT
 def _compute_hash_string(self, data):
     final_hash_str = ""
     hash_string = ""
     for data_item in data:
         data = "".encode('UTF-8')
         datahash = "".encode('UTF-8')
         e_key = "".encode('UTF-8')
         iv = "".encode('UTF-8')
         if 'dataHash' in data_item:
             datahash = data_item['dataHash'].encode('UTF-8')
         if 'data' in data_item:
             data = data_item['data'].encode('UTF-8')
         if 'encryptedDataEncryptionKey' in data_item:
             e_key = \
                 data_item['encryptedDataEncryptionKey'].encode('UTF-8')
         if 'iv' in data_item:
             iv = data_item['iv'].encode('UTF-8')
         hash_string = datahash + data + e_key + iv
         complete_bytes = bytes(hash_string)
         hash = crypto.compute_message_hash(complete_bytes)
         final_hash_str = final_hash_str + crypto.byte_array_to_base64(hash)
     return final_hash_str
    def _verify_wo_response_signature(self, wo_response,
                                      wo_res_verification_key):
        """
        Function to verify the work order response signature
        Parameters:
            @param wo_response - dictionary contains work order response
            as per Trusted Compute EEA API 6.1.2 Work Order Result Payload
            @param wo_res_verification_key - ECDSA/SECP256K1 public key
            used to verify work order response signature.
        Returns enum type SignatureStatus
        """
        worker_nonce = (wo_response["workerNonce"]).encode('UTF-8')
        signature = wo_response['workerSignature']
        hash_string_1 = self.__calculate_hash_on_concatenated_string(
            wo_response, worker_nonce)
        data_objects = wo_response['outData']
        hash_string_2 = self.calculate_datahash(data_objects)
        concat_string = hash_string_1 + hash_string_2
        concat_hash = bytes(concat_string, 'UTF-8')
        final_hash = crypto.compute_message_hash(concat_hash)

        try:
            _verifying_key = crypto.SIG_PublicKey(wo_res_verification_key)
        except Exception as error:
            logger.error(
                "Error in verification key of "
                "work order response : %s", error)
            return SignatureStatus.INVALID_VERIFICATION_KEY

        decoded_signature = crypto.base64_to_byte_array(signature)
        sig_result = _verifying_key.VerifySignature(final_hash,
                                                    decoded_signature)

        if sig_result == 1:
            return SignatureStatus.PASSED
        elif sig_result == 0:
            return SignatureStatus.FAILED
        else:
            return SignatureStatus.INVALID_SIGNATURE_FORMAT
    def _verify_wo_verification_key_signature(self, wo_response,
                                              wo_verification_key,
                                              requester_nonce):
        """
        Function to verify the work order response signature
        Parameters:
            @param wo_response - dictionary contains work order response
            as per Trusted Compute EEA API 6.1.2 Work Order Result Payload
            @param wo_verification_key - ECDSA/SECP256K1 public key used
            to verify work order verification key signature.
            @param requester_nonce - requester generated nonce passed in work
            order request. Required in 2 step verification.
        Returns enum type SignatureStatus
        """
        if requester_nonce is None:
            logger.error("Missing requester_nonce argument")
            return SignatureStatus.FAILED

        concat_string = wo_response["extVerificationKey"] + requester_nonce
        v_key_sig = wo_response["extVerificationKeySignature"]
        v_key_hash = crypto.compute_message_hash(bytes(concat_string, 'UTF-8'))
        try:
            _verifying_key = crypto.SIG_PublicKey(wo_verification_key)
        except Exception as error:
            logger.error(
                "Error in verification key of"
                "verification key signature : %s", error)
            return SignatureStatus.INVALID_VERIFICATION_KEY
        decoded_v_key_sig = crypto.base64_to_byte_array(v_key_sig)
        sig_result = _verifying_key.VerifySignature(v_key_hash,
                                                    decoded_v_key_sig)
        if sig_result == 1:
            return SignatureStatus.PASSED
        elif sig_result == 0:
            return SignatureStatus.FAILED
        else:
            return SignatureStatus.INVALID_SIGNATURE_FORMAT
Ejemplo n.º 15
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 input_json_str, SignatureStatus.FAILED

        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 input_json_str, SignatureStatus.FAILED

        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 input_json_str, SignatureStatus.FAILED

        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 "requesterNonce" in input_json_params:
            if len(input_json_params["requesterNonce"]) == 0:
                # [NO_OF_BYTES] 16 BYTES for nonce.
                # This is the recommendation by NIST to
                # avoid collisions by the "Birthday Paradox".
                input_json_params["requesterNonce"] = secrets.token_hex(
                    NO_OF_BYTES)
            elif not is_valid_hex_str(input_json_params["requesterNonce"]):
                logger.error("Invalid data format for requesterNonce")
                return input_json_params, SignatureStatus.FAILED
        else:
            logger.error("Missing parameter requesterNonce")
            return input_json_params, SignatureStatus.FAILED

        hash_string_1 = self.__calculate_hash_on_concatenated_string(
            input_json_params, input_json_params["requesterNonce"].encode(
                'UTF-8'
            ))
        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']
            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 input_json_str, 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'] = input_json_params
        input_json_str = json.dumps(input_json)
        logger.info("Request Json successfully Signed")

        return input_json_str, SignatureStatus.PASSED
    def _add_data_item(self, data_copy, data_item):

        try:
            index = data_item['index']
            data = data_item['data'].encode('UTF-8')
            if 'encryptedDataEncryptionKey' in data_item:
                e_key = data_item['encryptedDataEncryptionKey'].encode('UTF-8')
            else:
                e_key = "null".encode('UTF-8')
            if (not e_key) or (e_key == "null".encode('UTF-8')):
                enc_data = self.encrypt_data(data, self.session_key,
                                             self.session_iv)
                base64_enc_data = (crypto.byte_array_to_base64(enc_data))
                if 'dataHash' in data_item:
                    if not data_item['dataHash']:
                        dataHash_enc_data = (self.byte_array_to_hex_str(
                            crypto.compute_message_hash(data)))
                    else:
                        dataHash_enc_data = (self.byte_array_to_hex_str(
                            crypto.compute_message_hash(
                                data_item['dataHash'])))
                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
                base64_enc_data = (crypto.byte_array_to_base64(data))
                if 'dataHash' in data_item:
                    if not data_item['dataHash']:
                        dataHash_enc_data = (self.byte_array_to_hex_str(
                            crypto.compute_message_hash(data)))
                    else:
                        dataHash_enc_data = (self.byte_array_to_hex_str(
                            crypto.compute_message_hash(
                                data_item['dataHash'])))
            else:
                data_key = None
                data_iv = None
                enc_data = self.encrypt_data(data, data_key, data_iv)
                base64_enc_data = (crypto.byte_array_to_base64(enc_data))
                if 'dataHash' in data_item:
                    if not data_item[dataHash]:
                        dataHash_enc_data = (self.byte_array_to_hex_str(
                            crypto.compute_message_hash(data)))
                    else:
                        dataHash_enc_data = (self.byte_array_to_hex_str(
                            crypto.compute_message_hash(
                                data_item['dataHash'])))
                logger.debug("encrypted indata - %s",
                             crypto.byte_array_to_base64(enc_data))

            enc_indata_item = {
                'index':
                index,
                'dataHash':
                dataHash_enc_data,
                'data':
                base64_enc_data,
                'encryptedDataEncryptionKey':
                data_item['encryptedDataEncryptionKey'],
                'iv':
                data_item['iv']
            }
            data_copy.append(enc_indata_item)

            return data_copy
        except Exception:
            return None
    def add_json_values(self, input_json_temp, worker_obj, private_key, tamper,
                        wo_submit):

        self.private_key = private_key
        self.worker_obj = worker_obj
        input_request_wo_submit = json.loads(wo_submit)
        # logger.info("------ Loaded string data: ABCDEFGHIJKLMNOP
        # %s ------2. %s\n", input_json_temp,  type(wo_submit))
        final_hash_str = \
            self.sig_obj.calculate_request_hash(input_request_wo_submit)
        nonce = None
        requester_nonce = nonce
        if nonce is None:
            requester_nonce = str(random.randint(1, 10**10))

        # public_key =  signing_key.GetPublicKey().Serialize()
        input_json_temp = input_json_temp["params"]

        wo_receipt_str = (input_json_temp["workOrderId"] +
                          input_json_temp["workerServiceId"] +
                          input_json_temp["workerId"] +
                          input_json_temp["requesterId"] +
                          str(input_json_temp["receiptCreateStatus"]) +
                          input_json_temp["workOrderRequestHash"] +
                          input_json_temp["requesterGeneratedNonce"])

        wo_receipt_bytes = bytes(wo_receipt_str, "UTF-8")
        wo_receipt_hash = crypto.compute_message_hash(wo_receipt_bytes)
        status, wo_receipt_sign = self.sig_obj.generate_signature(
            wo_receipt_hash, private_key)

        input_params_list = input_json_temp.keys()
        if "workOrderId" in input_params_list:
            # if input_json_temp["workOrderId"] != "" :
            self.set_work_order_id(
                input_request_wo_submit["params"]["workOrderId"])
            # else :
            #    work_order_id = hex(random.randint(1, 2**64 -1))
            #    self.set_work_order_id(work_order_id)

        if "workerId" in input_params_list:
            if input_json_temp["workerId"] != "" or \
                    input_json_temp["workerServiceId"] != "":
                self.set_worker_id(input_json_temp["workerId"])
                self.set_worker_id(input_json_temp["workerServiceId"])
            else:
                self.set_worker_id(worker_obj.worker_id)

        if "requesterId" in input_params_list:
            if input_json_temp["requesterId"] != "":
                self.set_requester_id(input_json_temp["requesterId"])
            else:
                self.set_requester_id("0x3456")

        if "signatureRules" in input_params_list:
            if input_json_temp["signatureRules"] != "":
                self.set_signatureRules(input_json_temp["signatureRules"])
            else:
                self.set_signatureRules("SHA-256/SECP256K1")

        if "receiptCreateStatus" in input_params_list:
            if input_json_temp["receiptCreateStatus"] != "":
                self.set_receiptCreateStatus(
                    input_json_temp["receiptCreateStatus"])
            else:
                self.set_receiptCreateStatus(0)

        if "workOrderRequestHash" in input_params_list:
            # if input_json_temp["workOrderRequestHash"] != "":
            #    self.set_workOrderRequestHash(input_json_temp["workOrderRequestHash"])
            # else:
            self.set_workOrderRequestHash(final_hash_str)

        if "requesterGeneratedNonce" in input_params_list:
            # if input_json_temp["requesterGeneratedNonce"] != "":
            #    self.set_requesterGeneratedNonce(input_json_temp["requesterGeneratedNonce"])
            # else:
            self.set_requesterGeneratedNonce(requester_nonce)

        if "requesterSignature" in input_params_list:
            # if input_json_temp["requesterSignature"] != "":
            # self.set_requesterSignature(input_json_temp["requesterSignature"])
            # else:
            self.set_requesterSignature(wo_receipt_sign)
Ejemplo n.º 18
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
def compute_data_hash(data):
    '''
    Computes SHA-256 hash of data
    '''
    data_hash = crypto.compute_message_hash(data.encode("UTF-8"))
    return data_hash