From d1a9fe74022b94584be4355561ac48fd7de418f6 Mon Sep 17 00:00:00 2001 From: June Blender Date: Thu, 24 Aug 2017 15:43:21 -0700 Subject: [PATCH 1/2] Scrub Python code comments --- README.rst | 7 ++-- test/integration/docs_examples_bytes.py | 21 +++++++----- .../docs_examples_multiple_providers.py | 34 ++++++++++++------- test/integration/docs_examples_strings.py | 14 +++++--- 4 files changed, 47 insertions(+), 29 deletions(-) diff --git a/README.rst b/README.rst index d6a90843c..213908bbc 100644 --- a/README.rst +++ b/README.rst @@ -44,7 +44,7 @@ An example of a CMM is the default CMM, which is automatically generated anywher key provider. The default CMM collects encrypted data keys from all master keys referenced by the master key provider. -An example of a more advanced CMM is the caching CMM, which caches cryptographic materials provided by a another CMM. +An example of a more advanced CMM is the caching CMM, which caches cryptographic materials provided by another CMM. Master Key Providers -------------------- @@ -57,12 +57,13 @@ To encrypt data in this client, a ``MasterKeyProvider`` object must contain at l Master Keys ----------- -Master keys provide data keys. +Master keys generate, encrypt, and decrypt data keys. An example of a master key is a `KMS customer master key (CMK)`_. Data Keys --------- -Data Keys are the actual encryption keys which are used to encrypt your data. +Data keys are the encryption keys that are used to encrypt your data. If your algorithm suite +uses a key derivation function, the data key is used to generate the key that directly encrypts the data. ***** Usage diff --git a/test/integration/docs_examples_bytes.py b/test/integration/docs_examples_bytes.py index b48c26913..ef7a46e6f 100644 --- a/test/integration/docs_examples_bytes.py +++ b/test/integration/docs_examples_bytes.py @@ -21,17 +21,17 @@ class StaticRandomMasterKeyProvider(RawMasterKeyProvider): - """Randomly generates and provides 256-bit keys consistently per unique key id.""" + """Randomly generates 256-bit keys for each unique key ID.""" provider_id = 'static-random' def __init__(self, **kwargs): self._static_keys = {} def _get_raw_key(self, key_id): - """Retrieves a static, randomly generated, symmetric key for the specified key id. + """Returns a static, randomly-generated symmetric key for the specified key ID. :param str key_id: Key ID - :returns: Wrapping key which contains the specified static key + :returns: Wrapping key that contains the specified static key :rtype: :class:`aws_encryption_sdk.internal.crypto.WrappingKey` """ try: @@ -47,12 +47,12 @@ def _get_raw_key(self, key_id): def cycle_file(source_plaintext_filename): - """Encrypts and then decrypts a file under a custom static Master Key Provider. + """Encrypts and then decrypts a file under a custom static master key provider. :param str source_plaintext_filename: Filename of file to encrypt """ - # Create the Static Random Master Key Provider + # Create a static random master key provider key_id = os.urandom(8) master_key_provider = StaticRandomMasterKeyProvider() master_key_provider.add_master_key(key_id) @@ -60,7 +60,7 @@ def cycle_file(source_plaintext_filename): ciphertext_filename = source_plaintext_filename + '.encrypted' cycled_plaintext_filename = source_plaintext_filename + '.decrypted' - # Encrypt the source plaintext + # Encrypt the plaintext source data with open(source_plaintext_filename, 'rb') as plaintext, open(ciphertext_filename, 'wb') as ciphertext: with aws_encryption_sdk.stream( mode='e', @@ -80,10 +80,15 @@ def cycle_file(source_plaintext_filename): for chunk in decryptor: plaintext.write(chunk) - # Validate that the cycled plaintext is identical to the source plaintext + # Verify that the "cycled" (encrypted, then decrypted) plaintext is identical to the source + # plaintext assert filecmp.cmp(source_plaintext_filename, cycled_plaintext_filename) - # Validate that the encryption context used by the decryptor has all the key-pairs from the encryptor + # Verify that the encryption context used in the decrypt operation includes all key pairs from + # the encrypt operation + # + # In production, always use a meaningful encryption context. In this sample, we omit the + # encryption context (no key pairs). assert all( pair in decryptor.header.encryption_context.items() for pair in encryptor.header.encryption_context.items() diff --git a/test/integration/docs_examples_multiple_providers.py b/test/integration/docs_examples_multiple_providers.py index 1860da8bf..5e8ad173c 100644 --- a/test/integration/docs_examples_multiple_providers.py +++ b/test/integration/docs_examples_multiple_providers.py @@ -33,8 +33,8 @@ def __init__(self, **kwargs): def _get_raw_key(self, key_id): """Retrieves a static, randomly generated, RSA key for the specified key id. - :param str key_id: Key ID - :returns: Wrapping key which contains the specified static key + :param str key_id: : User-defined ID for the static key + :returns: Wrapping key that contains the specified static key :rtype: :class:`aws_encryption_sdk.internal.crypto.WrappingKey` """ try: @@ -59,33 +59,36 @@ def _get_raw_key(self, key_id): def cycle_file(key_arn, source_plaintext_filename, botocore_session=None): - """Encrypts and then decrypts a file under both a KMS Master Key Provider and a custom static Master Key Provider. +"""Encrypts and then decrypts a file using a KMS master key provider and a custom static master + key provider. Both master key providers are used to encrypt the plaintext file, so either one alone + can decrypt it. - :param str key_arn: Amazon Resource Name (Arn) of the KMS CMK + :param str key_arn: Amazon Resource Name (ARN) of the KMS Customer Master Key (CMK) (http://docs.aws.amazon.com/kms/latest/developerguide/viewing-keys.html) :param str source_plaintext_filename: Filename of file to encrypt :param botocore_session: existing botocore session instance :type botocore_session: botocore.session.Session """ - + + # "Cycled" means encrypted and then decrypted ciphertext_filename = source_plaintext_filename + '.encrypted' cycled_kms_plaintext_filename = source_plaintext_filename + '.kms.decrypted' cycled_static_plaintext_filename = source_plaintext_filename + '.static.decrypted' - # Create KMS Master Key Provider + # Create a KMS master key provider kms_kwargs = dict(key_ids=[key_arn]) if botocore_session is not None: kms_kwargs['botocore_session'] = botocore_session kms_master_key_provider = aws_encryption_sdk.KMSMasterKeyProvider(**kms_kwargs) - # Create Static Master Key Provider and add to KMS Master Key Provider + # Create a static master key provider and add a master key to it static_key_id = os.urandom(8) static_master_key_provider = StaticRandomMasterKeyProvider() static_master_key_provider.add_master_key(static_key_id) - # Add Static Master Key Provider to KMS Master Key Provider + # Create a master key provider that includes the KMS and static master key providers kms_master_key_provider.add_master_key_provider(static_master_key_provider) - # Encrypt plaintext with both KMS and Static Master Keys + # Encrypt plaintext with both KMS and static master keys with open(source_plaintext_filename, 'rb') as plaintext, open(ciphertext_filename, 'wb') as ciphertext: with aws_encryption_sdk.stream( source=plaintext, @@ -95,7 +98,7 @@ def cycle_file(key_arn, source_plaintext_filename, botocore_session=None): for chunk in encryptor: ciphertext.write(chunk) - # Decrypt the ciphertext with the KMS Master Key + # Decrypt the ciphertext with only the KMS master key with open(ciphertext_filename, 'rb') as ciphertext, open(cycled_kms_plaintext_filename, 'wb') as plaintext: with aws_encryption_sdk.stream( source=ciphertext, @@ -105,7 +108,7 @@ def cycle_file(key_arn, source_plaintext_filename, botocore_session=None): for chunk in kms_decryptor: plaintext.write(chunk) - # Decrypt the ciphertext with the Static Master Key only + # Decrypt the ciphertext with only the static master key with open(ciphertext_filename, 'rb') as ciphertext, open(cycled_static_plaintext_filename, 'wb') as plaintext: with aws_encryption_sdk.stream( source=ciphertext, @@ -115,11 +118,16 @@ def cycle_file(key_arn, source_plaintext_filename, botocore_session=None): for chunk in static_decryptor: plaintext.write(chunk) - # Validate that the cycled plaintext is identical to the source plaintext + # Verify that the "cycled" (encrypted, then decrypted) plaintext is identical to the source plaintext assert filecmp.cmp(source_plaintext_filename, cycled_kms_plaintext_filename) assert filecmp.cmp(source_plaintext_filename, cycled_static_plaintext_filename) - # Validate that the encryption context used by the decryptor has all the key-pairs from the encryptor + + # Verify that the encryption context in the decrypt operation includes all key pairs from the + # encrypt operation. + # + # In production, always use a meaningful encryption context. In this sample, we omit the + # encryption context (no key pairs). assert all( pair in kms_decryptor.header.encryption_context.items() for pair in encryptor.header.encryption_context.items() diff --git a/test/integration/docs_examples_strings.py b/test/integration/docs_examples_strings.py index 12de4d02f..cb9b906b5 100644 --- a/test/integration/docs_examples_strings.py +++ b/test/integration/docs_examples_strings.py @@ -19,19 +19,19 @@ def cycle_string(key_arn, source_plaintext, botocore_session=None): """Encrypts and then decrypts a string under a KMS customer master key (CMK) - :param str key_arn: Amazon Resource Name (Arn) of the KMS CMK + :param str key_arn: Amazon Resource Name (ARN) of the KMS CMK :param bytes source_plaintext: Data to encrypt :param botocore_session: existing botocore session instance :type botocore_session: botocore.session.Session """ - # Create the KMS Master Key Provider + # Create a KMS master key provider kms_kwargs = dict(key_ids=[key_arn]) if botocore_session is not None: kms_kwargs['botocore_session'] = botocore_session master_key_provider = aws_encryption_sdk.KMSMasterKeyProvider(**kms_kwargs) - # Encrypt the source plaintext + # Encrypt the plaintext source data ciphertext, encryptor_header = aws_encryption_sdk.encrypt( source=source_plaintext, key_provider=master_key_provider @@ -44,10 +44,14 @@ def cycle_string(key_arn, source_plaintext, botocore_session=None): key_provider=master_key_provider ) - # Validate that the cycled plaintext is identical to the source plaintext + # Verify that the "cycled" (encrypted, then decrypted) plaintext is identical to the source plaintext assert cycled_plaintext == source_plaintext - # Validate that the encryption context used by the decryptor has all the key-pairs from the encryptor + # Verify that the encryption context used in the decrypt operation includes all key pairs from + # the encrypt operation. (The SDK can add pairs, so don't require an exact match.) + # + # In production, always use a meaningful encryption context. In this sample, we omit the + # encryption context (no key pairs). assert all( pair in decrypted_header.encryption_context.items() for pair in encryptor_header.encryption_context.items() From b41465749328624aeb58901e66eecc05147af252 Mon Sep 17 00:00:00 2001 From: June Blender Date: Thu, 31 Aug 2017 09:56:35 -0700 Subject: [PATCH 2/2] Responding to PR issues --- test/integration/docs_examples_multiple_providers.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/test/integration/docs_examples_multiple_providers.py b/test/integration/docs_examples_multiple_providers.py index 5e8ad173c..65d514030 100644 --- a/test/integration/docs_examples_multiple_providers.py +++ b/test/integration/docs_examples_multiple_providers.py @@ -33,7 +33,7 @@ def __init__(self, **kwargs): def _get_raw_key(self, key_id): """Retrieves a static, randomly generated, RSA key for the specified key id. - :param str key_id: : User-defined ID for the static key + :param str key_id: User-defined ID for the static key :returns: Wrapping key that contains the specified static key :rtype: :class:`aws_encryption_sdk.internal.crypto.WrappingKey` """ @@ -59,7 +59,7 @@ def _get_raw_key(self, key_id): def cycle_file(key_arn, source_plaintext_filename, botocore_session=None): -"""Encrypts and then decrypts a file using a KMS master key provider and a custom static master + """Encrypts and then decrypts a file using a KMS master key provider and a custom static master key provider. Both master key providers are used to encrypt the plaintext file, so either one alone can decrypt it. @@ -85,7 +85,9 @@ def cycle_file(key_arn, source_plaintext_filename, botocore_session=None): static_master_key_provider = StaticRandomMasterKeyProvider() static_master_key_provider.add_master_key(static_key_id) - # Create a master key provider that includes the KMS and static master key providers + # Add the static master key provider to the KMS master key provider + # The resulting master key provider uses KMS master keys to generate (and encrypt) + # data keys and static master keys to create an additional encrypted copy of each data key. kms_master_key_provider.add_master_key_provider(static_master_key_provider) # Encrypt plaintext with both KMS and static master keys