Esempio n. 1
0
    def test_has_been_revoked_true(self, mock_thing, mock_crypto,
                                   mock_request):
        mock_crypto.load_certificate.return_value = MagicMock()
        mock_crypto.load_certificate(
        ).get_serial_number.return_value = 0x000111222333
        serial_number = hex(
            mock_crypto.load_certificate().get_serial_number())[2:]

        url = "{0}/ca/CN={1},O=EJBCA/certificate/{2}/status".format(
            MOCK_CONFIG["security"]["ejbca_url"],
            MOCK_CONFIG["security"]["ejbca_ca_name"], serial_number)

        mock_request.get.return_value = MagicMock()
        mock_request.get().json().get.return_value = MagicMock()
        mock_request.get().json.return_value = {
            'status': {
                'return': {
                    'reason': 0
                },
            },
        }

        result = CertClient.has_been_revoked(mock_thing)
        mock_request.get.assert_called_with(url)
        self.assertTrue(result)

        mock_request.get().json.return_value = {}

        result = CertClient.has_been_revoked(mock_thing)
        self.assertFalse(result)
Esempio n. 2
0
    def revoke_cert(self) -> None:
        """
        Revoke a certificate and emit an event whether it succeeded or not.
        """
        if self.should_revoke_now():
            try:
                CertClient.revoke_cert(self.new_cert)

            except Exception as exception:
                Utils.fire_locust_failure(request_type=REQUEST_TYPE,
                                          name=MESSAGE_TYPE_REVOKE,
                                          response_time=0,
                                          response_length=0,
                                          exception=exception)

            else:
                if CertClient.has_been_revoked(self.new_cert):
                    Utils.fire_locust_success(request_type=REQUEST_TYPE,
                                              name=MESSAGE_TYPE_REVOKE,
                                              response_time=0,
                                              response_length=0)
                    self.should_revoke = False
                else:
                    Utils.fire_locust_failure(
                        request_type=REQUEST_TYPE,
                        name=MESSAGE_TYPE_REVOKE,
                        response_time=0,
                        response_length=0,
                        exception=CertRevogationError("failed to revoke"))
Esempio n. 3
0
    def configure_mqtt(self) -> None:
        """
        Configures the MQTT connection.
        """
        # Certification files
        cert_dir = CONFIG["security"]["cert_dir"]
        ca_cert_file = cert_dir + CONFIG["security"]["ca_cert_file"]
        cert_file = self.device_cert_dir + CertClient.get_certificate_file(
            self.device_id)
        key_file = self.device_cert_dir + CertClient.get_private_key_file(
            self.device_id)

        # Configuring MQTT client
        self.mqttc = mqtt.Client(client_id=self.device_id)

        # Sets exponential reconnect delay
        self.mqttc.reconnect_delay_set(
            min_delay=CONFIG["security"]["min_time_reconn"],
            max_delay=CONFIG["security"]["max_time_reconn"])

        # Setting up TLS
        self.mqttc.tls_set(ca_cert_file, cert_file, key_file)
        # TODO: investigate the problem when the insecure TLS mode is False
        # This problem seems to happen because the TLS implementation does not
        # expects an IP, but a hostname
        self.mqttc.tls_insecure_set(True)

        # Registering MQTT client callbacks
        self.mqttc.on_connect = self.locust_on_connect
        self.mqttc.on_disconnect = self.locust_on_disconnect
        self.mqttc.on_publish = self.locust_on_publish
        self.mqttc.on_subscribe = self.locust_on_subscribe
        self.mqttc.on_message = self.locust_on_message
Esempio n. 4
0
    def test_create_cert_files_exception(self, mock_thing):
        """
            Should not build a correct filename for the certificate.
        """
        mock_thing.device_id = 'thind-dev-id'
        mock_thing.thing_certificate = 'thing-certificate'
        mock_thing.private_key = 'private-key'
        directory = 'dir-to-create-certs/'
        with patch('src.ejbca.cert_client.open',
                   mock_open()) as mock_builtin_open:
            mock_builtin_open.side_effect = Exception()

            with self.assertRaises(Exception):
                CertClient.create_cert_files(mock_thing, directory)
Esempio n. 5
0
 def test_get_certificate_file(self, mock_utils):
     """
         Should build a correct filename for the certificate.
     """
     mock_utils.validate_device_id.return_value = MagicMock()
     device_id = "dev-id"
     filename = device_id + ".crt"
     self.assertEqual(CertClient.get_certificate_file(device_id), filename)
     mock_utils.reset_mock()
Esempio n. 6
0
    def test_revoke_cert(mock_thing, mock_crypto, mock_request):
        """
            Test certifcate revoke cert
        """
        mock_crypto.load_certificate.return_value = MagicMock()
        mock_crypto.load_certificate(
        ).get_serial_number.return_value = 0x000111222333
        serial_number = hex(
            mock_crypto.load_certificate().get_serial_number())[2:]

        url = MOCK_CONFIG["security"][
            "ejbca_url"] + "/ca/CN={0},O=EJBCA/certificate/{1}".format(
                MOCK_CONFIG["security"]["ejbca_ca_name"], serial_number)

        CertClient.revoke_cert(mock_thing)
        mock_request.delete.assert_called_with(url)
        mock_thing.reset_mock()
        mock_crypto.reset_mock()
        mock_request.reset_mock()
Esempio n. 7
0
 def test_new_cert(self, mock_utils, mock_thing):
     """
         Test certifcate new cert creation
     """
     tenant = 'tenant'
     dev_id = 'dev-id'
     created_thing = CertClient.new_cert(tenant, dev_id)
     self.assertIsNotNone(created_thing)
     mock_utils.validate_tenant.assert_called()
     mock_utils.validate_device_id.assert_called()
     mock_thing.assert_called_with(tenant, dev_id)
     mock_thing.reset_mock()
Esempio n. 8
0
    def setup(self) -> None:
        """
        Initializes the required parameters.
        """
        logging.basicConfig(**CONFIG["app"]["log_config"])

        self.username = '******'.format(self.tenant, self.device_id)
        self.topic = "{0}/attrs".format(self.username)
        self.sub_topic = "{0}/config".format(self.username)

        self.device_cert_dir = CONFIG["security"]["cert_dir"]

        # Creating a new certificate if the client was chosen to be revoked
        if self.should_revoke:
            self.device_cert_dir = self.device_cert_dir + CONFIG["security"][
                "revoke_cert_dir"]
            self.new_cert = CertClient.new_cert(self.tenant, self.device_id)
            CertClient.create_cert_files(self.new_cert, self.device_cert_dir)

        elif self.should_renew:
            self.device_cert_dir = self.device_cert_dir + CONFIG["security"][
                "renew_cert_dir"]
            self.new_cert = CertClient.new_cert(self.tenant, self.device_id)
            CertClient.create_cert_files(self.new_cert, self.device_cert_dir)

        self.configure_mqtt()
Esempio n. 9
0
    def test_create_cert_files(self, mock_thing):
        """
            Should build a correct filename for the certificate.
        """
        mock_thing.device_id = 'thind-dev-id'
        mock_thing.thing_certificate = 'thing-certificate'
        mock_thing.private_key = 'private-key'
        directory = 'dir-to-create-certs/'
        thing_path = directory + mock_thing.device_id
        with patch('src.ejbca.cert_client.open',
                   mock_open()) as mock_builtin_open:
            CertClient.create_cert_files(mock_thing, directory)

            calls = [
                call(thing_path + '.key', "w"),
                call(thing_path + '.crt', "w"),
                call().write(mock_thing.thing_certificate),
                call().write(mock_thing.private_key)
            ]
            mock_builtin_open.assert_has_calls(calls, any_order=True)
            mock_builtin_open.reset_mock()
        mock_thing.reset_mock()
Esempio n. 10
0
    def initialize_mqtt(self) -> None:
        """
        Initializes the MQTT connection.
        """
        # Certification files
        cert_dir = CONFIG["security"]["cert_dir"]
        ca_cert_file = cert_dir + CONFIG["security"]["ca_cert_file"]
        cert_file = self.device_cert_dir + CertClient.get_certificate_file(
            self.device_id)
        key_file = self.device_cert_dir + CertClient.get_private_key_file(
            self.device_id)

        self.username = '******'.format(self.tenant, self.device_id)
        self.topic = "{0}/attrs".format(self.username)
        self.sub_topic = "{0}/config".format(self.username)

        self.log = LogController(self.run_id)

        # Configuring MQTT client
        self.mqttc = mqtt.Client(client_id=self.device_id)

        # Sets exponential reconnect delay
        self.mqttc.reconnect_delay_set(
            min_delay=CONFIG["security"]["min_time_reconn"],
            max_delay=CONFIG["security"]["max_time_reconn"])

        # Setting up TLS
        self.mqttc.tls_set(ca_cert_file, cert_file, key_file)
        # TODO: investigate the problem when the insecure TLS mode is False
        self.mqttc.tls_insecure_set(True)

        # Registering MQTT client callbacks
        self.mqttc.on_connect = self.locust_on_connect
        self.mqttc.on_disconnect = self.locust_on_disconnect
        self.mqttc.on_publish = self.locust_on_publish
        self.mqttc.on_subscribe = self.locust_on_subscribe
        self.mqttc.on_message = self.locust_on_message
Esempio n. 11
0
    def __init__(self, device_id: str, run_id: str, should_revoke: bool,
                 should_renew: bool):
        """MQTT client constructor.

        Args:
            device_id: device identifier
            run_id: client run identifier
            should_revoke: whether this client should have its certificate revoked
            should_renew: whether this client should have its certificate renewed
            tenant: tenant that owns the device
        """

        self.device_id = device_id
        self.run_id = run_id
        self.should_revoke = should_revoke
        self.should_renew = should_renew

        self.tenant = CONFIG["app"]["tenant"]
        self.is_connected = False
        self.start_time = 0

        # Creating a new certificate if the client was chosen to be revoked
        self.device_cert_dir = CONFIG["security"]["cert_dir"]

        if self.should_revoke:
            self.device_cert_dir = self.device_cert_dir + CONFIG["security"][
                "revoke_cert_dir"]
            self.new_cert = CertClient.new_cert(self.tenant, self.device_id)
            CertClient.create_cert_files(self.device_id, self.new_cert, \
                self.device_cert_dir)

        elif self.should_renew:
            self.device_cert_dir = self.device_cert_dir + CONFIG["security"][
                "renew_cert_dir"]
            self.new_cert = CertClient.new_cert(self.tenant, self.device_id)
            CertClient.create_cert_files(self.device_id, self.new_cert, \
                self.device_cert_dir)

        self.pubmmap = {}
        self.submmap = {}
        self.recvmqueue = Queue()

        self.initialize_mqtt()