diff --git a/src/aws_encryption_sdk/__init__.py b/src/aws_encryption_sdk/__init__.py index 3f6d86e2e..3aae2c9c7 100644 --- a/src/aws_encryption_sdk/__init__.py +++ b/src/aws_encryption_sdk/__init__.py @@ -14,7 +14,7 @@ # Below are imported for ease of use by implementors from aws_encryption_sdk.caches.local import LocalCryptoMaterialsCache # noqa from aws_encryption_sdk.caches.null import NullCryptoMaterialsCache # noqa -from aws_encryption_sdk.identifiers import Algorithm, __version__ # noqa +from aws_encryption_sdk.identifiers import AlgorithmSuite, __version__ # noqa from aws_encryption_sdk.key_providers.kms import KMSMasterKeyProvider, KMSMasterKeyProviderConfig # noqa from aws_encryption_sdk.materials_managers.caching import CachingCryptoMaterialsManager # noqa from aws_encryption_sdk.materials_managers.default import DefaultCryptoMaterialsManager # noqa @@ -69,8 +69,8 @@ def encrypt(**kwargs): this is not enforced if a `key_provider` is provided. :param dict encryption_context: Dictionary defining encryption context - :param algorithm: Algorithm to use for encryption - :type algorithm: aws_encryption_sdk.identifiers.Algorithm + :param algorithm: Algorithm suite to use for encryption + :type algorithm: aws_encryption_sdk.identifiers.AlgorithmSuite :param int frame_length: Frame length in bytes :returns: Tuple containing the encrypted ciphertext and the message header object :rtype: tuple of bytes and :class:`aws_encryption_sdk.structures.MessageHeader` diff --git a/src/aws_encryption_sdk/identifiers.py b/src/aws_encryption_sdk/identifiers.py index e3c13c1ea..940ff7317 100644 --- a/src/aws_encryption_sdk/identifiers.py +++ b/src/aws_encryption_sdk/identifiers.py @@ -240,6 +240,8 @@ def safe_to_cache(self): return self.kdf is not KDFSuite.NONE +# algorithm is just an alias for AlgorithmSuite ... but Sphinx does not recognize this fact +# so we need to go through and fix the references Algorithm = AlgorithmSuite @@ -271,9 +273,27 @@ class WrappingAlgorithm(Enum): :type padding_mgf: """ - AES_128_GCM_IV12_TAG16_NO_PADDING = (EncryptionType.SYMMETRIC, Algorithm.AES_128_GCM_IV12_TAG16, None, None, None) - AES_192_GCM_IV12_TAG16_NO_PADDING = (EncryptionType.SYMMETRIC, Algorithm.AES_192_GCM_IV12_TAG16, None, None, None) - AES_256_GCM_IV12_TAG16_NO_PADDING = (EncryptionType.SYMMETRIC, Algorithm.AES_256_GCM_IV12_TAG16, None, None, None) + AES_128_GCM_IV12_TAG16_NO_PADDING = ( + EncryptionType.SYMMETRIC, + AlgorithmSuite.AES_128_GCM_IV12_TAG16, + None, + None, + None, + ) + AES_192_GCM_IV12_TAG16_NO_PADDING = ( + EncryptionType.SYMMETRIC, + AlgorithmSuite.AES_192_GCM_IV12_TAG16, + None, + None, + None, + ) + AES_256_GCM_IV12_TAG16_NO_PADDING = ( + EncryptionType.SYMMETRIC, + AlgorithmSuite.AES_256_GCM_IV12_TAG16, + None, + None, + None, + ) RSA_PKCS1 = (EncryptionType.ASYMMETRIC, rsa, padding.PKCS1v15, None, None) RSA_OAEP_SHA1_MGF1 = (EncryptionType.ASYMMETRIC, rsa, padding.OAEP, hashes.SHA1, padding.MGF1) RSA_OAEP_SHA256_MGF1 = (EncryptionType.ASYMMETRIC, rsa, padding.OAEP, hashes.SHA256, padding.MGF1) diff --git a/src/aws_encryption_sdk/internal/crypto/authentication.py b/src/aws_encryption_sdk/internal/crypto/authentication.py index 560fdb2a2..dc9929bf7 100644 --- a/src/aws_encryption_sdk/internal/crypto/authentication.py +++ b/src/aws_encryption_sdk/internal/crypto/authentication.py @@ -33,8 +33,8 @@ class _PrehashingAuthenticator(object): """Parent class for Signer/Verifier. Provides common behavior and interface. - :param algorithm: Algorithm on which to base authenticator - :type algorithm: aws_encryption_sdk.identifiers.Algorithm + :param algorithm: Algorithm suite on which to base authenticator + :type algorithm: aws_encryption_sdk.identifiers.AlgorithmSuite :param key: Key with which to build authenticator """ @@ -46,7 +46,7 @@ def __init__(self, algorithm, key): self._hasher = self._build_hasher() def _set_signature_type(self): - """Ensures that the algorithm signature type is a known type and sets a reference value.""" + """Ensures that the algorithm (suite) signature type is a known type and sets a reference value.""" try: verify_interface(ec.EllipticCurve, self.algorithm.signing_algorithm_info) return ec.EllipticCurve @@ -64,8 +64,8 @@ def _build_hasher(self): class Signer(_PrehashingAuthenticator): """Abstract signing handler. - :param algorithm: Algorithm on which to base signer - :type algorithm: aws_encryption_sdk.identifiers.Algorithm + :param algorithm: Algorithm suite on which to base signer + :type algorithm: aws_encryption_sdk.identifiers.AlgorithmSuite :param key: Private key from which a signer can be generated :type key: currently only Elliptic Curve Private Keys are supported """ @@ -74,8 +74,8 @@ class Signer(_PrehashingAuthenticator): def from_key_bytes(cls, algorithm, key_bytes): """Builds a `Signer` from an algorithm suite and a raw signing key. - :param algorithm: Algorithm on which to base signer - :type algorithm: aws_encryption_sdk.identifiers.Algorithm + :param algorithm: Algorithm suite on which to base signer + :type algorithm: aws_encryption_sdk.identifiers.AlgorithmSuite :param bytes key_bytes: Raw signing key :rtype: aws_encryption_sdk.internal.crypto.Signer """ @@ -127,18 +127,18 @@ class Verifier(_PrehashingAuthenticator): .. note:: For ECC curves, the signature must be DER encoded as specified in RFC 3279. - :param algorithm: Algorithm on which to base verifier - :type algorithm: aws_encryption_sdk.identifiers.Algorithm - :param public_key: Appropriate public key object for algorithm + :param algorithm: Algorithm suite on which to base verifier + :type algorithm: aws_encryption_sdk.identifiers.AlgorithmSuite + :param public_key: Appropriate public key object for algorithm suite :type public_key: may vary """ @classmethod def from_encoded_point(cls, algorithm, encoded_point): - """Creates a Verifier object based on the supplied algorithm and encoded compressed ECC curve point. + """Creates a Verifier object based on the supplied algorithm suite and encoded compressed ECC curve point. - :param algorithm: Algorithm on which to base verifier - :type algorithm: aws_encryption_sdk.identifiers.Algorithm + :param algorithm: Algorithm suite on which to base verifier + :type algorithm: aws_encryption_sdk.identifiers.AlgorithmSuite :param bytes encoded_point: ECC public point compressed and encoded with _ecc_encode_compressed_point :returns: Instance of Verifier generated from encoded point :rtype: aws_encryption_sdk.internal.crypto.Verifier @@ -152,10 +152,10 @@ def from_encoded_point(cls, algorithm, encoded_point): @classmethod def from_key_bytes(cls, algorithm, key_bytes): - """Creates a `Verifier` object based on the supplied algorithm and raw verification key. + """Creates a `Verifier` object based on the supplied algorithm suite and raw verification key. - :param algorithm: Algorithm on which to base verifier - :type algorithm: aws_encryption_sdk.identifiers.Algorithm + :param algorithm: Algorithm suite on which to base verifier + :type algorithm: aws_encryption_sdk.identifiers.AlgorithmSuite :param bytes encoded_point: Raw verification key :returns: Instance of Verifier generated from encoded point :rtype: aws_encryption_sdk.internal.crypto.Verifier diff --git a/src/aws_encryption_sdk/internal/crypto/data_keys.py b/src/aws_encryption_sdk/internal/crypto/data_keys.py index f16873106..4d773f9ec 100644 --- a/src/aws_encryption_sdk/internal/crypto/data_keys.py +++ b/src/aws_encryption_sdk/internal/crypto/data_keys.py @@ -20,11 +20,11 @@ def derive_data_encryption_key(source_key, algorithm, message_id): - """Derives the data encryption key using the defined algorithm. + """Derives the data encryption key using the defined algorithm suite. :param bytes source_key: Raw source key - :param algorithm: Algorithm used to encrypt this body - :type algorithm: aws_encryption_sdk.identifiers.Algorithm + :param algorithm: Algorithm suite used to encrypt this body + :type algorithm: aws_encryption_sdk.identifiers.AlgorithmSuite :param bytes message_id: Message ID :returns: Derived data encryption key :rtype: bytes diff --git a/src/aws_encryption_sdk/internal/crypto/elliptic_curve.py b/src/aws_encryption_sdk/internal/crypto/elliptic_curve.py index 47af50b8c..56f49976e 100644 --- a/src/aws_encryption_sdk/internal/crypto/elliptic_curve.py +++ b/src/aws_encryption_sdk/internal/crypto/elliptic_curve.py @@ -57,8 +57,8 @@ def _ecc_static_length_signature(key, algorithm, digest): :param key: Elliptic curve private key :type key: cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePrivateKey - :param algorithm: Master algorithm to use - :type algorithm: aws_encryption_sdk.identifiers.Algorithm + :param algorithm: Master algorithm suite to use + :type algorithm: aws_encryption_sdk.identifiers.AlgorithmSuite :param bytes digest: Pre-calculated hash digest :returns: Signature with required length :rtype: bytes @@ -177,10 +177,10 @@ def _ecc_public_numbers_from_compressed_point(curve, compressed_point): def generate_ecc_signing_key(algorithm): """Returns an ECC signing key. - :param algorithm: Algorithm object which determines what signature to generate - :type algorithm: aws_encryption_sdk.identifiers.Algorithm + :param algorithm: Algorithm suite object which determines what signature to generate + :type algorithm: aws_encryption_sdk.identifiers.AlgorithmSuite :returns: Generated signing key - :raises NotSupportedError: if signing algorithm is not supported on this platform + :raises NotSupportedError: if signing algorithm suite is not supported on this platform """ try: verify_interface(ec.EllipticCurve, algorithm.signing_algorithm_info) diff --git a/src/aws_encryption_sdk/internal/crypto/encryption.py b/src/aws_encryption_sdk/internal/crypto/encryption.py index 1e5523826..b6251e3ca 100644 --- a/src/aws_encryption_sdk/internal/crypto/encryption.py +++ b/src/aws_encryption_sdk/internal/crypto/encryption.py @@ -24,8 +24,8 @@ class Encryptor(object): """Abstract encryption handler. - :param algorithm: Algorithm used to encrypt this body - :type algorithm: aws_encryption_sdk.identifiers.Algorithm + :param algorithm: Algorithm suite used to encrypt this body + :type algorithm: aws_encryption_sdk.identifiers.AlgorithmSuite :param bytes key: Encryption key :param bytes associated_data: Associated Data to send to encryption subsystem :param bytes iv: IV to use when encrypting message @@ -76,8 +76,8 @@ def tag(self): def encrypt(algorithm, key, plaintext, associated_data, iv): """Encrypts a frame body. - :param algorithm: Algorithm used to encrypt this body - :type algorithm: aws_encryption_sdk.identifiers.Algorithm + :param algorithm: Algorithm suite used to encrypt this body + :type algorithm: aws_encryption_sdk.identifiers.AlgorithmSuite :param bytes key: Encryption key :param bytes plaintext: Body plaintext :param bytes associated_data: Body AAD Data @@ -93,8 +93,8 @@ def encrypt(algorithm, key, plaintext, associated_data, iv): class Decryptor(object): """Abstract decryption handler. - :param algorithm: Algorithm used to encrypt this body - :type algorithm: aws_encryption_sdk.identifiers.Algorithm + :param algorithm: Algorithm suite used to encrypt this body + :type algorithm: aws_encryption_sdk.identifiers.AlgorithmSuite :param bytes key: Raw source key :param bytes associated_data: Associated Data to send to decryption subsystem :param bytes iv: IV value with which to initialize decryption subsystem @@ -135,8 +135,8 @@ def finalize(self): def decrypt(algorithm, key, encrypted_data, associated_data): """Decrypts a frame body. - :param algorithm: Algorithm used to encrypt this body - :type algorithm: aws_encryption_sdk.identifiers.Algorithm + :param algorithm: Algorithm suite used to encrypt this body + :type algorithm: aws_encryption_sdk.identifiers.AlgorithmSuite :param bytes key: Plaintext data key :param encrypted_data: EncryptedData containing body data :type encrypted_data: :class:`aws_encryption_sdk.internal.structures.EncryptedData`, diff --git a/src/aws_encryption_sdk/internal/crypto/iv.py b/src/aws_encryption_sdk/internal/crypto/iv.py index e5424057b..d6515df7c 100644 --- a/src/aws_encryption_sdk/internal/crypto/iv.py +++ b/src/aws_encryption_sdk/internal/crypto/iv.py @@ -46,8 +46,8 @@ def frame_iv(algorithm, sequence_number): """Builds the deterministic IV for a body frame. - :param algorithm: Algorithm for which to build IV - :type algorithm: aws_encryption_sdk.identifiers.Algorithm + :param algorithm: Algorithm suite for which to build IV + :type algorithm: aws_encryption_sdk.identifiers.AlgorithmSuite :param int sequence_number: Frame sequence number :returns: Generated IV :rtype: bytes @@ -67,8 +67,8 @@ def frame_iv(algorithm, sequence_number): def non_framed_body_iv(algorithm): """Builds the deterministic IV for a non-framed body. - :param algorithm: Algorithm for which to build IV - :type algorithm: aws_encryption_sdk.identifiers.Algorithm + :param algorithm: Algorithm suite for which to build IV + :type algorithm: aws_encryption_sdk.identifiers.AlgorithmSuite :returns: Generated IV :rtype: bytes """ @@ -78,8 +78,8 @@ def non_framed_body_iv(algorithm): def header_auth_iv(algorithm): """Builds the deterministic IV for header authentication. - :param algorithm: Algorithm for which to build IV - :type algorithm: aws_encryption_sdk.identifiers.Algorithm + :param algorithm: Algorithm suite for which to build IV + :type algorithm: aws_encryption_sdk.identifiers.AlgorithmSuite :returns: Generated IV :rtype: bytes """ diff --git a/src/aws_encryption_sdk/internal/defaults.py b/src/aws_encryption_sdk/internal/defaults.py index f63a42d61..2dc4ae0c4 100644 --- a/src/aws_encryption_sdk/internal/defaults.py +++ b/src/aws_encryption_sdk/internal/defaults.py @@ -29,7 +29,7 @@ #: Default message structure Type as defined in specification TYPE = aws_encryption_sdk.identifiers.ObjectType.CUSTOMER_AE_DATA #: Default algorithm as defined in specification -ALGORITHM = aws_encryption_sdk.identifiers.Algorithm.AES_256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384 +ALGORITHM = aws_encryption_sdk.identifiers.AlgorithmSuite.AES_256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384 #: Key to add encoded signing key to encryption context dictionary as defined in specification ENCODED_SIGNER_KEY = "aws-crypto-public-key" diff --git a/src/aws_encryption_sdk/internal/formatting/deserialize.py b/src/aws_encryption_sdk/internal/formatting/deserialize.py index 894205eb5..74a61bfe7 100644 --- a/src/aws_encryption_sdk/internal/formatting/deserialize.py +++ b/src/aws_encryption_sdk/internal/formatting/deserialize.py @@ -29,6 +29,7 @@ ) from aws_encryption_sdk.internal.crypto.encryption import decrypt from aws_encryption_sdk.internal.defaults import MAX_FRAME_SIZE +# necessary for it to call the correct deserialize_encryption_context from aws_encryption_sdk.internal.formatting.encryption_context import deserialize_encryption_context from aws_encryption_sdk.internal.str_ops import to_str from aws_encryption_sdk.internal.structures import ( @@ -242,6 +243,7 @@ def deserialize_header(stream): tee = io.BytesIO() tee_stream = TeeStream(stream, tee) version_id, message_type_id = unpack_values(">BB", tee_stream) + header = dict() header["version"] = _verified_version_from_id(version_id) header["type"] = _verified_message_type_from_id(message_type_id) @@ -251,7 +253,10 @@ def deserialize_header(stream): header["algorithm"] = _verified_algorithm_from_id(algorithm_id) header["message_id"] = message_id - header["encryption_context"] = deserialize_encryption_context(tee_stream.read(ser_encryption_context_length)) + aad = tee_stream.read(ser_encryption_context_length) + # d_aad = aws_encryption_sdk.internal.formatting.encryption_context.deserialize_encryption_context(aad) + d_aad = deserialize_encryption_context(aad) + header["encryption_context"] = d_aad header["encrypted_data_keys"] = _deserialize_encrypted_data_keys(tee_stream) diff --git a/src/aws_encryption_sdk/internal/formatting/encryption_context.py b/src/aws_encryption_sdk/internal/formatting/encryption_context.py index 4d3a5e773..793d56ebc 100644 --- a/src/aws_encryption_sdk/internal/formatting/encryption_context.py +++ b/src/aws_encryption_sdk/internal/formatting/encryption_context.py @@ -139,18 +139,23 @@ def deserialize_encryption_context(serialized_encryption_context): :raises SerializationError: if duplicate key found in serialized encryption context :raises SerializationError: if malformed data found in serialized encryption context """ + _LOGGER.debug("Deserializing Encryption Context") if len(serialized_encryption_context) > aws_encryption_sdk.internal.defaults.MAX_BYTE_ARRAY_SIZE: raise SerializationError("Serialized context is too long.") - if serialized_encryption_context == b"": _LOGGER.debug("No encryption context data found") return {} deserialized_size = 0 encryption_context = {} - dict_size, deserialized_size = read_short(source=serialized_encryption_context, offset=deserialized_size) _LOGGER.debug("Found %d keys", dict_size) + + # either the dict_size is just wrong, or this is malformed + # (and we assume the worst case and more common is the latter... former caught later) + if dict_size == 0: + raise SerializationError("Malformed AAD: zero length AAD with non-zero length AAD length field") + for _ in range(dict_size): key_size, deserialized_size = read_short(source=serialized_encryption_context, offset=deserialized_size) key, deserialized_size = read_string( diff --git a/src/aws_encryption_sdk/internal/formatting/serialize.py b/src/aws_encryption_sdk/internal/formatting/serialize.py index e7c86a0cb..ee6e388c1 100644 --- a/src/aws_encryption_sdk/internal/formatting/serialize.py +++ b/src/aws_encryption_sdk/internal/formatting/serialize.py @@ -121,8 +121,8 @@ def serialize_header(header, signer=None): def serialize_header_auth(algorithm, header, data_encryption_key, signer=None): """Creates serialized header authentication data. - :param algorithm: Algorithm to use for encryption - :type algorithm: aws_encryption_sdk.identifiers.Algorithm + :param algorithm: Algorithm suite to use for encryption + :type algorithm: aws_encryption_sdk.identifiers.AlgorithmSuite :param bytes header: Serialized message header :param bytes data_encryption_key: Data key with which to encrypt message :param signer: Cryptographic signer object (optional) @@ -150,8 +150,8 @@ def serialize_header_auth(algorithm, header, data_encryption_key, signer=None): def serialize_non_framed_open(algorithm, iv, plaintext_length, signer=None): """Serializes the opening block for a non-framed message body. - :param algorithm: Algorithm to use for encryption - :type algorithm: aws_encryption_sdk.identifiers.Algorithm + :param algorithm: Algorithm suite to use for encryption + :type algorithm: aws_encryption_sdk.identifiers.AlgorithmSuite :param bytes iv: IV value used to encrypt body :param int plaintext_length: Length of plaintext (and thus ciphertext) in body :param signer: Cryptographic signer object (optional) @@ -187,8 +187,8 @@ def serialize_frame( """Receives a message plaintext, breaks off a frame, encrypts and serializes the frame, and returns the encrypted frame and the remaining plaintext. - :param algorithm: Algorithm to use for encryption - :type algorithm: aws_encryption_sdk.identifiers.Algorithm + :param algorithm: Algorithm suite to use for encryption + :type algorithm: aws_encryption_sdk.identifiers.AlgorithmSuite :param bytes plaintext: Source plaintext to encrypt and serialize :param bytes message_id: Message ID :param bytes data_encryption_key: Data key with which to encrypt message diff --git a/src/aws_encryption_sdk/internal/utils/__init__.py b/src/aws_encryption_sdk/internal/utils/__init__.py index 1e7400c3a..2288b1ebc 100644 --- a/src/aws_encryption_sdk/internal/utils/__init__.py +++ b/src/aws_encryption_sdk/internal/utils/__init__.py @@ -45,8 +45,8 @@ def validate_frame_length(frame_length, algorithm): """Validates that frame length is within the defined limits and is compatible with the selected algorithm. :param int frame_length: Frame size in bytes - :param algorithm: Algorithm to use for encryption - :type algorithm: aws_encryption_sdk.identifiers.Algorithm + :param algorithm: Algorithm suite to use for encryption + :type algorithm: aws_encryption_sdk.identifiers.AlgorithmSuite :raises SerializationError: if frame size is negative or not a multiple of the algorithm block size :raises SerializationError: if frame size is larger than the maximum allowed frame size """ @@ -103,8 +103,8 @@ def prepare_data_keys(primary_master_key, master_keys, algorithm, encryption_con :type primary_master_key: aws_encryption_sdk.key_providers.base.MasterKey :param master_keys: All master keys with which to encrypt data keys :type master_keys: list of :class:`aws_encryption_sdk.key_providers.base.MasterKey` - :param algorithm: Algorithm to use for encryption - :type algorithm: aws_encryption_sdk.identifiers.Algorithm + :param algorithm: Algorithm suite to use for encryption + :type algorithm: aws_encryption_sdk.identifiers.AlgorithmSuite :param dict encryption_context: Encryption context to use when generating data key :rtype: tuple containing :class:`aws_encryption_sdk.structures.DataKey` and set of :class:`aws_encryption_sdk.structures.EncryptedDataKey` @@ -151,8 +151,8 @@ def source_data_key_length_check(source_data_key, algorithm): :param source_data_key: Source data key object received from MasterKey decrypt or generate data_key methods :type source_data_key: :class:`aws_encryption_sdk.structures.RawDataKey` or :class:`aws_encryption_sdk.structures.DataKey` - :param algorithm: Algorithm object which directs how this data key will be used - :type algorithm: aws_encryption_sdk.identifiers.Algorithm + :param algorithm: Algorithm suite object which directs how this data key will be used + :type algorithm: aws_encryption_sdk.identifiers.AlgorithmSuite :raises InvalidDataKeyError: if data key length does not match required kdf input length """ if len(source_data_key.data_key) != algorithm.kdf_input_len: diff --git a/src/aws_encryption_sdk/key_providers/base.py b/src/aws_encryption_sdk/key_providers/base.py index 3112cba6d..9554eb44d 100644 --- a/src/aws_encryption_sdk/key_providers/base.py +++ b/src/aws_encryption_sdk/key_providers/base.py @@ -218,8 +218,8 @@ def decrypt_data_key(self, encrypted_data_key, algorithm, encryption_context): :param encrypted_data_key: Encrypted data key to decrypt :type encrypted_data_key: aws_encryption_sdk.structures.EncryptedDataKey - :param algorithm: Algorithm object which directs how this Master Key will encrypt the data key - :type algorithm: aws_encryption_sdk.identifiers.Algorithm + :param algorithm: Algorithm suite object which directs how this Master Key will encrypt the data key + :type algorithm: aws_encryption_sdk.identifiers.AlgorithmSuite :param dict encryption_context: Encryption context to use in encryption :returns: Decrypted data key :rtype: aws_encryption_sdk.structures.DataKey diff --git a/src/aws_encryption_sdk/key_providers/kms.py b/src/aws_encryption_sdk/key_providers/kms.py index c0a2dc46e..7c1e1d563 100644 --- a/src/aws_encryption_sdk/key_providers/kms.py +++ b/src/aws_encryption_sdk/key_providers/kms.py @@ -115,7 +115,6 @@ def __init__(self, **kwargs): # pylint: disable=unused-argument def _process_config(self): """Traverses the config and adds master keys and regional clients as needed.""" self._user_agent_adding_config = botocore.config.Config(user_agent_extra=USER_AGENT_SUFFIX) - if self.config.region_names: self.add_regional_clients_from_list(self.config.region_names) self.default_region = self.config.region_names[0] @@ -123,7 +122,6 @@ def _process_config(self): self.default_region = self.config.botocore_session.get_config_variable("region") if self.default_region is not None: self.add_regional_client(self.default_region) - if self.config.key_ids: self.add_master_keys_from_list(self.config.key_ids) @@ -244,8 +242,8 @@ def __init__(self, **kwargs): # pylint: disable=unused-argument def _generate_data_key(self, algorithm, encryption_context=None): """Generates data key and returns plaintext and ciphertext of key. - :param algorithm: Algorithm on which to base data key - :type algorithm: aws_encryption_sdk.identifiers.Algorithm + :param algorithm: Algorithm suite on which to base data key + :type algorithm: aws_encryption_sdk.identifiers.AlgorithmSuite :param dict encryption_context: Encryption context to pass to KMS :returns: Generated data key :rtype: aws_encryption_sdk.structures.DataKey @@ -306,7 +304,7 @@ def _decrypt_data_key(self, encrypted_data_key, algorithm, encryption_context=No :param data_key: Encrypted data key :type data_key: aws_encryption_sdk.structures.EncryptedDataKey - :type algorithm: `aws_encryption_sdk.identifiers.Algorithm` (not used for KMS) + :type algorithm: `aws_encryption_sdk.identifiers.AlgorithmSuite` (not used for KMS) :param dict encryption_context: Encryption context to use in decryption :returns: Decrypted data key :rtype: aws_encryption_sdk.structures.DataKey diff --git a/src/aws_encryption_sdk/key_providers/raw.py b/src/aws_encryption_sdk/key_providers/raw.py index 57a1d5edf..ca6c690d6 100644 --- a/src/aws_encryption_sdk/key_providers/raw.py +++ b/src/aws_encryption_sdk/key_providers/raw.py @@ -115,8 +115,8 @@ def owns_data_key(self, data_key): def _generate_data_key(self, algorithm, encryption_context): """Generates data key and returns :class:`aws_encryption_sdk.structures.DataKey`. - :param algorithm: Algorithm on which to base data key - :type algorithm: aws_encryption_sdk.identifiers.Algorithm + :param algorithm: Algorithm suite on which to base data key + :type algorithm: aws_encryption_sdk.identifiers.AlgorithmSuite :param dict encryption_context: Encryption context to use in encryption :returns: Generated data key :rtype: aws_encryption_sdk.structures.DataKey @@ -139,8 +139,8 @@ def _encrypt_data_key(self, data_key, algorithm, encryption_context): :param data_key: Unencrypted data key :type data_key: :class:`aws_encryption_sdk.structures.RawDataKey` or :class:`aws_encryption_sdk.structures.DataKey` - :param algorithm: Algorithm object which directs how this Master Key will encrypt the data key - :type algorithm: aws_encryption_sdk.identifiers.Algorithm + :param algorithm: Algorithm suite object which directs how this Master Key will encrypt the data key + :type algorithm: aws_encryption_sdk.identifiers.AlgorithmSuite :param dict encryption_context: Encryption context to use in encryption :returns: Decrypted data key :rtype: aws_encryption_sdk.structures.EncryptedDataKey @@ -163,8 +163,8 @@ def _decrypt_data_key(self, encrypted_data_key, algorithm, encryption_context): :param data_key: Encrypted data key :type data_key: aws_encryption_sdk.structures.EncryptedDataKey - :param algorithm: Algorithm object which directs how this Master Key will encrypt the data key - :type algorithm: aws_encryption_sdk.identifiers.Algorithm + :param algorithm: Algorithm suite object which directs how this Master Key will encrypt the data key + :type algorithm: aws_encryption_sdk.identifiers.AlgorithmSuite :param dict encryption_context: Encryption context to use in decryption :returns: Data key containing decrypted data key :rtype: aws_encryption_sdk.structures.DataKey diff --git a/src/aws_encryption_sdk/materials_managers/__init__.py b/src/aws_encryption_sdk/materials_managers/__init__.py index bc5230c51..a086feb7c 100644 --- a/src/aws_encryption_sdk/materials_managers/__init__.py +++ b/src/aws_encryption_sdk/materials_managers/__init__.py @@ -17,7 +17,7 @@ import attr import six -from ..identifiers import Algorithm +from ..identifiers import AlgorithmSuite from ..internal.utils.streams import ROStream from ..structures import DataKey @@ -35,8 +35,8 @@ class EncryptionMaterialsRequest(object): :param int frame_length: Frame length to be used while encrypting stream :param plaintext_rostream: Source plaintext read-only stream (optional) :type plaintext_rostream: aws_encryption_sdk.internal.utils.streams.ROStream - :param algorithm: Algorithm passed to underlying master key provider and master keys (optional) - :type algorithm: aws_encryption_sdk.identifiers.Algorithm + :param algorithm: Algorithm suite passed to underlying master key provider and master keys (optional) + :type algorithm: aws_encryption_sdk.identifiers.AlgorithmSuite :param int plaintext_length: Length of source plaintext (optional) """ @@ -45,7 +45,7 @@ class EncryptionMaterialsRequest(object): plaintext_rostream = attr.ib( default=None, validator=attr.validators.optional(attr.validators.instance_of(ROStream)) ) - algorithm = attr.ib(default=None, validator=attr.validators.optional(attr.validators.instance_of(Algorithm))) + algorithm = attr.ib(default=None, validator=attr.validators.optional(attr.validators.instance_of(AlgorithmSuite))) plaintext_length = attr.ib( default=None, validator=attr.validators.optional(attr.validators.instance_of(six.integer_types)) ) @@ -57,8 +57,8 @@ class EncryptionMaterials(object): .. versionadded:: 1.3.0 - :param algorithm: Algorithm to use for encrypting message - :type algorithm: aws_encryption_sdk.identifiers.Algorithm + :param algorithm: Algorithm suite to use for encrypting message + :type algorithm: aws_encryption_sdk.identifiers.AlgorithmSuite :param data_encryption_key: Plaintext data key to use for encrypting message :type data_encryption_key: aws_encryption_sdk.structures.DataKey :param encrypted_data_keys: List of encrypted data keys @@ -67,7 +67,7 @@ class EncryptionMaterials(object): :param bytes signing_key: Encoded signing key """ - algorithm = attr.ib(validator=attr.validators.instance_of(Algorithm)) + algorithm = attr.ib(validator=attr.validators.instance_of(AlgorithmSuite)) data_encryption_key = attr.ib(validator=attr.validators.instance_of(DataKey)) encrypted_data_keys = attr.ib(validator=attr.validators.instance_of(set)) encryption_context = attr.ib(validator=attr.validators.instance_of(dict)) @@ -80,14 +80,14 @@ class DecryptionMaterialsRequest(object): .. versionadded:: 1.3.0 - :param algorithm: Algorithm to provide to master keys for underlying decrypt requests - :type algorithm: aws_encryption_sdk.identifiers.Algorithm + :param algorithm: Algorithm suite to provide to master keys for underlying decrypt requests + :type algorithm: aws_encryption_sdk.identifiers.AlgorithmSuite :param encrypted_data_keys: Set of encrypted data keys :type encrypted_data_keys: set of `aws_encryption_sdk.structures.EncryptedDataKey` :param dict encryption_context: Encryption context to provide to master keys for underlying decrypt requests """ - algorithm = attr.ib(validator=attr.validators.instance_of(Algorithm)) + algorithm = attr.ib(validator=attr.validators.instance_of(AlgorithmSuite)) encrypted_data_keys = attr.ib(validator=attr.validators.instance_of(set)) encryption_context = attr.ib(validator=attr.validators.instance_of(dict)) diff --git a/src/aws_encryption_sdk/materials_managers/default.py b/src/aws_encryption_sdk/materials_managers/default.py index 6d10465a9..402a853ce 100644 --- a/src/aws_encryption_sdk/materials_managers/default.py +++ b/src/aws_encryption_sdk/materials_managers/default.py @@ -44,8 +44,8 @@ class DefaultCryptoMaterialsManager(CryptoMaterialsManager): def _generate_signing_key_and_update_encryption_context(self, algorithm, encryption_context): """Generates a signing key based on the provided algorithm. - :param algorithm: Algorithm for which to generate signing key - :type algorithm: aws_encryption_sdk.identifiers.Algorithm + :param algorithm: Algorithm suite for which to generate signing key + :type algorithm: aws_encryption_sdk.identifiers.AlgorithmSuite :param dict encryption_context: Encryption context from request :returns: Signing key bytes :rtype: bytes or None @@ -104,8 +104,8 @@ def get_encryption_materials(self, request): def _load_verification_key_from_encryption_context(self, algorithm, encryption_context): """Loads the verification key from the encryption context if used by algorithm suite. - :param algorithm: Algorithm for which to generate signing key - :type algorithm: aws_encryption_sdk.identifiers.Algorithm + :param algorithm: Algorithm suite for which to generate signing key + :type algorithm: aws_encryption_sdk.identifiers.AlgorithmSuite :param dict encryption_context: Encryption context from request :returns: Raw verification key :rtype: bytes diff --git a/src/aws_encryption_sdk/streaming_client.py b/src/aws_encryption_sdk/streaming_client.py index 504f68977..a5d69d5ea 100644 --- a/src/aws_encryption_sdk/streaming_client.py +++ b/src/aws_encryption_sdk/streaming_client.py @@ -29,7 +29,7 @@ NotSupportedError, SerializationError, ) -from aws_encryption_sdk.identifiers import Algorithm, ContentType +from aws_encryption_sdk.identifiers import AlgorithmSuite, ContentType from aws_encryption_sdk.internal.crypto.authentication import Signer, Verifier from aws_encryption_sdk.internal.crypto.data_keys import derive_data_encryption_key from aws_encryption_sdk.internal.crypto.encryption import Decryptor, Encryptor, decrypt @@ -333,8 +333,8 @@ class EncryptorConfig(_ClientConfig): this is not enforced if a `key_provider` is provided. :param dict encryption_context: Dictionary defining encryption context - :param algorithm: Algorithm to use for encryption (optional) - :type algorithm: aws_encryption_sdk.identifiers.Algorithm + :param algorithm: Algorithm suite to use for encryption (optional) + :type algorithm: aws_encryption_sdk.identifiers.AlgorithmSuite :param int frame_length: Frame length in bytes (optional) """ @@ -344,7 +344,7 @@ class EncryptorConfig(_ClientConfig): validator=attr.validators.instance_of(dict), ) algorithm = attr.ib( - hash=True, default=None, validator=attr.validators.optional(attr.validators.instance_of(Algorithm)) + hash=True, default=None, validator=attr.validators.optional(attr.validators.instance_of(AlgorithmSuite)) ) frame_length = attr.ib(hash=True, default=FRAME_LENGTH, validator=attr.validators.instance_of(six.integer_types)) @@ -384,8 +384,8 @@ class StreamEncryptor(_EncryptionStream): # pylint: disable=too-many-instance-a this is not enforced if a `key_provider` is provided. :param dict encryption_context: Dictionary defining encryption context - :param algorithm: Algorithm to use for encryption - :type algorithm: aws_encryption_sdk.identifiers.Algorithm + :param algorithm: Algorithm suite to use for encryption + :type algorithm: aws_encryption_sdk.identifiers.AlgorithmSuite :param int frame_length: Frame length in bytes """ diff --git a/src/aws_encryption_sdk/structures.py b/src/aws_encryption_sdk/structures.py index 97e4c1d13..e3ea97648 100644 --- a/src/aws_encryption_sdk/structures.py +++ b/src/aws_encryption_sdk/structures.py @@ -27,8 +27,8 @@ class MessageHeader(object): :type version: aws_encryption_sdk.identifiers.SerializationVersion :param type: Message content type, per spec :type type: aws_encryption_sdk.identifiers.ObjectType - :param algorithm: Algorithm to use for encryption - :type algorithm: aws_encryption_sdk.identifiers.Algorithm + :param algorithm: Algorithm suite to use for encryption + :type algorithm: aws_encryption_sdk.identifiers.AlgorithmSuite :param bytes message_id: Message ID :param dict encryption_context: Dictionary defining encryption context :param encrypted_data_keys: Encrypted data keys @@ -44,7 +44,7 @@ class MessageHeader(object): hash=True, validator=attr.validators.instance_of(aws_encryption_sdk.identifiers.SerializationVersion) ) type = attr.ib(hash=True, validator=attr.validators.instance_of(aws_encryption_sdk.identifiers.ObjectType)) - algorithm = attr.ib(hash=True, validator=attr.validators.instance_of(aws_encryption_sdk.identifiers.Algorithm)) + algorithm = attr.ib(hash=True, validator=attr.validators.instance_of(aws_encryption_sdk.identifiers.AlgorithmSuite)) message_id = attr.ib(hash=True, validator=attr.validators.instance_of(bytes)) encryption_context = attr.ib(hash=True, validator=attr.validators.instance_of(dict)) encrypted_data_keys = attr.ib(hash=True, validator=attr.validators.instance_of(set)) diff --git a/test/functional/test_f_aws_encryption_sdk_client.py b/test/functional/test_f_aws_encryption_sdk_client.py index fb19e868a..6e05ec8ee 100644 --- a/test/functional/test_f_aws_encryption_sdk_client.py +++ b/test/functional/test_f_aws_encryption_sdk_client.py @@ -30,7 +30,7 @@ from aws_encryption_sdk import KMSMasterKeyProvider from aws_encryption_sdk.caches import build_decryption_materials_cache_key, build_encryption_materials_cache_key from aws_encryption_sdk.exceptions import CustomMaximumValueExceeded -from aws_encryption_sdk.identifiers import Algorithm, EncryptionKeyType, WrappingAlgorithm +from aws_encryption_sdk.identifiers import AlgorithmSuite, EncryptionKeyType, WrappingAlgorithm from aws_encryption_sdk.internal.crypto.wrapping_keys import WrappingKey from aws_encryption_sdk.internal.defaults import LINE_LENGTH from aws_encryption_sdk.internal.formatting.encryption_context import serialize_encryption_context @@ -255,7 +255,7 @@ def test_no_infinite_encryption_cycle_on_empty_source(): def test_encrypt_load_header(): """Test that StreamEncryptor can extract header without reading plaintext.""" # Using a non-signed algorithm to simplify header size calculation - algorithm = aws_encryption_sdk.Algorithm.AES_256_GCM_IV12_TAG16_HKDF_SHA256 + algorithm = aws_encryption_sdk.AlgorithmSuite.AES_256_GCM_IV12_TAG16_HKDF_SHA256 key_provider = fake_kms_key_provider(algorithm.kdf_input_len) header_length = len(serialize_encryption_context(VALUES["encryption_context"])) header_length += 34 @@ -296,7 +296,7 @@ def test_encrypt_decrypt_header_only(): [ [frame_length, algorithm_suite, encryption_context] for frame_length in VALUES["frame_lengths"] - for algorithm_suite in Algorithm + for algorithm_suite in AlgorithmSuite for encryption_context in [{}, VALUES["encryption_context"]] ], ) @@ -374,7 +374,7 @@ def test_encryption_cycle_raw_mkp_openssl_102_plus(wrapping_algorithm, encryptio [ [frame_length, algorithm_suite, encryption_context] for frame_length in VALUES["frame_lengths"] - for algorithm_suite in Algorithm + for algorithm_suite in AlgorithmSuite for encryption_context in [{}, VALUES["encryption_context"]] ], ) @@ -399,7 +399,7 @@ def test_encryption_cycle_oneshot_kms(frame_length, algorithm, encryption_contex [ [frame_length, algorithm_suite, encryption_context] for frame_length in VALUES["frame_lengths"] - for algorithm_suite in Algorithm + for algorithm_suite in AlgorithmSuite for encryption_context in [{}, VALUES["encryption_context"]] ], ) @@ -446,7 +446,7 @@ def test_decrypt_legacy_provided_message(): def test_encryption_cycle_with_caching(): - algorithm = Algorithm.AES_256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384 + algorithm = AlgorithmSuite.AES_256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384 frame_length = 1024 key_provider = fake_kms_key_provider(algorithm.kdf_input_len) cache = aws_encryption_sdk.LocalCryptoMaterialsCache(capacity=10) diff --git a/test/functional/test_f_crypto.py b/test/functional/test_f_crypto.py index 9242deedd..9d71c040a 100644 --- a/test/functional/test_f_crypto.py +++ b/test/functional/test_f_crypto.py @@ -26,8 +26,8 @@ # Run several of each type to make get a high probability of forcing signature length correction @pytest.mark.parametrize( "algorithm", - [aws_encryption_sdk.Algorithm.AES_128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256 for i in range(10)] - + [aws_encryption_sdk.Algorithm.AES_256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384 for i in range(10)], + [aws_encryption_sdk.AlgorithmSuite.AES_128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256 for i in range(10)] + + [aws_encryption_sdk.AlgorithmSuite.AES_256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384 for i in range(10)], ) def test_ecc_static_length_signature(algorithm): private_key = ec.generate_private_key(curve=algorithm.signing_algorithm_info(), backend=default_backend()) @@ -44,9 +44,9 @@ def test_ecc_static_length_signature(algorithm): def test_signer_key_bytes_cycle(): key = ec.generate_private_key(curve=ec.SECP384R1, backend=default_backend()) - signer = Signer(algorithm=aws_encryption_sdk.Algorithm.AES_256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384, key=key) + signer = Signer(algorithm=aws_encryption_sdk.AlgorithmSuite.AES_256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384, key=key) key_bytes = signer.key_bytes() new_signer = Signer.from_key_bytes( - algorithm=aws_encryption_sdk.Algorithm.AES_256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384, key_bytes=key_bytes + algorithm=aws_encryption_sdk.AlgorithmSuite.AES_256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384, key_bytes=key_bytes ) assert new_signer.key.private_numbers().private_value == signer.key.private_numbers().private_value diff --git a/test/functional/test_f_xcompat.py b/test/functional/test_f_xcompat.py index e87082503..d97835b4c 100644 --- a/test/functional/test_f_xcompat.py +++ b/test/functional/test_f_xcompat.py @@ -147,7 +147,7 @@ def _generate_test_cases(): # noqa=C901 # Collect test cases from ciphertext manifest for test_case in ciphertext_manifest["test_cases"]: key_ids = [] - algorithm = aws_encryption_sdk.Algorithm.get_by_id(int(test_case["algorithm"], 16)) + algorithm = aws_encryption_sdk.AlgorithmSuite.get_by_id(int(test_case["algorithm"], 16)) for key in test_case["master_keys"]: sys.stderr.write("XC:: " + json.dumps(key) + "\n") if key["provider_id"] == StaticStoredMasterKeyProvider.provider_id: diff --git a/test/integration/test_i_aws_encrytion_sdk_client.py b/test/integration/test_i_aws_encrytion_sdk_client.py index 26df431dc..f8f05271d 100644 --- a/test/integration/test_i_aws_encrytion_sdk_client.py +++ b/test/integration/test_i_aws_encrytion_sdk_client.py @@ -18,7 +18,7 @@ from botocore.exceptions import BotoCoreError import aws_encryption_sdk -from aws_encryption_sdk.identifiers import USER_AGENT_SUFFIX, Algorithm +from aws_encryption_sdk.identifiers import USER_AGENT_SUFFIX, AlgorithmSuite from aws_encryption_sdk.key_providers.kms import KMSMasterKey, KMSMasterKeyProvider from .integration_test_utils import ( @@ -48,7 +48,7 @@ def test_encrypt_verify_user_agent_kms_master_key_provider(caplog): mkp = setup_kms_master_key_provider() mk = mkp.master_key(get_cmk_arn()) - mk.generate_data_key(algorithm=Algorithm.AES_256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384, encryption_context={}) + mk.generate_data_key(algorithm=AlgorithmSuite.AES_256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384, encryption_context={}) assert USER_AGENT_SUFFIX in caplog.text @@ -57,7 +57,7 @@ def test_encrypt_verify_user_agent_kms_master_key(caplog): caplog.set_level(level=logging.DEBUG) mk = KMSMasterKey(key_id=get_cmk_arn()) - mk.generate_data_key(algorithm=Algorithm.AES_256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384, encryption_context={}) + mk.generate_data_key(algorithm=AlgorithmSuite.AES_256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384, encryption_context={}) assert USER_AGENT_SUFFIX in caplog.text @@ -65,11 +65,18 @@ def test_encrypt_verify_user_agent_kms_master_key(caplog): def test_remove_bad_client(): test = KMSMasterKeyProvider() test.add_regional_client("us-fakey-12") - with pytest.raises(BotoCoreError): test._regional_clients["us-fakey-12"].list_keys() - assert not test._regional_clients + # I believe that because KMSMasterKeyProvider() sets a default regional client + # we want to test that the fake key was properly removed, instead of the dict (of regional clients) + # being empty. That is to say, after the first line of this test function + # the dict is NOT EMPTY, and this default first value will stay with us, so + # if we test for emptiness of the dict then we will get a non-passing test, when really + # it might be passing. The old line is commented out in case it matters later. + + # assert not test._regional_clients + assert "us-fakey-12" not in test._regional_clients def test_regional_client_does_not_modify_botocore_session(caplog): @@ -191,7 +198,7 @@ def test_encryption_cycle_aes_128_gcm_iv12_tag16_single_frame(self): key_provider=self.kms_master_key_provider, encryption_context=VALUES["encryption_context"], frame_length=1024, - algorithm=Algorithm.AES_128_GCM_IV12_TAG16, + algorithm=AlgorithmSuite.AES_128_GCM_IV12_TAG16, ) plaintext, _ = aws_encryption_sdk.decrypt(source=ciphertext, key_provider=self.kms_master_key_provider) assert plaintext == VALUES["plaintext_128"] @@ -206,7 +213,7 @@ def test_encryption_cycle_aes_128_gcm_iv12_tag16_non_framed(self): key_provider=self.kms_master_key_provider, encryption_context=VALUES["encryption_context"], frame_length=0, - algorithm=Algorithm.AES_128_GCM_IV12_TAG16, + algorithm=AlgorithmSuite.AES_128_GCM_IV12_TAG16, ) plaintext, _ = aws_encryption_sdk.decrypt(source=ciphertext, key_provider=self.kms_master_key_provider) assert plaintext == VALUES["plaintext_128"] @@ -221,7 +228,7 @@ def test_encryption_cycle_aes_192_gcm_iv12_tag16_single_frame(self): key_provider=self.kms_master_key_provider, encryption_context=VALUES["encryption_context"], frame_length=1024, - algorithm=Algorithm.AES_192_GCM_IV12_TAG16, + algorithm=AlgorithmSuite.AES_192_GCM_IV12_TAG16, ) plaintext, _ = aws_encryption_sdk.decrypt(source=ciphertext, key_provider=self.kms_master_key_provider) assert plaintext == VALUES["plaintext_128"] @@ -236,7 +243,7 @@ def test_encryption_cycle_aes_192_gcm_iv12_tag16_non_framed(self): key_provider=self.kms_master_key_provider, encryption_context=VALUES["encryption_context"], frame_length=0, - algorithm=Algorithm.AES_192_GCM_IV12_TAG16, + algorithm=AlgorithmSuite.AES_192_GCM_IV12_TAG16, ) plaintext, _ = aws_encryption_sdk.decrypt(source=ciphertext, key_provider=self.kms_master_key_provider) assert plaintext == VALUES["plaintext_128"] @@ -251,7 +258,7 @@ def test_encryption_cycle_aes_256_gcm_iv12_tag16_single_frame(self): key_provider=self.kms_master_key_provider, encryption_context=VALUES["encryption_context"], frame_length=1024, - algorithm=Algorithm.AES_256_GCM_IV12_TAG16, + algorithm=AlgorithmSuite.AES_256_GCM_IV12_TAG16, ) plaintext, _ = aws_encryption_sdk.decrypt(source=ciphertext, key_provider=self.kms_master_key_provider) assert plaintext == VALUES["plaintext_128"] @@ -266,7 +273,7 @@ def test_encryption_cycle_aes_256_gcm_iv12_tag16_non_framed(self): key_provider=self.kms_master_key_provider, encryption_context=VALUES["encryption_context"], frame_length=0, - algorithm=Algorithm.AES_256_GCM_IV12_TAG16, + algorithm=AlgorithmSuite.AES_256_GCM_IV12_TAG16, ) plaintext, _ = aws_encryption_sdk.decrypt(source=ciphertext, key_provider=self.kms_master_key_provider) assert plaintext == VALUES["plaintext_128"] @@ -281,7 +288,7 @@ def test_encryption_cycle_aes_128_gcm_iv12_tag16_hkdf_sha256_single_frame(self): key_provider=self.kms_master_key_provider, encryption_context=VALUES["encryption_context"], frame_length=1024, - algorithm=Algorithm.AES_128_GCM_IV12_TAG16_HKDF_SHA256, + algorithm=AlgorithmSuite.AES_128_GCM_IV12_TAG16_HKDF_SHA256, ) plaintext, _ = aws_encryption_sdk.decrypt(source=ciphertext, key_provider=self.kms_master_key_provider) assert plaintext == VALUES["plaintext_128"] @@ -296,7 +303,7 @@ def test_encryption_cycle_aes_128_gcm_iv12_tag16_hkdf_sha256_non_framed(self): key_provider=self.kms_master_key_provider, encryption_context=VALUES["encryption_context"], frame_length=0, - algorithm=Algorithm.AES_128_GCM_IV12_TAG16_HKDF_SHA256, + algorithm=AlgorithmSuite.AES_128_GCM_IV12_TAG16_HKDF_SHA256, ) plaintext, _ = aws_encryption_sdk.decrypt(source=ciphertext, key_provider=self.kms_master_key_provider) assert plaintext == VALUES["plaintext_128"] @@ -311,7 +318,7 @@ def test_encryption_cycle_aes_192_gcm_iv12_tag16_hkdf_sha256_single_frame(self): key_provider=self.kms_master_key_provider, encryption_context=VALUES["encryption_context"], frame_length=1024, - algorithm=Algorithm.AES_192_GCM_IV12_TAG16_HKDF_SHA256, + algorithm=AlgorithmSuite.AES_192_GCM_IV12_TAG16_HKDF_SHA256, ) plaintext, _ = aws_encryption_sdk.decrypt(source=ciphertext, key_provider=self.kms_master_key_provider) assert plaintext == VALUES["plaintext_128"] @@ -326,7 +333,7 @@ def test_encryption_cycle_aes_192_gcm_iv12_tag16_hkdf_sha256_non_framed(self): key_provider=self.kms_master_key_provider, encryption_context=VALUES["encryption_context"], frame_length=0, - algorithm=Algorithm.AES_192_GCM_IV12_TAG16_HKDF_SHA256, + algorithm=AlgorithmSuite.AES_192_GCM_IV12_TAG16_HKDF_SHA256, ) plaintext, _ = aws_encryption_sdk.decrypt(source=ciphertext, key_provider=self.kms_master_key_provider) assert plaintext == VALUES["plaintext_128"] @@ -341,7 +348,7 @@ def test_encryption_cycle_aes_256_gcm_iv12_tag16_hkdf_sha256_single_frame(self): key_provider=self.kms_master_key_provider, encryption_context=VALUES["encryption_context"], frame_length=1024, - algorithm=Algorithm.AES_256_GCM_IV12_TAG16_HKDF_SHA256, + algorithm=AlgorithmSuite.AES_256_GCM_IV12_TAG16_HKDF_SHA256, ) plaintext, _ = aws_encryption_sdk.decrypt(source=ciphertext, key_provider=self.kms_master_key_provider) assert plaintext == VALUES["plaintext_128"] @@ -356,7 +363,7 @@ def test_encryption_cycle_aes_256_gcm_iv12_tag16_hkdf_sha256_non_framed(self): key_provider=self.kms_master_key_provider, encryption_context=VALUES["encryption_context"], frame_length=0, - algorithm=Algorithm.AES_256_GCM_IV12_TAG16_HKDF_SHA256, + algorithm=AlgorithmSuite.AES_256_GCM_IV12_TAG16_HKDF_SHA256, ) plaintext, _ = aws_encryption_sdk.decrypt(source=ciphertext, key_provider=self.kms_master_key_provider) assert plaintext == VALUES["plaintext_128"] @@ -371,7 +378,7 @@ def test_encryption_cycle_aes_128_gcm_iv12_tag16_hkdf_sha256_ecdsa_p256_single_f key_provider=self.kms_master_key_provider, encryption_context=VALUES["encryption_context"], frame_length=1024, - algorithm=Algorithm.AES_128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256, + algorithm=AlgorithmSuite.AES_128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256, ) plaintext, _ = aws_encryption_sdk.decrypt(source=ciphertext, key_provider=self.kms_master_key_provider) assert plaintext == VALUES["plaintext_128"] @@ -386,7 +393,7 @@ def test_encryption_cycle_aes_128_gcm_iv12_tag16_hkdf_sha256_ecdsa_p256_non_fram key_provider=self.kms_master_key_provider, encryption_context=VALUES["encryption_context"], frame_length=0, - algorithm=Algorithm.AES_128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256, + algorithm=AlgorithmSuite.AES_128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256, ) plaintext, _ = aws_encryption_sdk.decrypt(source=ciphertext, key_provider=self.kms_master_key_provider) assert plaintext == VALUES["plaintext_128"] @@ -401,7 +408,7 @@ def test_encryption_cycle_aes_192_gcm_iv12_tag16_hkdf_sha384_ecdsa_p384_single_f key_provider=self.kms_master_key_provider, encryption_context=VALUES["encryption_context"], frame_length=1024, - algorithm=Algorithm.AES_192_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384, + algorithm=AlgorithmSuite.AES_192_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384, ) plaintext, _ = aws_encryption_sdk.decrypt(source=ciphertext, key_provider=self.kms_master_key_provider) assert plaintext == VALUES["plaintext_128"] @@ -416,7 +423,7 @@ def test_encryption_cycle_aes_192_gcm_iv12_tag16_hkdf_sha384_ecdsa_p384_non_fram key_provider=self.kms_master_key_provider, encryption_context=VALUES["encryption_context"], frame_length=0, - algorithm=Algorithm.AES_192_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384, + algorithm=AlgorithmSuite.AES_192_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384, ) plaintext, _ = aws_encryption_sdk.decrypt(source=ciphertext, key_provider=self.kms_master_key_provider) assert plaintext == VALUES["plaintext_128"] @@ -431,7 +438,7 @@ def test_encryption_cycle_aes_256_gcm_iv12_tag16_hkdf_sha384_ecdsa_p384_single_f key_provider=self.kms_master_key_provider, encryption_context=VALUES["encryption_context"], frame_length=1024, - algorithm=Algorithm.AES_256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384, + algorithm=AlgorithmSuite.AES_256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384, ) plaintext, _ = aws_encryption_sdk.decrypt(source=ciphertext, key_provider=self.kms_master_key_provider) assert plaintext == VALUES["plaintext_128"] @@ -446,7 +453,7 @@ def test_encryption_cycle_aes_256_gcm_iv12_tag16_hkdf_sha384_ecdsa_p384_non_fram key_provider=self.kms_master_key_provider, encryption_context=VALUES["encryption_context"], frame_length=0, - algorithm=Algorithm.AES_256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384, + algorithm=AlgorithmSuite.AES_256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384, ) plaintext, _ = aws_encryption_sdk.decrypt(source=ciphertext, key_provider=self.kms_master_key_provider) assert plaintext == VALUES["plaintext_128"] diff --git a/test/unit/test_deserialize.py b/test/unit/test_deserialize.py index 8a96ea4ca..1d162949c 100644 --- a/test/unit/test_deserialize.py +++ b/test/unit/test_deserialize.py @@ -11,6 +11,7 @@ # ANY KIND, either express or implied. See the License for the specific # language governing permissions and limitations under the License. """Unit test suite for aws_encryption_sdk.deserialize""" +import base64 import io import struct @@ -54,6 +55,32 @@ def test_deserialize_tag(): assert parsed_tag == tag +# important to have this outside of the class to avoid mocking issues +def test_deserialize_header_malformed_aad(): + # line was too long before which is why linters failed + mencoded = ( + "AYAAFJwN8IgQ9+0sxyy7+90cCCgAAgAA" + + "AAEAE1dFQi1DUllQVE8tUlNBLU9BRVAAKDhD" + + "RUQyRkQyMEZDODhBOUMwNkVGREIwNzM3MDdFQj" + + "FFRjE2NTU3ODABAFbIi+gmSrvejfOCjbE08rTYHy" + + "m2uLWsiizQHnTy3z8/VeR+7MKvNv7ZfPf5LX7i9amY" + + "wxCMISvY+BCcndLakH/RlDUdgz5/Q0KAxrE5LX7DHxO/w" + + "MviJCi+qXWMb+5u0mhwepRihO/dk+3kGqyaLhnGuA6xqYmT" + + "hUlCZR5BwfyEddSango7umEWw1YQ8vokjqUzCKRyk3VpXwQTXQ" + + "LLrBz7ZmZ7Anzn0SoaLYk8D0rPWhKHvUXQDJYDYdQ7vped" + + "xpsE5vliLI98CAcIWllkst964DIBwKgAX6Ic8Nj+8T7VurdK2" + + "SFuTH4LIvkebmEGCxngdRpfopEU/Rd0LYXZik4CAAAAAAwAAAAG" + + "AAAAAAAAAAAAAAAAK9vNRvymDkoxO6dy67pDuf////8AAAABAAAAA" + + "AAAAAAAAAABAAAABTAqmilQragTFTYdPz23w1NMR+c8Uw==" + ) + mencoded = mencoded.encode("utf-8") + mdecoded = base64.b64decode(mencoded) + malformed_header = io.BytesIO(mdecoded) + with pytest.raises(SerializationError) as excinfo: + aws_encryption_sdk.internal.formatting.deserialize.deserialize_header(malformed_header) + excinfo.match(r"Malformed AAD: zero length AAD with non-zero length AAD length field") + + class TestDeserialize(object): @pytest.fixture(autouse=True) def apply_fixtures(self): @@ -72,7 +99,7 @@ def apply_fixtures(self): self.mock_decrypt = self.mock_decrypt_patcher.start() # Set up encryption_context patch self.mock_deserialize_ec_patcher = patch( - "aws_encryption_sdk.internal.formatting.deserialize.deserialize_encryption_context" + "aws_encryption_sdk.internal.formatting.encryption_context.deserialize_encryption_context" ) self.mock_deserialize_ec = self.mock_deserialize_ec_patcher.start() self.mock_deserialize_ec.return_value = VALUES["updated_encryption_context"] diff --git a/test/unit/test_encryption_context.py b/test/unit/test_encryption_context.py index 187365783..08d1c5025 100644 --- a/test/unit/test_encryption_context.py +++ b/test/unit/test_encryption_context.py @@ -190,3 +190,9 @@ def test_deserialize_encryption_context_empty(self): serialized_encryption_context=b"" ) assert test == {} + + def test_malformed_aad(self): + malformed_aad = b"\x00\x00" + with pytest.raises(SerializationError) as excinfo: + aws_encryption_sdk.internal.formatting.encryption_context.deserialize_encryption_context(malformed_aad) + excinfo.match(r"Malformed AAD: zero length AAD with non-zero length AAD length field") diff --git a/tox.ini b/tox.ini index 08ec65251..b885442d8 100644 --- a/tox.ini +++ b/tox.ini @@ -251,7 +251,7 @@ commands = python setup.py check -r -s [testenv:bandit] basepython = python3 -deps = +deps = bandit>=1.5.1 commands = bandit -r src/aws_encryption_sdk/