diff --git a/src/aws_encryption_sdk/key_providers/base.py b/src/aws_encryption_sdk/key_providers/base.py index a855ee596..5fa99cc1c 100644 --- a/src/aws_encryption_sdk/key_providers/base.py +++ b/src/aws_encryption_sdk/key_providers/base.py @@ -12,6 +12,7 @@ ConfigMismatchError, DecryptKeyError, IncorrectMasterKeyError, + InvalidDataKeyError, InvalidKeyIdError, MasterKeyProviderError, ) @@ -256,7 +257,7 @@ def decrypt_data_key(self, encrypted_data_key, algorithm, encryption_context): # //# input encryption context. data_key = master_key.decrypt_data_key(encrypted_data_key, algorithm, encryption_context) - except (IncorrectMasterKeyError, DecryptKeyError) as error: + except (IncorrectMasterKeyError, DecryptKeyError, InvalidDataKeyError) as error: _LOGGER.debug( "%s raised when attempting to decrypt data key with master key %s", repr(error), @@ -304,8 +305,8 @@ def decrypt_data_key_from_list(self, encrypted_data_keys, algorithm, encryption_ try: data_key = self.decrypt_data_key(encrypted_data_key, algorithm, encryption_context) # MasterKeyProvider.decrypt_data_key throws DecryptKeyError - # but MasterKey.decrypt_data_key throws IncorrectMasterKeyError - except (DecryptKeyError, IncorrectMasterKeyError): + # but MasterKey.decrypt_data_key throws IncorrectMasterKeyError and InvalidDataKeyError + except (DecryptKeyError, IncorrectMasterKeyError, InvalidDataKeyError): continue else: break diff --git a/test_vector_handlers/src/awses_test_vectors/manifests/master_key.py b/test_vector_handlers/src/awses_test_vectors/manifests/master_key.py index 49b517eae..a81c37a03 100644 --- a/test_vector_handlers/src/awses_test_vectors/manifests/master_key.py +++ b/test_vector_handlers/src/awses_test_vectors/manifests/master_key.py @@ -7,8 +7,9 @@ """ import attr import six +from aws_encryption_sdk.exceptions import InvalidKeyIdError from aws_encryption_sdk.identifiers import EncryptionKeyType, WrappingAlgorithm -from aws_encryption_sdk.key_providers.base import MasterKeyProvider # noqa pylint: disable=unused-import +from aws_encryption_sdk.key_providers.base import MasterKeyProvider, MasterKeyProviderConfig from aws_encryption_sdk.key_providers.kms import ( # noqa pylint: disable=unused-import DiscoveryFilter, KMSMasterKey, @@ -290,6 +291,44 @@ def scenario_spec(self): return spec +class TestVectorsMultiMasterKeyProvider(MasterKeyProvider): + """ + Provider for other MasterKeyProviders. + Acts as a "multi" MasterKeyProvider for use in test vectors. + + There is some disagreement between the spec + and how Python ESDK implements MasterKey; + this class fills that gap. + + In the ESDK-Python, MasterKey extends MasterKeyProvider; + i.e. MasterKey "is a" MasterKeyProvider; isinstance(some_master_key, MasterKeyProvider) == True. + + From AWS ESDK specification: + "A master key MUST supply itself and MUST NOT supply any other master keys." + https://github.com/awslabs/aws-encryption-sdk-specification/blob/master/framework/master-key-interface.md#get-master-key + + The MasterKey class overrides MasterKeyProvider's `decrypt_data_key` method to correct this gap. + However, this modification suggests that this "is a" relationship is not entirely true. + + master_key_provider_from_master_key_specs expects to return a MasterKeyProvider, not a MasterKey. + master_key_provider_from_master_key_specs uses this class to always return a MasterKeyProvider + that wraps any MasterKeyProvider or MasterKey loaded from a spec. + """ + + _config_class = MasterKeyProviderConfig + provider_id = "aws-test-vectors-multi-master-key-provider" + _members = [] + + def add_key(self, key_provider): + """Add a MKP to the list of configured MKPs.""" + self._members.append(key_provider) + + def _new_master_key(self, key_id): + # This MKP does not have a key associated with it. + # ESDK-Python will find keys in _members. + raise InvalidKeyIdError() + + def master_key_provider_from_master_key_specs(keys, master_key_specs): # type: (KeysManifest, Iterable[MasterKeySpec]) -> MasterKeyProvider """Build and combine all master key providers identified by the provided specs and @@ -302,8 +341,7 @@ def master_key_provider_from_master_key_specs(keys, master_key_specs): :rtype: MasterKeyProvider """ master_keys = [spec.master_key(keys) for spec in master_key_specs] - primary = master_keys[0] - others = master_keys[1:] - for master_key in others: - primary.add_master_key_provider(master_key) - return primary + mkp = TestVectorsMultiMasterKeyProvider() + for master_key in master_keys: + mkp.add_key(master_key) + return mkp