fix: MKPs attempt to decrypt with remaining keys if a preceding raw RSA key failed to decrypt by lucasmcdonald3 · Pull Request #707 · aws/aws-encryption-sdk-python

Expand Up @@ -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, Expand Down Expand Up @@ -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 Expand All @@ -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