Beispiel #1
0
    def load_worker(self, input_str):
        """
        Function to load the member variables of this class
        based on worker retrieved details.
        """
        worker_data = input_str['result']['details']
        logger.info("*********Updating Worker Details*********")
        self.hashing_algorithm = worker_data['hashingAlgorithm']
        self.signing_algorithm = worker_data['signingAlgorithm']
        self.key_encryption_algorithm = worker_data['keyEncryptionAlgorithm']
        self.data_encryption_algorithm = worker_data['dataEncryptionAlgorithm']
        self.verification_key = \
            worker_data['workerTypeData']['verificationKey']
        self.encryption_key = worker_data['workerTypeData']['encryptionKey']
        if 'proofData' in worker_data['workerTypeData'] and \
                worker_data['workerTypeData']['proofData']:
            # proofData will be initialized only in HW mode by the
            # tcf_enclave_bridge module when signup info is obtained from
            # the worker.
            self.proof_data = json.loads(
                worker_data['workerTypeData']['proofData'])

        self.worker_id = utility.strip_begin_end_key(
            worker_data['workerTypeData']['verificationKey']) \
            .encode("UTF-8").hex()
        ''' worker_id - newline, BEGIN PUB KEY and END PUB KEY are removed
                        from worker's verification key and converted to hex '''
        logger.info("Hashing Algorithm : %s", self.hashing_algorithm)
        logger.info("Signing Algorithm : %s", self.signing_algorithm)
Beispiel #2
0
    def test_strip_begin_end_key(self):
        """Tests to verify strip_begin_end_key(key) function
        """
        expected = "123456aghdfgasdasdkommkf"       # Positive case
        self.assertEquals(expected, strip_begin_end_key(
            "-----BEGIN PUBLIC KEY-----123456aghdfgas\n"
            "dasdkommkf-----END PUBLIC KEY-----"))

        expected = "123456aghdfgasdasdkommkf"       # Interspersed with '\n'
        self.assertEquals(expected, strip_begin_end_key(
            "\n-----BEGIN PUBLIC KEY\n"
            "-----123456aghdfgas\n"
            "dasdkommkf\n"
            "-----END PUBLIC KEY-----\n"))

        expected = "123456+/aghdfgasdasdkommkf==="  # Other base64 characters
        self.assertEquals(expected, strip_begin_end_key(
            "-----BEGIN PUBLIC KEY-----123456+/aghdfgasdasdkommkf==="
            "-----END PUBLIC KEY-----"))
    def update_receipt(self, work_order_id, update_type, update_data,
                       signing_key):
        """
        Update the existing work order receipt with
        update_type, update_data.
        Parameters:
            - work_order_id is work order id whose receipt
              needs to be updated.
            - update_type is integer, these values corresponds to
              receipt status as defined in 7.1.1
            - update_data is update-specific data that depend on
              the workOrderStatus
        Returns jrpc 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 = utility.strip_begin_end_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
Beispiel #4
0
    def load_worker(self,input_str):
        """
        Function to load the member variables of this class based on worker retrieved details
        """
        worker_data = input_str ['result']['details']
        logger.info("*********Updating Worker Details*********")
        self.hashing_algorithm = worker_data['hashingAlgorithm']
        self.signing_algorithm = worker_data['signingAlgorithm']
        self.key_encryption_algorithm = worker_data['keyEncryptionAlgorithm']
        self.data_encryption_algorithm = worker_data['dataEncryptionAlgorithm']
        self.verification_key = worker_data['workerTypeData']['verificationKey']
        self.encryption_key = worker_data['workerTypeData']['encryptionKey']
        self.worker_id = utility.strip_begin_end_key(
                worker_data['workerTypeData']['verificationKey']).encode("UTF-8").hex()
        ''' worker_id - newline, BEGIN PUB KEY and END PUB KEY are removed
                        from worker's verification key and converted to hex '''
        logger.info("Hashing Algorithm : %s", self.hashing_algorithm)
        logger.info("Signing Algorithm : %s", self.signing_algorithm)

#-----------------------------------------------------------------------------------------------
    def manager_on_boot(self, kv_helper):
        """
        Executes Boot flow of enclave manager
        """
        logger.info("Executing boot time procedure")

        # Cleanup "workers" table
        workers_list = kv_helper.lookup("workers")

        if len(workers_list) == 0:
            logger.info(
                "No worker entries available in workers table, skipping Cleanup"
            )
        else:
            logger.info("Clearing entries in workers table")
            for worker in workers_list:
                kv_helper.remove("workers", worker)

        worker_info = create_json_worker(self, self.config)
        logger.info("Adding enclave workers to workers table")
        worker_id = utils.strip_begin_end_key(
            self.enclave_id).encode("UTF-8").hex()
        kv_helper.set("workers", worker_id, worker_info)

        # Cleanup wo-processing" table
        processing_list = kv_helper.lookup("wo-processing")
        if len(processing_list) == 0:
            logger.info(
                "No workorder entries found in wo-processing table, skipping Cleanup"
            )
            return
        for wo in processing_list:
            logger.info("Validating workorders in wo-processing table")
            wo_json_resp = kv_helper.get("wo-responses", wo)
            wo_processed = kv_helper.get("wo-processed", wo)

            if wo_json_resp is not None:
                try:
                    wo_resp = json.loads(wo_json_resp)
                except ValueError as e:
                    logger.error(
                        "Invalid JSON format found for the response for workorder %s - %s",
                        wo, e)
                    if wo_processed is None:
                        kv_helper.set("wo-processed", wo,
                                      WorkOrderStatus.FAILED.name)
                    kv_helper.remove("wo-processing", wo)
                    continue

                if "Response" in wo_resp and wo_resp["Response"][
                        "Status"] == WorkOrderStatus.FAILED:
                    if wo_processed is None:
                        kv_helper.set("wo-processed", wo,
                                      WorkOrderStatus.FAILED.name)
                    logger.error(
                        "Work order processing failed, removing it from wo-processing table"
                    )
                    kv_helper.remove("wo-processing", wo)
                    continue

                wo_receipt = kv_helper.get("wo-receipts", wo)
                if wo_receipt is None:
                    # create receipt
                    logger.info("Creating receipt in boot flow")
                    wo_receipt = create_receipt(wo, wo_json_resp)
                    logger.info("Receipt created for workorder %s during boot",
                                wo_receipt)
                    kv_helper.set("wo-receipts", wo, wo_receipt)

                if wo_processed is None:
                    kv_helper.set("wo-processed", wo,
                                  WorkOrderStatus.SUCCESS.name)
            else:
                logger.info("No response found for the workorder %s," \
                            "hence placing the workorder request back in wo-scheduled", wo)
                kv_helper.set("wo-scheduled", wo,
                              WorkOrderStatus.SCHEDULED.name)

            logger.info(
                "Finally deleting workorder %s from wo-processing table", wo)
            kv_helper.remove("wo-processing", wo)