Merge pull request #254 from vbnmmnbv/client
Add MAC operation support at client side
This commit is contained in:
commit
7fca09fa75
kmip
demos
pie
services
tests/unit
59
kmip/demos/pie/mac.py
Normal file
59
kmip/demos/pie/mac.py
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
# Copyright (c) 2017 Pure Storage, Inc. All Rights Reserved.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
import logging
|
||||||
|
import sys
|
||||||
|
import binascii
|
||||||
|
|
||||||
|
from kmip.core import enums
|
||||||
|
from kmip.demos import utils
|
||||||
|
|
||||||
|
from kmip.pie import client
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
logger = utils.build_console_logger(logging.INFO)
|
||||||
|
|
||||||
|
# Build and parse arguments
|
||||||
|
parser = utils.build_cli_parser(enums.Operation.MAC)
|
||||||
|
opts, args = parser.parse_args(sys.argv[1:])
|
||||||
|
|
||||||
|
config = opts.config
|
||||||
|
uid = opts.uuid
|
||||||
|
algorithm = opts.algorithm
|
||||||
|
|
||||||
|
data = (
|
||||||
|
b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E'
|
||||||
|
b'\x0F')
|
||||||
|
|
||||||
|
# Exit early if the arguments are not specified
|
||||||
|
if uid is None:
|
||||||
|
logger.error('No UUID provided, exiting early from demo')
|
||||||
|
sys.exit()
|
||||||
|
if algorithm is None:
|
||||||
|
logger.error('No algorithm provided, exiting early from demo')
|
||||||
|
sys.exit()
|
||||||
|
|
||||||
|
algorithm = getattr(enums.CryptographicAlgorithm, algorithm, None)
|
||||||
|
|
||||||
|
# Build the client and connect to the server
|
||||||
|
with client.ProxyKmipClient(config=config) as client:
|
||||||
|
try:
|
||||||
|
uid, mac_data = client.mac(uid, algorithm, data)
|
||||||
|
logger.info("Successfully done MAC using key with ID: "
|
||||||
|
"{0}".format(uid))
|
||||||
|
logger.info("MACed data: {0}".format(
|
||||||
|
str(binascii.hexlify(mac_data))))
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(e)
|
@ -214,15 +214,32 @@ def build_cli_parser(operation=None):
|
|||||||
"SECRET_DATA"))
|
"SECRET_DATA"))
|
||||||
elif operation is Operation.DISCOVER_VERSIONS:
|
elif operation is Operation.DISCOVER_VERSIONS:
|
||||||
parser.add_option(
|
parser.add_option(
|
||||||
"-v",
|
"-v",
|
||||||
"--protocol-versions",
|
"--protocol-versions",
|
||||||
action="store",
|
action="store",
|
||||||
type="str",
|
type="str",
|
||||||
default=None,
|
default=None,
|
||||||
dest="protocol_versions",
|
dest="protocol_versions",
|
||||||
help=("Protocol versions supported by client. "
|
help=("Protocol versions supported by client. "
|
||||||
"ex. '1.1,1.2 1.3'"))
|
"ex. '1.1,1.2 1.3'"))
|
||||||
|
elif operation is Operation.MAC:
|
||||||
|
parser.add_option(
|
||||||
|
"-i",
|
||||||
|
"--uuid",
|
||||||
|
action="store",
|
||||||
|
type="str",
|
||||||
|
default=None,
|
||||||
|
dest="uuid",
|
||||||
|
help="The unique ID of the managed object that is the key"
|
||||||
|
"to use for the MAC operation")
|
||||||
|
parser.add_option(
|
||||||
|
"-a",
|
||||||
|
"--algorithm",
|
||||||
|
action="store",
|
||||||
|
type="str",
|
||||||
|
default=None,
|
||||||
|
dest="algorithm",
|
||||||
|
help="Encryption algorithm for the secret (e.g., AES)")
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
|
|
||||||
|
@ -90,3 +90,17 @@ class KmipClient:
|
|||||||
uid (string): The unique ID of the managed object to destroy.
|
uid (string): The unique ID of the managed object to destroy.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@abc.abstractmethod
|
||||||
|
def mac(self, uid, algorithm, data):
|
||||||
|
"""
|
||||||
|
Get the message authentication code for data.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
uid (string): The unique ID of the managed object that is the key
|
||||||
|
to use for the MAC operation.
|
||||||
|
algorithm (CryptographicAlgorithm): An enumeration defining the
|
||||||
|
algorithm to use to generate the MAC.
|
||||||
|
data (string): The data to be MACed.
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
@ -21,6 +21,9 @@ from kmip.core import objects as cobjects
|
|||||||
|
|
||||||
from kmip.core.factories import attributes
|
from kmip.core.factories import attributes
|
||||||
|
|
||||||
|
from kmip.core.attributes import CryptographicParameters, \
|
||||||
|
CryptographicAlgorithm
|
||||||
|
|
||||||
from kmip.pie import api
|
from kmip.pie import api
|
||||||
from kmip.pie import exceptions
|
from kmip.pie import exceptions
|
||||||
from kmip.pie import factory
|
from kmip.pie import factory
|
||||||
@ -476,6 +479,58 @@ class ProxyKmipClient(api.KmipClient):
|
|||||||
message = result.result_message.value
|
message = result.result_message.value
|
||||||
raise exceptions.KmipOperationFailure(status, reason, message)
|
raise exceptions.KmipOperationFailure(status, reason, message)
|
||||||
|
|
||||||
|
def mac(self, uid, algorithm, data):
|
||||||
|
"""
|
||||||
|
Get the message authentication code for data.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
uid (string): The unique ID of the managed object that is the key
|
||||||
|
to use for the MAC operation.
|
||||||
|
algorithm (CryptographicAlgorithm): An enumeration defining the
|
||||||
|
algorithm to use to generate the MAC.
|
||||||
|
data (string): The data to be MACed.
|
||||||
|
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
string: The unique ID of the managed object that is the key
|
||||||
|
to use for the MAC operation.
|
||||||
|
string: The data MACed
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
ClientConnectionNotOpen: if the client connection is unusable
|
||||||
|
KmipOperationFailure: if the operation result is a failure
|
||||||
|
TypeError: if the input arguments are invalid
|
||||||
|
"""
|
||||||
|
# Check inputs
|
||||||
|
if not isinstance(uid, six.string_types):
|
||||||
|
raise TypeError("uid must be a string")
|
||||||
|
if not isinstance(algorithm, enums.CryptographicAlgorithm):
|
||||||
|
raise TypeError(
|
||||||
|
"algorithm must be a CryptographicAlgorithm enumeration")
|
||||||
|
if not isinstance(data, six.binary_type):
|
||||||
|
raise TypeError(
|
||||||
|
"data must be bytes")
|
||||||
|
|
||||||
|
# Verify that operations can be given at this time
|
||||||
|
if not self._is_open:
|
||||||
|
raise exceptions.ClientConnectionNotOpen()
|
||||||
|
|
||||||
|
parameters_attribute = CryptographicParameters(
|
||||||
|
cryptographic_algorithm=CryptographicAlgorithm(algorithm))
|
||||||
|
|
||||||
|
# Create the symmetric key and handle the results
|
||||||
|
result = self.proxy.mac(uid, parameters_attribute, data)
|
||||||
|
|
||||||
|
status = result.result_status.value
|
||||||
|
if status == enums.ResultStatus.SUCCESS:
|
||||||
|
uid = result.uuid.value
|
||||||
|
mac_data = result.mac_data.value
|
||||||
|
return uid, mac_data
|
||||||
|
else:
|
||||||
|
reason = result.result_reason.value
|
||||||
|
message = result.result_message.value
|
||||||
|
raise exceptions.KmipOperationFailure(status, reason, message)
|
||||||
|
|
||||||
def _build_key_attributes(self, algorithm, length):
|
def _build_key_attributes(self, algorithm, length):
|
||||||
# Build a list of core key attributes.
|
# Build a list of core key attributes.
|
||||||
algorithm_attribute = self.attribute_factory.create_attribute(
|
algorithm_attribute = self.attribute_factory.create_attribute(
|
||||||
|
@ -27,6 +27,7 @@ from kmip.services.results import QueryResult
|
|||||||
from kmip.services.results import RegisterResult
|
from kmip.services.results import RegisterResult
|
||||||
from kmip.services.results import RekeyKeyPairResult
|
from kmip.services.results import RekeyKeyPairResult
|
||||||
from kmip.services.results import RevokeResult
|
from kmip.services.results import RevokeResult
|
||||||
|
from kmip.services.results import MACResult
|
||||||
|
|
||||||
from kmip.core import attributes as attr
|
from kmip.core import attributes as attr
|
||||||
|
|
||||||
@ -60,6 +61,7 @@ from kmip.core.messages.payloads import query
|
|||||||
from kmip.core.messages.payloads import rekey_key_pair
|
from kmip.core.messages.payloads import rekey_key_pair
|
||||||
from kmip.core.messages.payloads import register
|
from kmip.core.messages.payloads import register
|
||||||
from kmip.core.messages.payloads import revoke
|
from kmip.core.messages.payloads import revoke
|
||||||
|
from kmip.core.messages.payloads import mac
|
||||||
|
|
||||||
from kmip.services.server.kmip_protocol import KMIPProtocol
|
from kmip.services.server.kmip_protocol import KMIPProtocol
|
||||||
|
|
||||||
@ -428,6 +430,14 @@ class KMIPProxy(KMIP):
|
|||||||
results = self._process_batch_items(response)
|
results = self._process_batch_items(response)
|
||||||
return results[0]
|
return results[0]
|
||||||
|
|
||||||
|
def mac(self, unique_identifier=None, cryptographic_parameters=None,
|
||||||
|
data=None, credential=None):
|
||||||
|
return self._mac(
|
||||||
|
unique_identifier=unique_identifier,
|
||||||
|
cryptographic_parameters=cryptographic_parameters,
|
||||||
|
data=data,
|
||||||
|
credential=credential)
|
||||||
|
|
||||||
def _create(self,
|
def _create(self,
|
||||||
object_type=None,
|
object_type=None,
|
||||||
template_attribute=None,
|
template_attribute=None,
|
||||||
@ -919,6 +929,43 @@ class KMIPProxy(KMIP):
|
|||||||
uuids)
|
uuids)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
def _mac(self,
|
||||||
|
unique_identifier=None,
|
||||||
|
cryptographic_parameters=None,
|
||||||
|
data=None,
|
||||||
|
credential=None):
|
||||||
|
operation = Operation(OperationEnum.MAC)
|
||||||
|
|
||||||
|
req_pl = mac.MACRequestPayload(
|
||||||
|
unique_identifier=attr.UniqueIdentifier(unique_identifier),
|
||||||
|
cryptographic_parameters=cryptographic_parameters,
|
||||||
|
data=objects.Data(data))
|
||||||
|
batch_item = messages.RequestBatchItem(operation=operation,
|
||||||
|
request_payload=req_pl)
|
||||||
|
|
||||||
|
message = self._build_request_message(credential, [batch_item])
|
||||||
|
self._send_message(message)
|
||||||
|
message = messages.ResponseMessage()
|
||||||
|
data = self._receive_message()
|
||||||
|
message.read(data)
|
||||||
|
batch_items = message.batch_items
|
||||||
|
batch_item = batch_items[0]
|
||||||
|
payload = batch_item.response_payload
|
||||||
|
|
||||||
|
if payload is None:
|
||||||
|
payload_unique_identifier = None
|
||||||
|
payload_mac_data = None
|
||||||
|
else:
|
||||||
|
payload_unique_identifier = payload.unique_identifier
|
||||||
|
payload_mac_data = payload.mac_data
|
||||||
|
|
||||||
|
result = MACResult(batch_item.result_status,
|
||||||
|
batch_item.result_reason,
|
||||||
|
batch_item.result_message,
|
||||||
|
payload_unique_identifier,
|
||||||
|
payload_mac_data)
|
||||||
|
return result
|
||||||
|
|
||||||
# TODO (peter-hamilton) Augment to handle device credentials
|
# TODO (peter-hamilton) Augment to handle device credentials
|
||||||
def _build_credential(self):
|
def _build_credential(self):
|
||||||
if (self.username is None) and (self.password is None):
|
if (self.username is None) and (self.password is None):
|
||||||
@ -937,7 +984,7 @@ class KMIPProxy(KMIP):
|
|||||||
return credential
|
return credential
|
||||||
|
|
||||||
def _build_request_message(self, credential, batch_items):
|
def _build_request_message(self, credential, batch_items):
|
||||||
protocol_version = ProtocolVersion.create(1, 1)
|
protocol_version = ProtocolVersion.create(1, 2)
|
||||||
|
|
||||||
if credential is None:
|
if credential is None:
|
||||||
credential = self._build_credential()
|
credential = self._build_credential()
|
||||||
|
@ -295,3 +295,20 @@ class RevokeResult(OperationResult):
|
|||||||
super(RevokeResult, self).__init__(
|
super(RevokeResult, self).__init__(
|
||||||
result_status, result_reason, result_message)
|
result_status, result_reason, result_message)
|
||||||
self.unique_identifier = unique_identifier
|
self.unique_identifier = unique_identifier
|
||||||
|
|
||||||
|
|
||||||
|
class MACResult(OperationResult):
|
||||||
|
|
||||||
|
def __init__(self,
|
||||||
|
result_status,
|
||||||
|
result_reason=None,
|
||||||
|
result_message=None,
|
||||||
|
uuid=None,
|
||||||
|
mac_data=None):
|
||||||
|
super(MACResult, self).__init__(
|
||||||
|
result_status,
|
||||||
|
result_reason,
|
||||||
|
result_message
|
||||||
|
)
|
||||||
|
self.uuid = uuid
|
||||||
|
self.mac_data = mac_data
|
||||||
|
@ -44,6 +44,9 @@ class DummyKmipClient(api.KmipClient):
|
|||||||
def destroy(self, uid):
|
def destroy(self, uid):
|
||||||
super(DummyKmipClient, self).destroy(uid)
|
super(DummyKmipClient, self).destroy(uid)
|
||||||
|
|
||||||
|
def mac(self, uid, algorithm, data):
|
||||||
|
super(DummyKmipClient, self).mac(uid, algorithm, data)
|
||||||
|
|
||||||
|
|
||||||
class TestKmipClient(testtools.TestCase):
|
class TestKmipClient(testtools.TestCase):
|
||||||
"""
|
"""
|
||||||
@ -106,3 +109,10 @@ class TestKmipClient(testtools.TestCase):
|
|||||||
"""
|
"""
|
||||||
dummy = DummyKmipClient()
|
dummy = DummyKmipClient()
|
||||||
dummy.destroy('uid')
|
dummy.destroy('uid')
|
||||||
|
|
||||||
|
def test_mac(self):
|
||||||
|
"""
|
||||||
|
Test that the mac method can be called without error.
|
||||||
|
"""
|
||||||
|
dummy = DummyKmipClient()
|
||||||
|
dummy.mac('uid', 'algorithm', 'data')
|
||||||
|
@ -1056,3 +1056,105 @@ class TestProxyKmipClient(testtools.TestCase):
|
|||||||
self.assertIsInstance(opn.attribute_value, attr.OperationPolicyName)
|
self.assertIsInstance(opn.attribute_value, attr.OperationPolicyName)
|
||||||
self.assertEqual(opn.attribute_name.value, 'Operation Policy Name')
|
self.assertEqual(opn.attribute_name.value, 'Operation Policy Name')
|
||||||
self.assertEqual(opn.attribute_value.value, 'test')
|
self.assertEqual(opn.attribute_value.value, 'test')
|
||||||
|
|
||||||
|
@mock.patch('kmip.pie.client.KMIPProxy',
|
||||||
|
mock.MagicMock(spec_set=KMIPProxy))
|
||||||
|
def test_mac(self):
|
||||||
|
"""
|
||||||
|
Test the MAC client with proper input.
|
||||||
|
"""
|
||||||
|
uuid = 'aaaaaaaa-1111-2222-3333-ffffffffffff'
|
||||||
|
algorithm = enums.CryptographicAlgorithm.HMAC_SHA256
|
||||||
|
data = (b'\x00\x01\x02\x03\x04')
|
||||||
|
|
||||||
|
result = results.MACResult(
|
||||||
|
contents.ResultStatus(enums.ResultStatus.SUCCESS),
|
||||||
|
uuid=attr.UniqueIdentifier(uuid),
|
||||||
|
mac_data=obj.MACData(data))
|
||||||
|
|
||||||
|
with ProxyKmipClient() as client:
|
||||||
|
client.proxy.mac.return_value = result
|
||||||
|
|
||||||
|
uid, mac_data = client.mac(uuid, algorithm, data)
|
||||||
|
self.assertEqual(uid, uuid)
|
||||||
|
self.assertEqual(mac_data, data)
|
||||||
|
|
||||||
|
@mock.patch('kmip.pie.client.KMIPProxy',
|
||||||
|
mock.MagicMock(spec_set=KMIPProxy))
|
||||||
|
def test_mac_on_invalid_inputs(self):
|
||||||
|
"""
|
||||||
|
Test that a TypeError exception is raised when wrong type
|
||||||
|
of arguments are given to mac operation.
|
||||||
|
"""
|
||||||
|
uuid = 'aaaaaaaa-1111-2222-3333-ffffffffffff'
|
||||||
|
uuid_invalid = int(123)
|
||||||
|
|
||||||
|
algorithm = enums.CryptographicAlgorithm.HMAC_SHA256
|
||||||
|
algorithm_invalid = enums.CryptographicUsageMask.MAC_GENERATE
|
||||||
|
|
||||||
|
data = (b'\x00\x01\x02\x03\x04')
|
||||||
|
data_invalid = int(123)
|
||||||
|
|
||||||
|
result = results.MACResult(
|
||||||
|
contents.ResultStatus(enums.ResultStatus.SUCCESS),
|
||||||
|
uuid=attr.UniqueIdentifier(uuid),
|
||||||
|
mac_data=obj.MACData(data))
|
||||||
|
|
||||||
|
args = [uuid_invalid, algorithm, data]
|
||||||
|
with ProxyKmipClient() as client:
|
||||||
|
client.proxy.mac.return_value = result
|
||||||
|
self.assertRaises(TypeError, client.mac, *args)
|
||||||
|
|
||||||
|
args = [uuid, algorithm_invalid, data]
|
||||||
|
with ProxyKmipClient() as client:
|
||||||
|
client.proxy.mac.return_value = result
|
||||||
|
self.assertRaises(TypeError, client.mac, *args)
|
||||||
|
|
||||||
|
args = [uuid, algorithm, data_invalid]
|
||||||
|
with ProxyKmipClient() as client:
|
||||||
|
client.proxy.mac.return_value = result
|
||||||
|
self.assertRaises(TypeError, client.mac, *args)
|
||||||
|
|
||||||
|
@mock.patch('kmip.pie.client.KMIPProxy',
|
||||||
|
mock.MagicMock(spec_set=KMIPProxy))
|
||||||
|
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)
|
||||||
|
|
||||||
|
@mock.patch('kmip.pie.client.KMIPProxy',
|
||||||
|
mock.MagicMock(spec_set=KMIPProxy))
|
||||||
|
def test_mac_on_closed(self):
|
||||||
|
"""
|
||||||
|
Test that a ClientConnectionNotOpen exception is raised when trying
|
||||||
|
to do mac on an unopened client connection.
|
||||||
|
"""
|
||||||
|
client = ProxyKmipClient()
|
||||||
|
uuid = 'aaaaaaaa-1111-2222-3333-ffffffffffff'
|
||||||
|
algorithm = enums.CryptographicAlgorithm.HMAC_SHA256
|
||||||
|
data = (b'\x00\x01\x02\x03\x04')
|
||||||
|
args = [uuid, algorithm, data]
|
||||||
|
self.assertRaises(
|
||||||
|
ClientConnectionNotOpen, client.mac, *args)
|
||||||
|
@ -16,6 +16,9 @@
|
|||||||
from testtools import TestCase
|
from testtools import TestCase
|
||||||
|
|
||||||
from kmip.core.attributes import PrivateKeyUniqueIdentifier
|
from kmip.core.attributes import PrivateKeyUniqueIdentifier
|
||||||
|
from kmip.core.attributes import CryptographicParameters, \
|
||||||
|
CryptographicAlgorithm
|
||||||
|
|
||||||
|
|
||||||
from kmip.core.enums import AuthenticationSuite
|
from kmip.core.enums import AuthenticationSuite
|
||||||
from kmip.core.enums import ConformanceClause
|
from kmip.core.enums import ConformanceClause
|
||||||
@ -24,6 +27,8 @@ from kmip.core.enums import ResultStatus as ResultStatusEnum
|
|||||||
from kmip.core.enums import ResultReason as ResultReasonEnum
|
from kmip.core.enums import ResultReason as ResultReasonEnum
|
||||||
from kmip.core.enums import Operation as OperationEnum
|
from kmip.core.enums import Operation as OperationEnum
|
||||||
from kmip.core.enums import QueryFunction as QueryFunctionEnum
|
from kmip.core.enums import QueryFunction as QueryFunctionEnum
|
||||||
|
from kmip.core.enums import CryptographicAlgorithm as \
|
||||||
|
CryptographicAlgorithmEnum
|
||||||
|
|
||||||
from kmip.core.factories.attributes import AttributeFactory
|
from kmip.core.factories.attributes import AttributeFactory
|
||||||
from kmip.core.factories.credentials import CredentialFactory
|
from kmip.core.factories.credentials import CredentialFactory
|
||||||
@ -714,6 +719,93 @@ class TestKMIPClient(TestCase):
|
|||||||
self.client._create_socket(sock)
|
self.client._create_socket(sock)
|
||||||
self.assertEqual(ssl.SSLSocket, type(self.client.socket))
|
self.assertEqual(ssl.SSLSocket, type(self.client.socket))
|
||||||
|
|
||||||
|
@mock.patch('kmip.services.kmip_client.KMIPProxy._send_message',
|
||||||
|
mock.MagicMock())
|
||||||
|
@mock.patch('kmip.services.kmip_client.KMIPProxy._receive_message',
|
||||||
|
mock.MagicMock())
|
||||||
|
def test_mac(self):
|
||||||
|
|
||||||
|
from kmip.core.utils import BytearrayStream
|
||||||
|
|
||||||
|
request_expected = (
|
||||||
|
b'\x42\x00\x78\x01\x00\x00\x00\xa0\x42\x00\x77\x01\x00\x00\x00\x38'
|
||||||
|
b'\x42\x00\x69\x01\x00\x00\x00\x20\x42\x00\x6a\x02\x00\x00\x00\x04'
|
||||||
|
b'\x00\x00\x00\x01\x00\x00\x00\x00\x42\x00\x6b\x02\x00\x00\x00\x04'
|
||||||
|
b'\x00\x00\x00\x02\x00\x00\x00\x00\x42\x00\x0d\x02\x00\x00\x00\x04'
|
||||||
|
b'\x00\x00\x00\x01\x00\x00\x00\x00\x42\x00\x0f\x01\x00\x00\x00\x58'
|
||||||
|
b'\x42\x00\x5c\x05\x00\x00\x00\x04\x00\x00\x00\x23\x00\x00\x00\x00'
|
||||||
|
b'\x42\x00\x79\x01\x00\x00\x00\x40\x42\x00\x94\x07\x00\x00\x00\x01'
|
||||||
|
b'\x31\x00\x00\x00\x00\x00\x00\x00\x42\x00\x2b\x01\x00\x00\x00\x10'
|
||||||
|
b'\x42\x00\x28\x05\x00\x00\x00\x04\x00\x00\x00\x0b\x00\x00\x00\x00'
|
||||||
|
b'\x42\x00\xc2\x08\x00\x00\x00\x10\x00\x01\x02\x03\x04\x05\x06\x07'
|
||||||
|
b'\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f')
|
||||||
|
response = (
|
||||||
|
b'\x42\x00\x7b\x01\x00\x00\x00\xd8\x42\x00\x7a\x01\x00\x00\x00\x48'
|
||||||
|
b'\x42\x00\x69\x01\x00\x00\x00\x20\x42\x00\x6a\x02\x00\x00\x00\x04'
|
||||||
|
b'\x00\x00\x00\x01\x00\x00\x00\x00\x42\x00\x6b\x02\x00\x00\x00\x04'
|
||||||
|
b'\x00\x00\x00\x02\x00\x00\x00\x00\x42\x00\x92\x09\x00\x00\x00\x08'
|
||||||
|
b'\x00\x00\x00\x00\x58\x8a\x3f\x23\x42\x00\x0d\x02\x00\x00\x00\x04'
|
||||||
|
b'\x00\x00\x00\x01\x00\x00\x00\x00\x42\x00\x0f\x01\x00\x00\x00\x80'
|
||||||
|
b'\x42\x00\x5c\x05\x00\x00\x00\x04\x00\x00\x00\x23\x00\x00\x00\x00'
|
||||||
|
b'\x42\x00\x7f\x05\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||||
|
b'\x42\x00\x7c\x01\x00\x00\x00\x58\x42\x00\x94\x07\x00\x00\x00\x01'
|
||||||
|
b'\x31\x00\x00\x00\x00\x00\x00\x00\x42\x00\xc6\x08\x00\x00\x00\x40'
|
||||||
|
b'\x99\x8b\x55\x59\x90\x9b\x85\x87\x5b\x90\x63\x13\x12\xbb\x32\x9f'
|
||||||
|
b'\x6a\xc4\xed\x97\x6e\xac\x99\xe5\x21\x53\xc4\x19\x28\xf2\x2a\x5b'
|
||||||
|
b'\xef\x79\xa4\xbe\x05\x3b\x31\x49\x19\xe0\x75\x23\xb9\xbe\xc8\x23'
|
||||||
|
b'\x35\x60\x7e\x49\xba\xa9\x7e\xe0\x9e\x6b\x3d\x55\xf4\x51\xff\x7c'
|
||||||
|
)
|
||||||
|
response_no_payload = (
|
||||||
|
b'\x42\x00\x7b\x01\x00\x00\x00\x78\x42\x00\x7a\x01\x00\x00\x00\x48'
|
||||||
|
b'\x42\x00\x69\x01\x00\x00\x00\x20\x42\x00\x6a\x02\x00\x00\x00\x04'
|
||||||
|
b'\x00\x00\x00\x01\x00\x00\x00\x00\x42\x00\x6b\x02\x00\x00\x00\x04'
|
||||||
|
b'\x00\x00\x00\x02\x00\x00\x00\x00\x42\x00\x92\x09\x00\x00\x00\x08'
|
||||||
|
b'\x00\x00\x00\x00\x58\x8a\x3f\x23\x42\x00\x0d\x02\x00\x00\x00\x04'
|
||||||
|
b'\x00\x00\x00\x01\x00\x00\x00\x00\x42\x00\x0f\x01\x00\x00\x00\x80'
|
||||||
|
b'\x42\x00\x5c\x05\x00\x00\x00\x04\x00\x00\x00\x23\x00\x00\x00\x00'
|
||||||
|
b'\x42\x00\x7f\x05\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||||
|
)
|
||||||
|
|
||||||
|
data = (b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B'
|
||||||
|
b'\x0C\x0D\x0E\x0F')
|
||||||
|
|
||||||
|
mdata = (b'\x99\x8b\x55\x59\x90\x9b\x85\x87\x5b\x90\x63\x13'
|
||||||
|
b'\x12\xbb\x32\x9f'
|
||||||
|
b'\x6a\xc4\xed\x97\x6e\xac\x99\xe5\x21\x53\xc4\x19'
|
||||||
|
b'\x28\xf2\x2a\x5b'
|
||||||
|
b'\xef\x79\xa4\xbe\x05\x3b\x31\x49\x19\xe0\x75\x23'
|
||||||
|
b'\xb9\xbe\xc8\x23'
|
||||||
|
b'\x35\x60\x7e\x49\xba\xa9\x7e\xe0\x9e\x6b\x3d\x55'
|
||||||
|
b'\xf4\x51\xff\x7c')
|
||||||
|
|
||||||
|
def verify_request(message):
|
||||||
|
stream = BytearrayStream()
|
||||||
|
message.write(stream)
|
||||||
|
self.assertEqual(stream.buffer, request_expected)
|
||||||
|
|
||||||
|
uuid = '1'
|
||||||
|
|
||||||
|
cryptographic_parameters = CryptographicParameters(
|
||||||
|
cryptographic_algorithm=CryptographicAlgorithm(
|
||||||
|
CryptographicAlgorithmEnum.HMAC_SHA512)
|
||||||
|
)
|
||||||
|
|
||||||
|
self.client._send_message.side_effect = verify_request
|
||||||
|
self.client._receive_message.return_value = BytearrayStream(response)
|
||||||
|
|
||||||
|
result = self.client.mac(uuid, cryptographic_parameters,
|
||||||
|
data)
|
||||||
|
self.assertEqual(result.uuid.value, uuid)
|
||||||
|
self.assertEqual(result.mac_data.value, mdata)
|
||||||
|
|
||||||
|
self.client._receive_message.return_value = \
|
||||||
|
BytearrayStream(response_no_payload)
|
||||||
|
|
||||||
|
result = self.client.mac(uuid, cryptographic_parameters,
|
||||||
|
data)
|
||||||
|
self.assertEqual(result.uuid, None)
|
||||||
|
self.assertEqual(result.mac_data, None)
|
||||||
|
|
||||||
|
|
||||||
class TestClientProfileInformation(TestCase):
|
class TestClientProfileInformation(TestCase):
|
||||||
"""
|
"""
|
||||||
|
Loading…
x
Reference in New Issue
Block a user