Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion kmip/core/factories/secrets.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
from kmip.core.secrets import PrivateKey
from kmip.core.secrets import PublicKey
from kmip.core.secrets import SecretData
from kmip.core.secrets import SplitKey
from kmip.core.secrets import SymmetricKey
from kmip.core.secrets import Template

Expand Down Expand Up @@ -116,7 +117,18 @@ def _create_private_key(self, value):
return PrivateKey(key_block)

def _create_split_key(self, value):
raise NotImplementedError()
if value is None:
return SplitKey()
else:
key_block = self._build_key_block(value)
return SplitKey(
split_key_parts=value.get("split_key_parts"),
key_part_identifier=value.get("key_part_identifier"),
split_key_threshold=value.get("split_key_threshold"),
split_key_method=value.get("split_key_method"),
prime_field_size=value.get("prime_field_size"),
key_block=key_block
)

def _create_template(self, value):
if value is None:
Expand Down
9 changes: 6 additions & 3 deletions kmip/pie/factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,11 @@ def _build_core_secret_data(self, secret):
def _build_core_split_key(self, secret):
key_material = cobjects.KeyMaterial(secret.value)
key_value = cobjects.KeyValue(key_material)
key_wrapping_data = None
if secret.key_wrapping_data:
key_wrapping_data = cobjects.KeyWrappingData(
**secret.key_wrapping_data
)
key_block = cobjects.KeyBlock(
key_format_type=misc.KeyFormatType(secret.key_format_type),
key_compression_type=None,
Expand All @@ -204,9 +209,7 @@ def _build_core_split_key(self, secret):
cryptographic_length=attributes.CryptographicLength(
secret.cryptographic_length
),
key_wrapping_data=cobjects.KeyWrappingData(
**secret.key_wrapping_data
)
key_wrapping_data=key_wrapping_data
)
return secrets.SplitKey(
split_key_parts=secret.split_key_parts,
Expand Down
13 changes: 13 additions & 0 deletions kmip/services/server/engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,19 @@ def _build_core_object(self, obj):
'opaque_data_type': obj.opaque_type,
'opaque_data_value': obj.value
}
elif object_type == enums.ObjectType.SPLIT_KEY:
value = {
"cryptographic_algorithm": obj.cryptographic_algorithm,
"cryptographic_length": obj.cryptographic_length,
"key_format_type": obj.key_format_type,
"key_value": obj.value,
"key_wrapping_data": obj.key_wrapping_data,
"split_key_parts": obj.split_key_parts,
"key_part_identifier": obj.key_part_identifier,
"split_key_threshold": obj.split_key_threshold,
"split_key_method": obj.split_key_method,
"prime_field_size": obj.prime_field_size
}
else:
name = object_type.name
raise exceptions.InvalidField(
Expand Down
103 changes: 103 additions & 0 deletions kmip/tests/integration/services/test_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
from kmip.core.secrets import Certificate
from kmip.core.secrets import SecretData
from kmip.core.secrets import OpaqueObject
from kmip.core.secrets import SplitKey


@pytest.mark.usefixtures("client")
Expand Down Expand Up @@ -1675,3 +1676,105 @@ def test_symmetric_key_create_getattributes_locate_destroy(self):
ResultStatus.OPERATION_FAILED,
result.result_status.value
)

def test_split_key_register_get_destroy(self):
"""
Tests that split keys are properly registered, retrieved, and
destroyed.
"""
usage_mask = self.attr_factory.create_attribute(
AttributeType.CRYPTOGRAPHIC_USAGE_MASK,
[CryptographicUsageMask.ENCRYPT, CryptographicUsageMask.DECRYPT]
)
key_name = "Integration Test - Register-Get-Destroy Split Key"
name = self.attr_factory.create_attribute(AttributeType.NAME, key_name)
template_attribute = TemplateAttribute(attributes=[usage_mask, name])

key_data = (
b'\x00\x00\x00\x00\x00\x00\x00\x00'
b'\x00\x00\x00\x00\x00\x00\x00\x00'
)

key_block = KeyBlock(
key_format_type=KeyFormatType(KeyFormatTypeEnum.RAW),
key_compression_type=None,
key_value=KeyValue(KeyMaterial(key_data)),
cryptographic_algorithm=CryptographicAlgorithm(
CryptoAlgorithmEnum.AES
),
cryptographic_length=CryptographicLength(128),
key_wrapping_data=None
)

secret = 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
)

result = self.client.register(
ObjectType.SPLIT_KEY,
template_attribute,
secret,
credential=None
)

self._check_result_status(result, ResultStatus, ResultStatus.SUCCESS)
self._check_uuid(result.uuid, str)

# Check that the returned key bytes match what was provided
uuid = result.uuid
result = self.client.get(uuid=uuid, credential=None)

self._check_result_status(result, ResultStatus, ResultStatus.SUCCESS)
self._check_object_type(
result.object_type,
ObjectType,
ObjectType.SPLIT_KEY
)
self._check_uuid(result.uuid, str)

self.assertEqual(3, result.secret.split_key_parts)
self.assertEqual(1, result.secret.key_part_identifier)
self.assertEqual(2, result.secret.split_key_threshold)
self.assertEqual(
enums.SplitKeyMethod.XOR,
result.secret.split_key_method
)
self.assertIsNone(result.secret.prime_field_size)

# Check the secret type
self.assertIsInstance(result.secret, SplitKey)
self.assertEqual(
key_data,
result.secret.key_block.key_value.key_material.value
)

self.logger.debug(
'Destroying key: ' + key_name + '\nWith UUID: ' + result.uuid
)

result = self.client.destroy(result.uuid)
self._check_result_status(
result,
ResultStatus,
ResultStatus.SUCCESS
)
self._check_uuid(result.uuid.value, str)

# Verify the secret was destroyed
result = self.client.get(uuid=uuid, credential=None)

self._check_result_status(
result,
ResultStatus,
ResultStatus.OPERATION_FAILED
)
self.assertIsInstance(result.result_reason.value, ResultReason)
self.assertEqual(
ResultReason.ITEM_NOT_FOUND,
result.result_reason.value
)
54 changes: 54 additions & 0 deletions kmip/tests/integration/services/test_proxykmipclient.py
Original file line number Diff line number Diff line change
Expand Up @@ -1295,3 +1295,57 @@ def test_create_getattributes_locate_destroy(self):
# Clean up the keys
self.client.destroy(a_id)
self.client.destroy(b_id)

def test_split_key_register_get_destroy(self):
"""
Test that the ProxyKmipClient can register, retrieve, and destroy a
split key.
"""
key = objects.SplitKey(
cryptographic_algorithm=enums.CryptographicAlgorithm.AES,
cryptographic_length=128,
key_value=(
b'\x00\x01\x02\x03\x04\x05\x06\x07'
b'\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F'
),
name="Test Split Key",
cryptographic_usage_masks=[enums.CryptographicUsageMask.EXPORT],
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
)

uid = self.client.register(key)
self.assertIsInstance(uid, six.string_types)

try:
result = self.client.get(uid)
self.assertIsInstance(result, objects.SplitKey)
self.assertEqual(
enums.CryptographicAlgorithm.AES,
result.cryptographic_algorithm
)
self.assertEqual(128, result.cryptographic_length)
self.assertEqual(
(
b'\x00\x01\x02\x03\x04\x05\x06\x07'
b'\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F'
),
result.value
)
self.assertEqual(enums.KeyFormatType.RAW, result.key_format_type)
self.assertEqual(3, result.split_key_parts)
self.assertEqual(1, result.key_part_identifier)
self.assertEqual(2, result.split_key_threshold)
self.assertEqual(enums.SplitKeyMethod.XOR, result.split_key_method)
self.assertIsNone(result.prime_field_size)
finally:
self.client.destroy(uid)
self.assertRaises(
exceptions.KmipOperationFailure, self.client.get, uid)
self.assertRaises(
exceptions.KmipOperationFailure, self.client.destroy, uid)
4 changes: 2 additions & 2 deletions kmip/tests/unit/services/server/test_engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -1038,10 +1038,10 @@ def test_build_core_object_unsupported_type(self):

class DummyObject:
def __init__(self):
self._object_type = enums.ObjectType.SPLIT_KEY
self._object_type = enums.ObjectType.TEMPLATE

args = (DummyObject(), )
regex = "The SplitKey object type is not supported."
regex = "The Template object type is not supported."
six.assertRaisesRegex(
self,
exceptions.InvalidField,
Expand Down