def test_add_master_keys_class(self, mock_client):
     """Check that the MRK-aware provider creates MRKAwareKMSMasterKeys"""
     mock_client.return_value = self.mock_boto3_client_instance
     key_id = "arn:aws:kms:eu-west-2:222222222222:key/mrk-aaaaaaaa-1111-2222-3333-bbbbbbbbbbbb"
     provider = StrictAwsKmsMasterKeyProvider(key_ids=[key_id])
     master_key = provider._new_master_key(key_id)
     assert master_key.__class__ == KMSMasterKey
def test_init_with_regionless_key_ids_and_region_names():
    key_ids = ("alias/key_1", )
    region_names = ("test-region-1", )
    provider = StrictAwsKmsMasterKeyProvider(region_names=region_names,
                                             key_ids=key_ids)
    assert provider.master_key(
        "alias/key_1").config.client.meta.region_name == region_names[0]
    def test_decrypt_failure_strict_mismatched_key_id(self):
        """Test that a Strict KMS Master Key Provider fails to decrypt an
        EDK when it has not been configured with the correct key id
        """
        cmk_arn = get_cmk_arn()
        encrypt_provider = StrictAwsKmsMasterKeyProvider(key_ids=[cmk_arn])

        ciphertext, _ = aws_encryption_sdk.EncryptionSDKClient().encrypt(
            source=VALUES["plaintext_128"],
            key_provider=encrypt_provider,
            encryption_context=VALUES["encryption_context"],
            frame_length=1024,
        )

        # Check that we can decrypt the ciphertext using the original provider
        plaintext, _ = aws_encryption_sdk.EncryptionSDKClient().decrypt(
            source=ciphertext, key_provider=encrypt_provider
        )
        assert plaintext == VALUES["plaintext_128"]

        # Check that we cannot decrypt the ciphertext using a non-discovery provider without the correct key_id
        second_cmk_arn = cmk_arn + "-doesnotexist"
        decrypt_provider = StrictAwsKmsMasterKeyProvider(key_ids=[second_cmk_arn])

        with pytest.raises(DecryptKeyError) as excinfo:
            aws_encryption_sdk.EncryptionSDKClient().decrypt(source=ciphertext, key_provider=decrypt_provider)
        excinfo.match("Unable to decrypt any data key")
コード例 #4
0
def setup_kms_master_key_provider_with_duplicate_keys(num_keys):
    """Reads the test_values config file and builds the requested KMS Master Key Provider with multiple copies of
    the requested key."""
    assert num_keys > 1
    cmk_arn = get_cmk_arn()
    provider = StrictAwsKmsMasterKeyProvider(key_ids=[cmk_arn])
    for _ in range(num_keys - 1):
        provider.add_master_key_provider(
            StrictAwsKmsMasterKeyProvider(key_ids=[cmk_arn]))
    return provider
    def test_decrypt_success_discovery_no_filter(self):
        """Test that a Discovery KMS Master Key Provider in unfiltered discovery mode can
        decrypt a valid EDK.
        """
        cmk_arn = get_cmk_arn()
        encrypt_provider = StrictAwsKmsMasterKeyProvider(key_ids=[cmk_arn])

        ciphertext, _ = aws_encryption_sdk.EncryptionSDKClient().encrypt(
            source=VALUES["plaintext_128"],
            key_provider=encrypt_provider,
            encryption_context=VALUES["encryption_context"],
            frame_length=1024,
        )

        # Check that we can decrypt the ciphertext using the original provider
        plaintext, _ = aws_encryption_sdk.EncryptionSDKClient().decrypt(
            source=ciphertext, key_provider=encrypt_provider
        )
        assert plaintext == VALUES["plaintext_128"]

        # Check that we can decrypt the ciphertext using a discovery provider with no filter
        decrypt_provider = DiscoveryAwsKmsMasterKeyProvider()

        plaintext, _ = aws_encryption_sdk.EncryptionSDKClient().decrypt(
            source=ciphertext, key_provider=decrypt_provider
        )
        assert plaintext == VALUES["plaintext_128"]
    def test_decrypt_success_discovery_filter(self):
        """Test that a Discovery KMS Master Key Provider in filtered discovery mode can
        decrypt a ciphertext when it is configured with the correct account id and partition.
        """
        cmk_arn = get_cmk_arn()
        encrypt_provider = StrictAwsKmsMasterKeyProvider(key_ids=[cmk_arn])

        ciphertext, _ = aws_encryption_sdk.EncryptionSDKClient().encrypt(
            source=VALUES["plaintext_128"],
            key_provider=encrypt_provider,
            encryption_context=VALUES["encryption_context"],
            frame_length=1024,
        )

        # Check that we can decrypt the ciphertext using the original provider
        plaintext, _ = aws_encryption_sdk.EncryptionSDKClient().decrypt(
            source=ciphertext, key_provider=encrypt_provider
        )
        assert plaintext == VALUES["plaintext_128"]

        # Check that we can decrypt the ciphertext using a discovery provider that allows this account and partition
        arn = arn_from_str(cmk_arn)
        discovery_filter = DiscoveryFilter(partition=arn.partition, account_ids=[arn.account_id])
        decrypt_provider = DiscoveryAwsKmsMasterKeyProvider(discovery_filter=discovery_filter)

        plaintext, _ = aws_encryption_sdk.EncryptionSDKClient().decrypt(
            source=ciphertext, key_provider=decrypt_provider
        )
        assert plaintext == VALUES["plaintext_128"]
 def test_init_null_key_id_fails(self):
     key_ids = (
         "arn:aws:kms:us-east-1:222222222222:key/aaaaaaaa-1111-2222-3333-bbbbbbbbbbbb",
         None)
     with pytest.raises(ConfigMismatchError) as excinfo:
         StrictAwsKmsMasterKeyProvider(key_ids=key_ids)
     excinfo.match("Key ids must be valid AWS KMS ARNs")
 def test_init_empty_key_ids_fails(self):
     # //= compliance/framework/aws-kms/aws-kms-mrk-aware-master-key-provider.txt#2.6
     # //= type=test
     # //# The key id list MUST NOT be empty or null in strict mode.
     with pytest.raises(ConfigMismatchError) as excinfo:
         StrictAwsKmsMasterKeyProvider(key_ids=[])
     excinfo.match("To enable strict mode you must provide key ids")
    def test_decrypt_failure_discovery_disallowed_partition(self):
        """Test that a KMS Master Key Provider in filtered discovery mode fails to
        decrypt an EDK if the EDK was wrapped by a KMS Master Key in an
        AWS partition that is not allowed by the filter.
        """
        cmk_arn = get_cmk_arn()
        encrypt_provider = StrictAwsKmsMasterKeyProvider(key_ids=[cmk_arn])

        ciphertext, _ = aws_encryption_sdk.EncryptionSDKClient().encrypt(
            source=VALUES["plaintext_128"],
            key_provider=encrypt_provider,
            encryption_context=VALUES["encryption_context"],
            frame_length=1024,
        )

        # Check that we can decrypt the ciphertext using the original provider
        plaintext, _ = aws_encryption_sdk.EncryptionSDKClient().decrypt(
            source=ciphertext, key_provider=encrypt_provider
        )
        assert plaintext == VALUES["plaintext_128"]

        # Check that we cannot decrypt the ciphertext using a discovery provider that does not match this key's
        # partition
        arn = arn_from_str(cmk_arn)
        discovery_filter = DiscoveryFilter(partition="aws-cn", account_ids=[arn.account_id])
        decrypt_provider = DiscoveryAwsKmsMasterKeyProvider(discovery_filter=discovery_filter)

        with pytest.raises(MasterKeyProviderError) as excinfo:
            aws_encryption_sdk.EncryptionSDKClient().decrypt(source=ciphertext, key_provider=decrypt_provider)
        excinfo.match("not allowed by this Master Key Provider")
コード例 #10
0
def arn_from_key_id(key_id):
    # type: (str) -> str
    """Determine the KMS CMK Arn for the identified key ID.

    To avoid needing additional KMS permissions, we just call ``generate_data_key``
    using a master key identified by ``key_id``.

    :param str key_id: Original key ID
    :returns: Full Arn for KMS CMK that key ID identifies
    :rtype: str
    """
    provider = StrictAwsKmsMasterKeyProvider(key_ids=[key_id])
    encrypted_data_key = provider.master_key(key_id.encode(ENCODING)).generate_data_key(
        algorithm=AlgorithmSuite.AES_256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384, encryption_context={}
    )
    return encrypted_data_key.key_provider.key_info.decode(ENCODING)
 def test_init_with_key_ids(self, mock_add_keys):
     key_ids = (
         "arn:aws:kms:us-east-1:222222222222:key/aaaaaaaa-1111-2222-3333-bbbbbbbbbbbb",
         "arn:aws:kms:us-east-1:333333333333:key/aaaaaaaa-1111-2222-3333-bbbbbbbbbbbb",
     )
     test = StrictAwsKmsMasterKeyProvider(key_ids=key_ids)
     assert not test.vend_masterkey_on_decrypt
     mock_add_keys.assert_called_once_with(key_ids)
 def test_init_empty_string_key_id_fails(self):
     # //= compliance/framework/aws-kms/aws-kms-mrk-aware-master-key-provider.txt#2.6
     # //= type=test
     # //# The key id list MUST NOT contain any null or empty string values.
     key_ids = (
         "arn:aws:kms:us-east-1:222222222222:key/aaaaaaaa-1111-2222-3333-bbbbbbbbbbbb",
         "")
     with pytest.raises(ConfigMismatchError) as excinfo:
         StrictAwsKmsMasterKeyProvider(key_ids=key_ids)
     excinfo.match("Key ids must be valid AWS KMS ARNs")
コード例 #13
0
def setup_kms_master_key_provider(cache=True):
    """Reads the test_values config file and builds the requested KMS Master Key Provider."""
    global _KMS_MKP  # pylint: disable=global-statement
    if cache and _KMS_MKP is not None:
        return _KMS_MKP

    cmk_arn = get_cmk_arn()
    kms_master_key_provider = StrictAwsKmsMasterKeyProvider(key_ids=[cmk_arn])

    if cache:
        _KMS_MKP = kms_master_key_provider

    return kms_master_key_provider
 def test_init_with_discovery_fails(self, mock_add_keys):
     key_ids = (
         "arn:aws:kms:us-east-1:222222222222:key/aaaaaaaa-1111-2222-3333-bbbbbbbbbbbb",
         "arn:aws:kms:us-east-1:333333333333:key/aaaaaaaa-1111-2222-3333-bbbbbbbbbbbb",
     )
     discovery_filter = DiscoveryFilter(account_ids=["1234"],
                                        partition="aws")
     with pytest.raises(ConfigMismatchError) as excinfo:
         StrictAwsKmsMasterKeyProvider(key_ids=key_ids,
                                       discovery_filter=discovery_filter)
     excinfo.match(
         "To enable discovery mode, use a DiscoveryAwsKmsMasterKeyProvider")
     mock_add_keys.assert_not_called()
コード例 #15
0
def kms_master_key_provider(cache: Optional[bool] = True):
    """Build the expected KMS Master Key Provider based on environment variables."""
    global _KMS_MKP  # pylint: disable=global-statement

    if cache and _KMS_MKP is not None:
        return _KMS_MKP

    cmk_arn = get_cmk_arn()
    _kms_master_key_provider = StrictAwsKmsMasterKeyProvider(key_ids=[cmk_arn])

    if cache:
        _KMS_MKP = _kms_master_key_provider

    return _kms_master_key_provider
 def test_init_with_key_ids(self, mock_add_keys):
     key_ids = (
         "arn:aws:kms:us-east-1:222222222222:key/aaaaaaaa-1111-2222-3333-bbbbbbbbbbbb",
         "arn:aws:kms:us-east-1:333333333333:key/aaaaaaaa-1111-2222-3333-bbbbbbbbbbbb",
     )
     test = StrictAwsKmsMasterKeyProvider(key_ids=key_ids)
     # //= compliance/framework/aws-kms/aws-kms-mrk-aware-master-key-provider.txt#2.8
     # //= type=test
     # //# If the configured mode is strict this function MUST return a
     # //# list of master keys obtained by calling Get Master Key (aws-kms-mrk-
     # //# aware-master-key-provider.md#get-master-key) for each AWS KMS key
     # //# identifier in the configured key ids
     assert not test.vend_masterkey_on_decrypt
     mock_add_keys.assert_called_once_with(key_ids)
コード例 #17
0
def setup_kms_master_key_provider_with_botocore_session(cache=True):
    """Reads the test_values config file and builds the requested KMS Master Key Provider with botocore_session."""
    global _KMS_MKP_BOTO  # pylint: disable=global-statement
    if cache and _KMS_MKP_BOTO is not None:
        return _KMS_MKP_BOTO

    cmk_arn = get_cmk_arn()
    kms_master_key_provider = StrictAwsKmsMasterKeyProvider(
        key_ids=[cmk_arn], botocore_session=botocore.session.Session())

    if cache:
        _KMS_MKP_BOTO = kms_master_key_provider

    return kms_master_key_provider
 def test_init_with_discovery_region_fails(self, mock_add_keys):
     # //= compliance/framework/aws-kms/aws-kms-mrk-aware-master-key-provider.txt#2.6
     # //= type=test
     # //# A default MRK Region MUST NOT be configured in strict mode.
     key_ids = (
         "arn:aws:kms:us-east-1:222222222222:key/aaaaaaaa-1111-2222-3333-bbbbbbbbbbbb",
         "arn:aws:kms:us-east-1:333333333333:key/aaaaaaaa-1111-2222-3333-bbbbbbbbbbbb",
     )
     with pytest.raises(ConfigMismatchError) as excinfo:
         StrictAwsKmsMasterKeyProvider(key_ids=key_ids,
                                       discovery_region="us-east-1")
     excinfo.match(
         "To enable MRK-aware discovery mode, use a MRKAwareDiscoveryAwsKmsMasterKeyProvider"
     )
     mock_add_keys.assert_not_called()
    def test_encrypt_failure_unknown_cmk(self):
        """Test that a Master Key Provider returns the correct error when one of the
        keys with which it was configured is unable to encrypt
        """
        cmk_arn = get_cmk_arn()
        second_cmk_arn = cmk_arn + "-doesnotexist"
        provider = StrictAwsKmsMasterKeyProvider(key_ids=[cmk_arn, second_cmk_arn])

        with pytest.raises(EncryptKeyError) as excinfo:
            aws_encryption_sdk.EncryptionSDKClient().encrypt(
                source=VALUES["plaintext_128"],
                key_provider=provider,
                encryption_context=VALUES["encryption_context"],
                frame_length=1024,
            )
        excinfo.match("Master Key {key_id} unable to encrypt".format(key_id=second_cmk_arn))
 def test_init_with_discovery_fails(self, mock_add_keys):
     # //= compliance/framework/aws-kms/aws-kms-mrk-aware-master-key-provider.txt#2.6
     # //= type=test
     # //# A discovery filter MUST NOT be configured in strict mode.
     key_ids = (
         "arn:aws:kms:us-east-1:222222222222:key/aaaaaaaa-1111-2222-3333-bbbbbbbbbbbb",
         "arn:aws:kms:us-east-1:333333333333:key/aaaaaaaa-1111-2222-3333-bbbbbbbbbbbb",
     )
     discovery_filter = DiscoveryFilter(account_ids=["1234"],
                                        partition="aws")
     with pytest.raises(ConfigMismatchError) as excinfo:
         StrictAwsKmsMasterKeyProvider(key_ids=key_ids,
                                       discovery_filter=discovery_filter)
     excinfo.match(
         "To enable discovery mode, use a DiscoveryAwsKmsMasterKeyProvider")
     mock_add_keys.assert_not_called()
    def test_decrypt_success_strict_matching_key_id(self):
        """Test that a Strict KMS Master Key Provider can successfully
        decrypt an EDK when it has been configured with the correct key id
        """
        cmk_arn = get_cmk_arn()
        provider = StrictAwsKmsMasterKeyProvider(key_ids=[cmk_arn])
        ciphertext, _ = aws_encryption_sdk.EncryptionSDKClient().encrypt(
            source=VALUES["plaintext_128"],
            key_provider=provider,
            encryption_context=VALUES["encryption_context"],
            frame_length=1024,
        )

        plaintext, _ = aws_encryption_sdk.EncryptionSDKClient().decrypt(
            source=ciphertext, key_provider=self.kms_master_key_provider
        )
        assert plaintext == VALUES["plaintext_128"]
 def test_init_bare_fails(self):
     with pytest.raises(ConfigMismatchError) as excinfo:
         StrictAwsKmsMasterKeyProvider()
     excinfo.match("To enable strict mode you must provide key ids")