77"""
88import attr
99import six
10+ from aws_encryption_sdk .exceptions import InvalidKeyIdError
1011from aws_encryption_sdk .identifiers import EncryptionKeyType , WrappingAlgorithm
11- from aws_encryption_sdk .key_providers .base import MasterKeyProvider # noqa pylint: disable=unused-import
12+ from aws_encryption_sdk .key_providers .base import MasterKeyProvider , MasterKeyProviderConfig
1213from aws_encryption_sdk .key_providers .kms import ( # noqa pylint: disable=unused-import
1314 DiscoveryFilter ,
1415 KMSMasterKey ,
@@ -290,6 +291,44 @@ def scenario_spec(self):
290291 return spec
291292
292293
294+ class TestVectorsMultiMasterKeyProvider (MasterKeyProvider ):
295+ """
296+ Provider for other MasterKeyProviders.
297+ Acts as a "multi" MasterKeyProvider for use in test vectors.
298+
299+ There is some disagreement between the spec
300+ and how Python ESDK implements MasterKey;
301+ this class fills that gap.
302+
303+ In the ESDK-Python, MasterKey extends MasterKeyProvider;
304+ i.e. MasterKey "is a" MasterKeyProvider; isinstance(some_master_key, MasterKeyProvider) == True.
305+
306+ From AWS ESDK specification:
307+ "A master key MUST supply itself and MUST NOT supply any other master keys."
308+ https://github.com/awslabs/aws-encryption-sdk-specification/blob/master/framework/master-key-interface.md#get-master-key
309+
310+ The MasterKey class overrides MasterKeyProvider's `decrypt_data_key` method to correct this gap.
311+ However, this modification suggests that this "is a" relationship is not entirely true.
312+
313+ master_key_provider_from_master_key_specs expects to return a MasterKeyProvider, not a MasterKey.
314+ master_key_provider_from_master_key_specs uses this class to always return a MasterKeyProvider
315+ that wraps any MasterKeyProvider or MasterKey loaded from a spec.
316+ """
317+
318+ _config_class = MasterKeyProviderConfig
319+ provider_id = "aws-test-vectors-multi-master-key-provider"
320+ _members = []
321+
322+ def add_key (self , key_provider ):
323+ """Add a MKP to the list of configured MKPs."""
324+ self ._members .append (key_provider )
325+
326+ def _new_master_key (self , key_id ):
327+ # This MKP does not have a key associated with it.
328+ # ESDK-Python will find keys in _members.
329+ raise InvalidKeyIdError ()
330+
331+
293332def master_key_provider_from_master_key_specs (keys , master_key_specs ):
294333 # type: (KeysManifest, Iterable[MasterKeySpec]) -> MasterKeyProvider
295334 """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):
302341 :rtype: MasterKeyProvider
303342 """
304343 master_keys = [spec .master_key (keys ) for spec in master_key_specs ]
305- primary = master_keys [0 ]
306- others = master_keys [1 :]
307- for master_key in others :
308- primary .add_master_key_provider (master_key )
309- return primary
344+ mkp = TestVectorsMultiMasterKeyProvider ()
345+ for master_key in master_keys :
346+ mkp .add_key (master_key )
347+ return mkp
0 commit comments