7
7
"""
8
8
import attr
9
9
import six
10
+ from aws_encryption_sdk .exceptions import InvalidKeyIdError
10
11
from 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
12
13
from aws_encryption_sdk .key_providers .kms import ( # noqa pylint: disable=unused-import
13
14
DiscoveryFilter ,
14
15
KMSMasterKey ,
@@ -290,6 +291,44 @@ def scenario_spec(self):
290
291
return spec
291
292
292
293
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
+
293
332
def master_key_provider_from_master_key_specs (keys , master_key_specs ):
294
333
# type: (KeysManifest, Iterable[MasterKeySpec]) -> MasterKeyProvider
295
334
"""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):
302
341
:rtype: MasterKeyProvider
303
342
"""
304
343
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