2
0
mirror of https://github.com/openkmip/pykmip synced 2025-12-14 23:33:19 +00:00

Add server support for Getting wrapped keys

This change adds support for retrieving wrapped keys from the KMIP
server. The only supported key wrapping algorithm currently is
the AES-based NIST Key Wrap algorithm (RFC 3394). MAC/signing is
not supported for key wrapping. Attribute-bundling with the wrapped
key value is not supported. Wrapping of the entire key block TTLV
encoding is not supported. Various additional error cases are
included and checked for.

Unit tests covering the additions to Get are included.
This commit is contained in:
Peter Hamilton
2017-07-24 13:52:21 -04:00
parent a3bd7f4b6f
commit 50b0ae9fee
3 changed files with 788 additions and 34 deletions

View File

@@ -30,7 +30,7 @@ from kmip.core import attributes
from kmip.core import enums
from kmip.core import exceptions
from kmip.core.objects import MACData
from kmip.core.objects import MACData, KeyWrappingData
from kmip.core.factories import attributes as attribute_factory
from kmip.core.factories import secrets
@@ -1389,14 +1389,6 @@ class KmipEngine(object):
"Key compression is not supported."
)
if payload.key_wrapping_specification:
raise exceptions.PermissionDenied(
"Key wrapping is not supported."
)
# TODO (peterhamilton) Process key wrapping information
# 1. Error check wrapping keys for accessibility and usability
managed_object = self._get_object_with_access_controls(
unique_identifier,
enums.Operation.GET
@@ -1426,7 +1418,107 @@ class KmipEngine(object):
)
)
core_secret = self._build_core_object(managed_object)
if payload.key_wrapping_specification:
key_wrapping_spec = payload.key_wrapping_specification
wrapping_method = key_wrapping_spec.wrapping_method
if wrapping_method != enums.WrappingMethod.ENCRYPT:
raise exceptions.OperationNotSupported(
"Wrapping method '{0}' is not supported.".format(
wrapping_method
)
)
if key_wrapping_spec.encryption_key_information:
key_info = key_wrapping_spec.encryption_key_information
encryption_key_uuid = key_info.unique_identifier
encryption_key_params = key_info.cryptographic_parameters
try:
key = self._get_object_with_access_controls(
encryption_key_uuid,
enums.Operation.GET
)
except Exception:
raise exceptions.ItemNotFound(
"Wrapping key does not exist."
)
if key._object_type != enums.ObjectType.SYMMETRIC_KEY:
raise exceptions.IllegalOperation(
"The wrapping encryption key specified by the "
"encryption key information is not a key."
)
if key.state != enums.State.ACTIVE:
raise exceptions.PermissionDenied(
"Encryption key {0} must be activated to be used for "
"key wrapping.".format(encryption_key_uuid)
)
mask = enums.CryptographicUsageMask.WRAP_KEY
if mask not in key.cryptographic_usage_masks:
raise exceptions.PermissionDenied(
"The WrapKey bit must be set in the cryptographic "
"usage mask of encryption key {0} for it to be used "
"for key wrapping.".format(encryption_key_uuid)
)
if key_wrapping_spec.attribute_names:
raise exceptions.IllegalOperation(
"Wrapping object attributes is not supported."
)
encoding_option = key_wrapping_spec.encoding_option
if encoding_option != enums.EncodingOption.NO_ENCODING:
raise exceptions.EncodingOptionError(
"Encoding option '{0}' is not supported.".format(
encoding_option
)
)
self._logger.info("Wrapping {0} {1} with {2} {3}.".format(
''.join([x.capitalize() for x in object_type.split('_')]),
managed_object.unique_identifier,
''.join(
[x.capitalize() for x in key._object_type.name.split(
'_'
)]
),
encryption_key_uuid
))
result = self._cryptography_engine.wrap_key(
key_material=managed_object.value,
wrapping_method=key_wrapping_spec.wrapping_method,
key_wrap_algorithm=encryption_key_params.block_cipher_mode,
encryption_key=key.value
)
wrapped_object = copy.deepcopy(managed_object)
wrapped_object.value = result
core_secret = self._build_core_object(wrapped_object)
key_wrapping_data = KeyWrappingData(
wrapping_method=wrapping_method,
encryption_key_information=key_info,
encoding_option=encoding_option
)
core_secret.key_block.key_wrapping_data = key_wrapping_data
elif key_wrapping_spec.mac_signature_key_information:
raise exceptions.PermissionDenied(
"Key wrapping with MAC/signing key information is not "
"supported."
)
else:
raise exceptions.PermissionDenied(
"Either the encryption key information or the "
"MAC/signature key information must be specified for key "
"wrapping to be performed."
)
else:
core_secret = self._build_core_object(managed_object)
response_payload = get.GetResponsePayload(
object_type=managed_object._object_type,