Exemple #1
0
    def test_register_on_operation_failure(self):
        """
        Test that a KmipOperationFailure exception is raised when the
        backend fails to register a key.
        """
        status = enums.ResultStatus.OPERATION_FAILED
        reason = enums.ResultReason.GENERAL_FAILURE
        message = "Test failure message"

        result = results.OperationResult(contents.ResultStatus(status),
                                         contents.ResultReason(reason),
                                         contents.ResultMessage(message))
        error_msg = str(KmipOperationFailure(status, reason, message))

        # Key encoding obtained from Section 14.2 of the KMIP 1.1 test
        # documentation.
        key_value = (
            b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E'
            b'\x0F')
        key = objects.SymmetricKey(enums.CryptographicAlgorithm.AES, 128,
                                   key_value)

        client = ProxyKmipClient()
        client.open()
        client.proxy.register.return_value = result
        args = [key]

        self.assertRaisesRegexp(KmipOperationFailure, error_msg,
                                client.register, *args)
Exemple #2
0
    def test_mac_on_operation_failure(self):
        """
        Test that a KmipOperationFailure exception is raised when the
        backend fails to generate MAC.
        """
        uuid = 'aaaaaaaa-1111-2222-3333-ffffffffffff'
        algorithm = enums.CryptographicAlgorithm.HMAC_SHA256
        data = (b'\x00\x01\x02\x03\x04')

        status = enums.ResultStatus.OPERATION_FAILED
        reason = enums.ResultReason.GENERAL_FAILURE
        message = "Test failure message"

        result = results.OperationResult(contents.ResultStatus(status),
                                         contents.ResultReason(reason),
                                         contents.ResultMessage(message))
        error_msg = str(KmipOperationFailure(status, reason, message))

        client = ProxyKmipClient()
        client.open()
        client.proxy.mac.return_value = result
        args = [uuid, algorithm, data]

        self.assertRaisesRegexp(KmipOperationFailure, error_msg, client.mac,
                                *args)
Exemple #3
0
    def test_handle_message_loop(self, request_mock):
        """
        Test that the correct logging and error handling occurs during the
        message handling loop.
        """
        data = utils.BytearrayStream()

        # Build a response and use it as a dummy processing result.
        batch_item = messages.ResponseBatchItem(
            result_status=contents.ResultStatus(enums.ResultStatus.SUCCESS),
            result_reason=contents.ResultReason(
                enums.ResultReason.OBJECT_ARCHIVED),
            result_message=contents.ResultMessage("Test message."))
        batch_items = [batch_item]
        header = messages.ResponseHeader(
            protocol_version=contents.ProtocolVersion(1, 0),
            time_stamp=contents.TimeStamp(int(time.time())),
            batch_count=contents.BatchCount(len(batch_items)))
        message = messages.ResponseMessage(response_header=header,
                                           batch_items=batch_items)

        kmip_engine = engine.KmipEngine()
        kmip_engine._logger = mock.MagicMock()
        kmip_session = session.KmipSession(kmip_engine, None, 'name')
        kmip_session._engine = mock.MagicMock()
        kmip_session._get_client_identity = mock.MagicMock()
        kmip_session._get_client_identity.return_value = 'test'
        kmip_session._engine.process_request = mock.MagicMock(
            return_value=(message, kmip_session._max_response_size))
        kmip_session._logger = mock.MagicMock()
        kmip_session._connection = mock.MagicMock()
        kmip_session._connection.shared_ciphers = mock.MagicMock(
            return_value=[('AES128-SHA256', 'TLSv1/SSLv3',
                           128), ('AES256-SHA256', 'TLSv1/SSLv3', 256)])
        kmip_session._connection.cipher = mock.MagicMock(
            return_value=('AES128-SHA256', 'TLSv1/SSLv3', 128))
        kmip_session._receive_request = mock.MagicMock(return_value=data)
        kmip_session._send_response = mock.MagicMock()

        kmip_session._handle_message_loop()

        kmip_session._receive_request.assert_called_once_with()
        kmip_session._logger.info.assert_not_called()
        kmip_session._logger.debug.assert_any_call(
            "Possible session ciphers: 2")
        kmip_session._logger.debug.assert_any_call(
            ('AES128-SHA256', 'TLSv1/SSLv3', 128))
        kmip_session._logger.debug.assert_any_call(
            ('AES256-SHA256', 'TLSv1/SSLv3', 256))
        kmip_session._logger.debug.assert_any_call(
            "Session cipher selected: {0}".format(
                ('AES128-SHA256', 'TLSv1/SSLv3', 128)))
        kmip_session._logger.warning.assert_not_called()
        kmip_session._logger.exception.assert_not_called()
        self.assertTrue(kmip_session._send_response.called)
Exemple #4
0
    def read(self, istream, kmip_version=enums.KMIPVersion.KMIP_1_0):
        super(ResponseBatchItem, self).read(
            istream,
            kmip_version=kmip_version
        )
        tstream = BytearrayStream(istream.read(self.length))

        # Read the batch item operation if it is present
        if self.is_tag_next(Tags.OPERATION, tstream):
            self.operation = contents.Operation()
            self.operation.read(tstream, kmip_version=kmip_version)

        # Read the unique batch item ID if it is present
        if self.is_tag_next(Tags.UNIQUE_BATCH_ITEM_ID, tstream):
            self.unique_batch_item_id = contents.UniqueBatchItemID()
            self.unique_batch_item_id.read(tstream, kmip_version=kmip_version)

        # Read the batch item result status
        self.result_status = contents.ResultStatus()
        self.result_status.read(tstream, kmip_version=kmip_version)

        # Read the batch item result reason if it is present
        if self.is_tag_next(Tags.RESULT_REASON, tstream):
            self.result_reason = contents.ResultReason()
            self.result_reason.read(tstream, kmip_version=kmip_version)

        # Read the batch item result message if it is present
        if self.is_tag_next(Tags.RESULT_MESSAGE, tstream):
            self.result_message = contents.ResultMessage()
            self.result_message.read(tstream, kmip_version=kmip_version)

        # Read the batch item asynchronous correlation value if it is present
        if self.is_tag_next(Tags.ASYNCHRONOUS_CORRELATION_VALUE, tstream):
            self.async_correlation_value = AsynchronousCorrelationValue()
            self.async_correlation_value.read(
                tstream,
                kmip_version=kmip_version
            )

        if (self.operation is not None):
            # Dynamically create the response payload class that belongs to the
            # operation
            expected = self.payload_factory.create(self.operation.value)
            if self.is_tag_next(expected.tag, tstream):
                self.response_payload = expected
                self.response_payload.read(tstream, kmip_version=kmip_version)

        # Read the message extension if it is present
        if self.is_tag_next(Tags.MESSAGE_EXTENSION, tstream):
            self.message_extension = contents.MessageExtension()
            self.message_extension.read(tstream, kmip_version=kmip_version)

        self.is_oversized(tstream)
        self.validate()
Exemple #5
0
    def test_destroy_on_operation_failure(self):
        """
        Test that a KmipOperationFailure exception is raised when the
        backend fails to destroy a secret.
        """
        status = enums.ResultStatus.OPERATION_FAILED
        reason = enums.ResultReason.GENERAL_FAILURE
        message = "Test failure message"

        result = results.OperationResult(contents.ResultStatus(status),
                                         contents.ResultReason(reason),
                                         contents.ResultMessage(message))
        error_msg = str(KmipOperationFailure(status, reason, message))

        client = ProxyKmipClient()
        client.open()
        client.proxy.destroy.return_value = result
        args = ['id']

        self.assertRaisesRegexp(KmipOperationFailure, error_msg,
                                client.destroy, *args)
Exemple #6
0
    def test_get_attribute_list_on_operation_failure(self):
        """
        Test that a KmipOperationFailure exception is raised when the
        backend fails to retrieve the attribute names of a managed object.
        """
        status = enums.ResultStatus.OPERATION_FAILED
        reason = enums.ResultReason.GENERAL_FAILURE
        message = "Test failure message"

        result = results.OperationResult(contents.ResultStatus(status),
                                         contents.ResultReason(reason),
                                         contents.ResultMessage(message))
        error_msg = str(KmipOperationFailure(status, reason, message))

        client = ProxyKmipClient()
        client.open()
        client.proxy.get_attribute_list.return_value = result
        args = ['id']

        self.assertRaisesRegexp(KmipOperationFailure, error_msg,
                                client.get_attribute_list, *args)
Exemple #7
0
    def test_create_key_pair_on_operation_failure(self):
        """
        Test that a KmipOperationFailure exception is raised when the
        backend fails to create an asymmetric key pair.
        """
        status = enums.ResultStatus.OPERATION_FAILED
        reason = enums.ResultReason.GENERAL_FAILURE
        message = "Test failure message"

        result = results.OperationResult(contents.ResultStatus(status),
                                         contents.ResultReason(reason),
                                         contents.ResultMessage(message))
        error_msg = str(KmipOperationFailure(status, reason, message))

        client = ProxyKmipClient()
        client.open()
        client.proxy.create_key_pair.return_value = result
        args = [enums.CryptographicAlgorithm.RSA, 2048]

        self.assertRaisesRegexp(KmipOperationFailure, error_msg,
                                client.create_key_pair, *args)
Exemple #8
0
    def test_handle_message_loop(self, request_mock):
        """
        Test that the correct logging and error handling occurs during the
        message handling loop.
        """
        data = utils.BytearrayStream()

        # Build a response and use it as a dummy processing result.
        batch_item = messages.ResponseBatchItem(
            result_status=contents.ResultStatus(enums.ResultStatus.SUCCESS),
            result_reason=contents.ResultReason(
                enums.ResultReason.OBJECT_ARCHIVED),
            result_message=contents.ResultMessage("Test message."))
        batch_items = [batch_item]
        header = messages.ResponseHeader(
            protocol_version=contents.ProtocolVersion.create(1, 0),
            time_stamp=contents.TimeStamp(int(time.time())),
            batch_count=contents.BatchCount(len(batch_items)))
        message = messages.ResponseMessage(response_header=header,
                                           batch_items=batch_items)

        kmip_engine = engine.KmipEngine()
        kmip_engine._logger = mock.MagicMock()
        kmip_session = session.KmipSession(kmip_engine, None, 'name')
        kmip_session._engine = mock.MagicMock()
        kmip_session._engine.process_request = mock.MagicMock(
            return_value=(message, kmip_session._max_response_size))
        kmip_session._logger = mock.MagicMock()
        kmip_session._connection = mock.MagicMock()
        kmip_session._receive_request = mock.MagicMock(return_value=data)
        kmip_session._send_response = mock.MagicMock()

        kmip_session._handle_message_loop()

        kmip_session._receive_request.assert_called_once_with()
        kmip_session._logger.info.assert_not_called()
        kmip_session._logger.warning.assert_not_called()
        kmip_session._logger.exception.assert_not_called()
        self.assertTrue(kmip_session._send_response.called)
Exemple #9
0
    def build_error_response(self, version, reason, message):
        """
        Build a simple ResponseMessage with a single error result.

        Args:
            version (ProtocolVersion): The protocol version the response
                should be addressed with.
            reason (ResultReason): An enumeration classifying the type of
                error occurred.
            message (str): A string providing additional information about
                the error.

        Returns:
            ResponseMessage: The simple ResponseMessage containing a
                single error result.
        """
        batch_item = messages.ResponseBatchItem(
            result_status=contents.ResultStatus(
                enums.ResultStatus.OPERATION_FAILED),
            result_reason=contents.ResultReason(reason),
            result_message=contents.ResultMessage(message))
        return self._build_response(version, [batch_item])
Exemple #10
0
    def _process_batch(self, request_batch, batch_handling, batch_order):
        response_batch = list()

        self._data_session = self._data_store_session_factory()

        for batch_item in request_batch:
            error_occurred = False

            response_payload = None
            result_status = None
            result_reason = None
            result_message = None

            operation = batch_item.operation
            request_payload = batch_item.request_payload

            # Process batch item ID.
            if len(request_batch) > 1:
                if not batch_item.unique_batch_item_id:
                    raise exceptions.InvalidMessage(
                        "Batch item ID is undefined.")

            # Process batch message extension.
            # TODO (peterhamilton) Add support for message extension handling.
            # 1. Extract the vendor identification and criticality indicator.
            # 2. If the indicator is True, raise an error.
            # 3. If the indicator is False, ignore the extension.

            # Process batch payload.
            try:
                response_payload = self._process_operation(
                    operation.value, request_payload)

                result_status = enums.ResultStatus.SUCCESS
            except exceptions.KmipError as e:
                error_occurred = True
                result_status = e.status
                result_reason = e.reason
                result_message = str(e)
            except Exception as e:
                self._logger.warning(
                    "Error occurred while processing operation.")
                self._logger.exception(e)

                error_occurred = True
                result_status = enums.ResultStatus.OPERATION_FAILED
                result_reason = enums.ResultReason.GENERAL_FAILURE
                result_message = (
                    "Operation failed. See the server logs for more "
                    "information.")

            # Compose operation result.
            result_status = contents.ResultStatus(result_status)
            if result_reason:
                result_reason = contents.ResultReason(result_reason)
            if result_message:
                result_message = contents.ResultMessage(result_message)

            batch_item = messages.ResponseBatchItem(
                operation=batch_item.operation,
                unique_batch_item_id=batch_item.unique_batch_item_id,
                result_status=result_status,
                result_reason=result_reason,
                result_message=result_message,
                response_payload=response_payload)
            response_batch.append(batch_item)

            # Handle batch error if necessary.
            if error_occurred:
                if batch_handling == enums.BatchErrorContinuationOption.STOP:
                    break

        return response_batch