def build_ccmm(**custom_kwargs):
    kwargs = dict(
        cache=MagicMock(__class__=CryptoMaterialsCache),
        max_age=10.0,
        backing_materials_manager=MagicMock(__class__=CryptoMaterialsManager))
    kwargs.update(custom_kwargs)
    return CachingCryptoMaterialsManager(**kwargs)
def test_mkp_to_default_cmm(mocker):
    mocker.patch.object(aws_encryption_sdk.materials_managers.caching,
                        'DefaultCryptoMaterialsManager')
    mock_mkp = MagicMock(__class__=MasterKeyProvider)
    test = CachingCryptoMaterialsManager(
        cache=MagicMock(__class__=CryptoMaterialsCache),
        max_age=10.0,
        master_key_provider=mock_mkp)

    aws_encryption_sdk.materials_managers.caching.DefaultCryptoMaterialsManager.assert_called_once_with(mock_mkp)  # noqa pylint: disable=line-too-long
    assert test.backing_materials_manager is aws_encryption_sdk.materials_managers.caching.DefaultCryptoMaterialsManager.return_value  # noqa pylint: disable=line-too-long
def test_keyring_to_default_cmm():
    keyring = ephemeral_raw_aes_keyring()

    test = CachingCryptoMaterialsManager(
        cache=LocalCryptoMaterialsCache(capacity=10),
        max_age=10.0,
        keyring=keyring)

    assert isinstance(test.backing_materials_manager,
                      DefaultCryptoMaterialsManager)
    assert test.backing_materials_manager.keyring is keyring
    assert test.backing_materials_manager.master_key_provider is None
Example #4
0
    def run_scenario_with_tampering(self, ciphertext_writer, generation_scenario, _plaintext_uri):
        """
        Run a given scenario, tampering with the input or the result.

        return: a list of (ciphertext, result) pairs.
        """
        master_key_provider = generation_scenario.encryption_scenario.master_key_provider_fn()

        # Use a caching CMM to avoid generating a new data key every time.
        cache = LocalCryptoMaterialsCache(10)
        caching_cmm = CachingCryptoMaterialsManager(
            master_key_provider=master_key_provider,
            cache=cache,
            max_age=60.0,
            max_messages_encrypted=100,
        )
        return [
            self.run_scenario_with_new_provider_info(
                ciphertext_writer, generation_scenario, caching_cmm, new_provider_info
            )
            for new_provider_info in self.new_provider_infos
        ]
Example #5
0
def run(aws_kms_cmk, source_plaintext):
    # type: (str, bytes) -> None
    """Demonstrate an encrypt/decrypt cycle using the caching cryptographic materials manager.

    :param str aws_kms_cmk: The ARN of an AWS KMS CMK that protects data keys
    :param bytes source_plaintext: Plaintext to encrypt
    """
    # Prepare your encryption context.
    # Remember that your encryption context is NOT SECRET.
    # https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/concepts.html#encryption-context
    encryption_context = {
        "encryption": "context",
        "is not": "secret",
        "but adds": "useful metadata",
        "that can help you": "be confident that",
        "the data you are handling": "is what you think it is",
    }

    # Create the keyring that determines how your data keys are protected.
    keyring = AwsKmsKeyring(generator_key_id=aws_kms_cmk)

    # Create the caching cryptographic materials manager using your keyring.
    cmm = CachingCryptoMaterialsManager(
        keyring=keyring,
        # The cache is where the caching CMM stores the materials.
        #
        # LocalCryptoMaterialsCache gives you a local, in-memory, cache.
        cache=LocalCryptoMaterialsCache(capacity=100),
        # max_age determines how long the caching CMM will reuse materials.
        #
        # This example uses two minutes.
        # In production, always choose as small a value as possible
        # that works for your requirements.
        max_age=120.0,
        # max_messages_encrypted determines how many messages
        # the caching CMM will protect with the same materials.
        #
        # In production, always choose as small a value as possible
        # that works for your requirements.
        max_messages_encrypted=10,
    )

    # Encrypt your plaintext data.
    ciphertext, _encrypt_header = aws_encryption_sdk.encrypt(
        source=source_plaintext,
        encryption_context=encryption_context,
        materials_manager=cmm)

    # Demonstrate that the ciphertext and plaintext are different.
    assert ciphertext != source_plaintext

    # Decrypt your encrypted data using the same cryptographic materials manager you used on encrypt.
    #
    # You do not need to specify the encryption context on decrypt
    # because the header of the encrypted message includes the encryption context.
    decrypted, decrypt_header = aws_encryption_sdk.decrypt(
        source=ciphertext, materials_manager=cmm)

    # Demonstrate that the decrypted plaintext is identical to the original plaintext.
    assert decrypted == source_plaintext

    # Verify that the encryption context used in the decrypt operation includes
    # the encryption context that you specified when encrypting.
    # The AWS Encryption SDK can add pairs, so don't require an exact match.
    #
    # In production, always use a meaningful encryption context.
    assert set(encryption_context.items()) <= set(
        decrypt_header.encryption_context.items())