def _prep_message(self): """Performs initial message setup. :raises MasterKeyProviderError: if primary master key is not a member of supplied MasterKeyProvider :raises MasterKeyProviderError: if no Master Keys are returned from key_provider """ validate_commitment_policy_on_encrypt(self.config.commitment_policy, self.config.algorithm) try: plaintext_length = self.stream_length except NotSupportedError: plaintext_length = None encryption_materials_request = EncryptionMaterialsRequest( algorithm=self.config.algorithm, encryption_context=self.config.encryption_context.copy(), frame_length=self.config.frame_length, plaintext_rostream=aws_encryption_sdk.internal.utils.streams. ROStream(self.source_stream), plaintext_length=plaintext_length, commitment_policy=self.config.commitment_policy, ) self._encryption_materials = self.config.materials_manager.get_encryption_materials( request=encryption_materials_request) if self.config.algorithm is not None and self._encryption_materials.algorithm != self.config.algorithm: raise ActionNotAllowedError( ("Cryptographic materials manager provided algorithm suite" " differs from algorithm suite in request.\n" "Required: {requested}\n" "Provided: {provided}").format( requested=self.config.algorithm, provided=self._encryption_materials.algorithm)) if self._encryption_materials.signing_key is None: self.signer = None else: self.signer = Signer.from_key_bytes( algorithm=self._encryption_materials.algorithm, key_bytes=self._encryption_materials.signing_key) aws_encryption_sdk.internal.utils.validate_frame_length( frame_length=self.config.frame_length, algorithm=self._encryption_materials.algorithm) message_id = aws_encryption_sdk.internal.utils.message_id( self._encryption_materials.algorithm.message_id_length()) self._derived_data_key = derive_data_encryption_key( source_key=self._encryption_materials.data_encryption_key.data_key, algorithm=self._encryption_materials.algorithm, message_id=message_id, ) self._header = self.generate_header(message_id) self._write_header() if self.content_type == ContentType.NO_FRAMING: self._prep_non_framed() self._message_prepped = True
def test_encryption_cycle_with_caching(): algorithm = Algorithm.AES_256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384 frame_length = 1024 key_provider = fake_kms_key_provider(algorithm.kdf_input_len) cache = aws_encryption_sdk.LocalCryptoMaterialsCache(capacity=10) ccmm = aws_encryption_sdk.CachingCryptoMaterialsManager( master_key_provider=key_provider, cache=cache, max_age=3600.0, max_messages_encrypted=5 ) encrypt_kwargs = dict( source=VALUES["plaintext_128"], materials_manager=ccmm, encryption_context=VALUES["encryption_context"], frame_length=frame_length, algorithm=algorithm, ) encrypt_cache_key = build_encryption_materials_cache_key( partition=ccmm.partition_name, request=EncryptionMaterialsRequest( encryption_context=VALUES["encryption_context"], frame_length=frame_length, algorithm=algorithm, plaintext_length=len(VALUES["plaintext_128"]), ), ) ciphertext, header = aws_encryption_sdk.encrypt(**encrypt_kwargs) decrypt_cache_key = build_decryption_materials_cache_key( partition=ccmm.partition_name, request=DecryptionMaterialsRequest( algorithm=algorithm, encrypted_data_keys=header.encrypted_data_keys, encryption_context=header.encryption_context, ), ) assert len(cache._cache) == 1 assert cache._cache[encrypt_cache_key].messages_encrypted == 1 assert cache._cache[encrypt_cache_key].bytes_encrypted == 128 _, _ = aws_encryption_sdk.decrypt(source=ciphertext, materials_manager=ccmm) assert len(cache._cache) == 2 assert decrypt_cache_key in cache._cache _, _ = aws_encryption_sdk.encrypt(**encrypt_kwargs) _, _ = aws_encryption_sdk.encrypt(**encrypt_kwargs) _, _ = aws_encryption_sdk.encrypt(**encrypt_kwargs) assert len(cache._cache) == 2 assert cache._cache[encrypt_cache_key].messages_encrypted == 4 assert cache._cache[encrypt_cache_key].bytes_encrypted == 512 _, _ = aws_encryption_sdk.encrypt(**encrypt_kwargs) _, _ = aws_encryption_sdk.encrypt(**encrypt_kwargs) _, _ = aws_encryption_sdk.encrypt(**encrypt_kwargs) assert len(cache._cache) == 2 assert cache._cache[encrypt_cache_key].messages_encrypted == 2 assert cache._cache[encrypt_cache_key].bytes_encrypted == 256
def test_encryption_materials_request_attributes_defaults(): test = EncryptionMaterialsRequest( encryption_context={}, frame_length=5, commitment_policy=CommitmentPolicy.FORBID_ENCRYPT_ALLOW_DECRYPT, ) assert test.plaintext_rostream is None assert test.algorithm is None assert test.plaintext_length is None
def test_encrypt_with_keyring_materials_incomplete(algorithm_suite): raw_aes256_keyring = ephemeral_raw_aes_keyring( WrappingAlgorithm.AES_256_GCM_IV12_TAG16_NO_PADDING) encrypt_cmm = DefaultCryptoMaterialsManager( keyring=NoEncryptedDataKeysKeyring(inner_keyring=raw_aes256_keyring)) encryption_materials_request = EncryptionMaterialsRequest( encryption_context={}, frame_length=1024, algorithm=algorithm_suite) with pytest.raises(InvalidCryptographicMaterialsError) as excinfo: encrypt_cmm.get_encryption_materials(encryption_materials_request) excinfo.match("Encryption materials are incomplete!")
def test_encrypt_with_keyring_materials_do_not_match_request( kwargs, algorithm_suite): raw_aes256_keyring = ephemeral_raw_aes_keyring( WrappingAlgorithm.AES_256_GCM_IV12_TAG16_NO_PADDING) encrypt_cmm = DefaultCryptoMaterialsManager( keyring=BrokenKeyring(inner_keyring=raw_aes256_keyring, **kwargs)) encryption_materials_request = EncryptionMaterialsRequest( encryption_context={}, frame_length=1024, algorithm=algorithm_suite) with pytest.raises(InvalidCryptographicMaterialsError) as excinfo: encrypt_cmm.get_encryption_materials(encryption_materials_request) excinfo.match("Encryption materials do not match request!")
def test_decrypt_with_keyring_materials_incomplete(algorithm_suite): raw_aes256_keyring = ephemeral_raw_aes_keyring( WrappingAlgorithm.AES_256_GCM_IV12_TAG16_NO_PADDING) raw_aes128_keyring = ephemeral_raw_aes_keyring( WrappingAlgorithm.AES_128_GCM_IV12_TAG16_NO_PADDING) encrypt_cmm = DefaultCryptoMaterialsManager(keyring=raw_aes256_keyring) decrypt_cmm = DefaultCryptoMaterialsManager(keyring=raw_aes128_keyring) encryption_materials_request = EncryptionMaterialsRequest( encryption_context={}, frame_length=1024, algorithm=algorithm_suite) encryption_materials = encrypt_cmm.get_encryption_materials( encryption_materials_request) decryption_materials_request = DecryptionMaterialsRequest( algorithm=encryption_materials.algorithm, encrypted_data_keys=encryption_materials.encrypted_data_keys, encryption_context=encryption_materials.encryption_context, ) with pytest.raises(InvalidCryptographicMaterialsError) as excinfo: decrypt_cmm.decrypt_materials(decryption_materials_request) excinfo.match("Decryption materials are incomplete!")
def test_encryption_materials_request_attributes_defaults(): test = EncryptionMaterialsRequest(encryption_context={}, frame_length=5) assert test.plaintext_rostream is None assert test.algorithm is None assert test.plaintext_length is None
@pytest.mark.parametrize( 'encryption_context, result', [(entry['raw'], entry['hash']) for entry in VALUES['basic']['encryption_context'].values()]) def test_encryption_context_hash(encryption_context, result): hasher = hashes.Hash(hashes.SHA512(), backend=default_backend()) assert _encryption_context_hash(hasher, encryption_context) == b64decode(result) @pytest.mark.parametrize( 'inner_request, result', [(dict(partition=scenario['components']['partition_name'], request=EncryptionMaterialsRequest( encryption_context=scenario['components']['encryption_context'], frame_length=0, algorithm=scenario['components']['algorithm'])), scenario['id']) for scenario in VALUES['cache_ids']['encrypt']]) def test_build_encryption_materials_cache_key(inner_request, result): assert build_encryption_materials_cache_key( **inner_request) == b64decode(result) @pytest.mark.parametrize( 'encrypted_data_keys, result', ((set([VALUES['basic']['encrypted_data_keys'][0]['key'] ]), [VALUES['basic']['encrypted_data_keys'][0]['hash']]), (set([VALUES['basic']['encrypted_data_keys'][1]['key'] ]), [VALUES['basic']['encrypted_data_keys'][1]['hash']]), ([ VALUES['basic']['encrypted_data_keys'][1]['key'], VALUES['basic']['encrypted_data_keys'][0]['key']
) def test_encryption_context_hash(encryption_context, result): hasher = hashes.Hash(hashes.SHA512(), backend=default_backend()) assert _encryption_context_hash(hasher, encryption_context) == b64decode(result) @pytest.mark.parametrize( "inner_request, result", [( dict( partition=scenario["components"]["partition_name"], request=EncryptionMaterialsRequest( encryption_context=scenario["components"] ["encryption_context"], frame_length=0, algorithm=scenario["components"]["algorithm"], commitment_policy=scenario["components"]["commitment_policy"], ), ), scenario["id"], ) for scenario in VALUES["cache_ids"]["encrypt"]], ) def test_build_encryption_materials_cache_key(inner_request, result): assert build_encryption_materials_cache_key( **inner_request) == b64decode(result) @pytest.mark.parametrize( "encrypted_data_keys, result", (
def _prep_message(self): """Performs initial message setup. :raises MasterKeyProviderError: if primary master key is not a member of supplied MasterKeyProvider :raises MasterKeyProviderError: if no Master Keys are returned from key_provider """ message_id = aws_encryption_sdk.internal.utils.message_id() try: plaintext_length = self.stream_length except NotSupportedError: plaintext_length = None encryption_materials_request = EncryptionMaterialsRequest( algorithm=self.config.algorithm, encryption_context=self.config.encryption_context.copy(), frame_length=self.config.frame_length, plaintext_rostream=aws_encryption_sdk.internal.utils.ROStream( self.source_stream), plaintext_length=plaintext_length) self._encryption_materials = self.config.materials_manager.get_encryption_materials( request=encryption_materials_request) if self.config.algorithm is not None and self._encryption_materials.algorithm != self.config.algorithm: raise ActionNotAllowedError( ('Cryptographic materials manager provided algorithm suite' ' differs from algorithm suite in request.\n' 'Required: {requested}\n' 'Provided: {provided}').format( requested=self.config.algorithm, provided=self._encryption_materials.algorithm)) if self._encryption_materials.signing_key is None: self.signer = None else: self.signer = aws_encryption_sdk.internal.crypto.Signer.from_key_bytes( algorithm=self._encryption_materials.algorithm, key_bytes=self._encryption_materials.signing_key) aws_encryption_sdk.internal.utils.validate_frame_length( frame_length=self.config.frame_length, algorithm=self._encryption_materials.algorithm) self._derived_data_key = aws_encryption_sdk.internal.crypto.derive_data_encryption_key( source_key=self._encryption_materials.data_encryption_key.data_key, algorithm=self._encryption_materials.algorithm, message_id=message_id) self._header = MessageHeader( version=VERSION, type=TYPE, algorithm=self._encryption_materials.algorithm, message_id=message_id, encryption_context=self._encryption_materials.encryption_context, encrypted_data_keys=self._encryption_materials.encrypted_data_keys, content_type=self.content_type, content_aad_length=0, header_iv_length=self._encryption_materials.algorithm.iv_len, frame_length=self.config.frame_length) self._write_header() if self.content_type == ContentType.NO_FRAMING: self._prep_non_framed() self._message_prepped = True