diff --git a/kmip/core/exceptions.py b/kmip/core/exceptions.py index 63a4cc3..368e5b2 100644 --- a/kmip/core/exceptions.py +++ b/kmip/core/exceptions.py @@ -57,6 +57,28 @@ class CryptographicFailure(KmipError): ) +class EncodingOptionError(KmipError): + """ + An encoding error generated during key wrapping. + + This error is generated during key wrapping when a requested encoding + option is not supported or is incompatible with other settings in the + key wrapping request (e.g., attributes are requested with the key but + the encoding does not support wrapping attributes with the key value). + """ + def __init__(self, message): + """ + Create an EncodingOptionError. + + Args: + message (string): A string containing information about the error. + """ + super(EncodingOptionError, self).__init__( + reason=enums.ResultReason.ENCODING_OPTION_ERROR, + message=message + ) + + class IllegalOperation(KmipError): """ An error generated when an improper operation is attempted. The operation diff --git a/kmip/services/server/engine.py b/kmip/services/server/engine.py index a0f6c7e..a3b539f 100644 --- a/kmip/services/server/engine.py +++ b/kmip/services/server/engine.py @@ -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, diff --git a/kmip/tests/unit/services/server/test_engine.py b/kmip/tests/unit/services/server/test_engine.py index 4407063..240b359 100644 --- a/kmip/tests/unit/services/server/test_engine.py +++ b/kmip/tests/unit/services/server/test_engine.py @@ -3735,10 +3735,10 @@ class TestKmipEngine(testtools.TestCase): e._data_session.commit() - def test_get_with_unsupported_features(self): + def test_get_unsupported_key_compression(self): """ - Test that the right errors are generated when unsupported features - are used in a Get request. + Test that the right error is generated when key compression is + provided in a Get request. """ e = engine.KmipEngine() e._data_store = self.engine @@ -3763,27 +3763,6 @@ class TestKmipEngine(testtools.TestCase): "Processing operation: Get" ) - e._logger.reset_mock() - - # Test that specifying the key wrapping specification generates an - # error. - payload = get.GetRequestPayload( - key_wrapping_specification=objects.KeyWrappingSpecification() - ) - - args = (payload, ) - regex = "Key wrapping is not supported." - six.assertRaisesRegex( - self, - exceptions.PermissionDenied, - regex, - e._process_get, - *args - ) - e._logger.info.assert_any_call( - "Processing operation: Get" - ) - def test_get_with_key_format_type(self): """ Test that the key format type is handled properly in a Get request. @@ -3922,6 +3901,667 @@ class TestKmipEngine(testtools.TestCase): *args ) + def test_get_wrapped_key(self): + """ + Test that a Get request for a wrapped key can be processed correctly. + """ + e = engine.KmipEngine() + e._data_store = self.engine + e._data_store_session_factory = self.session_factory + e._data_session = e._data_store_session_factory() + e._logger = mock.MagicMock() + e._cryptography_engine.logger = mock.MagicMock() + + wrapping_key = pie_objects.SymmetricKey( + enums.CryptographicAlgorithm.AES, + 128, + ( + b'\x00\x01\x02\x03\x04\x05\x06\x07' + b'\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F' + ), + [enums.CryptographicUsageMask.WRAP_KEY] + ) + wrapping_key.state = enums.State.ACTIVE + + unwrapped_key = pie_objects.SymmetricKey( + enums.CryptographicAlgorithm.AES, + 128, + ( + b'\x00\x11\x22\x33\x44\x55\x66\x77' + b'\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF' + ), + [enums.CryptographicUsageMask.ENCRYPT] + ) + + e._data_session.add(wrapping_key) + e._data_session.add(unwrapped_key) + e._data_session.commit() + e._data_session = e._data_store_session_factory() + + wrapping_key_uuid = str(wrapping_key.unique_identifier) + unwrapped_key_uuid = str(unwrapped_key.unique_identifier) + + cryptographic_parameters = attributes.CryptographicParameters( + block_cipher_mode=enums.BlockCipherMode.NIST_KEY_WRAP + ) + payload = get.GetRequestPayload( + unique_identifier=unwrapped_key_uuid, + key_wrapping_specification=objects.KeyWrappingSpecification( + wrapping_method=enums.WrappingMethod.ENCRYPT, + encryption_key_information=objects.EncryptionKeyInformation( + unique_identifier=wrapping_key_uuid, + cryptographic_parameters=cryptographic_parameters + ), + encoding_option=enums.EncodingOption.NO_ENCODING + ) + ) + + response_payload = e._process_get(payload) + + e._logger.info.assert_any_call("Processing operation: Get") + e._logger.info.assert_any_call( + "Wrapping SymmetricKey 2 with SymmetricKey 1." + ) + self.assertEqual( + enums.ObjectType.SYMMETRIC_KEY, + response_payload.object_type + ) + self.assertEqual( + unwrapped_key_uuid, + response_payload.unique_identifier + ) + self.assertIsInstance( + response_payload.secret, + secrets.SymmetricKey + ) + self.assertEqual( + ( + b'\x1F\xA6\x8B\x0A\x81\x12\xB4\x47' + b'\xAE\xF3\x4B\xD8\xFB\x5A\x7B\x82' + b'\x9D\x3E\x86\x23\x71\xD2\xCF\xE5' + ), + response_payload.secret.key_block.key_value.key_material.value + ) + self.assertIsInstance( + response_payload.secret.key_block.key_wrapping_data, + objects.KeyWrappingData + ) + k = response_payload.secret.key_block.key_wrapping_data + self.assertEqual( + enums.WrappingMethod.ENCRYPT, + k.wrapping_method + ) + self.assertIsInstance( + k.encryption_key_information, + objects.EncryptionKeyInformation + ) + self.assertEqual( + '1', + k.encryption_key_information.unique_identifier + ) + self.assertIsInstance( + k.encryption_key_information.cryptographic_parameters, + attributes.CryptographicParameters + ) + c = k.encryption_key_information.cryptographic_parameters + self.assertEqual( + enums.BlockCipherMode.NIST_KEY_WRAP, + c.block_cipher_mode + ) + self.assertEqual( + enums.EncodingOption.NO_ENCODING, + k.encoding_option + ) + + def test_get_wrapped_key_unsupported_mac_sig(self): + """ + Test that the right error is thrown when key wrapping is requested + via MAC/signing in a Get request. + """ + e = engine.KmipEngine() + e._data_store = self.engine + e._data_store_session_factory = self.session_factory + e._data_session = e._data_store_session_factory() + e._logger = mock.MagicMock() + e._cryptography_engine.logger = mock.MagicMock() + + wrapping_key = pie_objects.SymmetricKey( + enums.CryptographicAlgorithm.AES, + 128, + ( + b'\x00\x01\x02\x03\x04\x05\x06\x07' + b'\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F' + ), + [enums.CryptographicUsageMask.WRAP_KEY] + ) + wrapping_key.state = enums.State.ACTIVE + + unwrapped_key = pie_objects.SymmetricKey( + enums.CryptographicAlgorithm.AES, + 128, + ( + b'\x00\x11\x22\x33\x44\x55\x66\x77' + b'\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF' + ), + [enums.CryptographicUsageMask.ENCRYPT] + ) + + e._data_session.add(wrapping_key) + e._data_session.add(unwrapped_key) + e._data_session.commit() + e._data_session = e._data_store_session_factory() + + wrapping_key_uuid = str(wrapping_key.unique_identifier) + unwrapped_key_uuid = str(unwrapped_key.unique_identifier) + cryptographic_parameters = attributes.CryptographicParameters( + block_cipher_mode=enums.BlockCipherMode.NIST_KEY_WRAP + ) + payload = get.GetRequestPayload( + unique_identifier=unwrapped_key_uuid, + key_wrapping_specification=objects.KeyWrappingSpecification( + wrapping_method=enums.WrappingMethod.MAC_SIGN, + mac_signature_key_information=objects. + MACSignatureKeyInformation( + unique_identifier=wrapping_key_uuid, + cryptographic_parameters=cryptographic_parameters + ), + encoding_option=enums.EncodingOption.NO_ENCODING + ) + ) + + args = (payload, ) + self.assertRaisesRegexp( + exceptions.OperationNotSupported, + "Wrapping method '{0}' is not supported.".format( + enums.WrappingMethod.MAC_SIGN + ), + e._process_get, + *args + ) + + def test_get_wrapped_key_unsupported_mac_sign_key_info(self): + """ + Test that the right error is thrown when key wrapping is requested + with MAC/signing key information in a Get request. + """ + e = engine.KmipEngine() + e._data_store = self.engine + e._data_store_session_factory = self.session_factory + e._data_session = e._data_store_session_factory() + e._logger = mock.MagicMock() + e._cryptography_engine.logger = mock.MagicMock() + + wrapping_key = pie_objects.SymmetricKey( + enums.CryptographicAlgorithm.AES, + 128, + ( + b'\x00\x01\x02\x03\x04\x05\x06\x07' + b'\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F' + ), + [enums.CryptographicUsageMask.WRAP_KEY] + ) + wrapping_key.state = enums.State.ACTIVE + + unwrapped_key = pie_objects.SymmetricKey( + enums.CryptographicAlgorithm.AES, + 128, + ( + b'\x00\x11\x22\x33\x44\x55\x66\x77' + b'\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF' + ), + [enums.CryptographicUsageMask.ENCRYPT] + ) + + e._data_session.add(wrapping_key) + e._data_session.add(unwrapped_key) + e._data_session.commit() + e._data_session = e._data_store_session_factory() + + wrapping_key_uuid = str(wrapping_key.unique_identifier) + unwrapped_key_uuid = str(unwrapped_key.unique_identifier) + cryptographic_parameters = attributes.CryptographicParameters( + block_cipher_mode=enums.BlockCipherMode.NIST_KEY_WRAP + ) + payload = get.GetRequestPayload( + unique_identifier=unwrapped_key_uuid, + key_wrapping_specification=objects.KeyWrappingSpecification( + wrapping_method=enums.WrappingMethod.ENCRYPT, + mac_signature_key_information=objects. + MACSignatureKeyInformation( + unique_identifier=wrapping_key_uuid, + cryptographic_parameters=cryptographic_parameters + ), + encoding_option=enums.EncodingOption.NO_ENCODING + ) + ) + + args = (payload, ) + self.assertRaisesRegexp( + exceptions.PermissionDenied, + "Key wrapping with MAC/signing key information is not supported.", + e._process_get, + *args + ) + + def test_get_wrapped_key_missing_key_information(self): + """ + Test that the right error is thrown when key wrapping is requested + with no settings in a Get request. + """ + e = engine.KmipEngine() + e._data_store = self.engine + e._data_store_session_factory = self.session_factory + e._data_session = e._data_store_session_factory() + e._logger = mock.MagicMock() + e._cryptography_engine.logger = mock.MagicMock() + + unwrapped_key = pie_objects.SymmetricKey( + enums.CryptographicAlgorithm.AES, + 128, + ( + b'\x00\x11\x22\x33\x44\x55\x66\x77' + b'\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF' + ), + [enums.CryptographicUsageMask.ENCRYPT] + ) + + e._data_session.add(unwrapped_key) + e._data_session.commit() + e._data_session = e._data_store_session_factory() + + unwrapped_key_uuid = str(unwrapped_key.unique_identifier) + payload = get.GetRequestPayload( + unique_identifier=unwrapped_key_uuid, + key_wrapping_specification=objects.KeyWrappingSpecification( + wrapping_method=enums.WrappingMethod.ENCRYPT, + encoding_option=enums.EncodingOption.NO_ENCODING + ) + ) + + args = (payload, ) + self.assertRaisesRegexp( + exceptions.PermissionDenied, + "Either the encryption key information or the MAC/signature key " + "information must be specified for key wrapping to be performed.", + e._process_get, + *args + ) + + def test_get_wrapped_key_nonexistent_wrapping_key(self): + """ + Test that the right error is thrown when key wrapping is requested + with a nonexistent wrapping key in a Get request. + """ + e = engine.KmipEngine() + e._data_store = self.engine + e._data_store_session_factory = self.session_factory + e._data_session = e._data_store_session_factory() + e._logger = mock.MagicMock() + e._cryptography_engine.logger = mock.MagicMock() + + unwrapped_key = pie_objects.SymmetricKey( + enums.CryptographicAlgorithm.AES, + 128, + ( + b'\x00\x11\x22\x33\x44\x55\x66\x77' + b'\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF' + ), + [enums.CryptographicUsageMask.ENCRYPT] + ) + + e._data_session.add(unwrapped_key) + e._data_session.commit() + e._data_session = e._data_store_session_factory() + + unwrapped_key_uuid = str(unwrapped_key.unique_identifier) + + cryptographic_parameters = attributes.CryptographicParameters( + block_cipher_mode=enums.BlockCipherMode.NIST_KEY_WRAP + ) + payload = get.GetRequestPayload( + unique_identifier=unwrapped_key_uuid, + key_wrapping_specification=objects.KeyWrappingSpecification( + wrapping_method=enums.WrappingMethod.ENCRYPT, + encryption_key_information=objects.EncryptionKeyInformation( + unique_identifier='invalid', + cryptographic_parameters=cryptographic_parameters + ), + encoding_option=enums.EncodingOption.NO_ENCODING + ) + ) + + args = (payload, ) + self.assertRaisesRegexp( + exceptions.ItemNotFound, + "Wrapping key does not exist.", + e._process_get, + *args + ) + + def test_get_wrapped_key_non_wrapping_key(self): + """ + Test that the right error is thrown when key wrapping is requested + with a non-wrapping key in a Get request. + """ + e = engine.KmipEngine() + e._data_store = self.engine + e._data_store_session_factory = self.session_factory + e._data_session = e._data_store_session_factory() + e._logger = mock.MagicMock() + e._cryptography_engine.logger = mock.MagicMock() + + wrapping_key = pie_objects.SecretData( + ( + b'\x00\x01\x02\x03\x04\x05\x06\x07' + b'\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F' + ), + enums.SecretDataType.SEED, + masks=[enums.CryptographicUsageMask.WRAP_KEY] + ) + wrapping_key.state = enums.State.ACTIVE + + unwrapped_key = pie_objects.SymmetricKey( + enums.CryptographicAlgorithm.AES, + 128, + ( + b'\x00\x11\x22\x33\x44\x55\x66\x77' + b'\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF' + ), + [enums.CryptographicUsageMask.ENCRYPT] + ) + + e._data_session.add(wrapping_key) + e._data_session.add(unwrapped_key) + e._data_session.commit() + e._data_session = e._data_store_session_factory() + + wrapping_key_uuid = str(wrapping_key.unique_identifier) + unwrapped_key_uuid = str(unwrapped_key.unique_identifier) + + cryptographic_parameters = attributes.CryptographicParameters( + block_cipher_mode=enums.BlockCipherMode.NIST_KEY_WRAP + ) + payload = get.GetRequestPayload( + unique_identifier=unwrapped_key_uuid, + key_wrapping_specification=objects.KeyWrappingSpecification( + wrapping_method=enums.WrappingMethod.ENCRYPT, + encryption_key_information=objects.EncryptionKeyInformation( + unique_identifier=wrapping_key_uuid, + cryptographic_parameters=cryptographic_parameters + ), + encoding_option=enums.EncodingOption.NO_ENCODING + ) + ) + + args = (payload, ) + self.assertRaisesRegexp( + exceptions.IllegalOperation, + "The wrapping encryption key specified by the encryption key " + "information is not a key.", + e._process_get, + *args + ) + + def test_get_wrapped_key_inactive_wrapping_key(self): + """ + Test that the right error is thrown when key wrapping is requested + with an inactive wrapping key in a Get request. + """ + e = engine.KmipEngine() + e._data_store = self.engine + e._data_store_session_factory = self.session_factory + e._data_session = e._data_store_session_factory() + e._logger = mock.MagicMock() + e._cryptography_engine.logger = mock.MagicMock() + + wrapping_key = pie_objects.SymmetricKey( + enums.CryptographicAlgorithm.AES, + 128, + ( + b'\x00\x01\x02\x03\x04\x05\x06\x07' + b'\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F' + ), + [enums.CryptographicUsageMask.WRAP_KEY] + ) + + unwrapped_key = pie_objects.SymmetricKey( + enums.CryptographicAlgorithm.AES, + 128, + ( + b'\x00\x11\x22\x33\x44\x55\x66\x77' + b'\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF' + ), + [enums.CryptographicUsageMask.ENCRYPT] + ) + + e._data_session.add(wrapping_key) + e._data_session.add(unwrapped_key) + e._data_session.commit() + e._data_session = e._data_store_session_factory() + + wrapping_key_uuid = str(wrapping_key.unique_identifier) + unwrapped_key_uuid = str(unwrapped_key.unique_identifier) + + cryptographic_parameters = attributes.CryptographicParameters( + block_cipher_mode=enums.BlockCipherMode.NIST_KEY_WRAP + ) + payload = get.GetRequestPayload( + unique_identifier=unwrapped_key_uuid, + key_wrapping_specification=objects.KeyWrappingSpecification( + wrapping_method=enums.WrappingMethod.ENCRYPT, + encryption_key_information=objects.EncryptionKeyInformation( + unique_identifier=wrapping_key_uuid, + cryptographic_parameters=cryptographic_parameters + ), + encoding_option=enums.EncodingOption.NO_ENCODING + ) + ) + + args = (payload, ) + self.assertRaisesRegexp( + exceptions.PermissionDenied, + "Encryption key 1 must be activated to be used for key " + "wrapping.", + e._process_get, + *args + ) + + def test_get_wrapped_key_invalid_wrapping_key(self): + """ + Test that the right error is thrown when key wrapping is requested + with a wrapping key not designated for key wrapping in a Get request. + """ + e = engine.KmipEngine() + e._data_store = self.engine + e._data_store_session_factory = self.session_factory + e._data_session = e._data_store_session_factory() + e._logger = mock.MagicMock() + e._cryptography_engine.logger = mock.MagicMock() + + wrapping_key = pie_objects.SymmetricKey( + enums.CryptographicAlgorithm.AES, + 128, + ( + b'\x00\x01\x02\x03\x04\x05\x06\x07' + b'\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F' + ), + [enums.CryptographicUsageMask.ENCRYPT] + ) + wrapping_key.state = enums.State.ACTIVE + + unwrapped_key = pie_objects.SymmetricKey( + enums.CryptographicAlgorithm.AES, + 128, + ( + b'\x00\x11\x22\x33\x44\x55\x66\x77' + b'\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF' + ), + [enums.CryptographicUsageMask.ENCRYPT] + ) + + e._data_session.add(wrapping_key) + e._data_session.add(unwrapped_key) + e._data_session.commit() + e._data_session = e._data_store_session_factory() + + wrapping_key_uuid = str(wrapping_key.unique_identifier) + unwrapped_key_uuid = str(unwrapped_key.unique_identifier) + + cryptographic_parameters = attributes.CryptographicParameters( + block_cipher_mode=enums.BlockCipherMode.NIST_KEY_WRAP + ) + payload = get.GetRequestPayload( + unique_identifier=unwrapped_key_uuid, + key_wrapping_specification=objects.KeyWrappingSpecification( + wrapping_method=enums.WrappingMethod.ENCRYPT, + encryption_key_information=objects.EncryptionKeyInformation( + unique_identifier=wrapping_key_uuid, + cryptographic_parameters=cryptographic_parameters + ), + encoding_option=enums.EncodingOption.NO_ENCODING + ) + ) + + args = (payload, ) + self.assertRaisesRegexp( + exceptions.PermissionDenied, + "The WrapKey bit must be set in the cryptographic usage mask of " + "encryption key 1 for it to be used for key wrapping.", + e._process_get, + *args + ) + + def test_get_wrapped_key_unsupported_attribute_wrapping(self): + """ + Test that the right error is thrown when key wrapping is requested + with attribute names in a Get request. + """ + e = engine.KmipEngine() + e._data_store = self.engine + e._data_store_session_factory = self.session_factory + e._data_session = e._data_store_session_factory() + e._logger = mock.MagicMock() + e._cryptography_engine.logger = mock.MagicMock() + + wrapping_key = pie_objects.SymmetricKey( + enums.CryptographicAlgorithm.AES, + 128, + ( + b'\x00\x01\x02\x03\x04\x05\x06\x07' + b'\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F' + ), + [enums.CryptographicUsageMask.WRAP_KEY] + ) + wrapping_key.state = enums.State.ACTIVE + + unwrapped_key = pie_objects.SymmetricKey( + enums.CryptographicAlgorithm.AES, + 128, + ( + b'\x00\x11\x22\x33\x44\x55\x66\x77' + b'\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF' + ), + [enums.CryptographicUsageMask.ENCRYPT] + ) + + e._data_session.add(wrapping_key) + e._data_session.add(unwrapped_key) + e._data_session.commit() + e._data_session = e._data_store_session_factory() + + wrapping_key_uuid = str(wrapping_key.unique_identifier) + unwrapped_key_uuid = str(unwrapped_key.unique_identifier) + + cryptographic_parameters = attributes.CryptographicParameters( + block_cipher_mode=enums.BlockCipherMode.NIST_KEY_WRAP + ) + payload = get.GetRequestPayload( + unique_identifier=unwrapped_key_uuid, + key_wrapping_specification=objects.KeyWrappingSpecification( + wrapping_method=enums.WrappingMethod.ENCRYPT, + encryption_key_information=objects.EncryptionKeyInformation( + unique_identifier=wrapping_key_uuid, + cryptographic_parameters=cryptographic_parameters + ), + attribute_names=['Cryptographic Algorithm'], + encoding_option=enums.EncodingOption.NO_ENCODING + ) + ) + + args = (payload, ) + self.assertRaisesRegexp( + exceptions.IllegalOperation, + "Wrapping object attributes is not supported.", + e._process_get, + *args + ) + + def test_get_wrapped_key_invalid_encoding(self): + """ + Test that the right error is thrown when key wrapping is requested + with an unsupported encoding option in a Get request. + """ + e = engine.KmipEngine() + e._data_store = self.engine + e._data_store_session_factory = self.session_factory + e._data_session = e._data_store_session_factory() + e._logger = mock.MagicMock() + e._cryptography_engine.logger = mock.MagicMock() + + wrapping_key = pie_objects.SymmetricKey( + enums.CryptographicAlgorithm.AES, + 128, + ( + b'\x00\x01\x02\x03\x04\x05\x06\x07' + b'\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F' + ), + [enums.CryptographicUsageMask.WRAP_KEY] + ) + wrapping_key.state = enums.State.ACTIVE + + unwrapped_key = pie_objects.SymmetricKey( + enums.CryptographicAlgorithm.AES, + 128, + ( + b'\x00\x11\x22\x33\x44\x55\x66\x77' + b'\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF' + ), + [enums.CryptographicUsageMask.ENCRYPT] + ) + + e._data_session.add(wrapping_key) + e._data_session.add(unwrapped_key) + e._data_session.commit() + e._data_session = e._data_store_session_factory() + + wrapping_key_uuid = str(wrapping_key.unique_identifier) + unwrapped_key_uuid = str(unwrapped_key.unique_identifier) + + cryptographic_parameters = attributes.CryptographicParameters( + block_cipher_mode=enums.BlockCipherMode.NIST_KEY_WRAP + ) + payload = get.GetRequestPayload( + unique_identifier=unwrapped_key_uuid, + key_wrapping_specification=objects.KeyWrappingSpecification( + wrapping_method=enums.WrappingMethod.ENCRYPT, + encryption_key_information=objects.EncryptionKeyInformation( + unique_identifier=wrapping_key_uuid, + cryptographic_parameters=cryptographic_parameters + ), + encoding_option=enums.EncodingOption.TTLV_ENCODING + ) + ) + + args = (payload, ) + self.assertRaisesRegexp( + exceptions.EncodingOptionError, + "Encoding option '{0}' is not supported.".format( + enums.EncodingOption.TTLV_ENCODING + ), + e._process_get, + *args + ) + def test_get_attributes(self): """ Test that a GetAttributes request can be processed correctly.