From 86f4332684bce94967c40fa2433d991328428ebd Mon Sep 17 00:00:00 2001 From: Lucas McDonald Date: Mon, 20 May 2024 11:30:05 -0700 Subject: [PATCH 01/16] mplv2 --- examples/src/aws_kms_discovery_keyring_example.py | 4 ---- examples/src/aws_kms_discovery_multi_keyring_example.py | 4 ---- examples/src/aws_kms_keyring_example.py | 4 ---- examples/src/aws_kms_mrk_discovery_keyring_example.py | 4 ---- examples/src/aws_kms_mrk_discovery_multi_keyring_example.py | 4 ---- examples/src/aws_kms_mrk_keyring_example.py | 4 ---- examples/src/aws_kms_mrk_multi_keyring_example.py | 4 ---- examples/src/aws_kms_multi_keyring_example.py | 4 ---- examples/src/aws_kms_rsa_keyring_example.py | 4 ---- examples/src/file_streaming_example.py | 4 ---- examples/src/hierarchical_keyring_example.py | 4 ---- examples/src/legacy/module_.py | 1 - examples/src/migration_set_commitment_policy_example.py | 4 ---- examples/src/module_.py | 1 - examples/src/multi_keyring_example.py | 4 ---- examples/src/raw_aes_keyring_example.py | 4 ---- examples/src/raw_rsa_keyring_example.py | 4 ---- examples/src/required_encryption_context_cmm.py | 5 ----- examples/src/set_encryption_algorithm_suite_example.py | 4 ---- setup.py | 2 +- .../test/aws-crypto-tools-test-vector-framework | 2 +- 21 files changed, 2 insertions(+), 73 deletions(-) delete mode 100644 examples/src/legacy/module_.py delete mode 100644 examples/src/module_.py diff --git a/examples/src/aws_kms_discovery_keyring_example.py b/examples/src/aws_kms_discovery_keyring_example.py index 4695e8783..2a9e40ea6 100644 --- a/examples/src/aws_kms_discovery_keyring_example.py +++ b/examples/src/aws_kms_discovery_keyring_example.py @@ -49,10 +49,6 @@ from aws_encryption_sdk import CommitmentPolicy from aws_encryption_sdk.exceptions import AWSEncryptionSDKClientError -# TODO-MPL: Remove this as part of removing PYTHONPATH hacks. -MODULE_ROOT_DIR = '/'.join(__file__.split("/")[:-1]) - -sys.path.append(MODULE_ROOT_DIR) EXAMPLE_DATA: bytes = b"Hello World" diff --git a/examples/src/aws_kms_discovery_multi_keyring_example.py b/examples/src/aws_kms_discovery_multi_keyring_example.py index 60d74ff31..452327da1 100644 --- a/examples/src/aws_kms_discovery_multi_keyring_example.py +++ b/examples/src/aws_kms_discovery_multi_keyring_example.py @@ -45,10 +45,6 @@ import aws_encryption_sdk from aws_encryption_sdk import CommitmentPolicy -# TODO-MPL: Remove this as part of removing PYTHONPATH hacks. -MODULE_ROOT_DIR = '/'.join(__file__.split("/")[:-1]) - -sys.path.append(MODULE_ROOT_DIR) EXAMPLE_DATA: bytes = b"Hello World" diff --git a/examples/src/aws_kms_keyring_example.py b/examples/src/aws_kms_keyring_example.py index b166aab99..4cbab444a 100644 --- a/examples/src/aws_kms_keyring_example.py +++ b/examples/src/aws_kms_keyring_example.py @@ -29,10 +29,6 @@ import aws_encryption_sdk from aws_encryption_sdk import CommitmentPolicy -# TODO-MPL: Remove this as part of removing PYTHONPATH hacks. -MODULE_ROOT_DIR = '/'.join(__file__.split("/")[:-1]) - -sys.path.append(MODULE_ROOT_DIR) EXAMPLE_DATA: bytes = b"Hello World" diff --git a/examples/src/aws_kms_mrk_discovery_keyring_example.py b/examples/src/aws_kms_mrk_discovery_keyring_example.py index 8ba80b621..bf7c47e4b 100644 --- a/examples/src/aws_kms_mrk_discovery_keyring_example.py +++ b/examples/src/aws_kms_mrk_discovery_keyring_example.py @@ -50,10 +50,6 @@ import aws_encryption_sdk from aws_encryption_sdk import CommitmentPolicy -# TODO-MPL: Remove this as part of removing PYTHONPATH hacks. -MODULE_ROOT_DIR = '/'.join(__file__.split("/")[:-1]) - -sys.path.append(MODULE_ROOT_DIR) EXAMPLE_DATA: bytes = b"Hello World" diff --git a/examples/src/aws_kms_mrk_discovery_multi_keyring_example.py b/examples/src/aws_kms_mrk_discovery_multi_keyring_example.py index 47cb80f1d..6154bdb16 100644 --- a/examples/src/aws_kms_mrk_discovery_multi_keyring_example.py +++ b/examples/src/aws_kms_mrk_discovery_multi_keyring_example.py @@ -52,10 +52,6 @@ import aws_encryption_sdk from aws_encryption_sdk import CommitmentPolicy -# TODO-MPL: Remove this as part of removing PYTHONPATH hacks. -MODULE_ROOT_DIR = '/'.join(__file__.split("/")[:-1]) - -sys.path.append(MODULE_ROOT_DIR) EXAMPLE_DATA: bytes = b"Hello World" diff --git a/examples/src/aws_kms_mrk_keyring_example.py b/examples/src/aws_kms_mrk_keyring_example.py index 65d8be71b..f09a2482b 100644 --- a/examples/src/aws_kms_mrk_keyring_example.py +++ b/examples/src/aws_kms_mrk_keyring_example.py @@ -33,10 +33,6 @@ import aws_encryption_sdk from aws_encryption_sdk import CommitmentPolicy -# TODO-MPL: Remove this as part of removing PYTHONPATH hacks. -MODULE_ROOT_DIR = '/'.join(__file__.split("/")[:-1]) - -sys.path.append(MODULE_ROOT_DIR) EXAMPLE_DATA: bytes = b"Hello World" diff --git a/examples/src/aws_kms_mrk_multi_keyring_example.py b/examples/src/aws_kms_mrk_multi_keyring_example.py index 9c87008fe..50b39b6b0 100644 --- a/examples/src/aws_kms_mrk_multi_keyring_example.py +++ b/examples/src/aws_kms_mrk_multi_keyring_example.py @@ -39,10 +39,6 @@ import aws_encryption_sdk from aws_encryption_sdk import CommitmentPolicy -# TODO-MPL: Remove this as part of removing PYTHONPATH hacks. -MODULE_ROOT_DIR = '/'.join(__file__.split("/")[:-1]) - -sys.path.append(MODULE_ROOT_DIR) EXAMPLE_DATA: bytes = b"Hello World" diff --git a/examples/src/aws_kms_multi_keyring_example.py b/examples/src/aws_kms_multi_keyring_example.py index 715181646..b98cb32ad 100644 --- a/examples/src/aws_kms_multi_keyring_example.py +++ b/examples/src/aws_kms_multi_keyring_example.py @@ -48,10 +48,6 @@ import aws_encryption_sdk from aws_encryption_sdk import CommitmentPolicy -# TODO-MPL: Remove this as part of removing PYTHONPATH hacks. -MODULE_ROOT_DIR = '/'.join(__file__.split("/")[:-1]) - -sys.path.append(MODULE_ROOT_DIR) EXAMPLE_DATA: bytes = b"Hello World" diff --git a/examples/src/aws_kms_rsa_keyring_example.py b/examples/src/aws_kms_rsa_keyring_example.py index 337dd14b6..09a51be98 100644 --- a/examples/src/aws_kms_rsa_keyring_example.py +++ b/examples/src/aws_kms_rsa_keyring_example.py @@ -27,10 +27,6 @@ from aws_encryption_sdk import CommitmentPolicy from aws_encryption_sdk.identifiers import AlgorithmSuite -# TODO-MPL: Remove this as part of removing PYTHONPATH hacks. -MODULE_ROOT_DIR = '/'.join(__file__.split("/")[:-1]) - -sys.path.append(MODULE_ROOT_DIR) EXAMPLE_DATA: bytes = b"Hello World" diff --git a/examples/src/file_streaming_example.py b/examples/src/file_streaming_example.py index 72decde60..344f2c4bc 100644 --- a/examples/src/file_streaming_example.py +++ b/examples/src/file_streaming_example.py @@ -36,10 +36,6 @@ import aws_encryption_sdk from aws_encryption_sdk import CommitmentPolicy -# TODO-MPL: Remove this as part of removing PYTHONPATH hacks. -MODULE_ROOT_DIR = '/'.join(__file__.split("/")[:-1]) - -sys.path.append(MODULE_ROOT_DIR) def encrypt_and_decrypt_with_keyring( diff --git a/examples/src/hierarchical_keyring_example.py b/examples/src/hierarchical_keyring_example.py index c781f4f40..3091ea4c9 100644 --- a/examples/src/hierarchical_keyring_example.py +++ b/examples/src/hierarchical_keyring_example.py @@ -55,10 +55,6 @@ from .branch_key_id_supplier_example import ExampleBranchKeyIdSupplier -# TODO-MPL: Remove this as part of removing PYTHONPATH hacks. -module_root_dir = '/'.join(__file__.split("/")[:-1]) - -sys.path.append(module_root_dir) EXAMPLE_DATA: bytes = b"Hello World" diff --git a/examples/src/legacy/module_.py b/examples/src/legacy/module_.py deleted file mode 100644 index 3e8d3062a..000000000 --- a/examples/src/legacy/module_.py +++ /dev/null @@ -1 +0,0 @@ -"""Should remove this once PYTHONPATH issues are resolved by adding doo files.""" diff --git a/examples/src/migration_set_commitment_policy_example.py b/examples/src/migration_set_commitment_policy_example.py index 4bd0bc372..87de2129b 100644 --- a/examples/src/migration_set_commitment_policy_example.py +++ b/examples/src/migration_set_commitment_policy_example.py @@ -32,10 +32,6 @@ import aws_encryption_sdk from aws_encryption_sdk import CommitmentPolicy -# TODO-MPL: Remove this as part of removing PYTHONPATH hacks. -MODULE_ROOT_DIR = '/'.join(__file__.split("/")[:-1]) - -sys.path.append(MODULE_ROOT_DIR) EXAMPLE_DATA: bytes = b"Hello World" diff --git a/examples/src/module_.py b/examples/src/module_.py deleted file mode 100644 index 3e8d3062a..000000000 --- a/examples/src/module_.py +++ /dev/null @@ -1 +0,0 @@ -"""Should remove this once PYTHONPATH issues are resolved by adding doo files.""" diff --git a/examples/src/multi_keyring_example.py b/examples/src/multi_keyring_example.py index b12ab61a3..73ae9e1e6 100644 --- a/examples/src/multi_keyring_example.py +++ b/examples/src/multi_keyring_example.py @@ -54,10 +54,6 @@ import aws_encryption_sdk from aws_encryption_sdk import CommitmentPolicy -# TODO-MPL: Remove this as part of removing PYTHONPATH hacks. -MODULE_ROOT_DIR = '/'.join(__file__.split("/")[:-1]) - -sys.path.append(MODULE_ROOT_DIR) EXAMPLE_DATA: bytes = b"Hello World" diff --git a/examples/src/raw_aes_keyring_example.py b/examples/src/raw_aes_keyring_example.py index d8634f774..5dcf64147 100644 --- a/examples/src/raw_aes_keyring_example.py +++ b/examples/src/raw_aes_keyring_example.py @@ -34,10 +34,6 @@ import aws_encryption_sdk from aws_encryption_sdk import CommitmentPolicy -# TODO-MPL: Remove this as part of removing PYTHONPATH hacks. -MODULE_ROOT_DIR = '/'.join(__file__.split("/")[:-1]) - -sys.path.append(MODULE_ROOT_DIR) EXAMPLE_DATA: bytes = b"Hello World" diff --git a/examples/src/raw_rsa_keyring_example.py b/examples/src/raw_rsa_keyring_example.py index 4a38fd166..4adbb911e 100644 --- a/examples/src/raw_rsa_keyring_example.py +++ b/examples/src/raw_rsa_keyring_example.py @@ -48,10 +48,6 @@ from aws_encryption_sdk import CommitmentPolicy from aws_encryption_sdk.exceptions import AWSEncryptionSDKClientError -# TODO-MPL: Remove this as part of removing PYTHONPATH hacks. -MODULE_ROOT_DIR = '/'.join(__file__.split("/")[:-1]) - -sys.path.append(MODULE_ROOT_DIR) EXAMPLE_DATA: bytes = b"Hello World" diff --git a/examples/src/required_encryption_context_cmm.py b/examples/src/required_encryption_context_cmm.py index 1d5140e6d..a1083be95 100644 --- a/examples/src/required_encryption_context_cmm.py +++ b/examples/src/required_encryption_context_cmm.py @@ -25,11 +25,6 @@ from aws_encryption_sdk import CommitmentPolicy from aws_encryption_sdk.exceptions import AWSEncryptionSDKClientError -# TODO-MPL: Remove this as part of removing PYTHONPATH hacks -module_root_dir = '/'.join(__file__.split("/")[:-1]) - -sys.path.append(module_root_dir) - EXAMPLE_DATA: bytes = b"Hello World" diff --git a/examples/src/set_encryption_algorithm_suite_example.py b/examples/src/set_encryption_algorithm_suite_example.py index 200570083..ea3950561 100644 --- a/examples/src/set_encryption_algorithm_suite_example.py +++ b/examples/src/set_encryption_algorithm_suite_example.py @@ -51,10 +51,6 @@ from aws_encryption_sdk import CommitmentPolicy from aws_encryption_sdk.identifiers import AlgorithmSuite -# TODO-MPL: Remove this as part of removing PYTHONPATH hacks. -MODULE_ROOT_DIR = '/'.join(__file__.split("/")[:-1]) - -sys.path.append(MODULE_ROOT_DIR) EXAMPLE_DATA: bytes = b"Hello World" diff --git a/setup.py b/setup.py index 697cb96ce..cd3e40738 100644 --- a/setup.py +++ b/setup.py @@ -45,7 +45,7 @@ def get_requirements(): extras_require={ "MPL": ["aws-cryptographic-material-providers @" \ "git+https://github.com/aws/aws-cryptographic-material-providers-library.git@" \ - "lucmcdon/python-mpl#subdirectory=AwsCryptographicMaterialProviders/runtimes/python"], + "lucmcdon/python-mpl-v2#subdirectory=AwsCryptographicMaterialProviders/runtimes/python"], }, classifiers=[ "Development Status :: 5 - Production/Stable", diff --git a/test_vector_handlers/test/aws-crypto-tools-test-vector-framework b/test_vector_handlers/test/aws-crypto-tools-test-vector-framework index 9eb2fcbbe..fc793e257 160000 --- a/test_vector_handlers/test/aws-crypto-tools-test-vector-framework +++ b/test_vector_handlers/test/aws-crypto-tools-test-vector-framework @@ -1 +1 @@ -Subproject commit 9eb2fcbbe47ab30c29d6ad9a8125b1064e0db42a +Subproject commit fc793e257f4a58ae49b92f95a519ba2c31ccff12 From cb8015269ec2bc9e55a4c3c66137a0ad8aa05604 Mon Sep 17 00:00:00 2001 From: Lucas McDonald Date: Mon, 20 May 2024 15:49:53 -0700 Subject: [PATCH 02/16] cleanup --- examples/src/aws_kms_discovery_keyring_example.py | 1 - examples/src/aws_kms_discovery_multi_keyring_example.py | 1 - examples/src/aws_kms_keyring_example.py | 1 - examples/src/aws_kms_mrk_discovery_keyring_example.py | 1 - examples/src/aws_kms_mrk_discovery_multi_keyring_example.py | 1 - examples/src/aws_kms_mrk_keyring_example.py | 1 - examples/src/aws_kms_mrk_multi_keyring_example.py | 1 - examples/src/aws_kms_multi_keyring_example.py | 1 - examples/src/aws_kms_rsa_keyring_example.py | 1 - examples/src/file_streaming_example.py | 1 - examples/src/hierarchical_keyring_example.py | 1 - examples/src/migration_set_commitment_policy_example.py | 1 - examples/src/multi_keyring_example.py | 1 - examples/src/raw_aes_keyring_example.py | 1 - examples/src/raw_rsa_keyring_example.py | 1 - examples/src/required_encryption_context_cmm.py | 1 - examples/src/set_encryption_algorithm_suite_example.py | 1 - 17 files changed, 17 deletions(-) diff --git a/examples/src/aws_kms_discovery_keyring_example.py b/examples/src/aws_kms_discovery_keyring_example.py index 2a9e40ea6..a6a1e1a26 100644 --- a/examples/src/aws_kms_discovery_keyring_example.py +++ b/examples/src/aws_kms_discovery_keyring_example.py @@ -32,7 +32,6 @@ For more information on how to use KMS Discovery keyrings, see https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/use-kms-keyring.html#kms-keyring-discovery """ -import sys import boto3 from aws_cryptographic_materialproviders.mpl import AwsCryptographicMaterialProviders diff --git a/examples/src/aws_kms_discovery_multi_keyring_example.py b/examples/src/aws_kms_discovery_multi_keyring_example.py index 452327da1..159647cbc 100644 --- a/examples/src/aws_kms_discovery_multi_keyring_example.py +++ b/examples/src/aws_kms_discovery_multi_keyring_example.py @@ -29,7 +29,6 @@ For more information on how to use KMS Discovery keyrings, see https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/use-kms-keyring.html#kms-keyring-discovery """ -import sys import boto3 from aws_cryptographic_materialproviders.mpl import AwsCryptographicMaterialProviders diff --git a/examples/src/aws_kms_keyring_example.py b/examples/src/aws_kms_keyring_example.py index 4cbab444a..4a927bb37 100644 --- a/examples/src/aws_kms_keyring_example.py +++ b/examples/src/aws_kms_keyring_example.py @@ -17,7 +17,6 @@ For more information on how to use KMS keyrings, see https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/use-kms-keyring.html """ -import sys import boto3 from aws_cryptographic_materialproviders.mpl import AwsCryptographicMaterialProviders diff --git a/examples/src/aws_kms_mrk_discovery_keyring_example.py b/examples/src/aws_kms_mrk_discovery_keyring_example.py index bf7c47e4b..8f13be3c8 100644 --- a/examples/src/aws_kms_mrk_discovery_keyring_example.py +++ b/examples/src/aws_kms_mrk_discovery_keyring_example.py @@ -34,7 +34,6 @@ For more information on how to use KMS Discovery keyrings, see https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/use-kms-keyring.html#kms-keyring-discovery """ -import sys import boto3 from aws_cryptographic_materialproviders.mpl import AwsCryptographicMaterialProviders diff --git a/examples/src/aws_kms_mrk_discovery_multi_keyring_example.py b/examples/src/aws_kms_mrk_discovery_multi_keyring_example.py index 6154bdb16..fd172c4a5 100644 --- a/examples/src/aws_kms_mrk_discovery_multi_keyring_example.py +++ b/examples/src/aws_kms_mrk_discovery_multi_keyring_example.py @@ -36,7 +36,6 @@ For more information on how to use KMS Discovery keyrings, see https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/use-kms-keyring.html#kms-keyring-discovery """ -import sys import boto3 from aws_cryptographic_materialproviders.mpl import AwsCryptographicMaterialProviders diff --git a/examples/src/aws_kms_mrk_keyring_example.py b/examples/src/aws_kms_mrk_keyring_example.py index f09a2482b..d7a594fdf 100644 --- a/examples/src/aws_kms_mrk_keyring_example.py +++ b/examples/src/aws_kms_mrk_keyring_example.py @@ -21,7 +21,6 @@ For more info on KMS MRK (multi-region keys), see the KMS documentation: https://docs.aws.amazon.com/kms/latest/developerguide/multi-region-keys-overview.html """ -import sys import boto3 from aws_cryptographic_materialproviders.mpl import AwsCryptographicMaterialProviders diff --git a/examples/src/aws_kms_mrk_multi_keyring_example.py b/examples/src/aws_kms_mrk_multi_keyring_example.py index 50b39b6b0..eed755bcd 100644 --- a/examples/src/aws_kms_mrk_multi_keyring_example.py +++ b/examples/src/aws_kms_mrk_multi_keyring_example.py @@ -27,7 +27,6 @@ For more info on KMS MRK (multi-region keys), see the KMS documentation: https://docs.aws.amazon.com/kms/latest/developerguide/multi-region-keys-overview.html """ -import sys import boto3 from aws_cryptographic_materialproviders.mpl import AwsCryptographicMaterialProviders diff --git a/examples/src/aws_kms_multi_keyring_example.py b/examples/src/aws_kms_multi_keyring_example.py index b98cb32ad..b639d4283 100644 --- a/examples/src/aws_kms_multi_keyring_example.py +++ b/examples/src/aws_kms_multi_keyring_example.py @@ -36,7 +36,6 @@ For more information on how to use Multi keyrings, see https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/use-multi-keyring.html """ -import sys import boto3 from aws_cryptographic_materialproviders.mpl import AwsCryptographicMaterialProviders diff --git a/examples/src/aws_kms_rsa_keyring_example.py b/examples/src/aws_kms_rsa_keyring_example.py index 09a51be98..f0319e957 100644 --- a/examples/src/aws_kms_rsa_keyring_example.py +++ b/examples/src/aws_kms_rsa_keyring_example.py @@ -14,7 +14,6 @@ # For more information on how to use KMS keyrings, see # https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/use-kms-keyring.html """ -import sys import boto3 from aws_cryptographic_materialproviders.mpl import AwsCryptographicMaterialProviders diff --git a/examples/src/file_streaming_example.py b/examples/src/file_streaming_example.py index 344f2c4bc..bbc117490 100644 --- a/examples/src/file_streaming_example.py +++ b/examples/src/file_streaming_example.py @@ -25,7 +25,6 @@ """ import filecmp import secrets -import sys from aws_cryptographic_materialproviders.mpl import AwsCryptographicMaterialProviders from aws_cryptographic_materialproviders.mpl.config import MaterialProvidersConfig diff --git a/examples/src/hierarchical_keyring_example.py b/examples/src/hierarchical_keyring_example.py index 3091ea4c9..84b05d3b8 100644 --- a/examples/src/hierarchical_keyring_example.py +++ b/examples/src/hierarchical_keyring_example.py @@ -31,7 +31,6 @@ This example also requires using a KMS Key. You need the following access on this key: - GenerateDataKeyWithoutPlaintext - Decrypt """ -import sys import boto3 # Ignore missing MPL for pylint, but the MPL is required for this example diff --git a/examples/src/migration_set_commitment_policy_example.py b/examples/src/migration_set_commitment_policy_example.py index 87de2129b..d34a1ef59 100644 --- a/examples/src/migration_set_commitment_policy_example.py +++ b/examples/src/migration_set_commitment_policy_example.py @@ -20,7 +20,6 @@ For more information on setting your commitment policy, see https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/concepts.html#commitment-policy """ -import sys import boto3 from aws_cryptographic_materialproviders.mpl import AwsCryptographicMaterialProviders diff --git a/examples/src/multi_keyring_example.py b/examples/src/multi_keyring_example.py index 73ae9e1e6..98b6228bb 100644 --- a/examples/src/multi_keyring_example.py +++ b/examples/src/multi_keyring_example.py @@ -37,7 +37,6 @@ https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/use-multi-keyring.html """ import secrets -import sys import boto3 from aws_cryptographic_materialproviders.mpl import AwsCryptographicMaterialProviders diff --git a/examples/src/raw_aes_keyring_example.py b/examples/src/raw_aes_keyring_example.py index 5dcf64147..f1d971b62 100644 --- a/examples/src/raw_aes_keyring_example.py +++ b/examples/src/raw_aes_keyring_example.py @@ -23,7 +23,6 @@ https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/use-raw-aes-keyring.html """ import secrets -import sys from aws_cryptographic_materialproviders.mpl import AwsCryptographicMaterialProviders from aws_cryptographic_materialproviders.mpl.config import MaterialProvidersConfig diff --git a/examples/src/raw_rsa_keyring_example.py b/examples/src/raw_rsa_keyring_example.py index 4adbb911e..ca488b474 100644 --- a/examples/src/raw_rsa_keyring_example.py +++ b/examples/src/raw_rsa_keyring_example.py @@ -33,7 +33,6 @@ For more information on how to use Raw RSA keyrings, see https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/use-raw-rsa-keyring.html """ -import sys from aws_cryptographic_materialproviders.mpl import AwsCryptographicMaterialProviders from aws_cryptographic_materialproviders.mpl.config import MaterialProvidersConfig diff --git a/examples/src/required_encryption_context_cmm.py b/examples/src/required_encryption_context_cmm.py index a1083be95..edbb3f414 100644 --- a/examples/src/required_encryption_context_cmm.py +++ b/examples/src/required_encryption_context_cmm.py @@ -6,7 +6,6 @@ on encrypt such that they will not be stored on the message, but WILL be included in the header signature. On decrypt, the client MUST supply the key/value pair(s) that were not stored to successfully decrypt the message. """ -import sys import boto3 # Ignore missing MPL for pylint, but the MPL is required for this example diff --git a/examples/src/set_encryption_algorithm_suite_example.py b/examples/src/set_encryption_algorithm_suite_example.py index ea3950561..ffa453a30 100644 --- a/examples/src/set_encryption_algorithm_suite_example.py +++ b/examples/src/set_encryption_algorithm_suite_example.py @@ -39,7 +39,6 @@ https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/use-raw-aes-keyring.html """ import secrets -import sys from aws_cryptographic_materialproviders.mpl import AwsCryptographicMaterialProviders from aws_cryptographic_materialproviders.mpl.config import MaterialProvidersConfig From efe2d1de47eee510dbe95b47dc1ae061583509c3 Mon Sep 17 00:00:00 2001 From: Lucas McDonald Date: Mon, 20 May 2024 15:51:41 -0700 Subject: [PATCH 03/16] isort --- examples/src/aws_kms_discovery_keyring_example.py | 1 - examples/src/aws_kms_discovery_multi_keyring_example.py | 1 - examples/src/aws_kms_keyring_example.py | 1 - examples/src/aws_kms_mrk_discovery_keyring_example.py | 1 - examples/src/aws_kms_mrk_discovery_multi_keyring_example.py | 1 - examples/src/aws_kms_mrk_keyring_example.py | 1 - examples/src/aws_kms_mrk_multi_keyring_example.py | 1 - examples/src/aws_kms_multi_keyring_example.py | 1 - examples/src/aws_kms_rsa_keyring_example.py | 1 - examples/src/file_streaming_example.py | 1 - examples/src/hierarchical_keyring_example.py | 1 - examples/src/migration_set_commitment_policy_example.py | 1 - examples/src/multi_keyring_example.py | 1 - examples/src/raw_aes_keyring_example.py | 1 - examples/src/raw_rsa_keyring_example.py | 1 - examples/src/set_encryption_algorithm_suite_example.py | 1 - 16 files changed, 16 deletions(-) diff --git a/examples/src/aws_kms_discovery_keyring_example.py b/examples/src/aws_kms_discovery_keyring_example.py index a6a1e1a26..d78121bc3 100644 --- a/examples/src/aws_kms_discovery_keyring_example.py +++ b/examples/src/aws_kms_discovery_keyring_example.py @@ -48,7 +48,6 @@ from aws_encryption_sdk import CommitmentPolicy from aws_encryption_sdk.exceptions import AWSEncryptionSDKClientError - EXAMPLE_DATA: bytes = b"Hello World" diff --git a/examples/src/aws_kms_discovery_multi_keyring_example.py b/examples/src/aws_kms_discovery_multi_keyring_example.py index 159647cbc..9381a740b 100644 --- a/examples/src/aws_kms_discovery_multi_keyring_example.py +++ b/examples/src/aws_kms_discovery_multi_keyring_example.py @@ -44,7 +44,6 @@ import aws_encryption_sdk from aws_encryption_sdk import CommitmentPolicy - EXAMPLE_DATA: bytes = b"Hello World" diff --git a/examples/src/aws_kms_keyring_example.py b/examples/src/aws_kms_keyring_example.py index 4a927bb37..8977e3750 100644 --- a/examples/src/aws_kms_keyring_example.py +++ b/examples/src/aws_kms_keyring_example.py @@ -28,7 +28,6 @@ import aws_encryption_sdk from aws_encryption_sdk import CommitmentPolicy - EXAMPLE_DATA: bytes = b"Hello World" diff --git a/examples/src/aws_kms_mrk_discovery_keyring_example.py b/examples/src/aws_kms_mrk_discovery_keyring_example.py index 8f13be3c8..23d6cb322 100644 --- a/examples/src/aws_kms_mrk_discovery_keyring_example.py +++ b/examples/src/aws_kms_mrk_discovery_keyring_example.py @@ -49,7 +49,6 @@ import aws_encryption_sdk from aws_encryption_sdk import CommitmentPolicy - EXAMPLE_DATA: bytes = b"Hello World" diff --git a/examples/src/aws_kms_mrk_discovery_multi_keyring_example.py b/examples/src/aws_kms_mrk_discovery_multi_keyring_example.py index fd172c4a5..adb249e2a 100644 --- a/examples/src/aws_kms_mrk_discovery_multi_keyring_example.py +++ b/examples/src/aws_kms_mrk_discovery_multi_keyring_example.py @@ -51,7 +51,6 @@ import aws_encryption_sdk from aws_encryption_sdk import CommitmentPolicy - EXAMPLE_DATA: bytes = b"Hello World" diff --git a/examples/src/aws_kms_mrk_keyring_example.py b/examples/src/aws_kms_mrk_keyring_example.py index d7a594fdf..edb3cc410 100644 --- a/examples/src/aws_kms_mrk_keyring_example.py +++ b/examples/src/aws_kms_mrk_keyring_example.py @@ -32,7 +32,6 @@ import aws_encryption_sdk from aws_encryption_sdk import CommitmentPolicy - EXAMPLE_DATA: bytes = b"Hello World" diff --git a/examples/src/aws_kms_mrk_multi_keyring_example.py b/examples/src/aws_kms_mrk_multi_keyring_example.py index eed755bcd..6b1e64eec 100644 --- a/examples/src/aws_kms_mrk_multi_keyring_example.py +++ b/examples/src/aws_kms_mrk_multi_keyring_example.py @@ -38,7 +38,6 @@ import aws_encryption_sdk from aws_encryption_sdk import CommitmentPolicy - EXAMPLE_DATA: bytes = b"Hello World" diff --git a/examples/src/aws_kms_multi_keyring_example.py b/examples/src/aws_kms_multi_keyring_example.py index b639d4283..7cba36167 100644 --- a/examples/src/aws_kms_multi_keyring_example.py +++ b/examples/src/aws_kms_multi_keyring_example.py @@ -47,7 +47,6 @@ import aws_encryption_sdk from aws_encryption_sdk import CommitmentPolicy - EXAMPLE_DATA: bytes = b"Hello World" diff --git a/examples/src/aws_kms_rsa_keyring_example.py b/examples/src/aws_kms_rsa_keyring_example.py index f0319e957..fd05fc20b 100644 --- a/examples/src/aws_kms_rsa_keyring_example.py +++ b/examples/src/aws_kms_rsa_keyring_example.py @@ -26,7 +26,6 @@ from aws_encryption_sdk import CommitmentPolicy from aws_encryption_sdk.identifiers import AlgorithmSuite - EXAMPLE_DATA: bytes = b"Hello World" diff --git a/examples/src/file_streaming_example.py b/examples/src/file_streaming_example.py index bbc117490..3f547d220 100644 --- a/examples/src/file_streaming_example.py +++ b/examples/src/file_streaming_example.py @@ -36,7 +36,6 @@ from aws_encryption_sdk import CommitmentPolicy - def encrypt_and_decrypt_with_keyring( plaintext_filename: str, ciphertext_filename: str, diff --git a/examples/src/hierarchical_keyring_example.py b/examples/src/hierarchical_keyring_example.py index 84b05d3b8..00dadf9d8 100644 --- a/examples/src/hierarchical_keyring_example.py +++ b/examples/src/hierarchical_keyring_example.py @@ -54,7 +54,6 @@ from .branch_key_id_supplier_example import ExampleBranchKeyIdSupplier - EXAMPLE_DATA: bytes = b"Hello World" diff --git a/examples/src/migration_set_commitment_policy_example.py b/examples/src/migration_set_commitment_policy_example.py index d34a1ef59..3851df0e2 100644 --- a/examples/src/migration_set_commitment_policy_example.py +++ b/examples/src/migration_set_commitment_policy_example.py @@ -31,7 +31,6 @@ import aws_encryption_sdk from aws_encryption_sdk import CommitmentPolicy - EXAMPLE_DATA: bytes = b"Hello World" diff --git a/examples/src/multi_keyring_example.py b/examples/src/multi_keyring_example.py index 98b6228bb..20af7ba81 100644 --- a/examples/src/multi_keyring_example.py +++ b/examples/src/multi_keyring_example.py @@ -53,7 +53,6 @@ import aws_encryption_sdk from aws_encryption_sdk import CommitmentPolicy - EXAMPLE_DATA: bytes = b"Hello World" diff --git a/examples/src/raw_aes_keyring_example.py b/examples/src/raw_aes_keyring_example.py index f1d971b62..ab9603af6 100644 --- a/examples/src/raw_aes_keyring_example.py +++ b/examples/src/raw_aes_keyring_example.py @@ -33,7 +33,6 @@ import aws_encryption_sdk from aws_encryption_sdk import CommitmentPolicy - EXAMPLE_DATA: bytes = b"Hello World" diff --git a/examples/src/raw_rsa_keyring_example.py b/examples/src/raw_rsa_keyring_example.py index ca488b474..1200a7c72 100644 --- a/examples/src/raw_rsa_keyring_example.py +++ b/examples/src/raw_rsa_keyring_example.py @@ -47,7 +47,6 @@ from aws_encryption_sdk import CommitmentPolicy from aws_encryption_sdk.exceptions import AWSEncryptionSDKClientError - EXAMPLE_DATA: bytes = b"Hello World" diff --git a/examples/src/set_encryption_algorithm_suite_example.py b/examples/src/set_encryption_algorithm_suite_example.py index ffa453a30..75eaee85a 100644 --- a/examples/src/set_encryption_algorithm_suite_example.py +++ b/examples/src/set_encryption_algorithm_suite_example.py @@ -50,7 +50,6 @@ from aws_encryption_sdk import CommitmentPolicy from aws_encryption_sdk.identifiers import AlgorithmSuite - EXAMPLE_DATA: bytes = b"Hello World" From dd285f6ece3d5d2bc05c32db4ce26946b6ca396a Mon Sep 17 00:00:00 2001 From: Lucas McDonald Date: Wed, 22 May 2024 12:26:23 -0700 Subject: [PATCH 04/16] win --- .github/workflows/ci_tests.yaml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/.github/workflows/ci_tests.yaml b/.github/workflows/ci_tests.yaml index 7ec273ba2..1a3229683 100644 --- a/.github/workflows/ci_tests.yaml +++ b/.github/workflows/ci_tests.yaml @@ -25,11 +25,7 @@ jobs: matrix: os: - ubuntu-latest - # Windows fails due to "No module named 'Wrappers'" - # This SHOULD be fixed once Dafny generates fully-qualified import statements - # (i.e. doo files, per-package module names) - # Disable for now - # - windows-latest + - windows-latest - macos-12 python: - 3.8 From bf1a15f013040c308148014e7ff2b311e54ac78f Mon Sep 17 00:00:00 2001 From: Lucas McDonald Date: Wed, 22 May 2024 12:36:51 -0700 Subject: [PATCH 05/16] debug win import --- src/aws_encryption_sdk/streaming_client.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/aws_encryption_sdk/streaming_client.py b/src/aws_encryption_sdk/streaming_client.py index 64d77b91a..62801eb6c 100644 --- a/src/aws_encryption_sdk/streaming_client.py +++ b/src/aws_encryption_sdk/streaming_client.py @@ -76,7 +76,8 @@ # Import internal ESDK modules that depend on the MPL from aws_encryption_sdk.materials_managers.mpl.cmm import CryptoMaterialsManagerFromMPL -except ImportError: +except ImportError as e: + print("streamingerror" + e) _HAS_MPL = False _LOGGER = logging.getLogger(__name__) From 2144b14689d16b2605fd5a1afe31b6880bc5782e Mon Sep 17 00:00:00 2001 From: Lucas McDonald Date: Wed, 22 May 2024 12:39:16 -0700 Subject: [PATCH 06/16] debug win import --- src/aws_encryption_sdk/streaming_client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/aws_encryption_sdk/streaming_client.py b/src/aws_encryption_sdk/streaming_client.py index 62801eb6c..5b87abba0 100644 --- a/src/aws_encryption_sdk/streaming_client.py +++ b/src/aws_encryption_sdk/streaming_client.py @@ -77,7 +77,7 @@ from aws_encryption_sdk.materials_managers.mpl.cmm import CryptoMaterialsManagerFromMPL except ImportError as e: - print("streamingerror" + e) + print("streamingerror " + str(e)) _HAS_MPL = False _LOGGER = logging.getLogger(__name__) From a83ab6d0c2330601c00880a73b6d671e0b1b05aa Mon Sep 17 00:00:00 2001 From: Lucas McDonald Date: Wed, 22 May 2024 12:43:20 -0700 Subject: [PATCH 07/16] actual v2 --- requirements_mpl.txt | 2 +- test_vector_handlers/requirements_mpl.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements_mpl.txt b/requirements_mpl.txt index 209e10f2c..28d7dc356 100644 --- a/requirements_mpl.txt +++ b/requirements_mpl.txt @@ -1 +1 @@ -aws-cryptographic-material-providers @ git+https://github.com/aws/aws-cryptographic-material-providers-library.git@lucmcdon/python-mpl#subdirectory=AwsCryptographicMaterialProviders/runtimes/python \ No newline at end of file +aws-cryptographic-material-providers @ git+https://github.com/aws/aws-cryptographic-material-providers-library.git@lucmcdon/python-mpl-v2#subdirectory=AwsCryptographicMaterialProviders/runtimes/python \ No newline at end of file diff --git a/test_vector_handlers/requirements_mpl.txt b/test_vector_handlers/requirements_mpl.txt index c7927a851..1aab5f534 100644 --- a/test_vector_handlers/requirements_mpl.txt +++ b/test_vector_handlers/requirements_mpl.txt @@ -1 +1 @@ -amazon-cryptographic-material-providers-test-vectors @ git+https://github.com/aws/aws-cryptographic-material-providers-library.git@lucmcdon/python-mpl#subdirectory=TestVectorsAwsCryptographicMaterialProviders/runtimes/python \ No newline at end of file +amazon-cryptographic-material-providers-test-vectors @ git+https://github.com/aws/aws-cryptographic-material-providers-library.git@lucmcdon/python-mpl-v2#subdirectory=TestVectorsAwsCryptographicMaterialProviders/runtimes/python \ No newline at end of file From a8c5b0dd9daa2bb925f971816fe21cc2884607e8 Mon Sep 17 00:00:00 2001 From: Lucas McDonald Date: Tue, 18 Jun 2024 15:41:39 -0700 Subject: [PATCH 08/16] test: Required encryption context CMM integration tests --- test/mpl/integ/test_required_ec_cmm.py | 733 +++++++++++++++++++++++++ 1 file changed, 733 insertions(+) create mode 100644 test/mpl/integ/test_required_ec_cmm.py diff --git a/test/mpl/integ/test_required_ec_cmm.py b/test/mpl/integ/test_required_ec_cmm.py new file mode 100644 index 000000000..8a3560f49 --- /dev/null +++ b/test/mpl/integ/test_required_ec_cmm.py @@ -0,0 +1,733 @@ +import copy +import random +import secrets +import string + +import boto3 +import pytest +from aws_cryptographic_materialproviders.keystore import KeyStore +from aws_cryptographic_materialproviders.keystore.config import KeyStoreConfig +from aws_cryptographic_materialproviders.keystore.models import ( + KMSConfigurationKmsKeyArn, +) +from aws_cryptographic_materialproviders.mpl import AwsCryptographicMaterialProviders +from aws_cryptographic_materialproviders.mpl.config import MaterialProvidersConfig +from aws_cryptographic_materialproviders.mpl.models import ( + AesWrappingAlg, + CacheTypeDefault, + CreateAwsKmsHierarchicalKeyringInput, + CreateAwsKmsKeyringInput, + CreateDefaultCryptographicMaterialsManagerInput, + CreateMultiKeyringInput, + CreateRawAesKeyringInput, + CreateRawRsaKeyringInput, + CreateRequiredEncryptionContextCMMInput, + DefaultCache, + PaddingScheme, +) +from aws_cryptographic_materialproviders.mpl.references import IKeyring +from cryptography.hazmat.backends import default_backend as crypto_default_backend +from cryptography.hazmat.primitives import serialization as crypto_serialization +from cryptography.hazmat.primitives.asymmetric import rsa + +import aws_encryption_sdk +from aws_encryption_sdk.exceptions import AWSEncryptionSDKClientError + +pytestmark = [pytest.mark.integ] + +# ESDK client. Used to encrypt/decrypt in each test. +client = aws_encryption_sdk.EncryptionSDKClient() + +# MPL client. Used to create keyrings. +mpl_client: AwsCryptographicMaterialProviders = AwsCryptographicMaterialProviders( + config=MaterialProvidersConfig() +) + + +# Private raw AES keyring creator. +# Lifted from raw AES keyring example. +def _create_raw_aes_keyring(): + static_key = secrets.token_bytes(32) + + keyring_input: CreateRawAesKeyringInput = CreateRawAesKeyringInput( + key_namespace="some_key_namespace", + key_name="some_key_name", + wrapping_key=static_key, + wrapping_alg=AesWrappingAlg.ALG_AES256_GCM_IV12_TAG16 + ) + + raw_aes_keyring: IKeyring = mpl_client.create_raw_aes_keyring( + input=keyring_input + ) + + return raw_aes_keyring + + +# Private raw RSA keyring creator. +# Lifted from raw RSA keyring example. +def _create_raw_rsa_keyring(): + ssh_rsa_exponent = 65537 + bit_strength = 4096 + key = rsa.generate_private_key( + backend=crypto_default_backend(), + public_exponent=ssh_rsa_exponent, + key_size=bit_strength + ) + + public_key = key.public_key().public_bytes( + encoding=crypto_serialization.Encoding.PEM, + format=crypto_serialization.PublicFormat.SubjectPublicKeyInfo + ) + private_key = key.private_bytes( + encoding=crypto_serialization.Encoding.PEM, + format=crypto_serialization.PrivateFormat.TraditionalOpenSSL, + encryption_algorithm=crypto_serialization.NoEncryption() + ) + + key_name_space = "some_key_name_space" + key_name = "some_key_name" + + keyring_input: CreateRawRsaKeyringInput = CreateRawRsaKeyringInput( + key_namespace=key_name_space, + key_name=key_name, + padding_scheme=PaddingScheme.OAEP_SHA256_MGF1, + public_key=public_key, + private_key=private_key + ) + + raw_rsa_keyring: IKeyring = mpl_client.create_raw_rsa_keyring( + input=keyring_input + ) + + return raw_rsa_keyring + + +# Private KMS keyring creator. +# Lifted KMS keyring example. +def _create_kms_keyring(): + kms_client = boto3.client('kms', region_name="us-west-2") + keyring_input: CreateAwsKmsKeyringInput = CreateAwsKmsKeyringInput( + kms_key_id="arn:aws:kms:us-west-2:658956600833:key/b3537ef1-d8dc-4780-9f5a-55776cbb2f7f", + kms_client=kms_client + ) + + kms_keyring: IKeyring = mpl_client.create_aws_kms_keyring( + input=keyring_input + ) + + return kms_keyring + + +# Private hierarchical keyring creator. +# Lifted hierarchical keyring example. +def _create_hierarchical_keyring(): + kms_client = boto3.client('kms', region_name="us-west-2") + ddb_client = boto3.client('dynamodb', region_name="us-west-2") + + keystore: KeyStore = KeyStore( + config=KeyStoreConfig( + ddb_client=ddb_client, + ddb_table_name="KeyStoreDdbTable", + logical_key_store_name="KeyStoreDdbTable", + kms_client=kms_client, + kms_configuration=KMSConfigurationKmsKeyArn( + value='arn:aws:kms:us-west-2:370957321024:key/9d989aa2-2f9c-438c-a745-cc57d3ad0126' + ), + ) + ) + + keyring_input: CreateAwsKmsHierarchicalKeyringInput = CreateAwsKmsHierarchicalKeyringInput( + key_store=keystore, + branch_key_id='a52dfaad-7dbd-4430-a1fd-abaa5299da07', + ttl_seconds=600, + cache=CacheTypeDefault( + value=DefaultCache( + entry_capacity=100 + ) + ), + ) + + hierarchical_keyring: IKeyring = mpl_client.create_aws_kms_hierarchical_keyring( + input=keyring_input + ) + + return hierarchical_keyring + + +# Private multi-keyring creator. +def _create_multi_keyring(keyrings): + a = mpl_client.create_multi_keyring(CreateMultiKeyringInput( + generator=keyrings[0], + child_keyrings=keyrings[1:] + )) + return a + + +# Encryption contexts under test +SOME_EMPTY_ENCRYPTION_CONTEXT = {} +SOME_SINGLE_ITEM_ENCRYPTION_CONTEXT = {"some_key": "some_value"} +SOME_DOUBLE_ITEM_ENCRYPTION_CONTEXT = {"some_key": "some_value", "some_other_key": "some_other_value"} +SOME_MANY_ITEM_ENCRYPTION_CONTEXT = { + ''.join(random.choices(string.ascii_letters, k=6)) + : ''.join(random.choices(string.ascii_letters, k=6)) for _ in range(20) +} +ENCRYPTION_CONTEXT_SUITE = [ + SOME_EMPTY_ENCRYPTION_CONTEXT, + SOME_SINGLE_ITEM_ENCRYPTION_CONTEXT, + SOME_DOUBLE_ITEM_ENCRYPTION_CONTEXT, + SOME_MANY_ITEM_ENCRYPTION_CONTEXT, +] + +# Keyrings under test +SOME_RSA_KEYRING = _create_raw_rsa_keyring() +SOME_AES_KEYRING = _create_raw_aes_keyring() +SOME_KMS_KEYRING = _create_kms_keyring() +SOME_HIERARCHICAL_KEYRING = _create_hierarchical_keyring() +TEST_KEYRINGS_LIST = [ + SOME_AES_KEYRING, + SOME_KMS_KEYRING, + SOME_RSA_KEYRING, + SOME_HIERARCHICAL_KEYRING, +] +# Multi-keyring composed of individual keyrings. +# In lots of tests in this file, +# this multi keyring encrypts one message, +# then the test attempts decryption with all of its component keyrings +# ("component" = generator + child keyrings). +SOME_MULTI_KEYRING = _create_multi_keyring(TEST_KEYRINGS_LIST) + + +SOME_PLAINTEXT = b"Hello World" + + +@pytest.mark.parametrize("encryption_context", ENCRYPTION_CONTEXT_SUITE) +# HAPPY CASE 1 +# Test supply same encryption context on encrypt and decrypt NO filtering +def test_GIVEN_same_EC_on_encrypt_and_decrypt_WHEN_encrypt_decrypt_cycle_THEN_decrypt_matches_plaintext( + encryption_context +): + # When: encrypt/decrypt cycle + ct, _ = client.encrypt( + source=SOME_PLAINTEXT, + keyring=SOME_MULTI_KEYRING, + # Given: same encryption context on encrypt and decrypt + encryption_context=encryption_context, + ) + + for decrypt_keyring in TEST_KEYRINGS_LIST: + pt, _ = client.decrypt( + source=ct, + # Given: same encryption context on encrypt and decrypt + keyring=decrypt_keyring + ) + + # Then: decrypted plaintext matches original plaintext + assert pt == SOME_PLAINTEXT + + +@pytest.mark.parametrize("encryption_context", ENCRYPTION_CONTEXT_SUITE) +# HAPPY CASE 2 +# On Encrypt we will only write one encryption context key value to the header +# we will then supply only what we didn't write wth no required ec cmm, +# This test case is checking that the default cmm is doing the correct filtering +def test_GIVEN_RECCMM_with_one_REC_key_on_encrypt_AND_default_CMM_with_valid_reproduced_EC_on_decrypt_WHEN_supply_reproduced_EC_with_REC_key_on_decrypt_THEN_decrypt_matches_plaintext( # noqa pylint: disable=line-too-long + encryption_context +): + # This test needs >1 item to supply as required encryption context + if len(encryption_context) < 1: + return + + # Grab one item from encryption_context to supply as reproduced EC + one_k, one_v = next(iter(encryption_context.items())) + reproduced_ec = {one_k: one_v} + # Given: one required encryption context (REC) key + required_ec_keys = [one_k] + + default_cmm = mpl_client.create_default_cryptographic_materials_manager( + CreateDefaultCryptographicMaterialsManagerInput( + keyring=SOME_MULTI_KEYRING, + ) + ) + + required_ec_cmm = mpl_client.create_required_encryption_context_cmm( + CreateRequiredEncryptionContextCMMInput( + underlying_cmm=default_cmm, + # Given: one required encryption context (REC) key + required_encryption_context_keys=required_ec_keys + ) + ) + + # When: encrypt/decrypt cycle + ct, _ = client.encrypt( + source=SOME_PLAINTEXT, + materials_manager=required_ec_cmm, + # Given: required encryption context CMM (RECCMM) on encrypt + encryption_context=encryption_context, + ) + + for decrypt_keyring in TEST_KEYRINGS_LIST: + pt, _ = client.decrypt( + source=ct, + # Given: default CMM on decrypt (ESDK auto-creates default CMM) + keyring=decrypt_keyring, + # When: supply valid reproduced EC (containing REC key) on decrypt + encryption_context=reproduced_ec, + ) + + # Then: decrypted plaintext matches original plaintext, no errors + assert pt == SOME_PLAINTEXT + + +@pytest.mark.parametrize("encryption_context", ENCRYPTION_CONTEXT_SUITE) +# HAPPY CASE 3 +# On Encrypt we will only write one encryption context key value to the header +# we will then supply only what we didn't write but included in the signature while we +# are configured with the required encryption context cmm +def test_GIVEN_RECCMM_with_one_REC_key_on_encrypt_AND_RECCMM_with_valid_reproduced_EC_on_decrypt_WHEN_supply_reproduced_EC_with_REC_key_on_decrypt_THEN_decrypt_matches_plaintext( # noqa pylint: disable=line-too-long + encryption_context +): + # This test needs >1 item to supply as required encryption context + if len(encryption_context) < 1: + return + + # Grab one item from encryption_context to supply as reproduced EC + one_k, one_v = next(iter(encryption_context.items())) + reproduced_ec = {one_k: one_v} + # Given: one required encryption context (REC) key + required_ec_keys = [one_k] + + default_cmm_encrypt = mpl_client.create_default_cryptographic_materials_manager( + CreateDefaultCryptographicMaterialsManagerInput( + keyring=SOME_MULTI_KEYRING, + ) + ) + + required_ec_cmm_encrypt = mpl_client.create_required_encryption_context_cmm( + CreateRequiredEncryptionContextCMMInput( + underlying_cmm=default_cmm_encrypt, + # Given: one required encryption context (REC) key + required_encryption_context_keys=required_ec_keys + ) + ) + + # When: encrypt/decrypt cycle + ct, _ = client.encrypt( + source=SOME_PLAINTEXT, + materials_manager=required_ec_cmm_encrypt, + # Given: required encryption context CMM (RECCMM) on encrypt + encryption_context=encryption_context, + ) + + for decrypt_keyring in TEST_KEYRINGS_LIST: + default_cmm_decrypt = mpl_client.create_default_cryptographic_materials_manager( + CreateDefaultCryptographicMaterialsManagerInput( + keyring=decrypt_keyring, + ) + ) + + required_ec_cmm_decrypt = mpl_client.create_required_encryption_context_cmm( + CreateRequiredEncryptionContextCMMInput( + underlying_cmm=default_cmm_decrypt, + # Given: one required encryption context (REC) key + required_encryption_context_keys=required_ec_keys + ) + ) + + pt, _ = client.decrypt( + source=ct, + # Given: required encryption context CMM (RECCMM) on decrypt + materials_manager=required_ec_cmm_decrypt, + # When: supply reproduced EC on decrypt + encryption_context=reproduced_ec, + ) + + # Then: decrypted plaintext matches original plaintext + assert pt == SOME_PLAINTEXT + + +@pytest.mark.parametrize("encryption_context", ENCRYPTION_CONTEXT_SUITE) +# HAPPY CASE 4 +# On Encrypt we write all encryption context +# as if the message was encrypted before the feature existed. +# We will then have a required encryption context cmm +# that will require us to supply the encryption context on decrypt. +def test_GIVEN_default_CMM_on_encrypt_AND_default_CMM_with_valid_reproduced_EC_on_decrypt_WHEN_supply_reproduced_EC_with_REC_key_on_decrypt_THEN_decrypt_matches_plaintext( # noqa pylint: disable=line-too-long + encryption_context +): + # This test needs >1 item to supply as required encryption context + if len(encryption_context) < 1: + return + + # Grab one item from encryption_context to supply as reproduced EC + one_k, one_v = next(iter(encryption_context.items())) + reproduced_ec = {one_k: one_v} + # Given: one required encryption context (REC) key + required_ec_keys = [one_k] + + default_cmm_encrypt = mpl_client.create_default_cryptographic_materials_manager( + CreateDefaultCryptographicMaterialsManagerInput( + keyring=SOME_MULTI_KEYRING, + ) + ) + + # When: encrypt/decrypt cycle + ct, _ = client.encrypt( + source=SOME_PLAINTEXT, + materials_manager=default_cmm_encrypt, + # Given: default CMM on encrypt + encryption_context=encryption_context, + ) + + for decrypt_keyring in TEST_KEYRINGS_LIST: + default_cmm_decrypt = mpl_client.create_default_cryptographic_materials_manager( + CreateDefaultCryptographicMaterialsManagerInput( + keyring=decrypt_keyring, + ) + ) + + required_ec_cmm_decrypt = mpl_client.create_required_encryption_context_cmm( + CreateRequiredEncryptionContextCMMInput( + underlying_cmm=default_cmm_decrypt, + # Given: one required encryption context (REC) key + required_encryption_context_keys=required_ec_keys + ) + ) + + pt, _ = client.decrypt( + source=ct, + # Given: required encryption context CMM (RECCMM) on decrypt + materials_manager=required_ec_cmm_decrypt, + # When: supply reproduced EC on decrypt + encryption_context=reproduced_ec, + ) + + # Then: decrypted plaintext matches original plaintext + assert pt == SOME_PLAINTEXT + + +@pytest.mark.parametrize("encryption_context", ENCRYPTION_CONTEXT_SUITE) +# FAILURE CASE 1 +# Encrypt with and store all encryption context in header +# On Decrypt supply additional encryption context not stored in the header; this MUST fail +# On Decrypt supply mismatched encryption context key values; this MUST fail +def test_GIVEN_default_CMM_with_EC_on_encrypt_AND_default_CMM_with_different_EC_on_decrypt_WHEN_decrypt_THEN_raise_AWSEncryptionSDKClientError( # noqa pylint: disable=line-too-long + encryption_context, +): + # This test swaps EC key/value pairs around; + # if there isn't a pair to swap, skip this test + if len(encryption_context) < 2: + return + + ct, _ = client.encrypt( + source=SOME_PLAINTEXT, + keyring=SOME_MULTI_KEYRING, + encryption_context=encryption_context, + ) + + # Create some different ECs to test failure on decrypt + + # Swap one key/value pair to create a "mismatched" EC + ec_iter = iter(encryption_context.items()) + one_k, one_v = next(ec_iter) + two_k, two_v = next(ec_iter) + some_mismatched_ec = copy.deepcopy(encryption_context) + some_mismatched_ec[one_k] = two_v + some_mismatched_ec[two_k] = one_v + + # Some other encryption context where its key/value pair is not in the encryption context on encrypt + some_reproduced_ec_not_in_ec = {"this is not in": "the original encryption context"} + + for decrypt_keyring in TEST_KEYRINGS_LIST: + # Then: decrypting with mismatched EC raises AWSEncryptionSDKClientError + with pytest.raises(AWSEncryptionSDKClientError): + # When: decrypt + client.decrypt( + source=ct, + keyring=decrypt_keyring, + # Given: different encryption context on decrypt + encryption_context=some_mismatched_ec, + ) + + # Then: decrypting with some other EC raises AWSEncryptionSDKClientError + with pytest.raises(AWSEncryptionSDKClientError): + # When: decrypt + client.decrypt( + source=ct, + keyring=decrypt_keyring, + # Given: different encryption context on decrypt + encryption_context=some_reproduced_ec_not_in_ec, + ) + + +@pytest.mark.parametrize("encryption_context", ENCRYPTION_CONTEXT_SUITE) +# FAILURE CASE 2 +# Encrypt will not store all Encryption Context, we will drop one entry but it will still get +# included in the +# header signture. +# Decrypt will not supply any reproduced Encryption Context; this MUST fail. +def test_GIVEN_RECCCMM_with_one_REC_key_on_encrypt_AND_default_CMM_with_no_EC_on_decrypt_WHEN_decrypt_THEN_raise_AWSEncryptionSDKClientError( # noqa pylint: disable=line-too-long + encryption_context, +): + # This test needs >1 item to supply as required encryption context + if len(encryption_context) < 1: + return + + # Grab one item from encryption_context to supply as reproduced EC + one_k, _ = next(iter(encryption_context.items())) + # Given: one required encryption context (REC) key + required_ec_keys = [one_k] + + default_cmm_encrypt = mpl_client.create_default_cryptographic_materials_manager( + CreateDefaultCryptographicMaterialsManagerInput( + keyring=SOME_MULTI_KEYRING, + ) + ) + + required_ec_cmm_encrypt = mpl_client.create_required_encryption_context_cmm( + CreateRequiredEncryptionContextCMMInput( + underlying_cmm=default_cmm_encrypt, + # Given: one required encryption context (REC) key + required_encryption_context_keys=required_ec_keys + ) + ) + + ct, _ = client.encrypt( + source=SOME_PLAINTEXT, + materials_manager=required_ec_cmm_encrypt, + encryption_context=encryption_context, + ) + + for decrypt_keyring in TEST_KEYRINGS_LIST: + # Then: decrypting with no EC raises AWSEncryptionSDKClientError + with pytest.raises(AWSEncryptionSDKClientError): + # When: decrypt + client.decrypt( + source=ct, + keyring=decrypt_keyring, + # Given: no encryption context on decrypt + ) + + +@pytest.mark.parametrize("encryption_context", ENCRYPTION_CONTEXT_SUITE) +# FAILURE CASE 3 +# Encrypt will not store all Encryption Context, we will drop one entry but it will still get +# included in the +# header signture. +# Decrypt will supply the correct key but incorrect value; this MUST fail. +def test_GIVEN_RECCMM_on_encrypt_AND_EC_with_wrong_value_for_key_on_decrypt_WHEN_decrypt_THEN_raise_AWSEncryptionSDKClientError( # noqa pylint: disable=line-too-long + encryption_context, +): + # This test needs >1 item to supply as required encryption context + if len(encryption_context) < 1: + return + + # Grab one item from encryption_context to supply as reproduced EC + one_k, _ = next(iter(encryption_context.items())) + # Given: one required encryption context (REC) key + required_ec_keys = [one_k] + # Create mismatched EC + some_mismatched_ec = copy.deepcopy(encryption_context) + some_mismatched_ec[one_k] = "some incorrect value NOT in the original encryption context" + + default_cmm_encrypt = mpl_client.create_default_cryptographic_materials_manager( + CreateDefaultCryptographicMaterialsManagerInput( + keyring=SOME_MULTI_KEYRING, + ) + ) + + required_ec_cmm_encrypt = mpl_client.create_required_encryption_context_cmm( + CreateRequiredEncryptionContextCMMInput( + underlying_cmm=default_cmm_encrypt, + required_encryption_context_keys=required_ec_keys + ) + ) + + ct, _ = client.encrypt( + source=SOME_PLAINTEXT, + materials_manager=required_ec_cmm_encrypt, + encryption_context=encryption_context, + ) + + for decrypt_keyring in TEST_KEYRINGS_LIST: + # Then: decrypting with mismatched EC raises AWSEncryptionSDKClientError + with pytest.raises(AWSEncryptionSDKClientError): + # When: decrypt + client.decrypt( + source=ct, + keyring=decrypt_keyring, + # Given: encryption context with wrong value for required key on decrypt + encryption_context=some_mismatched_ec, + ) + + +@pytest.mark.parametrize("encryption_context", ENCRYPTION_CONTEXT_SUITE) +# FAILURE CASE 4 +# Encrypt will not store all Encryption Context, we will drop one entry but it will still get +# included in the +# header signture. +# Decrypt will supply the correct key but incorrect value; this MUST fail. +def test_GIVEN_RECCMM_on_encrypt_AND_reproduced_EC_missing_REC_key_on_decrypt_WHEN_decrypt_THEN_raise_AWSEncryptionSDKClientError( # noqa pylint: disable=line-too-long + encryption_context, +): + # This test needs two EC items to have an incorrect reproduced EC + if len(encryption_context) < 2: + return + + # Grab one item from encryption_context to supply as reproduced EC + ec_iter = iter(encryption_context.items()) + required_k, _ = next(ec_iter) + required_ec_keys = [required_k] + # Grab another item to use as the reproduced EC + # where the key in reproduced EC is not in required encryption context keys + some_other_k, some_other_v = next(ec_iter) + incorrect_reproduced_ec = {some_other_k : some_other_v} + + default_cmm_encrypt = mpl_client.create_default_cryptographic_materials_manager( + CreateDefaultCryptographicMaterialsManagerInput( + keyring=SOME_MULTI_KEYRING, + ) + ) + + required_ec_cmm_encrypt = mpl_client.create_required_encryption_context_cmm( + CreateRequiredEncryptionContextCMMInput( + underlying_cmm=default_cmm_encrypt, + required_encryption_context_keys=required_ec_keys + ) + ) + + ct, _ = client.encrypt( + source=SOME_PLAINTEXT, + materials_manager=required_ec_cmm_encrypt, + encryption_context=encryption_context, + ) + + for decrypt_keyring in TEST_KEYRINGS_LIST: + # Then: decrypting with invalid EC raises AWSEncryptionSDKClientError + with pytest.raises(AWSEncryptionSDKClientError): + # When: decrypt + client.decrypt( + source=ct, + keyring=decrypt_keyring, + # Given: encryption context on decrypt does not have required EC key + encryption_context=incorrect_reproduced_ec, + ) + + +@pytest.mark.parametrize("encryption_context", ENCRYPTION_CONTEXT_SUITE) +# FAILURE CASE 5 +# Although we are requesting that we remove a RESERVED key word from the encryption context +# The CMM instantiation will still succeed because the CMM is meant to work with different +# higher level +# encryption libraries who may have different reserved keys. Encryption will ultimately fail. +def test_GIVEN_RECCMM_with_reserved_key_on_encrypt_WHEN_encrypt_THEN_raise_AWSEncryptionSDKClientError( + encryption_context +): + invalid_encryption_context = copy.deepcopy(encryption_context) + # Add reserved EC item to encryption context to make it invalid + reserved_ec_keyword = "aws-crypto-public-key" + invalid_encryption_context[reserved_ec_keyword] = "some value in reserved key" + required_ec_keys = [reserved_ec_keyword] + + default_cmm_encrypt = mpl_client.create_default_cryptographic_materials_manager( + CreateDefaultCryptographicMaterialsManagerInput( + keyring=SOME_MULTI_KEYRING, + ) + ) + + required_ec_cmm_encrypt = mpl_client.create_required_encryption_context_cmm( + CreateRequiredEncryptionContextCMMInput( + underlying_cmm=default_cmm_encrypt, + # Given: required encryption context keys has a reserved value + required_encryption_context_keys=required_ec_keys + ) + ) + + # Then: encrypting with reserved key in encryption context raises AWSEncryptionSDKClientError + with pytest.raises(AWSEncryptionSDKClientError): + # When: encrypt + client.encrypt( + source=SOME_PLAINTEXT, + materials_manager=required_ec_cmm_encrypt, + encryption_context=invalid_encryption_context, + ) + + +@pytest.mark.parametrize("encryption_context", ENCRYPTION_CONTEXT_SUITE) +@pytest.mark.parametrize("keyring", TEST_KEYRINGS_LIST) +def test_GIVEN_some_keyring_AND_some_EC_WHEN_decrypt_valid_message_with_mutated_EC_THEN_decryption_matches_expected_result( # noqa pylint: disable=line-too-long + keyring, + encryption_context, +): + # This test needs two EC items to have an incorrect reproduced EC + if len(encryption_context) < 2: + return + + # Additional EC + some_additional_ec = copy.deepcopy(encryption_context) + some_additional_ec["some extra key to add"] = "some extra value added" + + # Mismatched EC. Swap key/value pair to create a mismatched EC + ec_iter = iter(encryption_context.items()) + one_k, one_v = next(ec_iter) + two_k, two_v = next(ec_iter) + some_mismatched_ec = copy.deepcopy(encryption_context) + some_mismatched_ec[one_k] = two_v + some_mismatched_ec[two_k] = one_v + + ct, _ = client.encrypt( + source=SOME_PLAINTEXT, + # Given: some keyring + keyring=keyring, + # Given: some encryption context + encryption_context=encryption_context, + ) + + # Expected failure: incorrect EC + + # Then: decrypting with incorrect EC raises AWSEncryptionSDKClientError + with pytest.raises(AWSEncryptionSDKClientError): + # When: decrypt + client.decrypt( + source=ct, + keyring=keyring, + # Given: incorrect encryption context with an extra item + encryption_context=some_additional_ec, + ) + + # Expected failure: Mismatched EC (swapped value for 2 keys) + + # Then: decrypting with mismatched EC raises AWSEncryptionSDKClientError + with pytest.raises(AWSEncryptionSDKClientError): + # When: decrypt + client.decrypt( + source=ct, + keyring=keyring, + # Given: mismatched encryption context on decrypt + encryption_context=some_mismatched_ec, + ) + + # Expected success: No encryption context supplied on decrypt + # (Success because the message was not encrypted with required EC CMM) + + # When: decrypt + pt, _ = client.decrypt( + source=ct, + keyring=keyring, + # Given: no encryption context on decrypt + ) + + # Then: decrypted plaintext matches original plaintext + assert pt == SOME_PLAINTEXT + + # Expected success: Correct encryption context supplied on decrypt + + # When: decrypt + pt, _ = client.decrypt( + source=ct, + keyring=keyring, + # Given: no encryption context on decrypt + encryption_context=encryption_context, + ) + + # Then: decrypted plaintext matches original plaintext + assert pt == SOME_PLAINTEXT From 6ba5dd34e404188f2bfbecabe93fc1a2ccc85255 Mon Sep 17 00:00:00 2001 From: Lucas McDonald Date: Tue, 6 Aug 2024 07:41:53 -0700 Subject: [PATCH 09/16] clean --- src/aws_encryption_sdk/streaming_client.py | 3 +-- test/mpl/integ/test_required_ec_cmm.py | 4 +--- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/aws_encryption_sdk/streaming_client.py b/src/aws_encryption_sdk/streaming_client.py index 5b87abba0..64d77b91a 100644 --- a/src/aws_encryption_sdk/streaming_client.py +++ b/src/aws_encryption_sdk/streaming_client.py @@ -76,8 +76,7 @@ # Import internal ESDK modules that depend on the MPL from aws_encryption_sdk.materials_managers.mpl.cmm import CryptoMaterialsManagerFromMPL -except ImportError as e: - print("streamingerror " + str(e)) +except ImportError: _HAS_MPL = False _LOGGER = logging.getLogger(__name__) diff --git a/test/mpl/integ/test_required_ec_cmm.py b/test/mpl/integ/test_required_ec_cmm.py index 8a3560f49..1dd329f51 100644 --- a/test/mpl/integ/test_required_ec_cmm.py +++ b/test/mpl/integ/test_required_ec_cmm.py @@ -7,9 +7,7 @@ import pytest from aws_cryptographic_materialproviders.keystore import KeyStore from aws_cryptographic_materialproviders.keystore.config import KeyStoreConfig -from aws_cryptographic_materialproviders.keystore.models import ( - KMSConfigurationKmsKeyArn, -) +from aws_cryptographic_materialproviders.keystore.models import KMSConfigurationKmsKeyArn from aws_cryptographic_materialproviders.mpl import AwsCryptographicMaterialProviders from aws_cryptographic_materialproviders.mpl.config import MaterialProvidersConfig from aws_cryptographic_materialproviders.mpl.models import ( From e821d29a32d85bbc3668112be9d50aa71def4d86 Mon Sep 17 00:00:00 2001 From: Lucas McDonald Date: Tue, 6 Aug 2024 07:42:40 -0700 Subject: [PATCH 10/16] clean --- test/mpl/integ/test_required_ec_cmm.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/mpl/integ/test_required_ec_cmm.py b/test/mpl/integ/test_required_ec_cmm.py index 1dd329f51..01b7d59f6 100644 --- a/test/mpl/integ/test_required_ec_cmm.py +++ b/test/mpl/integ/test_required_ec_cmm.py @@ -1,3 +1,5 @@ +# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 import copy import random import secrets From a6cdf60740853287bcd4dc2211bfc050426669dd Mon Sep 17 00:00:00 2001 From: Lucas McDonald Date: Tue, 6 Aug 2024 07:47:00 -0700 Subject: [PATCH 11/16] clean --- test/mpl/integ/test_required_ec_cmm.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/test/mpl/integ/test_required_ec_cmm.py b/test/mpl/integ/test_required_ec_cmm.py index 01b7d59f6..14085d1b0 100644 --- a/test/mpl/integ/test_required_ec_cmm.py +++ b/test/mpl/integ/test_required_ec_cmm.py @@ -218,6 +218,7 @@ def test_GIVEN_same_EC_on_encrypt_and_decrypt_WHEN_encrypt_decrypt_cycle_THEN_de pt, _ = client.decrypt( source=ct, # Given: same encryption context on encrypt and decrypt + encryption_context=encryption_context, keyring=decrypt_keyring ) @@ -260,8 +261,9 @@ def test_GIVEN_RECCMM_with_one_REC_key_on_encrypt_AND_default_CMM_with_valid_rep # When: encrypt/decrypt cycle ct, _ = client.encrypt( source=SOME_PLAINTEXT, - materials_manager=required_ec_cmm, # Given: required encryption context CMM (RECCMM) on encrypt + materials_manager=required_ec_cmm, + # Given: encryption context with REC key on encrypt encryption_context=encryption_context, ) @@ -313,8 +315,9 @@ def test_GIVEN_RECCMM_with_one_REC_key_on_encrypt_AND_RECCMM_with_valid_reproduc # When: encrypt/decrypt cycle ct, _ = client.encrypt( source=SOME_PLAINTEXT, - materials_manager=required_ec_cmm_encrypt, # Given: required encryption context CMM (RECCMM) on encrypt + materials_manager=required_ec_cmm_encrypt, + # Given: encryption context with REC key on encrypt encryption_context=encryption_context, ) @@ -327,8 +330,9 @@ def test_GIVEN_RECCMM_with_one_REC_key_on_encrypt_AND_RECCMM_with_valid_reproduc required_ec_cmm_decrypt = mpl_client.create_required_encryption_context_cmm( CreateRequiredEncryptionContextCMMInput( + # Given: required encryption context CMM (RECCMM) on decrypt underlying_cmm=default_cmm_decrypt, - # Given: one required encryption context (REC) key + # Given: correct required encryption context (REC) keys on decrypt required_encryption_context_keys=required_ec_keys ) ) @@ -373,8 +377,8 @@ def test_GIVEN_default_CMM_on_encrypt_AND_default_CMM_with_valid_reproduced_EC_o # When: encrypt/decrypt cycle ct, _ = client.encrypt( source=SOME_PLAINTEXT, - materials_manager=default_cmm_encrypt, # Given: default CMM on encrypt + materials_manager=default_cmm_encrypt, encryption_context=encryption_context, ) From 0b8a4afcde15fc30e2fa0a951efee27640a9afcc Mon Sep 17 00:00:00 2001 From: Lucas McDonald Date: Fri, 9 Aug 2024 11:11:45 -0700 Subject: [PATCH 12/16] clean --- test/mpl/integ/test_required_ec_cmm.py | 228 +++---------------------- test/mpl/utils.py | 193 +++++++++++++++++++++ 2 files changed, 218 insertions(+), 203 deletions(-) create mode 100644 test/mpl/utils.py diff --git a/test/mpl/integ/test_required_ec_cmm.py b/test/mpl/integ/test_required_ec_cmm.py index 14085d1b0..82e69b79c 100644 --- a/test/mpl/integ/test_required_ec_cmm.py +++ b/test/mpl/integ/test_required_ec_cmm.py @@ -1,38 +1,20 @@ # Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. # SPDX-License-Identifier: Apache-2.0 import copy -import random -import secrets -import string -import boto3 import pytest -from aws_cryptographic_materialproviders.keystore import KeyStore -from aws_cryptographic_materialproviders.keystore.config import KeyStoreConfig -from aws_cryptographic_materialproviders.keystore.models import KMSConfigurationKmsKeyArn from aws_cryptographic_materialproviders.mpl import AwsCryptographicMaterialProviders from aws_cryptographic_materialproviders.mpl.config import MaterialProvidersConfig from aws_cryptographic_materialproviders.mpl.models import ( - AesWrappingAlg, - CacheTypeDefault, - CreateAwsKmsHierarchicalKeyringInput, - CreateAwsKmsKeyringInput, CreateDefaultCryptographicMaterialsManagerInput, - CreateMultiKeyringInput, - CreateRawAesKeyringInput, - CreateRawRsaKeyringInput, CreateRequiredEncryptionContextCMMInput, - DefaultCache, - PaddingScheme, ) -from aws_cryptographic_materialproviders.mpl.references import IKeyring -from cryptography.hazmat.backends import default_backend as crypto_default_backend -from cryptography.hazmat.primitives import serialization as crypto_serialization -from cryptography.hazmat.primitives.asymmetric import rsa import aws_encryption_sdk from aws_encryption_sdk.exceptions import AWSEncryptionSDKClientError +from ..utils import TestEncryptionContexts, TestKeyringCreator + pytestmark = [pytest.mark.integ] # ESDK client. Used to encrypt/decrypt in each test. @@ -44,145 +26,11 @@ ) -# Private raw AES keyring creator. -# Lifted from raw AES keyring example. -def _create_raw_aes_keyring(): - static_key = secrets.token_bytes(32) - - keyring_input: CreateRawAesKeyringInput = CreateRawAesKeyringInput( - key_namespace="some_key_namespace", - key_name="some_key_name", - wrapping_key=static_key, - wrapping_alg=AesWrappingAlg.ALG_AES256_GCM_IV12_TAG16 - ) - - raw_aes_keyring: IKeyring = mpl_client.create_raw_aes_keyring( - input=keyring_input - ) - - return raw_aes_keyring - - -# Private raw RSA keyring creator. -# Lifted from raw RSA keyring example. -def _create_raw_rsa_keyring(): - ssh_rsa_exponent = 65537 - bit_strength = 4096 - key = rsa.generate_private_key( - backend=crypto_default_backend(), - public_exponent=ssh_rsa_exponent, - key_size=bit_strength - ) - - public_key = key.public_key().public_bytes( - encoding=crypto_serialization.Encoding.PEM, - format=crypto_serialization.PublicFormat.SubjectPublicKeyInfo - ) - private_key = key.private_bytes( - encoding=crypto_serialization.Encoding.PEM, - format=crypto_serialization.PrivateFormat.TraditionalOpenSSL, - encryption_algorithm=crypto_serialization.NoEncryption() - ) - - key_name_space = "some_key_name_space" - key_name = "some_key_name" - - keyring_input: CreateRawRsaKeyringInput = CreateRawRsaKeyringInput( - key_namespace=key_name_space, - key_name=key_name, - padding_scheme=PaddingScheme.OAEP_SHA256_MGF1, - public_key=public_key, - private_key=private_key - ) - - raw_rsa_keyring: IKeyring = mpl_client.create_raw_rsa_keyring( - input=keyring_input - ) - - return raw_rsa_keyring - - -# Private KMS keyring creator. -# Lifted KMS keyring example. -def _create_kms_keyring(): - kms_client = boto3.client('kms', region_name="us-west-2") - keyring_input: CreateAwsKmsKeyringInput = CreateAwsKmsKeyringInput( - kms_key_id="arn:aws:kms:us-west-2:658956600833:key/b3537ef1-d8dc-4780-9f5a-55776cbb2f7f", - kms_client=kms_client - ) - - kms_keyring: IKeyring = mpl_client.create_aws_kms_keyring( - input=keyring_input - ) - - return kms_keyring - - -# Private hierarchical keyring creator. -# Lifted hierarchical keyring example. -def _create_hierarchical_keyring(): - kms_client = boto3.client('kms', region_name="us-west-2") - ddb_client = boto3.client('dynamodb', region_name="us-west-2") - - keystore: KeyStore = KeyStore( - config=KeyStoreConfig( - ddb_client=ddb_client, - ddb_table_name="KeyStoreDdbTable", - logical_key_store_name="KeyStoreDdbTable", - kms_client=kms_client, - kms_configuration=KMSConfigurationKmsKeyArn( - value='arn:aws:kms:us-west-2:370957321024:key/9d989aa2-2f9c-438c-a745-cc57d3ad0126' - ), - ) - ) - - keyring_input: CreateAwsKmsHierarchicalKeyringInput = CreateAwsKmsHierarchicalKeyringInput( - key_store=keystore, - branch_key_id='a52dfaad-7dbd-4430-a1fd-abaa5299da07', - ttl_seconds=600, - cache=CacheTypeDefault( - value=DefaultCache( - entry_capacity=100 - ) - ), - ) - - hierarchical_keyring: IKeyring = mpl_client.create_aws_kms_hierarchical_keyring( - input=keyring_input - ) - - return hierarchical_keyring - - -# Private multi-keyring creator. -def _create_multi_keyring(keyrings): - a = mpl_client.create_multi_keyring(CreateMultiKeyringInput( - generator=keyrings[0], - child_keyrings=keyrings[1:] - )) - return a - - -# Encryption contexts under test -SOME_EMPTY_ENCRYPTION_CONTEXT = {} -SOME_SINGLE_ITEM_ENCRYPTION_CONTEXT = {"some_key": "some_value"} -SOME_DOUBLE_ITEM_ENCRYPTION_CONTEXT = {"some_key": "some_value", "some_other_key": "some_other_value"} -SOME_MANY_ITEM_ENCRYPTION_CONTEXT = { - ''.join(random.choices(string.ascii_letters, k=6)) - : ''.join(random.choices(string.ascii_letters, k=6)) for _ in range(20) -} -ENCRYPTION_CONTEXT_SUITE = [ - SOME_EMPTY_ENCRYPTION_CONTEXT, - SOME_SINGLE_ITEM_ENCRYPTION_CONTEXT, - SOME_DOUBLE_ITEM_ENCRYPTION_CONTEXT, - SOME_MANY_ITEM_ENCRYPTION_CONTEXT, -] - # Keyrings under test -SOME_RSA_KEYRING = _create_raw_rsa_keyring() -SOME_AES_KEYRING = _create_raw_aes_keyring() -SOME_KMS_KEYRING = _create_kms_keyring() -SOME_HIERARCHICAL_KEYRING = _create_hierarchical_keyring() +SOME_RSA_KEYRING = TestKeyringCreator._create_raw_rsa_keyring() +SOME_AES_KEYRING = TestKeyringCreator._create_raw_aes_keyring() +SOME_KMS_KEYRING = TestKeyringCreator._create_kms_keyring() +SOME_HIERARCHICAL_KEYRING = TestKeyringCreator._create_hierarchical_keyring() TEST_KEYRINGS_LIST = [ SOME_AES_KEYRING, SOME_KMS_KEYRING, @@ -194,13 +42,13 @@ def _create_multi_keyring(keyrings): # this multi keyring encrypts one message, # then the test attempts decryption with all of its component keyrings # ("component" = generator + child keyrings). -SOME_MULTI_KEYRING = _create_multi_keyring(TEST_KEYRINGS_LIST) +SOME_MULTI_KEYRING = TestKeyringCreator._create_multi_keyring(TEST_KEYRINGS_LIST) SOME_PLAINTEXT = b"Hello World" -@pytest.mark.parametrize("encryption_context", ENCRYPTION_CONTEXT_SUITE) +@pytest.mark.parametrize("encryption_context", TestEncryptionContexts.ALL_ENCRYPTION_CONTEXTS) # HAPPY CASE 1 # Test supply same encryption context on encrypt and decrypt NO filtering def test_GIVEN_same_EC_on_encrypt_and_decrypt_WHEN_encrypt_decrypt_cycle_THEN_decrypt_matches_plaintext( @@ -226,7 +74,8 @@ def test_GIVEN_same_EC_on_encrypt_and_decrypt_WHEN_encrypt_decrypt_cycle_THEN_de assert pt == SOME_PLAINTEXT -@pytest.mark.parametrize("encryption_context", ENCRYPTION_CONTEXT_SUITE) +# This test needs >=1 item to supply as required encryption context +@pytest.mark.parametrize("encryption_context", TestEncryptionContexts.NONEMPTY_ENCRYPTION_CONTEXTS) # HAPPY CASE 2 # On Encrypt we will only write one encryption context key value to the header # we will then supply only what we didn't write wth no required ec cmm, @@ -234,10 +83,6 @@ def test_GIVEN_same_EC_on_encrypt_and_decrypt_WHEN_encrypt_decrypt_cycle_THEN_de def test_GIVEN_RECCMM_with_one_REC_key_on_encrypt_AND_default_CMM_with_valid_reproduced_EC_on_decrypt_WHEN_supply_reproduced_EC_with_REC_key_on_decrypt_THEN_decrypt_matches_plaintext( # noqa pylint: disable=line-too-long encryption_context ): - # This test needs >1 item to supply as required encryption context - if len(encryption_context) < 1: - return - # Grab one item from encryption_context to supply as reproduced EC one_k, one_v = next(iter(encryption_context.items())) reproduced_ec = {one_k: one_v} @@ -280,7 +125,8 @@ def test_GIVEN_RECCMM_with_one_REC_key_on_encrypt_AND_default_CMM_with_valid_rep assert pt == SOME_PLAINTEXT -@pytest.mark.parametrize("encryption_context", ENCRYPTION_CONTEXT_SUITE) +# This test needs >=1 item to supply as required encryption context +@pytest.mark.parametrize("encryption_context", TestEncryptionContexts.NONEMPTY_ENCRYPTION_CONTEXTS) # HAPPY CASE 3 # On Encrypt we will only write one encryption context key value to the header # we will then supply only what we didn't write but included in the signature while we @@ -288,10 +134,6 @@ def test_GIVEN_RECCMM_with_one_REC_key_on_encrypt_AND_default_CMM_with_valid_rep def test_GIVEN_RECCMM_with_one_REC_key_on_encrypt_AND_RECCMM_with_valid_reproduced_EC_on_decrypt_WHEN_supply_reproduced_EC_with_REC_key_on_decrypt_THEN_decrypt_matches_plaintext( # noqa pylint: disable=line-too-long encryption_context ): - # This test needs >1 item to supply as required encryption context - if len(encryption_context) < 1: - return - # Grab one item from encryption_context to supply as reproduced EC one_k, one_v = next(iter(encryption_context.items())) reproduced_ec = {one_k: one_v} @@ -349,7 +191,8 @@ def test_GIVEN_RECCMM_with_one_REC_key_on_encrypt_AND_RECCMM_with_valid_reproduc assert pt == SOME_PLAINTEXT -@pytest.mark.parametrize("encryption_context", ENCRYPTION_CONTEXT_SUITE) +# This test needs >=1 item to supply as required encryption context +@pytest.mark.parametrize("encryption_context", TestEncryptionContexts.NONEMPTY_ENCRYPTION_CONTEXTS) # HAPPY CASE 4 # On Encrypt we write all encryption context # as if the message was encrypted before the feature existed. @@ -358,10 +201,6 @@ def test_GIVEN_RECCMM_with_one_REC_key_on_encrypt_AND_RECCMM_with_valid_reproduc def test_GIVEN_default_CMM_on_encrypt_AND_default_CMM_with_valid_reproduced_EC_on_decrypt_WHEN_supply_reproduced_EC_with_REC_key_on_decrypt_THEN_decrypt_matches_plaintext( # noqa pylint: disable=line-too-long encryption_context ): - # This test needs >1 item to supply as required encryption context - if len(encryption_context) < 1: - return - # Grab one item from encryption_context to supply as reproduced EC one_k, one_v = next(iter(encryption_context.items())) reproduced_ec = {one_k: one_v} @@ -408,8 +247,8 @@ def test_GIVEN_default_CMM_on_encrypt_AND_default_CMM_with_valid_reproduced_EC_o # Then: decrypted plaintext matches original plaintext assert pt == SOME_PLAINTEXT - -@pytest.mark.parametrize("encryption_context", ENCRYPTION_CONTEXT_SUITE) +# This test needs >=2 items in EC so it can swap their key/value pairs +@pytest.mark.parametrize("encryption_context", TestEncryptionContexts.AT_LEAST_TWO_ITEMS_ENCRYPTION_CONTEXTS) # FAILURE CASE 1 # Encrypt with and store all encryption context in header # On Decrypt supply additional encryption context not stored in the header; this MUST fail @@ -417,11 +256,6 @@ def test_GIVEN_default_CMM_on_encrypt_AND_default_CMM_with_valid_reproduced_EC_o def test_GIVEN_default_CMM_with_EC_on_encrypt_AND_default_CMM_with_different_EC_on_decrypt_WHEN_decrypt_THEN_raise_AWSEncryptionSDKClientError( # noqa pylint: disable=line-too-long encryption_context, ): - # This test swaps EC key/value pairs around; - # if there isn't a pair to swap, skip this test - if len(encryption_context) < 2: - return - ct, _ = client.encrypt( source=SOME_PLAINTEXT, keyring=SOME_MULTI_KEYRING, @@ -463,7 +297,8 @@ def test_GIVEN_default_CMM_with_EC_on_encrypt_AND_default_CMM_with_different_EC_ ) -@pytest.mark.parametrize("encryption_context", ENCRYPTION_CONTEXT_SUITE) +# This test needs >=1 item to supply as required encryption context +@pytest.mark.parametrize("encryption_context", TestEncryptionContexts.NONEMPTY_ENCRYPTION_CONTEXTS) # FAILURE CASE 2 # Encrypt will not store all Encryption Context, we will drop one entry but it will still get # included in the @@ -472,10 +307,6 @@ def test_GIVEN_default_CMM_with_EC_on_encrypt_AND_default_CMM_with_different_EC_ def test_GIVEN_RECCCMM_with_one_REC_key_on_encrypt_AND_default_CMM_with_no_EC_on_decrypt_WHEN_decrypt_THEN_raise_AWSEncryptionSDKClientError( # noqa pylint: disable=line-too-long encryption_context, ): - # This test needs >1 item to supply as required encryption context - if len(encryption_context) < 1: - return - # Grab one item from encryption_context to supply as reproduced EC one_k, _ = next(iter(encryption_context.items())) # Given: one required encryption context (REC) key @@ -512,7 +343,8 @@ def test_GIVEN_RECCCMM_with_one_REC_key_on_encrypt_AND_default_CMM_with_no_EC_on ) -@pytest.mark.parametrize("encryption_context", ENCRYPTION_CONTEXT_SUITE) +# This test needs >=1 item to supply as required encryption context +@pytest.mark.parametrize("encryption_context", TestEncryptionContexts.NONEMPTY_ENCRYPTION_CONTEXTS) # FAILURE CASE 3 # Encrypt will not store all Encryption Context, we will drop one entry but it will still get # included in the @@ -521,10 +353,6 @@ def test_GIVEN_RECCCMM_with_one_REC_key_on_encrypt_AND_default_CMM_with_no_EC_on def test_GIVEN_RECCMM_on_encrypt_AND_EC_with_wrong_value_for_key_on_decrypt_WHEN_decrypt_THEN_raise_AWSEncryptionSDKClientError( # noqa pylint: disable=line-too-long encryption_context, ): - # This test needs >1 item to supply as required encryption context - if len(encryption_context) < 1: - return - # Grab one item from encryption_context to supply as reproduced EC one_k, _ = next(iter(encryption_context.items())) # Given: one required encryption context (REC) key @@ -564,7 +392,8 @@ def test_GIVEN_RECCMM_on_encrypt_AND_EC_with_wrong_value_for_key_on_decrypt_WHEN ) -@pytest.mark.parametrize("encryption_context", ENCRYPTION_CONTEXT_SUITE) +# This test needs >=2 items in EC so it create incorrect reproduced EC scenarios +@pytest.mark.parametrize("encryption_context", TestEncryptionContexts.AT_LEAST_TWO_ITEMS_ENCRYPTION_CONTEXTS) # FAILURE CASE 4 # Encrypt will not store all Encryption Context, we will drop one entry but it will still get # included in the @@ -573,10 +402,6 @@ def test_GIVEN_RECCMM_on_encrypt_AND_EC_with_wrong_value_for_key_on_decrypt_WHEN def test_GIVEN_RECCMM_on_encrypt_AND_reproduced_EC_missing_REC_key_on_decrypt_WHEN_decrypt_THEN_raise_AWSEncryptionSDKClientError( # noqa pylint: disable=line-too-long encryption_context, ): - # This test needs two EC items to have an incorrect reproduced EC - if len(encryption_context) < 2: - return - # Grab one item from encryption_context to supply as reproduced EC ec_iter = iter(encryption_context.items()) required_k, _ = next(ec_iter) @@ -617,7 +442,7 @@ def test_GIVEN_RECCMM_on_encrypt_AND_reproduced_EC_missing_REC_key_on_decrypt_WH ) -@pytest.mark.parametrize("encryption_context", ENCRYPTION_CONTEXT_SUITE) +@pytest.mark.parametrize("encryption_context", TestEncryptionContexts.ALL_ENCRYPTION_CONTEXTS) # FAILURE CASE 5 # Although we are requesting that we remove a RESERVED key word from the encryption context # The CMM instantiation will still succeed because the CMM is meant to work with different @@ -656,16 +481,13 @@ def test_GIVEN_RECCMM_with_reserved_key_on_encrypt_WHEN_encrypt_THEN_raise_AWSEn ) -@pytest.mark.parametrize("encryption_context", ENCRYPTION_CONTEXT_SUITE) +# This test needs >=2 items in EC so it create invalid reproduced EC scenarios +@pytest.mark.parametrize("encryption_context", TestEncryptionContexts.AT_LEAST_TWO_ITEMS_ENCRYPTION_CONTEXTS) @pytest.mark.parametrize("keyring", TEST_KEYRINGS_LIST) def test_GIVEN_some_keyring_AND_some_EC_WHEN_decrypt_valid_message_with_mutated_EC_THEN_decryption_matches_expected_result( # noqa pylint: disable=line-too-long keyring, encryption_context, ): - # This test needs two EC items to have an incorrect reproduced EC - if len(encryption_context) < 2: - return - # Additional EC some_additional_ec = copy.deepcopy(encryption_context) some_additional_ec["some extra key to add"] = "some extra value added" diff --git a/test/mpl/utils.py b/test/mpl/utils.py new file mode 100644 index 000000000..1de0a3405 --- /dev/null +++ b/test/mpl/utils.py @@ -0,0 +1,193 @@ +# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 +import random +import secrets +import string + +import boto3 +import pytest +from aws_cryptographic_materialproviders.keystore import KeyStore +from aws_cryptographic_materialproviders.keystore.config import KeyStoreConfig +from aws_cryptographic_materialproviders.keystore.models import KMSConfigurationKmsKeyArn +from aws_cryptographic_materialproviders.mpl import AwsCryptographicMaterialProviders +from aws_cryptographic_materialproviders.mpl.config import MaterialProvidersConfig +from aws_cryptographic_materialproviders.mpl.models import ( + AesWrappingAlg, + CacheTypeDefault, + CreateAwsKmsHierarchicalKeyringInput, + CreateAwsKmsKeyringInput, + CreateMultiKeyringInput, + CreateRawAesKeyringInput, + CreateRawRsaKeyringInput, + DefaultCache, + PaddingScheme, +) +from aws_cryptographic_materialproviders.mpl.references import IKeyring +from cryptography.hazmat.backends import default_backend as crypto_default_backend +from cryptography.hazmat.primitives import serialization as crypto_serialization +from cryptography.hazmat.primitives.asymmetric import rsa + +import aws_encryption_sdk + +pytestmark = [pytest.mark.integ] + +# ESDK client. Used to encrypt/decrypt in each test. +client = aws_encryption_sdk.EncryptionSDKClient() + +# MPL client. Used to create keyrings. +mpl_client: AwsCryptographicMaterialProviders = AwsCryptographicMaterialProviders( + config=MaterialProvidersConfig() +) + +class TestKeyringCreator: + + # Private raw AES keyring creator. + # Lifted from raw AES keyring example. + @staticmethod + def _create_raw_aes_keyring(): + static_key = secrets.token_bytes(32) + + keyring_input: CreateRawAesKeyringInput = CreateRawAesKeyringInput( + key_namespace="some_key_namespace", + key_name="some_key_name", + wrapping_key=static_key, + wrapping_alg=AesWrappingAlg.ALG_AES256_GCM_IV12_TAG16 + ) + + raw_aes_keyring: IKeyring = mpl_client.create_raw_aes_keyring( + input=keyring_input + ) + + return raw_aes_keyring + + + # Private raw RSA keyring creator. + # Lifted from raw RSA keyring example. + @staticmethod + def _create_raw_rsa_keyring(): + ssh_rsa_exponent = 65537 + bit_strength = 4096 + key = rsa.generate_private_key( + backend=crypto_default_backend(), + public_exponent=ssh_rsa_exponent, + key_size=bit_strength + ) + + public_key = key.public_key().public_bytes( + encoding=crypto_serialization.Encoding.PEM, + format=crypto_serialization.PublicFormat.SubjectPublicKeyInfo + ) + private_key = key.private_bytes( + encoding=crypto_serialization.Encoding.PEM, + format=crypto_serialization.PrivateFormat.TraditionalOpenSSL, + encryption_algorithm=crypto_serialization.NoEncryption() + ) + + key_name_space = "some_key_name_space" + key_name = "some_key_name" + + keyring_input: CreateRawRsaKeyringInput = CreateRawRsaKeyringInput( + key_namespace=key_name_space, + key_name=key_name, + padding_scheme=PaddingScheme.OAEP_SHA256_MGF1, + public_key=public_key, + private_key=private_key + ) + + raw_rsa_keyring: IKeyring = mpl_client.create_raw_rsa_keyring( + input=keyring_input + ) + + return raw_rsa_keyring + + + # Private KMS keyring creator. + # Lifted KMS keyring example. + @staticmethod + def _create_kms_keyring(): + kms_client = boto3.client('kms', region_name="us-west-2") + keyring_input: CreateAwsKmsKeyringInput = CreateAwsKmsKeyringInput( + kms_key_id="arn:aws:kms:us-west-2:658956600833:key/b3537ef1-d8dc-4780-9f5a-55776cbb2f7f", + kms_client=kms_client + ) + + kms_keyring: IKeyring = mpl_client.create_aws_kms_keyring( + input=keyring_input + ) + + return kms_keyring + + + # Private hierarchical keyring creator. + # Lifted hierarchical keyring example. + @staticmethod + def _create_hierarchical_keyring(): + kms_client = boto3.client('kms', region_name="us-west-2") + ddb_client = boto3.client('dynamodb', region_name="us-west-2") + + keystore: KeyStore = KeyStore( + config=KeyStoreConfig( + ddb_client=ddb_client, + ddb_table_name="KeyStoreDdbTable", + logical_key_store_name="KeyStoreDdbTable", + kms_client=kms_client, + kms_configuration=KMSConfigurationKmsKeyArn( + value='arn:aws:kms:us-west-2:370957321024:key/9d989aa2-2f9c-438c-a745-cc57d3ad0126' + ), + ) + ) + + keyring_input: CreateAwsKmsHierarchicalKeyringInput = CreateAwsKmsHierarchicalKeyringInput( + key_store=keystore, + branch_key_id='a52dfaad-7dbd-4430-a1fd-abaa5299da07', + ttl_seconds=600, + cache=CacheTypeDefault( + value=DefaultCache( + entry_capacity=100 + ) + ), + ) + + hierarchical_keyring: IKeyring = mpl_client.create_aws_kms_hierarchical_keyring( + input=keyring_input + ) + + return hierarchical_keyring + + + # Private multi-keyring creator. + @staticmethod + def _create_multi_keyring(keyrings): + a = mpl_client.create_multi_keyring(CreateMultiKeyringInput( + generator=keyrings[0], + child_keyrings=keyrings[1:] + )) + return a + +class TestEncryptionContexts: + + # Encryption contexts under test + SOME_EMPTY_ENCRYPTION_CONTEXT = {} + SOME_SINGLE_ITEM_ENCRYPTION_CONTEXT = {"some_key": "some_value"} + SOME_DOUBLE_ITEM_ENCRYPTION_CONTEXT = {"some_key": "some_value", "some_other_key": "some_other_value"} + SOME_MANY_ITEM_ENCRYPTION_CONTEXT = { + ''.join(random.choices(string.ascii_letters, k=6)) + : ''.join(random.choices(string.ascii_letters, k=6)) for _ in range(20) + } + ALL_ENCRYPTION_CONTEXTS = [ + SOME_EMPTY_ENCRYPTION_CONTEXT, + SOME_SINGLE_ITEM_ENCRYPTION_CONTEXT, + SOME_DOUBLE_ITEM_ENCRYPTION_CONTEXT, + SOME_MANY_ITEM_ENCRYPTION_CONTEXT, + ] + + NONEMPTY_ENCRYPTION_CONTEXTS = [ + SOME_SINGLE_ITEM_ENCRYPTION_CONTEXT, + SOME_DOUBLE_ITEM_ENCRYPTION_CONTEXT, + SOME_MANY_ITEM_ENCRYPTION_CONTEXT, + ] + + AT_LEAST_TWO_ITEMS_ENCRYPTION_CONTEXTS = [ + SOME_DOUBLE_ITEM_ENCRYPTION_CONTEXT, + SOME_MANY_ITEM_ENCRYPTION_CONTEXT, + ] \ No newline at end of file From d4266a4ce603484fcf1aea59361c7da5f7b0852a Mon Sep 17 00:00:00 2001 From: Lucas McDonald Date: Fri, 9 Aug 2024 11:13:18 -0700 Subject: [PATCH 13/16] clean --- test/mpl/integ/test_required_ec_cmm.py | 2 +- test/mpl/utils.py | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/test/mpl/integ/test_required_ec_cmm.py b/test/mpl/integ/test_required_ec_cmm.py index 82e69b79c..3567ffbeb 100644 --- a/test/mpl/integ/test_required_ec_cmm.py +++ b/test/mpl/integ/test_required_ec_cmm.py @@ -20,7 +20,7 @@ # ESDK client. Used to encrypt/decrypt in each test. client = aws_encryption_sdk.EncryptionSDKClient() -# MPL client. Used to create keyrings. +# MPL client. Used to create CMMs. mpl_client: AwsCryptographicMaterialProviders = AwsCryptographicMaterialProviders( config=MaterialProvidersConfig() ) diff --git a/test/mpl/utils.py b/test/mpl/utils.py index 1de0a3405..c05d7d9ff 100644 --- a/test/mpl/utils.py +++ b/test/mpl/utils.py @@ -27,12 +27,9 @@ from cryptography.hazmat.primitives import serialization as crypto_serialization from cryptography.hazmat.primitives.asymmetric import rsa -import aws_encryption_sdk pytestmark = [pytest.mark.integ] -# ESDK client. Used to encrypt/decrypt in each test. -client = aws_encryption_sdk.EncryptionSDKClient() # MPL client. Used to create keyrings. mpl_client: AwsCryptographicMaterialProviders = AwsCryptographicMaterialProviders( From f6319232dcbc44d99c297c63fbb3ed134dd226c5 Mon Sep 17 00:00:00 2001 From: Lucas McDonald Date: Fri, 9 Aug 2024 11:15:42 -0700 Subject: [PATCH 14/16] new --- test/mpl/integ/__init__.py | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 test/mpl/integ/__init__.py diff --git a/test/mpl/integ/__init__.py b/test/mpl/integ/__init__.py new file mode 100644 index 000000000..f94fd12a2 --- /dev/null +++ b/test/mpl/integ/__init__.py @@ -0,0 +1,2 @@ +# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 From 889f5c0bf48c06f62e8c45d03ce588e749a3cc34 Mon Sep 17 00:00:00 2001 From: Lucas McDonald Date: Fri, 9 Aug 2024 11:18:18 -0700 Subject: [PATCH 15/16] clean --- test/mpl/utils.py | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/test/mpl/utils.py b/test/mpl/utils.py index c05d7d9ff..0809aace4 100644 --- a/test/mpl/utils.py +++ b/test/mpl/utils.py @@ -5,7 +5,6 @@ import string import boto3 -import pytest from aws_cryptographic_materialproviders.keystore import KeyStore from aws_cryptographic_materialproviders.keystore.config import KeyStoreConfig from aws_cryptographic_materialproviders.keystore.models import KMSConfigurationKmsKeyArn @@ -27,15 +26,12 @@ from cryptography.hazmat.primitives import serialization as crypto_serialization from cryptography.hazmat.primitives.asymmetric import rsa - -pytestmark = [pytest.mark.integ] - - # MPL client. Used to create keyrings. mpl_client: AwsCryptographicMaterialProviders = AwsCryptographicMaterialProviders( config=MaterialProvidersConfig() ) + class TestKeyringCreator: # Private raw AES keyring creator. @@ -57,7 +53,6 @@ def _create_raw_aes_keyring(): return raw_aes_keyring - # Private raw RSA keyring creator. # Lifted from raw RSA keyring example. @staticmethod @@ -97,7 +92,6 @@ def _create_raw_rsa_keyring(): return raw_rsa_keyring - # Private KMS keyring creator. # Lifted KMS keyring example. @staticmethod @@ -114,7 +108,6 @@ def _create_kms_keyring(): return kms_keyring - # Private hierarchical keyring creator. # Lifted hierarchical keyring example. @staticmethod @@ -151,7 +144,6 @@ def _create_hierarchical_keyring(): return hierarchical_keyring - # Private multi-keyring creator. @staticmethod def _create_multi_keyring(keyrings): @@ -161,6 +153,7 @@ def _create_multi_keyring(keyrings): )) return a + class TestEncryptionContexts: # Encryption contexts under test @@ -187,4 +180,4 @@ class TestEncryptionContexts: AT_LEAST_TWO_ITEMS_ENCRYPTION_CONTEXTS = [ SOME_DOUBLE_ITEM_ENCRYPTION_CONTEXT, SOME_MANY_ITEM_ENCRYPTION_CONTEXT, - ] \ No newline at end of file + ] From 00ff40059aafab19324eb82f9311d3c34710994f Mon Sep 17 00:00:00 2001 From: Lucas McDonald Date: Fri, 9 Aug 2024 11:20:11 -0700 Subject: [PATCH 16/16] clean --- test/mpl/integ/test_required_ec_cmm.py | 1 + 1 file changed, 1 insertion(+) diff --git a/test/mpl/integ/test_required_ec_cmm.py b/test/mpl/integ/test_required_ec_cmm.py index 3567ffbeb..c99528f70 100644 --- a/test/mpl/integ/test_required_ec_cmm.py +++ b/test/mpl/integ/test_required_ec_cmm.py @@ -247,6 +247,7 @@ def test_GIVEN_default_CMM_on_encrypt_AND_default_CMM_with_valid_reproduced_EC_o # Then: decrypted plaintext matches original plaintext assert pt == SOME_PLAINTEXT + # This test needs >=2 items in EC so it can swap their key/value pairs @pytest.mark.parametrize("encryption_context", TestEncryptionContexts.AT_LEAST_TWO_ITEMS_ENCRYPTION_CONTEXTS) # FAILURE CASE 1