Add conversion utilities for SplitKey objects

This change adds conversion utilities for SplitKey objects,
allowing for conversions between the Pie and Core object spaces.
The server is also updated to recognize the new Pie SplitKey
object. Unit tests have been added and tweaked to accommodate
these changes.

Partially implements #545
This commit is contained in:
Peter Hamilton 2019-09-20 10:38:16 -04:00 committed by Peter Hamilton
parent 84ab77cd8d
commit a8713fc909
4 changed files with 214 additions and 3 deletions

View File

@ -68,6 +68,10 @@ class ObjectFactory:
return self._build_core_opaque_object(obj)
elif isinstance(obj, secrets.OpaqueObject):
return self._build_pie_opaque_object(obj)
elif isinstance(obj, pobjects.SplitKey):
return self._build_core_split_key(obj)
elif isinstance(obj, secrets.SplitKey):
return self._build_pie_split_key(obj)
else:
raise TypeError("object type unsupported and cannot be converted")
@ -125,6 +129,23 @@ class ObjectFactory:
value = obj.opaque_data_value.value
return pobjects.OpaqueObject(value, opaque_type)
def _build_pie_split_key(self, secret):
algorithm = secret.key_block.cryptographic_algorithm.value
return pobjects.SplitKey(
cryptographic_algorithm=algorithm,
cryptographic_length=secret.key_block.cryptographic_length.value,
key_value=secret.key_block.key_value.key_material.value,
key_format_type=secret.key_block.key_format_type.value,
key_wrapping_data=self._build_key_wrapping_data(
secret.key_block.key_wrapping_data
),
split_key_parts=secret.split_key_parts,
key_part_identifier=secret.key_part_identifier,
split_key_threshold=secret.split_key_threshold,
split_key_method=secret.split_key_method,
prime_field_size=secret.prime_field_size
)
def _build_core_key(self, key, cls):
algorithm = key.cryptographic_algorithm
length = key.cryptographic_length
@ -170,6 +191,32 @@ class ObjectFactory:
return secrets.SecretData(data_type, key_block)
def _build_core_split_key(self, secret):
key_material = cobjects.KeyMaterial(secret.value)
key_value = cobjects.KeyValue(key_material)
key_block = cobjects.KeyBlock(
key_format_type=misc.KeyFormatType(secret.key_format_type),
key_compression_type=None,
key_value=key_value,
cryptographic_algorithm=attributes.CryptographicAlgorithm(
secret.cryptographic_algorithm
),
cryptographic_length=attributes.CryptographicLength(
secret.cryptographic_length
),
key_wrapping_data=cobjects.KeyWrappingData(
**secret.key_wrapping_data
)
)
return secrets.SplitKey(
split_key_parts=secret.split_key_parts,
key_part_identifier=secret.key_part_identifier,
split_key_threshold=secret.split_key_threshold,
split_key_method=secret.split_key_method,
prime_field_size=secret.prime_field_size,
key_block=key_block
)
def _build_core_opaque_object(self, obj):
opaque_type = obj.opaque_type
value = obj.value

View File

@ -123,7 +123,7 @@ class KmipEngine(object):
enums.ObjectType.SYMMETRIC_KEY: objects.SymmetricKey,
enums.ObjectType.PUBLIC_KEY: objects.PublicKey,
enums.ObjectType.PRIVATE_KEY: objects.PrivateKey,
enums.ObjectType.SPLIT_KEY: None,
enums.ObjectType.SPLIT_KEY: objects.SplitKey,
enums.ObjectType.TEMPLATE: None,
enums.ObjectType.SECRET_DATA: objects.SecretData,
enums.ObjectType.OPAQUE_DATA: objects.OpaqueObject

View File

@ -430,6 +430,88 @@ class TestObjectFactory(testtools.TestCase):
self.assertEqual(enums.OpaqueDataType.NONE, pie_obj.opaque_type)
self.assertEqual(self.opaque_bytes, pie_obj.value)
def test_convert_split_key_pie_to_core(self):
"""
Test that a Pie split key object can be converted into a core split
key object.
"""
pie_split_key = pobjects.SplitKey(
cryptographic_algorithm=enums.CryptographicAlgorithm.AES,
cryptographic_length=128,
key_value=self.symmetric_bytes,
cryptographic_usage_masks=[enums.CryptographicUsageMask.EXPORT],
name="Split Key",
key_format_type=enums.KeyFormatType.RAW,
key_wrapping_data=None,
split_key_parts=3,
key_part_identifier=1,
split_key_threshold=2,
split_key_method=enums.SplitKeyMethod.XOR,
prime_field_size=None
)
core_split_key = self.factory.convert(pie_split_key)
self.assertIsInstance(core_split_key, secrets.SplitKey)
self._test_core_key(
core_split_key,
enums.CryptographicAlgorithm.AES,
128,
self.symmetric_bytes,
enums.KeyFormatType.RAW
)
self.assertEqual(3, core_split_key.split_key_parts)
self.assertEqual(1, core_split_key.key_part_identifier)
self.assertEqual(2, core_split_key.split_key_threshold)
self.assertEqual(
enums.SplitKeyMethod.XOR,
core_split_key.split_key_method
)
self.assertIsNone(core_split_key.prime_field_size)
def test_convert_split_key_core_to_pie(self):
"""
Test that a core split key object can be converted into a Pie split
key object.
"""
key_block = cobjects.KeyBlock(
key_format_type=misc.KeyFormatType(enums.KeyFormatType.RAW),
key_compression_type=None,
key_value=cobjects.KeyValue(
cobjects.KeyMaterial(self.symmetric_bytes)
),
cryptographic_algorithm=attributes.CryptographicAlgorithm(
enums.CryptographicAlgorithm.AES
),
cryptographic_length=attributes.CryptographicLength(128),
key_wrapping_data=None
)
core_split_key = secrets.SplitKey(
split_key_parts=3,
key_part_identifier=1,
split_key_threshold=2,
split_key_method=enums.SplitKeyMethod.XOR,
prime_field_size=None,
key_block=key_block
)
pie_split_key = self.factory.convert(core_split_key)
self.assertIsInstance(pie_split_key, pobjects.SplitKey)
self._test_pie_key(
pie_split_key,
enums.CryptographicAlgorithm.AES,
128,
self.symmetric_bytes,
enums.KeyFormatType.RAW
)
self.assertEqual(3, pie_split_key.split_key_parts)
self.assertEqual(1, pie_split_key.key_part_identifier)
self.assertEqual(2, pie_split_key.split_key_threshold)
self.assertEqual(
enums.SplitKeyMethod.XOR,
pie_split_key.split_key_method
)
self.assertIsNone(pie_split_key.prime_field_size)
def test_build_pie_symmetric_key(self):
"""
Test that a core SymmetricKey object can be converted into a Pie
@ -531,6 +613,88 @@ class TestObjectFactory(testtools.TestCase):
self.assertRaises(
TypeError, self.factory._build_pie_certificate, *args)
def test_build_core_split_key(self):
"""
Test that a Pie split key object can be converted into a core key
object.
"""
pie_split_key = pobjects.SplitKey(
cryptographic_algorithm=enums.CryptographicAlgorithm.AES,
cryptographic_length=128,
key_value=self.symmetric_bytes,
cryptographic_usage_masks=[enums.CryptographicUsageMask.EXPORT],
name="Split Key",
key_format_type=enums.KeyFormatType.RAW,
key_wrapping_data=None,
split_key_parts=3,
key_part_identifier=1,
split_key_threshold=2,
split_key_method=enums.SplitKeyMethod.XOR,
prime_field_size=None
)
core_split_key = self.factory._build_core_split_key(pie_split_key)
self.assertIsInstance(core_split_key, secrets.SplitKey)
self._test_core_key(
core_split_key,
enums.CryptographicAlgorithm.AES,
128,
self.symmetric_bytes,
enums.KeyFormatType.RAW
)
self.assertEqual(3, core_split_key.split_key_parts)
self.assertEqual(1, core_split_key.key_part_identifier)
self.assertEqual(2, core_split_key.split_key_threshold)
self.assertEqual(
enums.SplitKeyMethod.XOR,
core_split_key.split_key_method
)
self.assertIsNone(core_split_key.prime_field_size)
def test_build_pie_split_key(self):
"""
Test that a core split key object can be converted into a Pie split
key object.
"""
key_block = cobjects.KeyBlock(
key_format_type=misc.KeyFormatType(enums.KeyFormatType.RAW),
key_compression_type=None,
key_value=cobjects.KeyValue(
cobjects.KeyMaterial(self.symmetric_bytes)
),
cryptographic_algorithm=attributes.CryptographicAlgorithm(
enums.CryptographicAlgorithm.AES
),
cryptographic_length=attributes.CryptographicLength(128),
key_wrapping_data=None
)
core_split_key = secrets.SplitKey(
split_key_parts=3,
key_part_identifier=1,
split_key_threshold=2,
split_key_method=enums.SplitKeyMethod.XOR,
prime_field_size=None,
key_block=key_block
)
pie_split_key = self.factory._build_pie_split_key(core_split_key)
self.assertIsInstance(pie_split_key, pobjects.SplitKey)
self._test_pie_key(
pie_split_key,
enums.CryptographicAlgorithm.AES,
128,
self.symmetric_bytes,
enums.KeyFormatType.RAW
)
self.assertEqual(3, pie_split_key.split_key_parts)
self.assertEqual(1, pie_split_key.key_part_identifier)
self.assertEqual(2, pie_split_key.split_key_threshold)
self.assertEqual(
enums.SplitKeyMethod.XOR,
pie_split_key.split_key_method
)
self.assertIsNone(pie_split_key.prime_field_size)
def _test_core_key(self, key, algorithm, length, value, format_type):
key_block = key.key_block
self.assertIsInstance(key_block, cobjects.KeyBlock)

View File

@ -3494,11 +3494,11 @@ class TestKmipEngine(testtools.TestCase):
e._data_session = e._data_store_session_factory()
e._logger = mock.MagicMock()
object_type = enums.ObjectType.SPLIT_KEY
object_type = enums.ObjectType.TEMPLATE
payload = payloads.RegisterRequestPayload(object_type=object_type)
args = (payload, )
regex = "The SplitKey object type is not supported."
regex = "The Template object type is not supported."
six.assertRaisesRegex(
self,
exceptions.InvalidField,