def test_aws_kms_single_cmk_keyring_on_decrypt_multiple_cmk(fake_generator_and_child): generator, child = fake_generator_and_child encrypting_keyring = AwsKmsKeyring(generator_key_id=generator, key_ids=(child,)) decrypting_keyring = _AwsKmsSingleCmkKeyring(key_id=child, client_supplier=DefaultClientSupplier()) initial_encryption_materials = EncryptionMaterials(algorithm=ALGORITHM, encryption_context={}) encryption_materials = encrypting_keyring.on_encrypt(initial_encryption_materials) initial_decryption_materials = DecryptionMaterials( algorithm=encryption_materials.algorithm, encryption_context=encryption_materials.encryption_context ) result_materials = decrypting_keyring.on_decrypt( decryption_materials=initial_decryption_materials, encrypted_data_keys=encryption_materials.encrypted_data_keys ) generator_flags = _matching_flags( MasterKeyInfo(provider_id=KEY_NAMESPACE, key_info=generator), result_materials.keyring_trace ) assert len(generator_flags) == 0 child_flags = _matching_flags( MasterKeyInfo(provider_id=KEY_NAMESPACE, key_info=child), result_materials.keyring_trace ) assert KeyringTraceFlag.DECRYPTED_DATA_KEY in child_flags assert KeyringTraceFlag.VERIFIED_ENCRYPTION_CONTEXT in child_flags
def test_aws_kms_discovery_keyring_on_decrypt_existing_data_key(caplog): # In this context there are no KMS CMKs, so any calls to KMS will fail. caplog.set_level(logging.DEBUG) keyring = _AwsKmsDiscoveryKeyring(client_supplier=DefaultClientSupplier()) initial_materials = DecryptionMaterials( algorithm=ALGORITHM, encryption_context={}, data_encryption_key=RawDataKey( key_provider=MasterKeyInfo(provider_id="foo", key_info=b"bar"), data_key=os.urandom(ALGORITHM.kdf_input_len) ), ) result_materials = keyring.on_decrypt( decryption_materials=initial_materials, encrypted_data_keys=( EncryptedDataKey( key_provider=MasterKeyInfo(provider_id=KEY_NAMESPACE, key_info=b"foo"), encrypted_data_key=b"bar" ), ), ) assert result_materials.data_encryption_key == initial_materials.data_encryption_key log_data = caplog.text # This means that it did NOT try to decrypt the EDK. assert "Unable to decrypt encrypted data key from" not in log_data
def test_try_aws_kms_decrypt_succeed(fake_generator): encryption_context = {"foo": "bar"} kms = boto3.client("kms", region_name=FAKE_REGION) plaintext = b"0123" * 8 response = kms.encrypt(KeyId=fake_generator, Plaintext=plaintext, EncryptionContext=encryption_context) encrypted_data_key = EncryptedDataKey( key_provider=MasterKeyInfo(provider_id=KEY_NAMESPACE, key_info=response["KeyId"]), encrypted_data_key=response["CiphertextBlob"], ) initial_decryption_materials = DecryptionMaterials(algorithm=ALGORITHM, encryption_context=encryption_context,) result_materials = _try_aws_kms_decrypt( client_supplier=DefaultClientSupplier(), decryption_materials=initial_decryption_materials, grant_tokens=[], encrypted_data_key=encrypted_data_key, ) assert result_materials.data_encryption_key.data_key == plaintext generator_flags = _matching_flags( MasterKeyInfo(provider_id=KEY_NAMESPACE, key_info=fake_generator), result_materials.keyring_trace ) assert KeyringTraceFlag.DECRYPTED_DATA_KEY in generator_flags assert KeyringTraceFlag.VERIFIED_ENCRYPTION_CONTEXT in generator_flags
def sample_encryption_materials(): return [ EncryptionMaterials( algorithm=Algorithm.AES_256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384, encryption_context=_ENCRYPTION_CONTEXT, signing_key=_SIGNING_KEY, ), EncryptionMaterials( algorithm=Algorithm.AES_256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384, data_encryption_key=RawDataKey( key_provider=MasterKeyInfo(provider_id=_PROVIDER_ID, key_info=_KEY_ID), data_key= b'*!\xa1"^-(\xf3\x105\x05i@B\xc2\xa2\xb7\xdd\xd5\xd5\xa9\xddm\xfae\xa8\\$\xf9d\x1e(', ), encryption_context=_ENCRYPTION_CONTEXT, signing_key=_SIGNING_KEY, keyring_trace=[ KeyringTrace( wrapping_key=MasterKeyInfo(provider_id=_PROVIDER_ID, key_info=_KEY_ID), flags={KeyringTraceFlag.GENERATED_DATA_KEY}, ) ], ), ]
def get_encryption_materials_with_encrypted_data_key(): return EncryptionMaterials( algorithm=AlgorithmSuite.AES_256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384, data_encryption_key=RawDataKey( key_provider=MasterKeyInfo(provider_id=_PROVIDER_ID, key_info=_EXISTING_KEY_ID), data_key= b'*!\xa1"^-(\xf3\x105\x05i@B\xc2\xa2\xb7\xdd\xd5\xd5\xa9\xddm\xfae\xa8\\$\xf9d\x1e(', ), encrypted_data_keys=[ EncryptedDataKey( key_provider=MasterKeyInfo(provider_id=_PROVIDER_ID, key_info=_EXISTING_KEY_ID), encrypted_data_key= b"\xde^\x97\x7f\x84\xe9\x9e\x98\xd0\xe2\xf8\xd5\xcb\xe9\x7f.}\x87\x16,\x11n#\xc8p" b"\xdb\xbf\x94\x86*Q\x06\xd2\xf5\xdah\x08\xa4p\x81\xf7\xf4G\x07FzE\xde", ) ], encryption_context=_ENCRYPTION_CONTEXT, signing_key=_SIGNING_KEY, keyring_trace=[ KeyringTrace( wrapping_key=MasterKeyInfo(provider_id=_PROVIDER_ID, key_info=_EXISTING_KEY_ID), flags={ KeyringTraceFlag.GENERATED_DATA_KEY, KeyringTraceFlag.ENCRYPTED_DATA_KEY }, ) ], )
def __attrs_post_init__(self): # type: () -> None """Prepares initial values not handled by attrs.""" key_size_to_wrapping_algorithm = { wrapper.algorithm.kdf_input_len: wrapper for wrapper in ( WrappingAlgorithm.AES_128_GCM_IV12_TAG16_NO_PADDING, WrappingAlgorithm.AES_192_GCM_IV12_TAG16_NO_PADDING, WrappingAlgorithm.AES_256_GCM_IV12_TAG16_NO_PADDING, ) } try: self._wrapping_algorithm = key_size_to_wrapping_algorithm[len( self._wrapping_key)] except KeyError: raise ValueError( "Invalid wrapping key length. Must be one of {} bytes.".format( sorted(key_size_to_wrapping_algorithm.keys()))) self._key_provider = MasterKeyInfo(provider_id=self.key_namespace, key_info=self.key_name) self._wrapping_key_structure = WrappingKey( wrapping_algorithm=self._wrapping_algorithm, wrapping_key=self._wrapping_key, wrapping_key_type=EncryptionKeyType.SYMMETRIC, ) self._key_info_prefix = self._get_key_info_prefix( key_namespace=self.key_namespace, key_name=self.key_name, wrapping_key=self._wrapping_key_structure)
def deserialize_encrypted_data_keys(stream, max_encrypted_data_keys=None): # type: (IO, Union[int, None]) -> Set[EncryptedDataKey] """Deserialize some encrypted data keys from a stream. :param stream: Stream from which to read encrypted data keys :param max_encrypted_data_keys: Maximum number of encrypted data keys to deserialize :return: Loaded encrypted data keys :rtype: set of :class:`EncryptedDataKey` """ (encrypted_data_key_count, ) = unpack_values(">H", stream) if max_encrypted_data_keys and encrypted_data_key_count > max_encrypted_data_keys: raise MaxEncryptedDataKeysExceeded(encrypted_data_key_count, max_encrypted_data_keys) encrypted_data_keys = set([]) for _ in range(encrypted_data_key_count): (key_provider_length, ) = unpack_values(">H", stream) (key_provider_identifier, ) = unpack_values( ">{}s".format(key_provider_length), stream) (key_provider_information_length, ) = unpack_values(">H", stream) (key_provider_information, ) = unpack_values( ">{}s".format(key_provider_information_length), stream) (encrypted_data_key_length, ) = unpack_values(">H", stream) encrypted_data_key = stream.read(encrypted_data_key_length) encrypted_data_keys.add( EncryptedDataKey( key_provider=MasterKeyInfo( provider_id=to_str(key_provider_identifier), key_info=key_provider_information), encrypted_data_key=encrypted_data_key, )) return encrypted_data_keys
def key_provider(self): """Provides the MasterKeyInfo object identifying this MasterKey. :returns: This MasterKey's Identifying Information :rtype: aws_encryption_sdk.structures.MasterKeyInfo """ return MasterKeyInfo(self.provider_id, self.key_id)
def _generate_data_key(self, algorithm, encryption_context=None): """Generates data key and returns plaintext and ciphertext of key. :param algorithm: Algorithm on which to base data key :type algorithm: aws_encryption_sdk.identifiers.Algorithm :param dict encryption_context: Encryption context to pass to KMS :returns: Generated data key :rtype: aws_encryption_sdk.structures.DataKey """ kms_params = { "KeyId": self._key_id, "NumberOfBytes": algorithm.kdf_input_len } if encryption_context is not None: kms_params["EncryptionContext"] = encryption_context if self.config.grant_tokens: kms_params["GrantTokens"] = self.config.grant_tokens # Catch any boto3 errors and normalize to expected EncryptKeyError try: response = self.config.client.generate_data_key(**kms_params) plaintext = response["Plaintext"] ciphertext = response["CiphertextBlob"] key_id = response["KeyId"] except (ClientError, KeyError): error_message = "Master Key {key_id} unable to generate data key".format( key_id=self._key_id) _LOGGER.exception(error_message) raise GenerateKeyError(error_message) return DataKey( key_provider=MasterKeyInfo(provider_id=self.provider_id, key_info=key_id), data_key=plaintext, encrypted_data_key=ciphertext, )
def _encrypt_data_key(self, data_key, algorithm, encryption_context=None): """Encrypts a data key and returns the ciphertext. :param data_key: Unencrypted data key :type data_key: :class:`aws_encryption_sdk.structures.RawDataKey` or :class:`aws_encryption_sdk.structures.DataKey` :param algorithm: Placeholder to maintain API compatibility with parent :param dict encryption_context: Encryption context to pass to KMS :returns: Data key containing encrypted data key :rtype: aws_encryption_sdk.structures.EncryptedDataKey :raises EncryptKeyError: if Master Key is unable to encrypt data key """ kms_params = {"KeyId": self._key_id, "Plaintext": data_key.data_key} if encryption_context: kms_params["EncryptionContext"] = encryption_context if self.config.grant_tokens: kms_params["GrantTokens"] = self.config.grant_tokens # Catch any boto3 errors and normalize to expected EncryptKeyError try: response = self.config.client.encrypt(**kms_params) ciphertext = response["CiphertextBlob"] key_id = response["KeyId"] except (ClientError, KeyError): error_message = "Master Key {key_id} unable to encrypt data key".format( key_id=self._key_id) _LOGGER.exception(error_message) raise EncryptKeyError(error_message) return EncryptedDataKey(key_provider=MasterKeyInfo( provider_id=self.provider_id, key_info=key_id), encrypted_data_key=ciphertext)
def test_encrypt_data_key(self, config_class, key_class, key_id): config = config_class(key_id=key_id, client=self.mock_client) test = key_class(config=config) self.mock_client.encrypt.return_value["KeyId"] = key_id # //= compliance/framework/aws-kms/aws-kms-mrk-aware-master-key.txt#2.11 # //= type=test # //# The inputs MUST be the same as the Master Key Encrypt Data Key # //# (../master-key-interface.md#encrypt-data-key) interface. encrypted_key = test._encrypt_data_key(self.mock_data_key, self.mock_algorithm) # //= compliance/framework/aws-kms/aws-kms-mrk-aware-master-key.txt#2.11 # //= type=test # //# The master key MUST use the configured AWS KMS client to make an AWS KMS Encrypt # //# (https://docs.aws.amazon.com/kms/latest/APIReference/ # //# API_Encrypt.html) request constructed as follows: self.mock_client.encrypt.assert_called_once_with( KeyId=key_id.decode("ascii"), Plaintext=VALUES["data_key"]) # //= compliance/framework/aws-kms/aws-kms-mrk-aware-master-key.txt#2.11 # //= type=test # //# The response's cipher text blob MUST be used as the "ciphertext" for the # //# encrypted data key. # //= compliance/framework/aws-kms/aws-kms-mrk-aware-master-key.txt#2.11 # //= type=test # //# The output MUST be the same as the Master Key Encrypt Data Key # //# (../master-key-interface.md#encrypt-data-key) interface. assert encrypted_key == EncryptedDataKey( key_provider=MasterKeyInfo(provider_id=test.provider_id, key_info=key_id.decode("ascii")), encrypted_data_key=VALUES["encrypted_data_key"], )
def test_generate_data_key_keyring_trace(): encryption_materials_without_data_key = EncryptionMaterials( algorithm=Algorithm.AES_256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384, encryption_context=_ENCRYPTION_CONTEXT, signing_key=_SIGNING_KEY, ) key_provider_info = MasterKeyInfo(provider_id=_PROVIDER_ID, key_info=_KEY_ID) new_materials = _generate_data_key( encryption_materials=encryption_materials_without_data_key, key_provider=key_provider_info, ) assert new_materials is not encryption_materials_without_data_key assert encryption_materials_without_data_key.data_encryption_key is None assert not encryption_materials_without_data_key.keyring_trace assert new_materials.data_encryption_key is not None assert new_materials.data_encryption_key.key_provider == key_provider_info trace_entries = [ entry for entry in new_materials.keyring_trace if entry.wrapping_key == key_provider_info ] assert len(trace_entries) == 1 generate_traces = [ entry for entry in trace_entries if entry.flags == {KeyringTraceFlag.GENERATED_DATA_KEY} ] assert len(generate_traces) == 1
def _deserialize_encrypted_data_keys(stream): # type: (IO) -> Set[EncryptedDataKey] """Deserialize some encrypted data keys from a stream. :param stream: Stream from which to read encrypted data keys :return: Loaded encrypted data keys :rtype: set of :class:`EncryptedDataKey` """ (encrypted_data_key_count,) = unpack_values(">H", stream) encrypted_data_keys = set([]) for _ in range(encrypted_data_key_count): (key_provider_length,) = unpack_values(">H", stream) (key_provider_identifier,) = unpack_values(">{}s".format(key_provider_length), stream) (key_provider_information_length,) = unpack_values(">H", stream) (key_provider_information,) = unpack_values(">{}s".format(key_provider_information_length), stream) (encrypted_data_key_length,) = unpack_values(">H", stream) encrypted_data_key = stream.read(encrypted_data_key_length) encrypted_data_keys.add( EncryptedDataKey( key_provider=MasterKeyInfo( provider_id=to_str(key_provider_identifier), key_info=key_provider_information ), encrypted_data_key=encrypted_data_key, ) ) return encrypted_data_keys
def serialize_wrapped_key(key_provider, wrapping_algorithm, wrapping_key_id, encrypted_wrapped_key): """Serializes EncryptedData into a Wrapped EncryptedDataKey. :param key_provider: Info for Wrapping MasterKey :type key_provider: aws_encryption_sdk.structure.MasterKeyInfo :param wrapping_algorithm: Wrapping Algorithm with which to wrap plaintext_data_key :type wrapping_algorithm: aws_encryption_sdk.identifiers.WrappingAlgorithm :param bytes wrapping_key_id: Key ID of wrapping MasterKey :param encrypted_wrapped_key: Encrypted data key :type encrypted_wrapped_key: aws_encryption_sdk.internal.structures.EncryptedData :returns: Wrapped EncryptedDataKey :rtype: aws_encryption_sdk.structure.EncryptedDataKey """ if encrypted_wrapped_key.iv is None: key_info = wrapping_key_id key_ciphertext = encrypted_wrapped_key.ciphertext else: key_info = struct.pack( '>{key_id_len}sII{iv_len}s'.format( key_id_len=len(wrapping_key_id), iv_len=wrapping_algorithm.algorithm.iv_len), to_bytes(wrapping_key_id), len(encrypted_wrapped_key.tag) * 8, # Tag Length is stored in bits, not bytes wrapping_algorithm.algorithm.iv_len, encrypted_wrapped_key.iv) key_ciphertext = encrypted_wrapped_key.ciphertext + encrypted_wrapped_key.tag return EncryptedDataKey(key_provider=MasterKeyInfo( provider_id=key_provider.provider_id, key_info=key_info), encrypted_data_key=key_ciphertext)
def setUp(self): self.mock_algorithm = MagicMock() self.mock_algorithm.encryption_algorithm.block_size = VALUES[ 'block_size'] self.mock_algorithm.algorithm_id = VALUES['algorithm_id'] self.mock_algorithm.iv_len = VALUES['iv_len'] self.mock_algorithm.tag_len = self.mock_algorithm.auth_len = VALUES[ 'tag_len'] self.mock_key_provider = MasterKeyInfo( provider_id=VALUES['provider_id'], key_info=VALUES['key_info']) self.mock_wrapping_algorithm = MagicMock() self.mock_wrapping_algorithm.algorithm = self.mock_algorithm # Set up encryption_context patch self.mock_serialize_acc_patcher = patch( 'aws_encryption_sdk.internal.formatting.serialize.aws_encryption_sdk.internal.formatting.encryption_context' ) self.mock_serialize_acc = self.mock_serialize_acc_patcher.start() self.mock_serialize_acc.serialize_encryption_context.return_value = VALUES[ 'serialized_encryption_context'] # Set up crypto patch self.mock_crypto_patcher = patch( 'aws_encryption_sdk.internal.formatting.serialize.aws_encryption_sdk.internal.crypto' ) self.mock_crypto = self.mock_crypto_patcher.start() # Set up validate_frame_length patch self.mock_valid_frame_length_patcher = patch( 'aws_encryption_sdk.internal.formatting.serialize.aws_encryption_sdk.internal.utils.validate_frame_length' ) self.mock_valid_frame_length = self.mock_valid_frame_length_patcher.start( ) # Set up mock signer self.mock_signer = MagicMock() self.mock_signer.update.return_value = None self.mock_signer.finalize.return_value = VALUES['signature']
def _do_aws_kms_decrypt(client_supplier, key_name, encrypted_data_key, encryption_context, grant_tokens): # type: (ClientSupplierType, str, EncryptedDataKey, Dict[str, str], Iterable[str]) -> RawDataKey """Attempt to call ``kms:Decrypt`` and return the resulting plaintext data key. Any errors encountered are passed up the chain without comment. .. versionadded:: 1.5.0 """ region = _region_from_key_id(encrypted_data_key.key_provider.key_info.decode("utf-8")) client = client_supplier(region) response = client.decrypt( CiphertextBlob=encrypted_data_key.encrypted_data_key, EncryptionContext=encryption_context, GrantTokens=grant_tokens, ) response_key_id = response["KeyId"] if response_key_id != key_name: raise DecryptKeyError( "Decryption results from AWS KMS are for an unexpected key ID!" " actual '{actual}' != expected '{expected}'".format(actual=response_key_id, expected=key_name) ) return RawDataKey( key_provider=MasterKeyInfo(provider_id=KEY_NAMESPACE, key_info=response_key_id), data_key=response["Plaintext"] )
def on_encrypt(self, encryption_materials): # type: (EncryptionMaterials) -> EncryptionMaterials trace_info = MasterKeyInfo(provider_id=KEY_NAMESPACE, key_info=self._key_id) new_materials = encryption_materials try: if new_materials.data_encryption_key is None: plaintext_key, encrypted_key = _do_aws_kms_generate_data_key( client_supplier=self._client_supplier, key_name=self._key_id, encryption_context=new_materials.encryption_context, algorithm=new_materials.algorithm, grant_tokens=self._grant_tokens, ) new_materials = new_materials.with_data_encryption_key( data_encryption_key=plaintext_key, keyring_trace=KeyringTrace(wrapping_key=trace_info, flags=_GENERATE_FLAGS), ) else: encrypted_key = _do_aws_kms_encrypt( client_supplier=self._client_supplier, key_name=self._key_id, plaintext_data_key=new_materials.data_encryption_key, encryption_context=new_materials.encryption_context, grant_tokens=self._grant_tokens, ) except Exception: # pylint: disable=broad-except # We intentionally WANT to catch all exceptions here message = "Unable to generate or encrypt data key using {}".format(trace_info) _LOGGER.exception(message) raise EncryptKeyError(message) return new_materials.with_encrypted_data_key( encrypted_data_key=encrypted_key, keyring_trace=KeyringTrace(wrapping_key=trace_info, flags=_ENCRYPT_FLAGS) )
def test_generate_data_key(self, config_class, key_class, key_id): # //= compliance/framework/aws-kms/aws-kms-mrk-aware-master-key.txt#2.10 # //= type=test # //# The inputs MUST be the same as the Master Key Generate Data Key # //# (../master-key-interface.md#generate-data-key) interface. config = config_class(key_id=key_id, client=self.mock_client) test = key_class(config=config) generated_key = test._generate_data_key(self.mock_algorithm) # //= compliance/framework/aws-kms/aws-kms-mrk-aware-master-key.txt#2.10 # //= type=test # //# This master key MUST use the configured AWS KMS client to make an AWS KMS # //# GenerateDatakey (https://docs.aws.amazon.com/kms/latest/APIReference/ # //# API_GenerateDataKey.html) request constructed as follows: self.mock_client.generate_data_key.assert_called_once_with( KeyId=key_id.decode("ascii"), NumberOfBytes=sentinel.kdf_input_len) # //= compliance/framework/aws-kms/aws-kms-mrk-aware-master-key.txt#2.10 # //= type=test # //# The output MUST be the same as the Master Key Generate Data Key # //# (../master-key-interface.md#generate-data-key) interface. # //= compliance/framework/aws-kms/aws-kms-mrk-aware-master-key.txt#2.10 # //= type=test # //# The response's cipher text blob MUST be used as the returned as the # //# ciphertext for the encrypted data key in the output. # //= compliance/framework/aws-kms/aws-kms-mrk-aware-master-key.txt#2.10 # //= type=test # //# The response's "Plaintext" MUST be the plaintext in the output. assert generated_key == DataKey( key_provider=MasterKeyInfo(provider_id=test.provider_id, key_info=VALUES["arn"]), data_key=VALUES["data_key"], encrypted_data_key=VALUES["encrypted_data_key"], )
def _encrypt_data_key(self, data_key, algorithm, encryption_context=None): encrypted_data_key = self._main_key.encrypt(data_key.data_key) return EncryptedDataKey( key_provider=MasterKeyInfo( provider_id=self.provider_id, key_info=self._main_key.key_id, ), encrypted_data_key=encrypted_data_key, )
def test_generate_data_key_error_when_data_key_exists(): with pytest.raises(TypeError) as exc_info: _generate_data_key( encryption_materials= get_encryption_materials_with_data_encryption_key(), key_provider=MasterKeyInfo(provider_id=_PROVIDER_ID, key_info=_KEY_ID), ) assert exc_info.match("Data encryption key already exists.")
def test_generate_data_key(self): test = KMSMasterKey(config=self.mock_kms_mkc_3) generated_key = test._generate_data_key(self.mock_algorithm) self.mock_client.generate_data_key.assert_called_once_with( KeyId='ex_key_info', NumberOfBytes=sentinel.kdf_input_len) assert generated_key == DataKey( key_provider=MasterKeyInfo(provider_id=test.provider_id, key_info=VALUES['arn']), data_key=VALUES['data_key'], encrypted_data_key=VALUES['encrypted_data_key'])
def test_key_check_valid(self): mock_master_key = MockMasterKey( key_id=VALUES['key_info'], mock_generated_data_key=sentinel.generated_data_key, mock_encrypted_data_key=sentinel.encrypted_data_key, mock_decrypted_data_key=sentinel.decrypted_data_key) mock_data_key = MagicMock() mock_data_key.key_provider = MasterKeyInfo(VALUES['provider_id'], VALUES['key_info']) mock_master_key._key_check(mock_data_key)
def test_generate_data_key_error_when_data_key_not_generated(patch_os_urandom): patch_os_urandom.side_effect = NotImplementedError with pytest.raises(GenerateKeyError) as exc_info: _generate_data_key( encryption_materials= get_encryption_materials_without_data_encryption_key(), key_provider=MasterKeyInfo(provider_id=_PROVIDER_ID, key_info=_KEY_ID), ) assert exc_info.match("Unable to generate data encryption key.")
def _generate_data_key(self, algorithm, encryption_context=None): data_key, encrypted_data_key = self._main_key.generate_data_key() return DataKey( key_provider=MasterKeyInfo( provider_id=self.provider_id, key_info=self._main_key.key_id, ), data_key=data_key, encrypted_data_key=encrypted_data_key, )
def test_encrypt_data_key(self): test = KMSMasterKey(config=self.mock_kms_mkc_3) encrypted_key = test._encrypt_data_key(self.mock_data_key, self.mock_algorithm) self.mock_client.encrypt.assert_called_once_with( KeyId='ex_key_info', Plaintext=VALUES['data_key']) assert encrypted_key == EncryptedDataKey( key_provider=MasterKeyInfo(provider_id=test.provider_id, key_info=VALUES['arn']), encrypted_data_key=VALUES['encrypted_data_key'])
def get_decryption_materials_with_data_encryption_key(): return DecryptionMaterials( algorithm=AlgorithmSuite.AES_256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384, data_encryption_key=RawDataKey( key_provider=MasterKeyInfo(provider_id=_PROVIDER_ID, key_info=_EXISTING_KEY_ID), data_key= b'*!\xa1"^-(\xf3\x105\x05i@B\xc2\xa2\xb7\xdd\xd5\xd5\xa9\xddm\xfae\xa8\\$\xf9d\x1e(', ), encryption_context=_ENCRYPTION_CONTEXT, verification_key=b"ex_verification_key", keyring_trace=[ KeyringTrace( wrapping_key=MasterKeyInfo(provider_id=_PROVIDER_ID, key_info=_EXISTING_KEY_ID), flags={KeyringTraceFlag.DECRYPTED_DATA_KEY}, ) ], )
def test_owns_data_key_not_owned_asymmetric_checking_symmetric(self): self.mock_wrapping_key.wrapping_algorithm = WrappingAlgorithm.RSA_OAEP_SHA1_MGF1 test_master_key = RawMasterKey( key_id=VALUES['wrapped_keys']['raw']['key_info'], provider_id=VALUES['provider_id'], wrapping_key=self.mock_wrapping_key) assert not test_master_key.owns_data_key( data_key=DataKey(key_provider=MasterKeyInfo( provider_id=VALUES['provider_id'], key_info=VALUES['wrapped_keys']['serialized']['key_info']), encrypted_data_key=VALUES['encrypted_data_key'], data_key=VALUES['data_key']))
def test_serialize_wrapped_key_asymmetric(self): test = aws_encryption_sdk.internal.formatting.serialize.serialize_wrapped_key( key_provider=self.mock_key_provider, wrapping_algorithm=self.mock_wrapping_algorithm, wrapping_key_id=VALUES['wrapped_keys']['raw']['key_info'], encrypted_wrapped_key=EncryptedData(iv=None, ciphertext=VALUES['data_128'], tag=None)) assert test == EncryptedDataKey(key_provider=MasterKeyInfo( provider_id=VALUES['provider_id'], key_info=VALUES['wrapped_keys']['raw']['key_info']), encrypted_data_key=VALUES['data_128'])
def test_owns_data_key_owned_symmetric(self, mock_prefix): self.mock_wrapping_key.wrapping_algorithm = WrappingAlgorithm.AES_256_GCM_IV12_TAG16_NO_PADDING test_master_key = RawMasterKey( key_id=VALUES['wrapped_keys']['raw']['key_info'], provider_id=VALUES['provider_id'], wrapping_key=self.mock_wrapping_key) assert test_master_key.owns_data_key( data_key=DataKey(key_provider=MasterKeyInfo( provider_id=VALUES['provider_id'], key_info=VALUES['wrapped_keys']['serialized']['key_info']), encrypted_data_key=VALUES['encrypted_data_key'], data_key=VALUES['data_key']))
def __attrs_post_init__(self): # type: () -> None """Prepares initial values not handled by attrs.""" self._key_provider = MasterKeyInfo(provider_id=self.key_namespace, key_info=self.key_name) if self._public_wrapping_key is None and self._private_wrapping_key is None: raise TypeError( "At least one of public key or private key must be provided.") if self._private_wrapping_key is not None and self._public_wrapping_key is None: self._public_wrapping_key = self._private_wrapping_key.public_key()