def test_read_crypto_params(self): CryptographicParameters.read(self.cp, self.key_req_with_crypt_params) self.assertEqual(Tags.BLOCK_CIPHER_MODE.value, self.cp.block_cipher_mode.tag.value) self.assertEqual(BlockCipherMode.CBC.value, self.cp.block_cipher_mode.value.value) self.assertEqual(Tags.PADDING_METHOD.value, self.cp.padding_method.tag.value) self.assertEqual(PaddingMethod.PKCS5.value, self.cp.padding_method.value.value) self.assertEqual(Tags.KEY_ROLE_TYPE.value, self.cp.key_role_type.tag.value) self.assertEqual(KeyRoleType.BDK.value, self.cp.key_role_type.value.value) self.assertEqual(Tags.HASHING_ALGORITHM.value, self.cp.hashing_algorithm.tag.value) self.assertEqual(HashingAlgorithmEnum.SHA_1.value, self.cp.hashing_algorithm.value.value) self.assertEqual(Tags.DIGITAL_SIGNATURE_ALGORITHM.value, self.cp.digital_signature_algorithm.tag.value) self.assertEqual( DigitalSignatureAlgorithm.SHA256_WITH_RSA_ENCRYPTION.value, self.cp.digital_signature_algorithm.value.value) self.assertEqual(Tags.CRYPTOGRAPHIC_ALGORITHM.value, self.cp.cryptographic_algorithm.tag.value) self.assertEqual(CryptographicAlgorithm.HMAC_SHA512.value, self.cp.cryptographic_algorithm.value.value)
def read(self, istream): super(KeyInformation, self).read(istream) tstream = BytearrayStream(istream.read(self.length)) self.unique_identifier = attributes.UniqueIdentifier() self.unique_identifier.read(tstream) if self.is_tag_next(Tags.CRYPTOGRAPHIC_PARAMETERS, tstream): self.cryptographic_parameters = CryptographicParameters() self.cryptographic_parameters.read(tstream) self.is_oversized(tstream) self.validate()
def _process_encrypt_patched(self, payload): self._logger.info("Processing operation: Encrypt") unique_identifier = self._id_placeholder if payload.unique_identifier: unique_identifier = payload.unique_identifier # The KMIP spec does not indicate that the Encrypt operation should # have it's own operation policy entry. Rather, the cryptographic # usage mask should be used to determine if the object can be used # to encrypt data (see below). managed_object = self._get_object_with_access_controls( unique_identifier, enums.Operation.GET) cryptographic_parameters = payload.cryptographic_parameters if cryptographic_parameters is None: # Monkey patched here -- rather than exception, we set to default params. default_crypto_params = CryptographicParameters( block_cipher_mode=enums.BlockCipherMode.CBC, padding_method=enums.PaddingMethod.PKCS5, cryptographic_algorithm=enums.CryptographicAlgorithm.AES, ) cryptographic_parameters = default_crypto_params if managed_object._object_type != enums.ObjectType.SYMMETRIC_KEY: raise exceptions.PermissionDenied( "The requested encryption key is not a symmetric key. " "Only symmetric encryption is currently supported.") if managed_object.state != enums.State.ACTIVE: raise exceptions.PermissionDenied( "The encryption key must be in the Active state to be used " "for encryption.") masks = managed_object.cryptographic_usage_masks if enums.CryptographicUsageMask.ENCRYPT not in masks: raise exceptions.PermissionDenied( "The Encrypt bit must be set in the encryption key's " "cryptographic usage mask.") result = self._cryptography_engine.encrypt( cryptographic_parameters.cryptographic_algorithm, managed_object.value, payload.data, cipher_mode=cryptographic_parameters.block_cipher_mode, padding_method=cryptographic_parameters.padding_method, iv_nonce=payload.iv_counter_nonce, auth_additional_data=payload.auth_additional_data, auth_tag_length=cryptographic_parameters.tag_length, ) response_payload = payloads.EncryptResponsePayload( unique_identifier, result.get("cipher_text"), result.get("iv_nonce"), result.get("auth_tag"), ) return response_payload
class KeyInformation(Struct): def __init__(self, unique_identifier=None, cryptographic_parameters=None, tag=Tags.ENCRYPTION_KEY_INFORMATION): super(self.__class__, self).\ __init__(tag=Tags.ENCRYPTION_KEY_INFORMATION) self.unique_identifier = unique_identifier self.cryptographic_parameters = cryptographic_parameters self.validate() def read(self, istream): super(self.__class__, self).read(istream) tstream = BytearrayStream(istream.read(self.length)) self.unique_identifier = attributes.UniqueIdentifier() self.unique_identifier.read(tstream) if self.is_tag_next(Tags.CRYPTOGRAPHIC_PARAMETERS, tstream): self.cryptographic_parameters = CryptographicParameters() self.cryptographic_parameters.read(tstream) self.is_oversized(tstream) self.validate() def write(self, ostream): tstream = BytearrayStream() self.unique_identifier.write(tstream) if self.cryptographic_parameters is not None: self.cryptographic_parameters.write(tstream) # Write the length and value of the template attribute self.length = tstream.length() super(self.__class__, self).write(ostream) ostream.write(tstream.buffer) def validate(self): self.__validate() def __validate(self): # TODO (peter-hamilton) Finish implementation. pass
class KeyInformation(Struct): def __init__(self, unique_identifier=None, cryptographic_parameters=None, tag=Tags.ENCRYPTION_KEY_INFORMATION): super(KeyInformation, self).__init__(tag=tag) self.unique_identifier = unique_identifier self.cryptographic_parameters = cryptographic_parameters self.validate() def read(self, istream): super(KeyInformation, self).read(istream) tstream = BytearrayStream(istream.read(self.length)) self.unique_identifier = attributes.UniqueIdentifier() self.unique_identifier.read(tstream) if self.is_tag_next(Tags.CRYPTOGRAPHIC_PARAMETERS, tstream): self.cryptographic_parameters = CryptographicParameters() self.cryptographic_parameters.read(tstream) self.is_oversized(tstream) self.validate() def write(self, ostream): tstream = BytearrayStream() self.unique_identifier.write(tstream) if self.cryptographic_parameters is not None: self.cryptographic_parameters.write(tstream) # Write the length and value of the template attribute self.length = tstream.length() super(KeyInformation, self).write(ostream) ostream.write(tstream.buffer) def validate(self): self.__validate() def __validate(self): # TODO (peter-hamilton) Finish implementation. pass
def test_encrypt(self, send_mock, build_mock): """ Test that the client can encrypt data. """ payload = payloads.EncryptResponsePayload( unique_identifier='1', data=( b'\x6B\x77\xB4\xD6\x30\x06\xDE\xE6' b'\x05\xB1\x56\xE2\x74\x03\x97\x93' b'\x58\xDE\xB9\xE7\x15\x46\x16\xD9' b'\x74\x9D\xEC\xBE\xC0\x5D\x26\x4B' ) ) batch_item = ResponseBatchItem( operation=Operation(OperationEnum.ENCRYPT), result_status=ResultStatus(ResultStatusEnum.SUCCESS), response_payload=payload ) response = ResponseMessage(batch_items=[batch_item]) build_mock.return_value = None send_mock.return_value = response result = self.client.encrypt( ( b'\x37\x36\x35\x34\x33\x32\x31\x20' b'\x4E\x6F\x77\x20\x69\x73\x20\x74' b'\x68\x65\x20\x74\x69\x6D\x65\x20' b'\x66\x6F\x72\x20\x00' ), unique_identifier='1', cryptographic_parameters=CryptographicParameters( block_cipher_mode=enums.BlockCipherMode.CBC, padding_method=enums.PaddingMethod.PKCS5, cryptographic_algorithm=enums.CryptographicAlgorithm.BLOWFISH ), iv_counter_nonce=b'\xFE\xDC\xBA\x98\x76\x54\x32\x10' ) self.assertEqual('1', result.get('unique_identifier')) self.assertEqual( ( b'\x6B\x77\xB4\xD6\x30\x06\xDE\xE6' b'\x05\xB1\x56\xE2\x74\x03\x97\x93' b'\x58\xDE\xB9\xE7\x15\x46\x16\xD9' b'\x74\x9D\xEC\xBE\xC0\x5D\x26\x4B' ), result.get('data') ) self.assertEqual(None, result.get('iv_counter_nonce')) self.assertEqual( ResultStatusEnum.SUCCESS, result.get('result_status') ) self.assertEqual(None, result.get('result_reason')) self.assertEqual(None, result.get('result_message'))
def test_read_crypto_params(self): CryptographicParameters.read(self.cp, self.key_req_with_crypt_params) self.assertEqual(Tags.BLOCK_CIPHER_MODE.value, self.cp.block_cipher_mode.tag.value) self.assertEqual(BlockCipherMode.CBC.value, self.cp.block_cipher_mode.value.value) self.assertEqual(Tags.PADDING_METHOD.value, self.cp.padding_method.tag.value) self.assertEqual(PaddingMethod.PKCS5.value, self.cp.padding_method.value.value) self.assertEqual(Tags.KEY_ROLE_TYPE.value, self.cp.key_role_type.tag.value) self.assertEqual(KeyRoleType.BDK.value, self.cp.key_role_type.value.value) self.assertEqual(Tags.HASHING_ALGORITHM.value, self.cp.hashing_algorithm.tag.value) self.assertEqual(HashingAlgorithmEnum.SHA_1.value, self.cp.hashing_algorithm.value.value)
def read(self, istream): super(self.__class__, self).read(istream) tstream = BytearrayStream(istream.read(self.length)) self.unique_identifier = attributes.UniqueIdentifier() self.unique_identifier.read(tstream) if self.is_tag_next(Tags.CRYPTOGRAPHIC_PARAMETERS, tstream): self.cryptographic_parameters = CryptographicParameters() self.cryptographic_parameters.read(tstream) self.is_oversized(tstream) self.validate()
def test_read_crypto_params(self): CryptographicParameters.read(self.cp, self.key_req_with_crypt_params) self.assertEqual(Tags.BLOCK_CIPHER_MODE.value, self.cp.block_cipher_mode.tag.value) self.assertEqual(BlockCipherMode.CBC.value, self.cp.block_cipher_mode.value.value) self.assertEqual(Tags.PADDING_METHOD.value, self.cp.padding_method.tag.value) self.assertEqual(PaddingMethod.PKCS5.value, self.cp.padding_method.value.value) self.assertEqual(Tags.KEY_ROLE_TYPE.value, self.cp.key_role_type.tag.value) self.assertEqual(KeyRoleType.BDK.value, self.cp.key_role_type.value.value) self.assertEqual(Tags.HASHING_ALGORITHM.value, self.cp.hashing_algorithm.tag.value) self.assertEqual(HashingAlgorithmEnum.SHA_1.value, self.cp.hashing_algorithm.value.value)
def test_derive_key(self, send_mock, build_mock): """ Test that the client can derive a key. """ payload = payloads.DeriveKeyResponsePayload( unique_identifier='1', ) batch_item = ResponseBatchItem( operation=Operation(OperationEnum.DERIVE_KEY), result_status=ResultStatus(ResultStatusEnum.SUCCESS), response_payload=payload ) response = ResponseMessage(batch_items=[batch_item]) build_mock.return_value = None send_mock.return_value = response result = self.client.derive_key( object_type=enums.ObjectType.SYMMETRIC_KEY, unique_identifiers=['2', '3'], derivation_method=enums.DerivationMethod.ENCRYPT, derivation_parameters=DerivationParameters( cryptographic_parameters=CryptographicParameters( block_cipher_mode=enums.BlockCipherMode.CBC, padding_method=enums.PaddingMethod.PKCS1v15, cryptographic_algorithm=enums.CryptographicAlgorithm.AES ), initialization_vector=b'\x01\x02\x03\x04', derivation_data=b'\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8' ), template_attribute=TemplateAttribute( attributes=[ self.attr_factory.create_attribute( 'Cryptographic Length', 128 ), self.attr_factory.create_attribute( 'Cryptographic Algorithm', enums.CryptographicAlgorithm.AES ) ] ), ) self.assertEqual('1', result.get('unique_identifier')) self.assertEqual( ResultStatusEnum.SUCCESS, result.get('result_status') ) self.assertEqual(None, result.get('result_reason')) self.assertEqual(None, result.get('result_message'))
def mac(self, data, uid=None, algorithm=None): """ Get the message authentication code for data. Args: data (string): The data to be MACed. 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. 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(data, six.binary_type): raise TypeError("data must be bytes") if uid is not None: if not isinstance(uid, six.string_types): raise TypeError("uid must be a string") if algorithm is not None: if not isinstance(algorithm, enums.CryptographicAlgorithm): raise TypeError( "algorithm must be a CryptographicAlgorithm enumeration") # Verify that operations can be given at this time if not self._is_open: raise exceptions.ClientConnectionNotOpen() parameters_attribute = CryptographicParameters( cryptographic_algorithm=CryptographicAlgorithm(algorithm)) # Get the message authentication code and handle the results result = self.proxy.mac(data, uid, parameters_attribute) 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 test_signature_verify(self, send_mock, build_mock): """ Test that the client can verify a signature. """ payload = payloads.SignatureVerifyResponsePayload( unique_identifier='1', validity_indicator=enums.ValidityIndicator.INVALID ) batch_item = ResponseBatchItem( operation=Operation(OperationEnum.SIGNATURE_VERIFY), result_status=ResultStatus(ResultStatusEnum.SUCCESS), response_payload=payload ) response = ResponseMessage(batch_items=[batch_item]) build_mock.return_value = None send_mock.return_value = response result = self.client.signature_verify( ( b'\x6B\x77\xB4\xD6\x30\x06\xDE\xE6' b'\x05\xB1\x56\xE2\x74\x03\x97\x93' b'\x58\xDE\xB9\xE7\x15\x46\x16\xD9' b'\x74\x9D\xEC\xBE\xC0\x5D\x26\x4B' ), ( b'\x11\x11\x11\x11\x11\x11\x11\x11' ), unique_identifier='1', cryptographic_parameters=CryptographicParameters( padding_method=enums.PaddingMethod.PKCS1v15, cryptographic_algorithm=enums.CryptographicAlgorithm.RSA, hashing_algorithm=enums.HashingAlgorithm.SHA_224 ) ) self.assertEqual('1', result.get('unique_identifier')) self.assertEqual( enums.ValidityIndicator.INVALID, result.get('validity_indicator') ) self.assertEqual( ResultStatusEnum.SUCCESS, result.get('result_status') ) self.assertEqual(None, result.get('result_reason')) self.assertEqual(None, result.get('result_message'))
def test_sign(self, send_mock, build_mock): """ Test that the client can sign data """ payload = payloads.SignResponsePayload( unique_identifier='1', signature_data=b'aaaaaaaaaaaaaaaa' ) batch_item = ResponseBatchItem( operation=Operation(OperationEnum.SIGN), result_status=ResultStatus(ResultStatusEnum.SUCCESS), response_payload=payload ) response = ResponseMessage(batch_items=[batch_item]) build_mock.return_value = None send_mock.return_value = response result = self.client.sign( b'\x11\x11\x11\x11\x11\x11\x11\x11', unique_identifier='1', cryptographic_parameters=CryptographicParameters( padding_method=enums.PaddingMethod.PKCS1v15, cryptographic_algorithm=enums.CryptographicAlgorithm.RSA, hashing_algorithm=enums.HashingAlgorithm.SHA_224 ) ) self.assertEqual('1', result.get('unique_identifier')) self.assertEqual( b'aaaaaaaaaaaaaaaa', result.get('signature') ) self.assertEqual( ResultStatusEnum.SUCCESS, result.get('result_status') ) self.assertEqual(None, result.get('result_reason')) self.assertEqual(None, result.get('result_message'))
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=CryptographicAlgorithmEnum.HMAC_SHA512 ) self.client._send_message.side_effect = verify_request self.client._receive_message.return_value = BytearrayStream(response) result = self.client.mac(data, uuid, cryptographic_parameters) 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(data, uuid, cryptographic_parameters) self.assertEqual(result.uuid, None) self.assertEqual(result.mac_data, None)