def test_raw_aes_encryption_decryption(encryption_materials_samples):

    # Initializing attributes
    key_namespace = _PROVIDER_ID
    key_name = _KEY_ID

    # Creating an instance of a raw AES keyring
    test_raw_aes_keyring = RawAESKeyring(
        key_namespace=key_namespace,
        key_name=key_name,
        wrapping_key=_WRAPPING_KEY,
    )

    # Call on_encrypt function for the keyring
    encryption_materials = test_raw_aes_keyring.on_encrypt(
        encryption_materials=encryption_materials_samples)

    # Generate decryption materials
    decryption_materials = DecryptionMaterials(
        algorithm=Algorithm.AES_256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384,
        verification_key=b"ex_verification_key",
        encryption_context=_ENCRYPTION_CONTEXT,
    )

    # Call on_decrypt function for the keyring
    decryption_materials = test_raw_aes_keyring.on_decrypt(
        decryption_materials=decryption_materials,
        encrypted_data_keys=encryption_materials.encrypted_data_keys)

    # Check if the data keys match
    assert encryption_materials.data_encryption_key.data_key == decryption_materials.data_encryption_key.data_key
예제 #2
0
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
예제 #3
0
def test_private_key_can_decrypt():
    complete_keyring = RawRSAKeyring(
        key_namespace=_PROVIDER_ID,
        key_name=_KEY_ID,
        wrapping_algorithm=_WRAPPING_ALGORITHM,
        private_wrapping_key=_PRIVATE_WRAPPING_KEY,
        public_wrapping_key=_PUBLIC_WRAPPING_KEY,
    )
    test_keyring = RawRSAKeyring(
        key_namespace=_PROVIDER_ID,
        key_name=_KEY_ID,
        wrapping_algorithm=_WRAPPING_ALGORITHM,
        private_wrapping_key=_PRIVATE_WRAPPING_KEY,
    )
    initial_materials = EncryptionMaterials(
        algorithm=Algorithm.AES_256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384,
        encryption_context=_ENCRYPTION_CONTEXT)

    encryption_materials = complete_keyring.on_encrypt(initial_materials)

    initial_decryption_materials = DecryptionMaterials(
        algorithm=Algorithm.AES_256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384,
        encryption_context=_ENCRYPTION_CONTEXT)

    test_materials = test_keyring.on_decrypt(
        decryption_materials=initial_decryption_materials,
        encrypted_data_keys=encryption_materials.encrypted_data_keys)

    assert test_materials is not initial_decryption_materials
    assert test_materials.data_encryption_key is not None
예제 #4
0
def test_aws_kms_single_cmk_keyring_on_decrypt_existing_datakey(caplog):
    # In this context there are no KMS CMKs, so any calls to KMS will fail.
    caplog.set_level(logging.DEBUG)
    keyring = _AwsKmsSingleCmkKeyring(key_id="foo", 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
예제 #5
0
    def decrypt_materials(self, request):
        """Obtains a plaintext data key from one or more encrypted data keys
        using underlying master key provider.

        :param request: decrypt materials request
        :type request: aws_encryption_sdk.materials_managers.DecryptionMaterialsRequest
        :returns: decryption materials
        :rtype: aws_encryption_sdk.materials_managers.DecryptionMaterials
        """
        try:
            return super(MrcryptLegacyCompatibilityCryptoMaterialsManager,
                         self).decrypt_materials(request)
        except (AWSEncryptionSDKClientError, KeyError):
            _LOGGER.debug(
                'Encountered error decrypting materials with DefaultCryptoMaterialsManager.'
                ' Attempting to decrypt using uncompressed elliptic curve point.'
            )
            # Once this issue is addressed, the caught exception classes should be narrowed appropriately:
            # https://github.com/awslabs/aws-encryption-sdk-python/issues/21

            _LOGGER.warning(
                "This file is encrypted using an uncompressed key, which may lead to compatibility issues "
                "with the AWS Encryption SDK.")

        data_key = self.master_key_provider.decrypt_data_key_from_list(  # subclasses confuse pylint: disable=no-member
            encrypted_data_keys=request.encrypted_data_keys,
            algorithm=request.algorithm,
            encryption_context=request.encryption_context)
        verification_key = self._load_uncompressed_verification_key_from_encryption_context(
            algorithm=request.algorithm,
            encryption_context=request.encryption_context)

        return DecryptionMaterials(data_key=data_key,
                                   verification_key=verification_key)
 def _break_decryption_materials(self, decryption_materials):
     # type: (DecryptionMaterials) -> DecryptionMaterials
     return DecryptionMaterials(
         algorithm=self._broken_algorithm(decryption_materials.algorithm),
         data_encryption_key=decryption_materials.data_encryption_key,
         encryption_context=self._broken_encryption_context(
             decryption_materials.encryption_context),
         verification_key=self._broken_key(
             decryption_materials.verification_key),
         keyring_trace=decryption_materials.keyring_trace,
     )
예제 #7
0
def test_multi_keyring_encryption_decryption(multi_keyring,
                                             encryption_materials):
    # Call on_encrypt function for the keyring
    encryption_materials = multi_keyring.on_encrypt(encryption_materials)

    # Generate decryption materials
    decryption_materials = DecryptionMaterials(
        algorithm=ALGORITHM,
        verification_key=b"ex_verification_key",
        encryption_context=_ENCRYPTION_CONTEXT)

    # Call on_decrypt function for the keyring
    decryption_materials = multi_keyring.on_decrypt(
        decryption_materials=decryption_materials,
        encrypted_data_keys=encryption_materials.encrypted_data_keys)

    # Check if the data keys match
    assert encryption_materials.data_encryption_key == decryption_materials.data_encryption_key
예제 #8
0
def test_raw_keyring_decrypts_what_raw_master_key_encrypts(
        encryption_materials_samples):

    # Create instance of raw master key
    test_raw_master_key = RawMasterKey(
        key_id=_KEY_ID,
        provider_id=_PROVIDER_ID,
        wrapping_key=WrappingKey(
            wrapping_algorithm=_WRAPPING_ALGORITHM,
            wrapping_key=_PRIVATE_WRAPPING_KEY_PEM,
            wrapping_key_type=EncryptionKeyType.PRIVATE,
        ),
    )

    test_raw_rsa_keyring = RawRSAKeyring.from_pem_encoding(
        key_namespace=_PROVIDER_ID,
        key_name=_KEY_ID,
        wrapping_algorithm=_WRAPPING_ALGORITHM,
        private_encoded_key=_PRIVATE_WRAPPING_KEY_PEM,
        public_encoded_key=_PUBLIC_WRAPPING_KEY_PEM,
    )

    raw_mkp_generated_data_key = test_raw_master_key.generate_data_key(
        algorithm=encryption_materials_samples.algorithm,
        encryption_context=encryption_materials_samples.encryption_context,
    )

    raw_mkp_encrypted_data_key = test_raw_master_key.encrypt_data_key(
        data_key=raw_mkp_generated_data_key,
        algorithm=encryption_materials_samples.algorithm,
        encryption_context=encryption_materials_samples.encryption_context,
    )

    decryption_materials = test_raw_rsa_keyring.on_decrypt(
        decryption_materials=DecryptionMaterials(
            algorithm=encryption_materials_samples.algorithm,
            encryption_context=encryption_materials_samples.encryption_context,
            verification_key=b"ex_verification_key",
        ),
        encrypted_data_keys=[raw_mkp_encrypted_data_key],
    )

    assert raw_mkp_generated_data_key.data_key == decryption_materials.data_encryption_key.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},
            )
        ],
    )
예제 #10
0
def test_aws_kms_single_cmk_keyring_on_decrypt_no_match(fake_generator_and_child):
    generator, child = fake_generator_and_child

    encrypting_keyring = _AwsKmsSingleCmkKeyring(key_id=generator, client_supplier=DefaultClientSupplier())
    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
    )

    assert result_materials.data_encryption_key is None
예제 #11
0
def test_aws_kms_discovery_keyring_on_decrypt_no_matching_edk(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={},)

    result_materials = keyring.on_decrypt(
        decryption_materials=initial_materials,
        encrypted_data_keys=(
            EncryptedDataKey(key_provider=MasterKeyInfo(provider_id="foo", key_info=b"bar"), encrypted_data_key=b"bar"),
        ),
    )

    assert result_materials.data_encryption_key is None

    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
예제 #12
0
    def _decrypt_materials_using_master_key_provider(self, request):
        """Obtains a plaintext data key from one or more encrypted data keys
        using underlying master key provider.

        :param request: decrypt materials request
        :type request: aws_encryption_sdk.materials_managers.DecryptionMaterialsRequest
        :returns: decryption materials
        :rtype: aws_encryption_sdk.materials_managers.DecryptionMaterials
        """
        data_key = self.master_key_provider.decrypt_data_key_from_list(
            encrypted_data_keys=request.encrypted_data_keys,
            algorithm=request.algorithm,
            encryption_context=request.encryption_context,
        )
        verification_key = self._load_verification_key_from_encryption_context(
            algorithm=request.algorithm,
            encryption_context=request.encryption_context)

        return DecryptionMaterials(data_key=data_key,
                                   verification_key=verification_key)
def test_raw_keyring_decrypts_what_raw_master_key_encrypts(
        encryption_materials_samples):

    # Initializing attributes
    key_namespace = _PROVIDER_ID
    key_name = _KEY_ID

    # Creating an instance of a raw AES keyring
    test_raw_aes_keyring = RawAESKeyring(
        key_namespace=key_namespace,
        key_name=key_name,
        wrapping_key=_WRAPPING_KEY,
    )

    # Creating an instance of a raw master key
    test_raw_master_key = RawMasterKey(
        key_id=test_raw_aes_keyring.key_name,
        provider_id=test_raw_aes_keyring.key_namespace,
        wrapping_key=test_raw_aes_keyring._wrapping_key_structure,
    )

    if encryption_materials_samples.data_encryption_key is None:
        return
    raw_master_key_encrypted_data_key = test_raw_master_key.encrypt_data_key(
        data_key=encryption_materials_samples.data_encryption_key,
        algorithm=encryption_materials_samples.algorithm,
        encryption_context=encryption_materials_samples.encryption_context,
    )

    # Check if plaintext data key encrypted by raw master key is decrypted by raw keyring

    raw_aes_keyring_decrypted_data_key = test_raw_aes_keyring.on_decrypt(
        decryption_materials=DecryptionMaterials(
            algorithm=encryption_materials_samples.algorithm,
            encryption_context=encryption_materials_samples.encryption_context,
            verification_key=b"ex_verification_key",
        ),
        encrypted_data_keys=[raw_master_key_encrypted_data_key],
    ).data_encryption_key.data_key

    assert encryption_materials_samples.data_encryption_key.data_key == raw_aes_keyring_decrypted_data_key
예제 #14
0
def test_aws_kms_single_cmk_keyring_on_decrypt_fail(caplog):
    # In this context there are no KMS CMKs, so any calls to KMS will fail.
    caplog.set_level(logging.DEBUG)
    keyring = _AwsKmsSingleCmkKeyring(key_id="foo", client_supplier=DefaultClientSupplier())

    initial_materials = DecryptionMaterials(algorithm=ALGORITHM, encryption_context={})

    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 not result_materials.data_encryption_key

    log_data = caplog.text

    # This means that it did actually try to decrypt the EDK but encountered an error talking to KMS.
    assert "Unable to decrypt encrypted data key from" in log_data
예제 #15
0
def test_try_aws_kms_decrypt_error(caplog):
    # In this context there are no KMS CMKs, so any calls to KMS will fail.
    caplog.set_level(logging.DEBUG)

    encrypted_data_key = EncryptedDataKey(
        key_provider=MasterKeyInfo(provider_id=KEY_NAMESPACE, key_info=b"foo"), encrypted_data_key=b"bar"
    )

    initial_decryption_materials = DecryptionMaterials(algorithm=ALGORITHM, 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 is None

    log_data = caplog.text
    # This means that it did actually try to decrypt the EDK but encountered an error talking to KMS.
    assert "Unable to decrypt encrypted data key from" in log_data
예제 #16
0
def test_aws_kms_discovery_keyring_on_decrypt(encryption_materials_for_discovery_decrypt):
    generator_key_id, encryption_materials = encryption_materials_for_discovery_decrypt

    decrypting_keyring = _AwsKmsDiscoveryKeyring(client_supplier=DefaultClientSupplier())

    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
    )

    assert result_materials is not initial_decryption_materials
    assert result_materials.data_encryption_key is not None

    generator_flags = _matching_flags(
        MasterKeyInfo(provider_id=KEY_NAMESPACE, key_info=generator_key_id), result_materials.keyring_trace
    )

    assert KeyringTraceFlag.DECRYPTED_DATA_KEY in generator_flags
    assert KeyringTraceFlag.VERIFIED_ENCRYPTION_CONTEXT in generator_flags
def test_raw_rsa_encryption_decryption(encryption_materials_samples, test_raw_rsa_keyring):

    # Call on_encrypt function for the keyring
    encryption_materials = test_raw_rsa_keyring.on_encrypt(encryption_materials=encryption_materials_samples)

    assert encryption_materials.encrypted_data_keys is not None

    # Generate decryption materials
    decryption_materials = DecryptionMaterials(
        algorithm=Algorithm.AES_256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384,
        verification_key=b"ex_verification_key",
        encryption_context=_ENCRYPTION_CONTEXT,
    )

    # Call on_decrypt function for the keyring
    decryption_materials = test_raw_rsa_keyring.on_decrypt(
        decryption_materials=decryption_materials, encrypted_data_keys=encryption_materials.encrypted_data_keys
    )

    if test_raw_rsa_keyring._private_wrapping_key is not None:
        # Check if the data keys match
        assert encryption_materials.data_encryption_key.data_key == decryption_materials.data_encryption_key.data_key
예제 #18
0
    def _decrypt_materials_using_keyring(self, request):
        """Obtains a plaintext data key from one or more encrypted data keys
        using underlying keyring.

        :param request: decrypt materials request
        :type request: aws_encryption_sdk.materials_managers.DecryptionMaterialsRequest
        :returns: decryption materials
        :rtype: aws_encryption_sdk.materials_managers.DecryptionMaterials
        :raises InvalidCryptographicMaterialsError: if keyring cannot complete decryption materials
        :raises InvalidCryptographicMaterialsError:
           if decryption materials received from keyring do not match request
        """
        verification_key = self._load_verification_key_from_encryption_context(
            algorithm=request.algorithm,
            encryption_context=request.encryption_context)
        decryption_materials = DecryptionMaterials(
            algorithm=request.algorithm,
            encryption_context=request.encryption_context.copy(),
            verification_key=verification_key,
        )

        final_materials = self.keyring.on_decrypt(
            decryption_materials=decryption_materials,
            encrypted_data_keys=request.encrypted_data_keys)

        materials_are_valid = (
            final_materials.algorithm is request.algorithm,
            final_materials.encryption_context == request.encryption_context,
            final_materials.verification_key is verification_key,
        )
        if not all(materials_are_valid):
            raise InvalidCryptographicMaterialsError(
                "Decryption materials do not match request!")

        if not final_materials.is_complete:
            raise InvalidCryptographicMaterialsError(
                "Decryption materials are incomplete!")

        return final_materials
예제 #19
0
def test_aws_kms_single_cmk_keyring_on_decrypt_single_cmk(fake_generator):
    keyring = _AwsKmsSingleCmkKeyring(key_id=fake_generator, client_supplier=DefaultClientSupplier())

    initial_encryption_materials = EncryptionMaterials(algorithm=ALGORITHM, encryption_context={})

    encryption_materials = keyring.on_encrypt(initial_encryption_materials)

    initial_decryption_materials = DecryptionMaterials(
        algorithm=encryption_materials.algorithm, encryption_context=encryption_materials.encryption_context
    )

    result_materials = keyring.on_decrypt(
        decryption_materials=initial_decryption_materials, encrypted_data_keys=encryption_materials.encrypted_data_keys
    )

    assert result_materials is not initial_decryption_materials
    assert result_materials.data_encryption_key is not None

    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
예제 #20
0
def test_decryption_materials_defaults():
    test = DecryptionMaterials(data_key=MagicMock(__class__=DataKey))
    assert test.verification_key is None
from aws_encryption_sdk.keyrings.base import Keyring
from aws_encryption_sdk.materials_managers import DecryptionMaterials, EncryptionMaterials

pytestmark = [pytest.mark.unit, pytest.mark.local]

_encryption_materials = EncryptionMaterials(
    algorithm=Algorithm.AES_256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384,
    encryption_context={
        "encryption": "context",
        "values": "here"
    },
    signing_key=b"aws-crypto-public-key",
)

_decryption_materials = DecryptionMaterials(
    algorithm=Algorithm.AES_256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384,
    verification_key=b"ex_verification_key")

_encrypted_data_keys = []


def test_keyring_no_encrypt():
    with pytest.raises(NotImplementedError) as exc_info:
        Keyring().on_encrypt(encryption_materials=_encryption_materials)
    assert exc_info.match("Keyring does not implement on_encrypt function")


def test_keyring_no_decrypt():
    with pytest.raises(NotImplementedError) as exc_info:
        Keyring().on_decrypt(decryption_materials=_decryption_materials,
                             encrypted_data_keys=_encrypted_data_keys)
def get_decryption_materials_without_data_encryption_key():
    return DecryptionMaterials(
        algorithm=AlgorithmSuite.AES_256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384,
        verification_key=b"ex_verification_key",
        encryption_context=_ENCRYPTION_CONTEXT,
    )
def get_decryption_materials_without_data_key():
    return DecryptionMaterials(encryption_context=_ENCRYPTION_CONTEXT,
                               verification_key=b"ex_verification_key")