def test_read_bytes_less_than_buffer(self, mock_read_non_framed, mock_read_framed): pt_stream = io.BytesIO(self.plaintext) test_encryptor = StreamEncryptor(source=pt_stream, key_provider=self.mock_key_provider) test_encryptor.output_buffer = b"1234567" test_encryptor._read_bytes(5) assert not mock_read_non_framed.called assert not mock_read_framed.called
def test_read_bytes_non_framed(self, mock_read_non_framed, mock_read_framed): pt_stream = io.BytesIO(self.plaintext) test_encryptor = StreamEncryptor(source=pt_stream, key_provider=self.mock_key_provider) test_encryptor.content_type = ContentType.NO_FRAMING test_encryptor._read_bytes(5) assert not mock_read_framed.called mock_read_non_framed.assert_called_once_with(5)
def test_read_bytes_to_non_framed_body_close(self): test_encryptor = StreamEncryptor( source=self.mock_input_stream, key_provider=self.mock_key_provider ) test_encryptor.signer = MagicMock() test_encryptor.encryptor = MagicMock() test_encryptor.encryptor.update.return_value = b'123' test_encryptor.encryptor.finalize.return_value = b'456' test_encryptor.encryptor.tag = sentinel.tag self.mock_serialize_non_framed_close.return_value = b'789' self.mock_serialize_footer.return_value = b'0-=' test = test_encryptor._read_bytes_to_non_framed_body(len(self.plaintext) + 1) test_encryptor.signer.update.assert_has_calls( calls=(call(b'123'), call(b'456')), any_order=False ) assert test_encryptor.source_stream.closed test_encryptor.encryptor.finalize.assert_called_once_with() self.mock_serialize_non_framed_close.assert_called_once_with( tag=test_encryptor.encryptor.tag, signer=test_encryptor.signer ) self.mock_serialize_footer.assert_called_once_with(test_encryptor.signer) assert test == b'1234567890-='
def test_read_bytes_completed(self, mock_read_non_framed, mock_read_framed): pt_stream = io.BytesIO(self.plaintext) test_encryptor = StreamEncryptor(source=pt_stream, key_provider=self.mock_key_provider) test_encryptor._StreamEncryptor__message_complete = True test_encryptor._read_bytes(5) assert not mock_read_non_framed.called assert not mock_read_framed.called
def test_write_header(self): self.mock_serialize_header.return_value = b"12345" self.mock_serialize_header_auth.return_value = b"67890" pt_stream = io.BytesIO(self.plaintext) test_encryptor = StreamEncryptor( source=pt_stream, materials_manager=self.mock_materials_manager, algorithm=aws_encryption_sdk.internal.defaults.ALGORITHM, frame_length=self.mock_frame_length, commitment_policy=self.mock_commitment_policy, ) test_encryptor.signer = sentinel.signer test_encryptor.content_type = sentinel.content_type test_encryptor._header = sentinel.header sentinel.header.version = SerializationVersion.V1 test_encryptor.output_buffer = b"" test_encryptor._encryption_materials = self.mock_encryption_materials test_encryptor._derived_data_key = sentinel.derived_data_key test_encryptor._write_header() self.mock_serialize_header.assert_called_once_with( header=test_encryptor._header, signer=sentinel.signer) self.mock_serialize_header_auth.assert_called_once_with( version=sentinel.header.version, algorithm=self.mock_encryption_materials.algorithm, header=b"12345", data_encryption_key=sentinel.derived_data_key, signer=sentinel.signer, ) assert test_encryptor.output_buffer == b"1234567890"
def test_write_header(self): self.mock_serialize_header.return_value = b'12345' self.mock_serialize_header_auth.return_value = b'67890' pt_stream = io.BytesIO(self.plaintext) test_encryptor = StreamEncryptor( source=pt_stream, key_provider=self.mock_key_provider, algorithm=aws_encryption_sdk.internal.defaults.ALGORITHM, frame_length=self.mock_frame_length ) test_encryptor.signer = sentinel.signer test_encryptor.content_type = sentinel.content_type test_encryptor._header = sentinel.header test_encryptor.output_buffer = b'' test_encryptor._encryption_materials = self.mock_encryption_materials test_encryptor._derived_data_key = sentinel.derived_data_key test_encryptor._write_header() self.mock_serialize_header.assert_called_once_with( header=test_encryptor._header, signer=sentinel.signer ) self.mock_serialize_header_auth.assert_called_once_with( algorithm=self.mock_encryption_materials.algorithm, header=b'12345', data_encryption_key=sentinel.derived_data_key, signer=sentinel.signer ) assert test_encryptor.output_buffer == b'1234567890'
def test_prep_message_framed_message( self, mock_write_header, mock_prep_non_framed, mock_rostream, mock_derive_datakey, mock_encryption_materials_request ): mock_rostream.return_value = sentinel.plaintext_rostream test_encryptor = StreamEncryptor( source=self.mock_input_stream, materials_manager=self.mock_materials_manager, frame_length=self.mock_frame_length, source_length=5, encryption_context=VALUES['encryption_context'] ) test_encryptor.content_type = ContentType.FRAMED_DATA test_encryption_context = {aws_encryption_sdk.internal.defaults.ENCODED_SIGNER_KEY: sentinel.decoded_bytes} self.mock_encryption_materials.encryption_context = test_encryption_context self.mock_encryption_materials.encrypted_data_keys = self.mock_encrypted_data_keys test_encryptor._prep_message() mock_encryption_materials_request.assert_called_once_with( algorithm=test_encryptor.config.algorithm, encryption_context=VALUES['encryption_context'], plaintext_rostream=sentinel.plaintext_rostream, frame_length=test_encryptor.config.frame_length, plaintext_length=5 ) self.mock_materials_manager.get_encryption_materials.assert_called_once_with( request=mock_encryption_materials_request.return_value ) self.mock_validate_frame_length.assert_called_once_with( frame_length=self.mock_frame_length, algorithm=self.mock_encryption_materials.algorithm ) mock_derive_datakey.assert_called_once_with( source_key=self.mock_encryption_materials.data_encryption_key.data_key, algorithm=self.mock_encryption_materials.algorithm, message_id=VALUES['message_id'] ) assert test_encryptor._derived_data_key is mock_derive_datakey.return_value assert test_encryptor._header == MessageHeader( version=aws_encryption_sdk.internal.defaults.VERSION, type=aws_encryption_sdk.internal.defaults.TYPE, algorithm=self.mock_encryption_materials.algorithm, message_id=VALUES['message_id'], encryption_context=test_encryption_context, encrypted_data_keys=self.mock_encrypted_data_keys, content_type=test_encryptor.content_type, content_aad_length=0, header_iv_length=self.mock_encryption_materials.algorithm.iv_len, frame_length=self.mock_frame_length ) mock_write_header.assert_called_once_with() assert not mock_prep_non_framed.called assert test_encryptor._message_prepped
def test_read_bytes_to_non_framed_body_too_large(self): pt_stream = io.BytesIO(self.plaintext) test_encryptor = StreamEncryptor(source=pt_stream, key_provider=self.mock_key_provider) test_encryptor.bytes_read = aws_encryption_sdk.internal.defaults.MAX_NON_FRAMED_SIZE with six.assertRaisesRegex(self, SerializationError, 'Source too large for non-framed message'): test_encryptor._read_bytes_to_non_framed_body(5)
def test_read_bytes_closed(self, mock_read_non_framed, mock_read_framed): pt_stream = io.BytesIO(self.plaintext) test_encryptor = StreamEncryptor(source=pt_stream, key_provider=self.mock_key_provider) test_encryptor.source_stream.close() test_encryptor._read_bytes(5) assert not mock_read_non_framed.called assert not mock_read_framed.called
def test_prep_message_non_framed_message(self, mock_write_header, mock_prep_non_framed): test_encryptor = StreamEncryptor( source=VALUES['data_128'], materials_manager=self.mock_materials_manager, frame_length=self.mock_frame_length ) test_encryptor.content_type = ContentType.NO_FRAMING test_encryptor._prep_message() mock_prep_non_framed.assert_called_once_with()
def test_prep_message_non_framed_message(self, mock_write_header, mock_prep_non_framed): test_encryptor = StreamEncryptor( source=self.mock_input_stream, key_provider=self.mock_key_provider, frame_length=self.mock_frame_length ) test_encryptor.content_type = ContentType.NO_FRAMING test_encryptor._prep_message() mock_prep_non_framed.assert_called_once_with()
def test_prep_message_no_signer(self): self.mock_encryption_materials.algorithm = Algorithm.AES_128_GCM_IV12_TAG16 test_encryptor = StreamEncryptor( source=VALUES['data_128'], materials_manager=self.mock_materials_manager, frame_length=self.mock_frame_length, algorithm=Algorithm.AES_128_GCM_IV12_TAG16) test_encryptor.content_type = ContentType.FRAMED_DATA test_encryptor._prep_message() assert not self.mock_signer.called
def test_close(self, mock_close): self.mock_data_encryption_key.key_provider = VALUES["key_provider"] self.mock_data_encryption_key.encrypted_data_key = VALUES["encrypted_data_key"] pt_stream = io.BytesIO(self.plaintext) test_encryptor = StreamEncryptor(source=pt_stream, key_provider=self.mock_key_provider) test_encryptor._derived_data_key = sentinel.derived_data_key test_encryptor.close() mock_close.assert_called_once_with()
def test_prep_message_no_max_encrypted_data_keys(self): test_encryptor = StreamEncryptor( source=io.BytesIO(self.plaintext), materials_manager=self.mock_materials_manager, frame_length=self.mock_frame_length, source_length=5, commitment_policy=self.mock_commitment_policy, ) self.mock_encryption_materials.encrypted_data_keys.__len__.return_value = 2**16 - 1 test_encryptor.content_type = ContentType.FRAMED_DATA test_encryptor._prep_message()
def test_close(self, mock_close): self.mock_encryption_data_key.key_provider = VALUES['key_provider'] self.mock_encryption_data_key.encrypted_data_key = VALUES['encrypted_data_key'] pt_stream = io.BytesIO(self.plaintext) test_encryptor = StreamEncryptor( source=pt_stream, key_provider=self.mock_key_provider ) test_encryptor.encryption_data_key = self.mock_encryption_data_key test_encryptor.close() mock_close.assert_called_once_with()
def test_prep_message_no_signer(self): test_encryptor = StreamEncryptor( source=self.mock_input_stream, key_provider=self.mock_key_provider, frame_length=self.mock_frame_length, algorithm=Algorithm.AES_128_GCM_IV12_TAG16 ) test_encryptor.content_type = ContentType.FRAMED_DATA test_encryptor._prep_message() assert not self.mock_signer.called assert test_encryptor._header.encryption_context == {}
def test_prep_message_no_master_keys(self): self.mock_key_provider.master_keys_for_encryption.return_value = sentinel.primary_master_key, set() test_encryptor = StreamEncryptor( source=io.BytesIO(self.plaintext), key_provider=self.mock_key_provider, frame_length=self.mock_frame_length, source_length=5, ) with pytest.raises(MasterKeyProviderError) as excinfo: test_encryptor._prep_message() excinfo.match("No Master Keys available from Master Key Provider")
def test_prep_message_no_master_keys(self): self.mock_key_provider.master_keys_for_encryption.return_value = sentinel.primary_master_key, set() test_encryptor = StreamEncryptor( source=self.mock_input_stream, key_provider=self.mock_key_provider, frame_length=self.mock_frame_length, source_length=5 ) with six.assertRaisesRegex(self, MasterKeyProviderError, 'No Master Keys available from Master Key Provider'): test_encryptor._prep_message()
def test_read_bytes_framed(self, mock_read_non_framed, mock_read_framed): pt_stream = io.BytesIO(self.plaintext) test_encryptor = StreamEncryptor( source=pt_stream, materials_manager=self.mock_materials_manager, commitment_policy=self.mock_commitment_policy, ) test_encryptor.content_type = ContentType.FRAMED_DATA test_encryptor._read_bytes(5) assert not mock_read_non_framed.called mock_read_framed.assert_called_once_with(5)
def test_prep_message_primary_master_key_not_in_master_keys(self): self.mock_key_provider.master_keys_for_encryption.return_value = ( sentinel.unknown_primary_master_key, self.mock_master_keys_set) test_encryptor = StreamEncryptor(source=self.mock_input_stream, key_provider=self.mock_key_provider, frame_length=self.mock_frame_length, source_length=5) with six.assertRaisesRegex( self, MasterKeyProviderError, 'Primary Master Key not in provided Master Keys'): test_encryptor._prep_message()
def test_read_bytes_completed(self, mock_read_non_framed, mock_read_framed): pt_stream = io.BytesIO(self.plaintext) test_encryptor = StreamEncryptor( source=pt_stream, materials_manager=self.mock_materials_manager, commitment_policy=self.mock_commitment_policy, ) test_encryptor._StreamEncryptor__message_complete = True test_encryptor._read_bytes(5) assert not mock_read_non_framed.called assert not mock_read_framed.called
def test_read_bytes_less_than_buffer(self, mock_read_non_framed, mock_read_framed): pt_stream = io.BytesIO(self.plaintext) test_encryptor = StreamEncryptor( source=pt_stream, materials_manager=self.mock_materials_manager, commitment_policy=self.mock_commitment_policy, ) test_encryptor.output_buffer = b"1234567" test_encryptor._read_bytes(5) assert not mock_read_non_framed.called assert not mock_read_framed.called
def test_prep_message_algorithm_change(self): self.mock_encryption_materials.algorithm = Algorithm.AES_256_GCM_IV12_TAG16 test_encryptor = StreamEncryptor( source=io.BytesIO(self.plaintext), materials_manager=self.mock_materials_manager, algorithm=Algorithm.AES_128_GCM_IV12_TAG16, source_length=128, ) with pytest.raises(ActionNotAllowedError) as excinfo: test_encryptor._prep_message() excinfo.match( "Cryptographic materials manager provided algorithm suite differs from algorithm suite in request.*" )
def test_prep_message_algorithm_change(self): self.mock_encryption_materials.algorithm = Algorithm.AES_256_GCM_IV12_TAG16 test_encryptor = StreamEncryptor( source=self.mock_input_stream, materials_manager=self.mock_materials_manager, algorithm=Algorithm.AES_128_GCM_IV12_TAG16, source_length=128) with six.assertRaisesRegex( self, ActionNotAllowedError, 'Cryptographic materials manager provided algorithm suite differs from algorithm suite in request.*' ): test_encryptor._prep_message()
def test_read_bytes_to_non_framed_body(self): pt_stream = io.BytesIO(self.plaintext) test_encryptor = StreamEncryptor( source=pt_stream, key_provider=self.mock_key_provider ) test_encryptor.signer = MagicMock() test_encryptor.encryptor = MagicMock() test_encryptor.encryptor.update.return_value = sentinel.ciphertext test = test_encryptor._read_bytes_to_non_framed_body(5) test_encryptor.encryptor.update.assert_called_once_with(self.plaintext[:5]) test_encryptor.signer.update.assert_called_once_with(sentinel.ciphertext) assert not test_encryptor.source_stream.closed assert test is sentinel.ciphertext
def test_prep_non_framed(self, mock_non_framed_iv): self.mock_serialize_non_framed_open.return_value = b'1234567890' test_encryptor = StreamEncryptor(source=self.mock_input_stream, key_provider=self.mock_key_provider) test_encryptor.signer = sentinel.signer test_encryptor._encryption_materials = self.mock_encryption_materials test_encryptor._header = MagicMock() test_encryptor._derived_data_key = sentinel.derived_data_key test_encryptor._prep_non_framed() self.mock_get_aad_content_string.assert_called_once_with( content_type=test_encryptor.content_type, is_final_frame=True) self.mock_assemble_content_aad.assert_called_once_with( message_id=test_encryptor._header.message_id, aad_content_string=sentinel.aad_content_string, seq_num=1, length=test_encryptor.stream_length) self.mock_encryptor.assert_called_once_with( algorithm=self.mock_encryption_materials.algorithm, key=sentinel.derived_data_key, associated_data=sentinel.associated_data, iv=mock_non_framed_iv.return_value) self.mock_serialize_non_framed_open.assert_called_once_with( algorithm=self.mock_encryption_materials.algorithm, iv=sentinel.iv, plaintext_length=test_encryptor.stream_length, signer=sentinel.signer) assert test_encryptor.output_buffer == b'1234567890'
def test_commitment_uncommitting_algorithm_allowed_by_policy(self): """Verifies that we can encrypt with an uncommitting algorithm with policy FORBID_ENCRYPT_REQUIRE_DECRYPT.""" algorithm = MagicMock(__class__=Algorithm, iv_len=12) algorithm.is_committing.return_value = False self.mock_encryption_materials.algorithm = algorithm test_encryptor = StreamEncryptor( source=VALUES["data_128"], materials_manager=self.mock_materials_manager, frame_length=self.mock_frame_length, algorithm=algorithm, commitment_policy=CommitmentPolicy.FORBID_ENCRYPT_ALLOW_DECRYPT, ) test_encryptor._prep_message()
def test_prep_message_over_max_encrypted_data_keys(self): test_encryptor = StreamEncryptor( source=io.BytesIO(self.plaintext), materials_manager=self.mock_materials_manager, frame_length=self.mock_frame_length, source_length=5, commitment_policy=self.mock_commitment_policy, max_encrypted_data_keys=3, ) self.mock_encryption_materials.encrypted_data_keys.__len__.return_value = 4 test_encryptor.content_type = ContentType.FRAMED_DATA with pytest.raises(CustomMaximumValueExceeded) as excinfo: test_encryptor._prep_message() excinfo.match( "Number of encrypted data keys found larger than configured value")
def test_prep_message_primary_master_key_not_in_master_keys(self): self.mock_key_provider.master_keys_for_encryption.return_value = ( sentinel.unknown_primary_master_key, self.mock_master_keys_set, ) test_encryptor = StreamEncryptor( source=io.BytesIO(self.plaintext), key_provider=self.mock_key_provider, frame_length=self.mock_frame_length, source_length=5, ) with pytest.raises(MasterKeyProviderError) as excinfo: test_encryptor._prep_message() excinfo.match("Primary Master Key not in provided Master Keys")
def test_close(self, mock_close): self.mock_data_encryption_key.key_provider = VALUES["key_provider"] self.mock_data_encryption_key.encrypted_data_key = VALUES[ "encrypted_data_key"] pt_stream = io.BytesIO(self.plaintext) test_encryptor = StreamEncryptor( source=pt_stream, materials_manager=self.mock_materials_manager, commitment_policy=self.mock_commitment_policy, signature_policy=self.mock_signature_policy, ) test_encryptor._derived_data_key = sentinel.derived_data_key test_encryptor.close() mock_close.assert_called_once_with()