def __attrs_post_init__(self):
        """Configure internal keyring."""
        key_ids_provided = self._generator_key_id is not None or self._key_ids
        both = key_ids_provided and self._is_discovery
        neither = not key_ids_provided and not self._is_discovery

        if both:
            raise TypeError("is_discovery cannot be True if key IDs are provided")

        if neither:
            raise TypeError("is_discovery cannot be False if no key IDs are provided")

        if self._is_discovery:
            self._inner_keyring = _AwsKmsDiscoveryKeyring(
                client_supplier=self._client_supplier, grant_tokens=self._grant_tokens
            )
            return

        if self._generator_key_id is None:
            generator_keyring = None
        else:
            generator_keyring = _AwsKmsSingleCmkKeyring(
                key_id=self._generator_key_id, client_supplier=self._client_supplier, grant_tokens=self._grant_tokens
            )

        child_keyrings = [
            _AwsKmsSingleCmkKeyring(
                key_id=key_id, client_supplier=self._client_supplier, grant_tokens=self._grant_tokens
            )
            for key_id in self._key_ids
        ]

        self._inner_keyring = MultiKeyring(generator=generator_keyring, children=child_keyrings)
Example #2
0
def test_identity_keyring_as_generator_and_no_data_encryption_key(
        identity_keyring):
    test_multi_keyring = MultiKeyring(generator=identity_keyring)
    with pytest.raises(GenerateKeyError) as exc_info:
        test_multi_keyring.on_encrypt(
            encryption_materials=get_encryption_materials_without_data_key())
    assert exc_info.match("Unable to generate data encryption key.")
Example #3
0
def test_on_encrypt_edk_length_when_keyring_generates_but_does_not_encrypt_encryption_materials_with_data_key(
):
    test_multi_keyring = MultiKeyring(generator=OnlyGenerateKeyring())
    test = test_multi_keyring.on_encrypt(
        encryption_materials=get_encryption_materials_with_encrypted_data_key(
        ))
    assert len(test.encrypted_data_keys) == len(
        get_encryption_materials_with_encrypted_data_key().encrypted_data_keys)
Example #4
0
def test_on_encrypt_when_data_encryption_key_given(mock_generator,
                                                   mock_child_1, mock_child_2):
    test_multi_keyring = MultiKeyring(generator=mock_generator,
                                      children=[mock_child_1, mock_child_2])
    initial_materials = get_encryption_materials_with_data_key()
    new_materials = test_multi_keyring.on_encrypt(
        encryption_materials=initial_materials)

    assert new_materials is not initial_materials

    for keyring in test_multi_keyring._decryption_keyrings:
        keyring.on_encrypt.assert_called_once()
Example #5
0
def test_on_decrypt_when_data_encryption_key_given(mock_generator,
                                                   mock_child_1, mock_child_2):
    test_multi_keyring = MultiKeyring(generator=mock_generator,
                                      children=[mock_child_1, mock_child_2])
    initial_materials = get_decryption_materials_with_data_key()
    new_materials = test_multi_keyring.on_decrypt(
        decryption_materials=initial_materials, encrypted_data_keys=[])

    assert new_materials is initial_materials

    for keyring in test_multi_keyring._decryption_keyrings:
        assert not keyring.on_decrypt.called
def get_multi_keyring_with_generator_and_children():
    private_key = rsa.generate_private_key(public_exponent=65537,
                                           key_size=2048,
                                           backend=default_backend())
    return MultiKeyring(
        generator=RawAESKeyring(
            key_namespace=_PROVIDER_ID,
            key_name=_KEY_ID,
            wrapping_key=_WRAPPING_KEY_AES,
        ),
        children=[
            RawRSAKeyring(
                key_namespace=_PROVIDER_ID,
                key_name=_KEY_ID,
                wrapping_algorithm=WrappingAlgorithm.RSA_OAEP_SHA256_MGF1,
                private_wrapping_key=private_key,
                public_wrapping_key=private_key.public_key(),
            ),
            RawRSAKeyring(
                key_namespace=_PROVIDER_ID,
                key_name=_KEY_ID,
                wrapping_algorithm=WrappingAlgorithm.RSA_OAEP_SHA256_MGF1,
                private_wrapping_key=private_key,
                public_wrapping_key=private_key.public_key(),
            ),
        ],
    )
Example #7
0
def get_multi_keyring_with_no_children():
    return MultiKeyring(generator=RawRSAKeyring(
        key_namespace=_PROVIDER_ID,
        key_name=_KEY_ID,
        wrapping_algorithm=WrappingAlgorithm.RSA_OAEP_SHA256_MGF1,
        private_wrapping_key=rsa.generate_private_key(
            public_exponent=65537, key_size=2048, backend=default_backend()),
    ))
Example #8
0
def test_on_decrypt_every_keyring_called_when_data_encryption_key_not_added(
        mock_generator, mock_child_1, mock_child_2):
    mock_generator.on_decrypt.side_effect = (
        lambda decryption_materials, encrypted_data_keys:
        get_decryption_materials_without_data_key())
    mock_child_1.on_decrypt.return_value = get_decryption_materials_without_data_key(
    )
    mock_child_2.on_decrypt.return_value = get_decryption_materials_without_data_key(
    )

    test_multi_keyring = MultiKeyring(generator=mock_generator,
                                      children=[mock_child_1, mock_child_2])
    test_multi_keyring.on_decrypt(
        decryption_materials=get_decryption_materials_without_data_key(),
        encrypted_data_keys=[])

    for keyring in test_multi_keyring._decryption_keyrings:
        assert keyring.on_decrypt.called
Example #9
0
def test_keyring_with_generator_but_no_children():
    generator_keyring = RawAESKeyring(
        key_namespace=_PROVIDER_ID,
        key_name=_KEY_ID,
        wrapping_key=_WRAPPING_KEY_AES,
    )
    test_multi_keyring = MultiKeyring(generator=generator_keyring)
    assert test_multi_keyring.generator is generator_keyring
    assert not test_multi_keyring.children
Example #10
0
def test_no_keyring_called_after_data_encryption_key_added_when_data_encryption_key_not_given(
        mock_generator, mock_child_1, mock_child_2, mock_child_3):

    mock_generator.on_decrypt.side_effect = (
        lambda decryption_materials, encrypted_data_keys:
        get_decryption_materials_without_data_key())

    test_multi_keyring = MultiKeyring(
        generator=mock_generator,
        children=[mock_child_3, mock_child_1, mock_child_2])
    initial_materials = get_decryption_materials_without_data_key()
    new_materials = test_multi_keyring.on_decrypt(
        decryption_materials=initial_materials, encrypted_data_keys=[])

    assert new_materials is not initial_materials
    assert mock_generator.on_decrypt.called
    assert mock_child_3.on_decrypt.called
    assert not mock_child_1.called
    assert not mock_child_2.called
Example #11
0
def test_keyring_with_children_but_no_generator():
    children_keyring = [
        RawAESKeyring(
            key_namespace=_PROVIDER_ID,
            key_name=_KEY_ID,
            wrapping_key=_WRAPPING_KEY_AES,
        )
    ]
    test_multi_keyring = MultiKeyring(children=children_keyring)
    assert test_multi_keyring.children is children_keyring
    assert test_multi_keyring.generator is None
Example #12
0
def run(aws_kms_cmk, aws_kms_additional_cmks, source_plaintext):
    # type: (str, Sequence[str], bytes) -> None
    """Demonstrate how to create a keyring that behaves like an AWS KMS master key provider.

    :param str aws_kms_cmk: The ARN of an AWS KMS CMK that protects data keys
    :param List[str] aws_kms_additional_cmks: Additional ARNs of secondary AWS KMS CMKs
    :param bytes source_plaintext: Plaintext to encrypt
    """
    # Prepare your encryption context.
    # 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",
    }

    # This is the master key provider whose behavior we want to reproduce.
    #
    # When encrypting, this master key provider generates the data key using the first CMK in the list
    # and encrypts the data key using all specified CMKs.
    # However, when decrypting, this master key provider attempts to decrypt
    # any data keys that were encrypted under an AWS KMS CMK.
    master_key_provider_cmks = [aws_kms_cmk] + aws_kms_additional_cmks
    _master_key_provider_to_replicate = KMSMasterKeyProvider(  # noqa: intentionally never used
        key_ids=master_key_provider_cmks, )

    # Create a CMK keyring that encrypts and decrypts using the specified AWS KMS CMKs.
    #
    # This keyring reproduces the encryption behavior of the AWS KMS master key provider.
    #
    # The AWS KMS keyring requires that you explicitly identify the CMK
    # that you want the keyring to use to generate the data key.
    cmk_keyring = AwsKmsKeyring(generator_key_id=aws_kms_cmk,
                                key_ids=aws_kms_additional_cmks)

    # Create an AWS KMS discovery keyring that will attempt to decrypt
    # any data keys that were encrypted under an AWS KMS CMK.
    discovery_keyring = AwsKmsKeyring(is_discovery=True)

    # Combine the CMK and discovery keyrings
    # to create a keyring that behaves like an AWS KMS master key provider.
    #
    # The CMK keyring reproduces the encryption behavior
    # and the discovery keyring reproduces the decryption behavior.
    # This also means that it does not matter if the CMK keyring fails to decrypt.
    # For example, if you configured the CMK keyring with aliases,
    # it works on encrypt but fails to match any encrypted data keys on decrypt
    # because the serialized key name is the resulting CMK ARN rather than the alias name.
    # However, because the discovery keyring attempts to decrypt any AWS KMS-encrypted
    # data keys that it finds, the message still decrypts successfully.
    keyring = MultiKeyring(generator=cmk_keyring, children=[discovery_keyring])

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

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

    # Decrypt your encrypted data using the same keyring 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,
                                                           keyring=keyring)

    # 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())
def run(aws_kms_cmk, source_plaintext):
    # type: (str, bytes) -> None
    """Demonstrate configuring a keyring to use an AWS KMS CMK and an RSA wrapping key.

    :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.
    # 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",
    }

    # Generate an RSA private key to use with your keyring.
    # In practice, you should get this key from a secure key management system such as an HSM.
    #
    # The National Institute of Standards and Technology (NIST) recommends a minimum of 2048-bit keys for RSA.
    # https://www.nist.gov/publications/transitioning-use-cryptographic-algorithms-and-key-lengths
    #
    # Why did we use this public exponent?
    # https://crypto.stanford.edu/~dabo/pubs/papers/RSA-survey.pdf
    private_key = rsa.generate_private_key(public_exponent=65537,
                                           key_size=4096,
                                           backend=default_backend())

    # Collect the public key from the private key.
    public_key = private_key.public_key()

    # Create the encrypt keyring that only has access to the public key.
    escrow_encrypt_keyring = RawRSAKeyring(
        # The key namespace and key name are defined by you
        # and are used by the raw RSA keyring
        # to determine whether it should attempt to decrypt
        # an encrypted data key.
        #
        # https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/choose-keyring.html#use-raw-rsa-keyring
        key_namespace="some managed raw keys",
        key_name=b"my RSA wrapping key",
        public_wrapping_key=public_key,
        # The wrapping algorithm tells the raw RSA keyring
        # how to use your wrapping key to encrypt data keys.
        #
        # We recommend using RSA_OAEP_SHA256_MGF1.
        # You should not use RSA_PKCS1 unless you require it for backwards compatibility.
        wrapping_algorithm=WrappingAlgorithm.RSA_OAEP_SHA256_MGF1,
    )

    # Create the decrypt keyring that has access to the private key.
    escrow_decrypt_keyring = RawRSAKeyring(
        # The key namespace and key name MUST match the encrypt keyring.
        key_namespace="some managed raw keys",
        key_name=b"my RSA wrapping key",
        private_wrapping_key=private_key,
        # The wrapping algorithm MUST match the encrypt keyring.
        wrapping_algorithm=WrappingAlgorithm.RSA_OAEP_SHA256_MGF1,
    )

    # Create the AWS KMS keyring that you will use for decryption during normal operations.
    kms_keyring = AwsKmsKeyring(generator_key_id=aws_kms_cmk)

    # Combine the AWS KMS keyring and the escrow encrypt keyring using the multi-keyring.
    encrypt_keyring = MultiKeyring(generator=kms_keyring,
                                   children=[escrow_encrypt_keyring])

    # Encrypt your plaintext data using the multi-keyring.
    ciphertext, encrypt_header = aws_encryption_sdk.encrypt(
        source=source_plaintext,
        encryption_context=encryption_context,
        keyring=encrypt_keyring)

    # Verify that the header contains the expected number of encrypted data keys (EDKs).
    # It should contain one EDK for AWS KMS and one for the escrow key.
    assert len(encrypt_header.encrypted_data_keys) == 2

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

    # Decrypt your encrypted data separately using the AWS KMS keyring and the escrow decrypt keyring.
    #
    # You do not need to specify the encryption context on decrypt
    # because the header of the encrypted message includes the encryption context.
    decrypted_kms, decrypt_header_kms = aws_encryption_sdk.decrypt(
        source=ciphertext, keyring=kms_keyring)
    decrypted_escrow, decrypt_header_escrow = aws_encryption_sdk.decrypt(
        source=ciphertext, keyring=escrow_decrypt_keyring)

    # Demonstrate that the decrypted plaintext is identical to the original plaintext.
    assert decrypted_kms == source_plaintext
    assert decrypted_escrow == 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_kms.encryption_context.items())
    assert set(encryption_context.items()) <= set(
        decrypt_header_escrow.encryption_context.items())
Example #14
0
def run(aws_kms_cmk, source_plaintext):
    # type: (str, bytes) -> None
    """Demonstrate configuring an AWS KMS discovery-like keyring a particular AWS region and failover to others.

    :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.
    encrypt_keyring = AwsKmsKeyring(generator_key_id=aws_kms_cmk)

    # To create our decrypt keyring, we need to know our current default AWS region.
    #
    # Create a throw-away boto3 session to discover the default region.
    local_region = Session().region_name

    # Now, use that region name to create two AWS KMS discovery keyrings:
    #
    # One that only works in the local region
    local_region_decrypt_keyring = AwsKmsKeyring(
        is_discovery=True, client_supplier=AllowRegionsClientSupplier(allowed_regions=[local_region])
    )
    # and one that will work in any other region but NOT the local region.
    other_regions_decrypt_keyring = AwsKmsKeyring(
        is_discovery=True, client_supplier=DenyRegionsClientSupplier(denied_regions=[local_region])
    )

    # Finally, combine those two keyrings into a multi-keyring.
    #
    # The multi-keyring steps through its member keyrings in the order that you provide them,
    # attempting to decrypt every encrypted data key with each keyring before moving on to the next keyring.
    # Because of this, other_regions_decrypt_keyring will not be called
    # unless local_region_decrypt_keyring fails to decrypt every encrypted data key.
    decrypt_keyring = MultiKeyring(children=[local_region_decrypt_keyring, other_regions_decrypt_keyring])

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

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

    # Decrypt your encrypted data using the multi-keyring.
    #
    # 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, keyring=decrypt_keyring)

    # 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())
class AwsKmsKeyring(Keyring):
    """Keyring that uses AWS Key Management Service (KMS) Customer Master Keys (CMKs) to manage wrapping keys.

    Set ``generator_key_id`` to require that the keyring use that CMK to generate the data key.
    If you do not set ``generator_key_id``, the keyring will not generate a data key.

    Set ``key_ids`` to specify additional CMKs that the keyring will use to encrypt the data key.

    The keyring will attempt to use any CMKs
    identified by CMK ARN in either ``generator_key_id`` or ``key_ids`` on decrypt.

    You can identify CMKs by any `valid key ID`_ for the keyring to use on encrypt,
    but for the keyring to attempt to use them on decrypt
    you MUST specify the CMK ARN.

    If you specify ``is_discovery=True`` the keyring will be a KMS discovery keyring,
    doing nothing on encrypt and attempting to decrypt any AWS KMS-encrypted data key on decrypt.

    .. note::

        You must either set ``is_discovery=True`` or provide key IDs.

    You can use the :class:`ClientSupplier` to customize behavior further,
    such as to provide different credentials for different regions
    or to restrict which regions are allowed.

    See the `AWS KMS Keyring specification`_ for more details.

    .. _AWS KMS Keyring specification:
       https://github.com/awslabs/aws-encryption-sdk-specification/blob/master/framework/kms-keyring.md
    .. _valid key ID:
       https://docs.aws.amazon.com/kms/latest/APIReference/API_GenerateDataKey.html#API_GenerateDataKey_RequestSyntax
    .. _discovery mode:
       https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/choose-keyring.html#kms-keyring-discovery

    .. versionadded:: 1.5.0

    :param ClientSupplier client_supplier: Client supplier that provides AWS KMS clients (optional)
    :param bool is_discovery: Should this be a discovery keyring (optional)
    :param str generator_key_id: Key ID of AWS KMS CMK to use when generating data keys (optional)
    :param List[str] key_ids: Key IDs that will be used to encrypt and decrypt data keys (optional)
    :param List[str] grant_tokens: AWS KMS grant tokens to include in requests (optional)
    """

    _client_supplier = attr.ib(default=attr.Factory(DefaultClientSupplier), validator=is_callable())
    _is_discovery = attr.ib(default=False, validator=instance_of(bool))
    _generator_key_id = attr.ib(default=None, validator=optional(instance_of(six.string_types)))
    _key_ids = attr.ib(
        default=attr.Factory(tuple),
        validator=(deep_iterable(member_validator=instance_of(six.string_types)), value_is_not_a_string),
    )
    _grant_tokens = attr.ib(
        default=attr.Factory(tuple),
        validator=(deep_iterable(member_validator=instance_of(six.string_types)), value_is_not_a_string),
    )

    def __attrs_post_init__(self):
        """Configure internal keyring."""
        key_ids_provided = self._generator_key_id is not None or self._key_ids
        both = key_ids_provided and self._is_discovery
        neither = not key_ids_provided and not self._is_discovery

        if both:
            raise TypeError("is_discovery cannot be True if key IDs are provided")

        if neither:
            raise TypeError("is_discovery cannot be False if no key IDs are provided")

        if self._is_discovery:
            self._inner_keyring = _AwsKmsDiscoveryKeyring(
                client_supplier=self._client_supplier, grant_tokens=self._grant_tokens
            )
            return

        if self._generator_key_id is None:
            generator_keyring = None
        else:
            generator_keyring = _AwsKmsSingleCmkKeyring(
                key_id=self._generator_key_id, client_supplier=self._client_supplier, grant_tokens=self._grant_tokens
            )

        child_keyrings = [
            _AwsKmsSingleCmkKeyring(
                key_id=key_id, client_supplier=self._client_supplier, grant_tokens=self._grant_tokens
            )
            for key_id in self._key_ids
        ]

        self._inner_keyring = MultiKeyring(generator=generator_keyring, children=child_keyrings)

    def on_encrypt(self, encryption_materials):
        # type: (EncryptionMaterials) -> EncryptionMaterials
        """Generate a data key using generator keyring
        and encrypt it using any available wrapping key in any child keyring.

        :param EncryptionMaterials encryption_materials: Encryption materials for keyring to modify.
        :returns: Optionally modified encryption materials.
        :rtype: EncryptionMaterials
        :raises EncryptKeyError: if unable to encrypt data key.
        """
        return self._inner_keyring.on_encrypt(encryption_materials=encryption_materials)

    def on_decrypt(self, decryption_materials, encrypted_data_keys):
        # type: (DecryptionMaterials, Iterable[EncryptedDataKey]) -> DecryptionMaterials
        """Attempt to decrypt the encrypted data keys.

        :param DecryptionMaterials decryption_materials: Decryption materials for keyring to modify.
        :param List[EncryptedDataKey] encrypted_data_keys: List of encrypted data keys.
        :returns: Optionally modified decryption materials.
        :rtype: DecryptionMaterials
        """
        return self._inner_keyring.on_decrypt(
            decryption_materials=decryption_materials, encrypted_data_keys=encrypted_data_keys
        )
Example #16
0
                                              backend=default_backend())
_rsa_private_key_b = rsa.generate_private_key(public_exponent=65537,
                                              key_size=2048,
                                              backend=default_backend())
_MULTI_KEYRING_WITH_GENERATOR_AND_CHILDREN = MultiKeyring(
    generator=RawAESKeyring(
        key_namespace=_PROVIDER_ID,
        key_name=_KEY_ID,
        wrapping_key=_WRAPPING_KEY_AES,
    ),
    children=[
        RawRSAKeyring(
            key_namespace=_PROVIDER_ID,
            key_name=_KEY_ID,
            wrapping_algorithm=WrappingAlgorithm.RSA_OAEP_SHA256_MGF1,
            private_wrapping_key=_rsa_private_key_a,
            public_wrapping_key=_rsa_private_key_a.public_key(),
        ),
        RawRSAKeyring(
            key_namespace=_PROVIDER_ID,
            key_name=_KEY_ID,
            wrapping_algorithm=WrappingAlgorithm.RSA_OAEP_SHA256_MGF1,
            private_wrapping_key=_rsa_private_key_b,
            public_wrapping_key=_rsa_private_key_b.public_key(),
        ),
    ],
)

_MULTI_KEYRING_WITHOUT_CHILDREN = MultiKeyring(generator=RawRSAKeyring(
    key_namespace=_PROVIDER_ID,
    key_name=_KEY_ID,
Example #17
0
)

_MULTI_KEYRING_WITH_GENERATOR_AND_CHILDREN = MultiKeyring(
    generator=RawAESKeyring(
        key_namespace=_PROVIDER_ID,
        key_name=_KEY_ID,
        wrapping_key=_WRAPPING_KEY_AES,
    ),
    children=[
        RawRSAKeyring(
            key_namespace=_PROVIDER_ID,
            key_name=_KEY_ID,
            wrapping_algorithm=WrappingAlgorithm.RSA_OAEP_SHA256_MGF1,
            private_wrapping_key=rsa.generate_private_key(
                public_exponent=65537,
                key_size=2048,
                backend=default_backend()),
        ),
        RawRSAKeyring(
            key_namespace=_PROVIDER_ID,
            key_name=_KEY_ID,
            wrapping_algorithm=WrappingAlgorithm.RSA_OAEP_SHA256_MGF1,
            private_wrapping_key=rsa.generate_private_key(
                public_exponent=65537,
                key_size=2048,
                backend=default_backend()),
        ),
    ],
)

_MULTI_KEYRING_WITHOUT_CHILDREN = MultiKeyring(generator=RawRSAKeyring(
Example #18
0
def test_keyring_with_no_generator_no_children():
    with pytest.raises(TypeError) as exc_info:
        MultiKeyring()
    assert exc_info.match(
        "At least one of generator or children must be provided")
Example #19
0
def test_keyring_with_invalid_parameters(generator, children):
    with pytest.raises(TypeError) as exc_info:
        MultiKeyring(generator=generator, children=children)
    assert exc_info.match(
        "('children'|'generator') must be <class 'aws_encryption_sdk.keyrings.base.Keyring'>.*"
    )