def test_read_bytes_no_read_required(self, mock_read_frame, mock_read_block):
     ct_stream = io.BytesIO(VALUES["data_128"])
     test_decryptor = StreamDecryptor(key_provider=self.mock_key_provider, source=ct_stream)
     test_decryptor.output_buffer = b"1234567"
     test_decryptor._read_bytes(5)
     assert not mock_read_frame.called
     assert not mock_read_block.called
Пример #2
0
 def test_close_no_footer(self, mock_close):
     self.mock_header.content_type = ContentType.FRAMED_DATA
     test_decryptor = StreamDecryptor(key_provider=self.mock_key_provider,
                                      source=self.mock_input_stream)
     with six.assertRaisesRegex(self, SerializationError,
                                'Footer not read'):
         test_decryptor.close()
 def test_read_bytes_completed(self, mock_read_frame, mock_read_block):
     ct_stream = io.BytesIO(VALUES["data_128"])
     test_decryptor = StreamDecryptor(key_provider=self.mock_key_provider, source=ct_stream)
     test_decryptor.footer = None
     test_decryptor._read_bytes(5)
     assert not mock_read_frame.called
     assert not mock_read_block.called
Пример #4
0
 def test_close_no_footer(self, mock_close):
     self.mock_header.content_type = ContentType.FRAMED_DATA
     test_decryptor = StreamDecryptor(key_provider=self.mock_key_provider,
                                      source=self.mock_input_stream)
     with pytest.raises(SerializationError) as excinfo:
         test_decryptor.close()
     excinfo.match("Footer not read")
Пример #5
0
 def test_read_bytes_closed(self, mock_read_frame, mock_read_block):
     ct_stream = io.BytesIO(VALUES['data_128'])
     test_decryptor = StreamDecryptor(key_provider=self.mock_key_provider,
                                      source=ct_stream)
     test_decryptor.source_stream.close()
     test_decryptor._read_bytes(5)
     assert not mock_read_frame.called
     assert not mock_read_block.called
 def test_read_bytes_non_framed(self, mock_read_frame, mock_read_block):
     ct_stream = io.BytesIO(VALUES["data_128"])
     test_decryptor = StreamDecryptor(key_provider=self.mock_key_provider, source=ct_stream)
     test_decryptor._header = MagicMock()
     test_decryptor._header.content_type = ContentType.NO_FRAMING
     test_decryptor._read_bytes(5)
     mock_read_block.assert_called_once_with(5)
     assert not mock_read_frame.called
 def test_read_bytes_unknown(self, mock_read_frame, mock_read_block):
     ct_stream = io.BytesIO(VALUES["data_128"])
     test_decryptor = StreamDecryptor(key_provider=self.mock_key_provider, source=ct_stream)
     test_decryptor._header = MagicMock()
     test_decryptor._header.content_type = None
     with pytest.raises(NotSupportedError) as excinfo:
         test_decryptor._read_bytes(5)
     excinfo.match("Unsupported content type")
Пример #8
0
 def test_prep_message_non_framed_message(self, mock_read_header,
                                          mock_prep_non_framed):
     self.mock_header.content_type = ContentType.NO_FRAMING
     mock_read_header.return_value = self.mock_header, sentinel.header_auth
     test_decryptor = StreamDecryptor(key_provider=self.mock_key_provider,
                                      source=self.mock_input_stream)
     test_decryptor._prep_message()
     mock_prep_non_framed.assert_called_once_with()
Пример #9
0
 def test_read_bytes_unknown(self, mock_read_frame, mock_read_block):
     ct_stream = io.BytesIO(VALUES['data_128'])
     test_decryptor = StreamDecryptor(key_provider=self.mock_key_provider,
                                      source=ct_stream)
     test_decryptor._header = MagicMock()
     test_decryptor._header.content_type = None
     with six.assertRaisesRegex(self, NotSupportedError,
                                'Unsupported content type'):
         test_decryptor._read_bytes(5)
 def test_prep_message_framed_message(self, mock_read_header, mock_prep_non_framed):
     self.mock_header.content_type = ContentType.FRAMED_DATA
     mock_read_header.return_value = self.mock_header, sentinel.header_auth
     test_decryptor = StreamDecryptor(key_provider=self.mock_key_provider, source=self.mock_input_stream)
     test_decryptor._prep_message()
     mock_read_header.assert_called_once_with()
     assert test_decryptor._header is self.mock_header
     assert test_decryptor.header_auth is sentinel.header_auth
     assert not mock_prep_non_framed.called
     assert test_decryptor._message_prepped
Пример #11
0
 def test_close_no_footer(self, mock_close):
     self.mock_header.content_type = ContentType.FRAMED_DATA
     test_decryptor = StreamDecryptor(
         materials_manager=self.mock_materials_manager,
         source=self.mock_input_stream,
         commitment_policy=self.mock_commitment_policy,
     )
     with pytest.raises(SerializationError) as excinfo:
         test_decryptor.close()
     excinfo.match("Footer not read")
Пример #12
0
    def test_read_bytes_from_non_framed_finalize(self):
        ct_stream = io.BytesIO(VALUES["data_128"])
        test_decryptor = StreamDecryptor(
            materials_manager=self.mock_materials_manager,
            source=ct_stream,
            commitment_policy=self.mock_commitment_policy,
        )
        test_decryptor.body_length = len(VALUES["data_128"])
        test_decryptor.decryptor = self.mock_decryptor_instance
        test_decryptor.verifier = MagicMock()
        test_decryptor._header = self.mock_header
        test_decryptor._derived_data_key = sentinel.derived_data_key
        test_decryptor._unframed_body_iv = sentinel.unframed_body_iv
        self.mock_decryptor_instance.update.return_value = b"1234"
        self.mock_decryptor_instance.finalize.return_value = b"5678"

        test = test_decryptor._read_bytes_from_non_framed_body(
            len(VALUES["data_128"]) + 1)

        test_decryptor.verifier.update.assert_called_once_with(
            VALUES["data_128"])
        self.mock_decryptor_instance.update.assert_called_once_with(
            VALUES["data_128"])
        self.mock_deserialize_footer.assert_called_once_with(
            stream=test_decryptor.source_stream,
            verifier=test_decryptor.verifier)
        assert test == b"12345678"
Пример #13
0
 def test_read_bytes_completed(self, mock_read_frame, mock_read_block):
     ct_stream = io.BytesIO(VALUES["data_128"])
     test_decryptor = StreamDecryptor(
         materials_manager=self.mock_materials_manager,
         source=ct_stream,
         commitment_policy=self.mock_commitment_policy,
     )
     test_decryptor.footer = None
     test_decryptor._read_bytes(5)
     assert not mock_read_frame.called
     assert not mock_read_block.called
Пример #14
0
 def test_prep_message_non_framed_message(self, mock_read_header,
                                          mock_prep_non_framed):
     self.mock_header.content_type = ContentType.NO_FRAMING
     mock_read_header.return_value = self.mock_header, sentinel.header_auth
     test_decryptor = StreamDecryptor(
         materials_manager=self.mock_materials_manager,
         source=self.mock_input_stream,
         commitment_policy=self.mock_commitment_policy,
     )
     test_decryptor._prep_message()
     mock_prep_non_framed.assert_called_once_with()
 def test_read_bytes_from_non_framed_no_verifier(self):
     ct_stream = io.BytesIO(VALUES["data_128"])
     test_decryptor = StreamDecryptor(key_provider=self.mock_key_provider, source=ct_stream)
     test_decryptor.body_length = len(VALUES["data_128"])
     test_decryptor.decryptor = self.mock_decryptor_instance
     test_decryptor._header = self.mock_header
     test_decryptor._derived_data_key = sentinel.derived_data_key
     test_decryptor._unframed_body_iv = sentinel.unframed_body_iv
     test_decryptor.verifier = None
     self.mock_decryptor_instance.update.return_value = b"1234"
     test_decryptor._read_bytes_from_non_framed_body(5)
Пример #16
0
 def test_read_bytes_no_read_required(self, mock_read_frame,
                                      mock_read_block):
     ct_stream = io.BytesIO(VALUES["data_128"])
     test_decryptor = StreamDecryptor(
         materials_manager=self.mock_materials_manager,
         source=ct_stream,
         commitment_policy=self.mock_commitment_policy,
     )
     test_decryptor.output_buffer = b"1234567"
     test_decryptor._read_bytes(5)
     assert not mock_read_frame.called
     assert not mock_read_block.called
Пример #17
0
 def test_read_bytes_non_framed(self, mock_read_frame, mock_read_block):
     ct_stream = io.BytesIO(VALUES["data_128"])
     test_decryptor = StreamDecryptor(
         materials_manager=self.mock_materials_manager,
         source=ct_stream,
         commitment_policy=self.mock_commitment_policy,
     )
     test_decryptor._header = MagicMock()
     test_decryptor._header.content_type = ContentType.NO_FRAMING
     test_decryptor._read_bytes(5)
     mock_read_block.assert_called_once_with(5)
     assert not mock_read_frame.called
Пример #18
0
    def test_read_header(self, mock_derive_datakey,
                         mock_decrypt_materials_request, mock_verifier):
        mock_verifier_instance = MagicMock()
        mock_verifier.from_key_bytes.return_value = mock_verifier_instance
        ct_stream = io.BytesIO(VALUES["data_128"])
        mock_commitment_policy = MagicMock(__class__=CommitmentPolicy)
        test_decryptor = StreamDecryptor(
            materials_manager=self.mock_materials_manager,
            source=ct_stream,
            commitment_policy=mock_commitment_policy,
        )
        test_decryptor.source_stream = ct_stream
        test_decryptor._stream_length = len(VALUES["data_128"])

        test_header, test_header_auth = test_decryptor._read_header()

        self.mock_deserialize_header.assert_called_once_with(ct_stream)
        mock_verifier.from_key_bytes.assert_called_once_with(
            algorithm=self.mock_header.algorithm,
            key_bytes=sentinel.verification_key)
        mock_decrypt_materials_request.assert_called_once_with(
            encrypted_data_keys=sentinel.encrypted_data_keys,
            algorithm=self.mock_header.algorithm,
            encryption_context=sentinel.encryption_context,
            commitment_policy=mock_commitment_policy,
        )
        self.mock_materials_manager.decrypt_materials.assert_called_once_with(
            request=mock_decrypt_materials_request.return_value)
        mock_verifier_instance.update.assert_called_once_with(
            self.mock_raw_header)
        self.mock_deserialize_header_auth.assert_called_once_with(
            version=self.mock_header.version,
            stream=ct_stream,
            algorithm=self.mock_header.algorithm,
            verifier=mock_verifier_instance,
        )
        mock_derive_datakey.assert_called_once_with(
            source_key=VALUES["data_key_obj"].data_key,
            algorithm=self.mock_header.algorithm,
            message_id=self.mock_header.message_id,
        )
        assert test_decryptor._derived_data_key is mock_derive_datakey.return_value
        self.mock_validate_header.assert_called_once_with(
            header=self.mock_header,
            header_auth=sentinel.header_auth,
            raw_header=self.mock_raw_header,
            data_key=mock_derive_datakey.return_value,
        )
        assert test_header is self.mock_header
        assert test_header_auth is sentinel.header_auth
 def test_init(self):
     ct_stream = io.BytesIO(VALUES['data_128'])
     test_decryptor = StreamDecryptor(
         key_provider=self.mock_key_provider,
         source=ct_stream
     )
     assert test_decryptor.last_sequence_number == 0
def decrypt(**kwargs):
    """Deserializes and decrypts provided ciphertext.

    .. note::
        When using this function, the entire ciphertext message is decrypted into memory before returning
        any data.  If streaming is desired, see :class:`aws_encryption_sdk.stream`.

    .. versionadded:: 1.5.0
       The *keyring* parameter.

    .. versionadded:: 1.5.0

        For backwards compatibility,
        the new :class:`CryptoResult` return value also unpacks like a 2-member tuple.
        This allows for backwards compatibility with the previous outputs
        so this change should not break any existing consumers.

    .. code:: python

        >>> import aws_encryption_sdk
        >>> from aws_encryption_sdk.keyrings.aws_kms import AwsKmsKeyring
        >>> keyring = AwsKmsKeyring(
        ...     generator_key_id="arn:aws:kms:us-east-1:2222222222222:key/22222222-2222-2222-2222-222222222222",
        ...     key_ids=["arn:aws:kms:us-east-1:3333333333333:key/33333333-3333-3333-3333-333333333333"],
        ... )
        >>> my_ciphertext, decryptor_header = aws_encryption_sdk.decrypt(
        ...     source=my_ciphertext,
        ...     keyring=keyring,
        ... )

    :param config: Client configuration object (config or individual parameters required)
    :type config: aws_encryption_sdk.streaming_client.DecryptorConfig
    :param source: Source data to encrypt or decrypt
    :type source: str, bytes, io.IOBase, or file
    :param CryptoMaterialsManager materials_manager:
        Cryptographic materials manager to use for encryption
        (either ``materials_manager``, ``keyring``, ``key_provider`` required)
    :param Keyring keyring: Keyring to use for encryption
        (either ``materials_manager``, ``keyring``, ``key_provider`` required)
    :param MasterKeyProvider key_provider:
        Master key provider to use for encryption
        (either ``materials_manager``, ``keyring``, ``key_provider`` required)
    :param int source_length: Length of source data (optional)

        .. note::
            If source_length is not provided and read() is called, will attempt to seek()
            to the end of the stream and tell() to find the length of source data.

    :param int max_body_length: Maximum frame size (or content length for non-framed messages)
        in bytes to read from ciphertext message.
    :returns: Decrypted plaintext, message metadata (header), and keyring trace
    :rtype: CryptoResult
    """
    with StreamDecryptor(**kwargs) as decryptor:
        plaintext = decryptor.read()

    header_copy = copy.deepcopy(decryptor.header)
    keyring_trace_copy = copy.deepcopy(decryptor.keyring_trace)

    return CryptoResult(result=plaintext, header=header_copy, keyring_trace=keyring_trace_copy)
Пример #21
0
 def test_init(self):
     ct_stream = io.BytesIO(VALUES["data_128"])
     test_decryptor = StreamDecryptor(
         materials_manager=self.mock_materials_manager,
         source=ct_stream,
         commitment_policy=self.mock_commitment_policy,
     )
     assert test_decryptor.last_sequence_number == 0
Пример #22
0
    def test_prep_non_framed(self):
        test_decryptor = StreamDecryptor(key_provider=self.mock_key_provider,
                                         source=self.mock_input_stream)
        test_decryptor._header = self.mock_header
        test_decryptor.verifier = sentinel.verifier
        test_decryptor._derived_data_key = sentinel.derived_data_key

        test_decryptor._prep_non_framed()

        self.mock_deserialize_non_framed_values.assert_called_once_with(
            stream=self.mock_input_stream,
            header=self.mock_header,
            verifier=sentinel.verifier)
        assert test_decryptor.body_length == len(VALUES['data_128'])
        self.mock_get_aad_content_string.assert_called_once_with(
            content_type=self.mock_header.content_type, is_final_frame=True)
        self.mock_assemble_content_aad.assert_called_once_with(
            message_id=self.mock_header.message_id,
            aad_content_string=sentinel.aad_content_string,
            seq_num=1,
            length=len(VALUES['data_128']))
        self.mock_decryptor.assert_called_once_with(
            algorithm=self.mock_header.algorithm,
            key=sentinel.derived_data_key,
            associated_data=sentinel.associated_data,
            iv=sentinel.iv,
            tag=sentinel.tag)
        assert test_decryptor.decryptor is self.mock_decryptor_instance
        assert test_decryptor.body_start == 0
        assert test_decryptor.body_end == len(VALUES['data_128'])
Пример #23
0
    def test_read_bytes_from_framed_body_single_frame(self):
        ct_stream = io.BytesIO(VALUES["data_128"])
        test_decryptor = StreamDecryptor(
            materials_manager=self.mock_materials_manager,
            source=ct_stream,
            commitment_policy=self.mock_commitment_policy,
        )
        test_decryptor.verifier = MagicMock()
        test_decryptor.data_key = MagicMock()
        test_decryptor._header = self.mock_header
        test_decryptor._derived_data_key = sentinel.derived_data_key
        frame_data = MagicMock()
        frame_data.sequence_number = 1
        frame_data.final_frame = False
        frame_data.ciphertext = b"asdfzxcv"
        self.mock_deserialize_frame.return_value = (frame_data, False)
        self.mock_get_aad_content_string.return_value = sentinel.aad_content_string
        self.mock_assemble_content_aad.return_value = sentinel.associated_data
        self.mock_decrypt.return_value = b"1234"

        test = test_decryptor._read_bytes_from_framed_body(4)

        self.mock_deserialize_frame.assert_called_once_with(
            stream=test_decryptor.source_stream,
            header=test_decryptor._header,
            verifier=test_decryptor.verifier)
        assert not self.mock_deserialize_footer.called
        assert test == b"1234"
 def test_read_bytes_from_non_framed_finalize(self):
     ct_stream = io.BytesIO(VALUES['data_128'])
     test_decryptor = StreamDecryptor(
         key_provider=self.mock_key_provider,
         source=ct_stream
     )
     test_decryptor.body_start = 0
     test_decryptor.body_length = test_decryptor.body_end = len(VALUES['data_128'])
     test_decryptor.decryptor = self.mock_decryptor_instance
     test_decryptor.verifier = MagicMock()
     test_decryptor._header = self.mock_header
     self.mock_decryptor_instance.update.return_value = b'1234'
     self.mock_decryptor_instance.finalize.return_value = b'5678'
     test = test_decryptor._read_bytes_from_non_framed_body(len(VALUES['data_128']) + 1)
     test_decryptor.verifier.update.assert_called_once_with(VALUES['data_128'])
     self.mock_decryptor_instance.update.assert_called_once_with(VALUES['data_128'])
     self.mock_update_verifier_with_tag.assert_called_once_with(
         stream=test_decryptor.source_stream,
         header=test_decryptor._header,
         verifier=test_decryptor.verifier
     )
     self.mock_deserialize_footer.assert_called_once_with(
         stream=test_decryptor.source_stream,
         verifier=test_decryptor.verifier
     )
     assert test_decryptor.source_stream.closed
     assert test == b'12345678'
Пример #25
0
 def test_read_bytes_from_non_framed_no_verifier(self):
     ct_stream = io.BytesIO(VALUES['data_128'])
     test_decryptor = StreamDecryptor(key_provider=self.mock_key_provider,
                                      source=ct_stream)
     test_decryptor.body_start = 0
     test_decryptor.body_length = test_decryptor.body_end = len(
         VALUES['data_128'])
     test_decryptor.decryptor = self.mock_decryptor_instance
     test_decryptor._header = self.mock_header
     test_decryptor.verifier = None
     self.mock_decryptor_instance.update.return_value = b'1234'
     test_decryptor._read_bytes_from_non_framed_body(5)
    def test_read_header(self, mock_init, mock_derive_datakey,
                         mock_decrypt_materials_request, mock_verifier):
        mock_verifier_instance = MagicMock()
        mock_verifier.from_key_bytes.return_value = mock_verifier_instance
        mock_init.return_value = None
        ct_stream = io.BytesIO(VALUES['data_128'])
        test_decryptor = StreamDecryptor(
            materials_manager=self.mock_materials_manager, source=ct_stream)
        test_decryptor.source_stream = ct_stream
        test_decryptor._stream_length = len(VALUES['data_128'])

        test_header, test_header_auth = test_decryptor._read_header()

        self.mock_deserialize_header.assert_called_once_with(ct_stream)
        mock_verifier.from_key_bytes.assert_called_once_with(
            algorithm=self.mock_header.algorithm,
            key_bytes=sentinel.verification_key)
        mock_decrypt_materials_request.assert_called_once_with(
            encrypted_data_keys=sentinel.encrypted_data_keys,
            algorithm=self.mock_header.algorithm,
            encryption_context=sentinel.encryption_context)
        self.mock_materials_manager.decrypt_materials.assert_called_once_with(
            request=mock_decrypt_materials_request.return_value)
        mock_verifier_instance.update.assert_called_once_with(b'')
        self.mock_deserialize_header_auth.assert_called_once_with(
            stream=ct_stream,
            algorithm=self.mock_header.algorithm,
            verifier=mock_verifier_instance)
        mock_derive_datakey.assert_called_once_with(
            source_key=VALUES['data_key_obj'].data_key,
            algorithm=self.mock_header.algorithm,
            message_id=self.mock_header.message_id)
        assert test_decryptor._derived_data_key is mock_derive_datakey.return_value
        self.mock_validate_header.assert_called_once_with(
            header=self.mock_header,
            header_auth=sentinel.header_auth,
            stream=ct_stream,
            header_start=0,
            header_end=
            0,  # Because we mock out deserialize_header, this stays at the start of the stream
            data_key=mock_derive_datakey.return_value)
        assert test_header is self.mock_header
        assert test_header_auth is sentinel.header_auth
Пример #27
0
    def test_commitment_uncommitting_algorithm_policy_allows(
            self, mock_derive_datakey, mock_decrypt_materials_request,
            mock_verifier, policy):
        """Verifies that we can successfully read the header on a message encrypted with an algorithm that
        does not provide commitment when the policy allows it."""
        self.mock_header.algorithm = MagicMock(
            __class__=Algorithm,
            iv_len=12,
            is_committing=MagicMock(return_value=False))

        test_decryptor = StreamDecryptor(
            materials_manager=self.mock_materials_manager,
            source=self.mock_input_stream,
            commitment_policy=policy,
        )
        test_decryptor._read_header()
        self.mock_deserialize_header.assert_called_once_with(
            self.mock_input_stream)
        self.mock_compare_digest.assert_not_called()
Пример #28
0
    def test_commitment_uncommitting_algorithm_policy_requires_encrypt(
            self, mock_derive_datakey, mock_decrypt_materials_request,
            mock_verifier):
        """Verifies that we emit the correct exception on a message encrypted with an algorithm that
        does not provide commitment when the policy requires commitment."""
        self.mock_header.algorithm = MagicMock(
            __class__=Algorithm,
            iv_len=12,
            is_committing=MagicMock(return_value=False))

        test_decryptor = StreamDecryptor(
            materials_manager=self.mock_materials_manager,
            source=self.mock_input_stream,
            commitment_policy=CommitmentPolicy.REQUIRE_ENCRYPT_REQUIRE_DECRYPT,
        )
        with pytest.raises(ActionNotAllowedError) as excinfo:
            test_decryptor._read_header()
        excinfo.match(
            "Configuration conflict. Cannot decrypt due to .* requiring only committed messages"
        )
Пример #29
0
    def test_commitment_committing_algorithm_policy_allows_check_fails(
            self, mock_derive_datakey, mock_decrypt_materials_request,
            mock_verifier):
        """Verifies that when the commitment check fails for a committing algorithm on decrypt, we emit the correct
        exception."""
        self.mock_compare_digest.return_value = False
        self.mock_header.algorithm = MagicMock(
            __class__=Algorithm,
            iv_len=12,
            is_committing=MagicMock(return_value=True))

        test_decryptor = StreamDecryptor(
            materials_manager=self.mock_materials_manager,
            source=self.mock_input_stream,
            commitment_policy=CommitmentPolicy.FORBID_ENCRYPT_ALLOW_DECRYPT,
        )

        with pytest.raises(MasterKeyProviderError) as excinfo:
            test_decryptor._read_header()
        excinfo.match("Key commitment validation failed")
 def test_read_header_no_verifier(self, mock_derive_datakey, mock_decrypt_materials_request, mock_verifier):
     self.mock_materials_manager.decrypt_materials.return_value = MagicMock(
         data_key=VALUES["data_key_obj"], verification_key=None
     )
     test_decryptor = StreamDecryptor(materials_manager=self.mock_materials_manager, source=self.mock_input_stream)
     test_decryptor.key_provider = self.mock_key_provider
     test_decryptor.source_stream = self.mock_input_stream
     test_decryptor._stream_length = len(VALUES["data_128"])
     test_decryptor._read_header()
     assert test_decryptor.verifier is None