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")
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_bare(self): test = DiscoveryAwsKmsMasterKeyProvider() # //= compliance/framework/aws-kms/aws-kms-mrk-aware-master-key-provider.txt#2.8 # //= type=test # //# If the configured mode is discovery the function MUST return an empty # //# list. assert test.vend_masterkey_on_decrypt
def test_init_failure_with_key_ids(self): with pytest.raises(ConfigMismatchError) as excinfo: DiscoveryAwsKmsMasterKeyProvider(discovery_filter=DiscoveryFilter( account_ids=["123"], partition="aws"), key_ids=["1234"]) excinfo.match( "To explicitly identify which keys should be used, use a StrictAwsKmsMasterKeyProvider." )
def test_init_success(self): discovery_filter = DiscoveryFilter(account_ids=["1234"], partition="aws") test = DiscoveryAwsKmsMasterKeyProvider( discovery_filter=discovery_filter) assert test.vend_masterkey_on_decrypt assert test.config.discovery_filter == discovery_filter
def test_init_failure_with_key_ids(self): # //= compliance/framework/aws-kms/aws-kms-mrk-aware-master-key-provider.txt#2.6 # //= type=test # //# The key id list MUST be empty in discovery mode. with pytest.raises(ConfigMismatchError) as excinfo: DiscoveryAwsKmsMasterKeyProvider(discovery_filter=DiscoveryFilter( account_ids=["123"], partition="aws"), key_ids=["1234"]) excinfo.match( "To explicitly identify which keys should be used, use a StrictAwsKmsMasterKeyProvider." )
def test_encrypt_failure_discovery_provider(self): """Test that a Discovery Master Key Provider cannot encrypt""" provider = DiscoveryAwsKmsMasterKeyProvider() with pytest.raises(MasterKeyProviderError) as excinfo: aws_encryption_sdk.EncryptionSDKClient().encrypt( source=VALUES["plaintext_128"], key_provider=provider, encryption_context=VALUES["encryption_context"], frame_length=1024, ) excinfo.match("No Master Keys available from Master Key Provider")
def test_kat(info): """Tests known answer tests""" client = aws_encryption_sdk.EncryptionSDKClient() provider = None if info["keyring-type"] == "static": key_bytes = b"\00" * 32 provider = StaticRawMasterKeyProvider( wrapping_algorithm=WrappingAlgorithm. AES_256_GCM_IV12_TAG16_NO_PADDING, encryption_key_type=EncryptionKeyType.SYMMETRIC, key_bytes=key_bytes, ) provider.add_master_key("KeyId") else: provider = DiscoveryAwsKmsMasterKeyProvider() ciphertext = base64.b64decode(info["ciphertext"]) if info["exception"]: with pytest.raises(MasterKeyProviderError) as excinfo: client.decrypt(source=ciphertext, key_provider=provider) expected_error = "Key commitment validation failed" excinfo.match(expected_error) else: plaintext, header = client.decrypt(source=ciphertext, key_provider=provider) # Only supporting single frame messages for now if sys.version_info[0] == 3: expected_plaintext = bytes("".join(info["plaintext-frames"]), "utf-8") else: expected_plaintext = bytes( str("".join(info["plaintext-frames"]).encode("utf-8"))) assert expected_plaintext == plaintext expected_commitment = base64.b64decode(info["commitment"]) assert expected_commitment == header.commitment_key expected_message_id = base64.b64decode(info["message-id"]) assert expected_message_id == header.message_id expected_encryption_context = info["encryption-context"] assert expected_encryption_context == header.encryption_context
def fake_kms_key_provider(keysize=32): mock_kms_key_provider = DiscoveryAwsKmsMasterKeyProvider() mock_kms_key_provider._regional_clients["us-east-1"] = fake_kms_client( keysize) mock_kms_key_provider.add_master_key(VALUES["arn"]) return mock_kms_key_provider
def test_init_failure_with_discovery_region(self): with pytest.raises(ConfigMismatchError) as excinfo: DiscoveryAwsKmsMasterKeyProvider(discovery_region="us-west-2") excinfo.match( "To enable MRK-aware discovery mode, use a MRKAwareDiscoveryAwsKmsMasterKeyProvider." )
def test_init_failure_discovery_filter_empty_partition(self): with pytest.raises(ConfigMismatchError) as excinfo: DiscoveryAwsKmsMasterKeyProvider(discovery_filter=DiscoveryFilter( account_ids=["123"], partition="")) excinfo.match("you must include both account ids and partition")
def test_init_failure_discovery_filter_empty_account_id_string(self): with pytest.raises(ConfigMismatchError) as excinfo: DiscoveryAwsKmsMasterKeyProvider(discovery_filter=DiscoveryFilter( account_ids=["123456789012", ""], partition="aws")) excinfo.match("account ids must be non-empty strings")
def test_init_failure_discovery_filter_missing_account_ids(self): with pytest.raises(ConfigMismatchError) as excinfo: DiscoveryAwsKmsMasterKeyProvider(discovery_filter=DiscoveryFilter( partition="aws")) excinfo.match("you must include both account ids and partition")
# language governing permissions and limitations under the License. """Helper utilities for interacting with AWS KMS.""" try: from aws_encryption_sdk.identifiers import AlgorithmSuite except ImportError: from aws_encryption_sdk.identifiers import Algorithm as AlgorithmSuite from aws_encryption_sdk.key_providers.kms import ( DiscoveryAwsKmsMasterKeyProvider, MRKAwareDiscoveryAwsKmsMasterKeyProvider, StrictAwsKmsMasterKeyProvider, ) from awses_test_vectors.internal.defaults import ENCODING # This lets us easily use a single boto3 client per region for all KMS master keys. KMS_MASTER_KEY_PROVIDER = DiscoveryAwsKmsMasterKeyProvider() KMS_MRK_AWARE_MASTER_KEY_PROVIDER = MRKAwareDiscoveryAwsKmsMasterKeyProvider( discovery_region="us-west-2") 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 """
def _master_key_provider() -> DiscoveryAwsKmsMasterKeyProvider: """Build the V0 master key provider.""" master_key_provider = DiscoveryAwsKmsMasterKeyProvider() master_key_provider.add_master_key_provider(NullMasterKey()) master_key_provider.add_master_key_provider(CountingMasterKey()) return master_key_provider
def test_init_bare(self): test = DiscoveryAwsKmsMasterKeyProvider() assert test.vend_masterkey_on_decrypt