Skip to content

Commit 61953f1

Browse files
fix: MKPs attempt to decrypt with remaining keys if a preceding raw RSA key failed to decrypt (#707)
1 parent f3fa225 commit 61953f1

File tree

2 files changed

+48
-9
lines changed
  • src/aws_encryption_sdk/key_providers
  • test_vector_handlers/src/awses_test_vectors/manifests

2 files changed

+48
-9
lines changed

src/aws_encryption_sdk/key_providers/base.py

+4-3
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
ConfigMismatchError,
1313
DecryptKeyError,
1414
IncorrectMasterKeyError,
15+
InvalidDataKeyError,
1516
InvalidKeyIdError,
1617
MasterKeyProviderError,
1718
)
@@ -256,7 +257,7 @@ def decrypt_data_key(self, encrypted_data_key, algorithm, encryption_context):
256257
# //# input encryption context.
257258

258259
data_key = master_key.decrypt_data_key(encrypted_data_key, algorithm, encryption_context)
259-
except (IncorrectMasterKeyError, DecryptKeyError) as error:
260+
except (IncorrectMasterKeyError, DecryptKeyError, InvalidDataKeyError) as error:
260261
_LOGGER.debug(
261262
"%s raised when attempting to decrypt data key with master key %s",
262263
repr(error),
@@ -304,8 +305,8 @@ def decrypt_data_key_from_list(self, encrypted_data_keys, algorithm, encryption_
304305
try:
305306
data_key = self.decrypt_data_key(encrypted_data_key, algorithm, encryption_context)
306307
# MasterKeyProvider.decrypt_data_key throws DecryptKeyError
307-
# but MasterKey.decrypt_data_key throws IncorrectMasterKeyError
308-
except (DecryptKeyError, IncorrectMasterKeyError):
308+
# but MasterKey.decrypt_data_key throws IncorrectMasterKeyError and InvalidDataKeyError
309+
except (DecryptKeyError, IncorrectMasterKeyError, InvalidDataKeyError):
309310
continue
310311
else:
311312
break

test_vector_handlers/src/awses_test_vectors/manifests/master_key.py

+44-6
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@
77
"""
88
import attr
99
import six
10+
from aws_encryption_sdk.exceptions import InvalidKeyIdError
1011
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
1213
from 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+
293332
def 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

Comments
 (0)