26
26
MasterKeyProviderError ,
27
27
)
28
28
from aws_encryption_sdk .internal .str_ops import to_bytes
29
+ from aws_encryption_sdk .structures import DataKey # pylint: disable=unused-import
30
+ from aws_encryption_sdk .structures import EncryptedDataKey # pylint: disable=unused-import
31
+ from aws_encryption_sdk .structures import RawDataKey # pylint: disable=unused-import
29
32
from aws_encryption_sdk .structures import MasterKeyInfo
30
33
34
+ try : # Python 3.5.0 and 3.5.1 have incompatible typing modules
35
+ from typing import Iterable , Union # noqa pylint: disable=unused-import
36
+ except ImportError : # pragma: no cover
37
+ # We only actually need these imports when running the mypy checks
38
+ pass
39
+
31
40
_LOGGER = logging .getLogger (__name__ )
32
41
33
42
@@ -212,6 +221,35 @@ def master_key_for_decrypt(self, key_info):
212
221
self ._decrypt_key_index [key_info ] = decrypt_master_key
213
222
return decrypt_master_key
214
223
224
+ def master_keys_for_data_key (self , data_key ):
225
+ # type: (Union[DataKey, EncryptedDataKey, RawDataKey]) -> Iterable[MasterKey]
226
+ """Locates the correct master keys from children for the specified data key.
227
+
228
+ :param data_key: Data key for which to locate owning master keys
229
+ :type data_key: :class:`EncryptedDataKey`, :class:`RawDataKey`, or :class:`DataKey`
230
+ :returns: Masters key that own data key
231
+ :rtype: iterator of :class:`MasterKey`
232
+ :raises UnknownIdentityError: if unable to locate the correct master key
233
+ """
234
+ for member in [self ] + self ._members :
235
+ if member .provider_id != data_key .key_provider .provider_id :
236
+ continue
237
+
238
+ _LOGGER .debug ("attempting to locate master key from key provider: %s" , member .provider_id )
239
+
240
+ if isinstance (member , MasterKey ):
241
+ if member .owns_data_key (data_key ):
242
+ _LOGGER .debug ("using existing master key" )
243
+ yield member
244
+
245
+ if self .vend_masterkey_on_decrypt :
246
+ try :
247
+ _LOGGER .debug ("attempting to add master key: %s" , data_key .key_provider .key_info )
248
+ yield member .master_key_for_decrypt (data_key .key_provider .key_info )
249
+ except InvalidKeyIdError :
250
+ _LOGGER .debug ("master key %s not available in provider" , data_key .key_provider .key_info )
251
+ continue
252
+
215
253
def decrypt_data_key (self , encrypted_data_key , algorithm , encryption_context ):
216
254
"""Iterates through all currently added Master Keys and Master Key Providers
217
255
to attempt to decrypt data key.
@@ -225,42 +263,25 @@ def decrypt_data_key(self, encrypted_data_key, algorithm, encryption_context):
225
263
:rtype: aws_encryption_sdk.structures.DataKey
226
264
:raises DecryptKeyError: if unable to decrypt encrypted data key
227
265
"""
228
- data_key = None
229
- master_key = None
230
266
_LOGGER .debug ("starting decrypt data key attempt" )
231
- for member in [self ] + self ._members :
232
- if member .provider_id == encrypted_data_key .key_provider .provider_id :
233
- _LOGGER .debug ("attempting to locate master key from key provider: %s" , member .provider_id )
234
- if isinstance (member , MasterKey ):
235
- _LOGGER .debug ("using existing master key" )
236
- master_key = member
237
- elif self .vend_masterkey_on_decrypt :
238
- try :
239
- _LOGGER .debug ("attempting to add master key: %s" , encrypted_data_key .key_provider .key_info )
240
- master_key = member .master_key_for_decrypt (encrypted_data_key .key_provider .key_info )
241
- except InvalidKeyIdError :
242
- _LOGGER .debug (
243
- "master key %s not available in provider" , encrypted_data_key .key_provider .key_info
244
- )
245
- continue
246
- else :
247
- continue
248
- try :
249
- _LOGGER .debug (
250
- "attempting to decrypt data key with provider %s" , encrypted_data_key .key_provider .key_info
251
- )
252
- data_key = master_key .decrypt_data_key (encrypted_data_key , algorithm , encryption_context )
253
- except (IncorrectMasterKeyError , DecryptKeyError ) as error :
254
- _LOGGER .debug (
255
- "%s raised when attempting to decrypt data key with master key %s" ,
256
- repr (error ),
257
- master_key .key_provider ,
258
- )
259
- continue
260
- break # If this point is reached without throwing any errors, the data key has been decrypted
261
- if not data_key :
262
- raise DecryptKeyError ("Unable to decrypt data key" )
263
- return data_key
267
+ for master_key in self .master_keys_for_data_key (encrypted_data_key ):
268
+ try :
269
+ _LOGGER .debug (
270
+ "attempting to decrypt data key with provider %s" , encrypted_data_key .key_provider .key_info
271
+ )
272
+ return master_key .decrypt_data_key (encrypted_data_key , algorithm , encryption_context )
273
+
274
+ # MasterKeyProvider.decrypt_data_key throws DecryptKeyError
275
+ # but MasterKey.decrypt_data_key throws IncorrectMasterKeyError
276
+ except (IncorrectMasterKeyError , DecryptKeyError ) as error :
277
+ _LOGGER .debug (
278
+ "%s raised when attempting to decrypt data key with master key %s" ,
279
+ repr (error ),
280
+ master_key .key_provider ,
281
+ )
282
+ continue
283
+
284
+ raise DecryptKeyError ("Unable to decrypt data key" )
264
285
265
286
def decrypt_data_key_from_list (self , encrypted_data_keys , algorithm , encryption_context ):
266
287
"""Receives a list of encrypted data keys and returns the first one which this provider is able to decrypt.
@@ -356,9 +377,7 @@ def owns_data_key(self, data_key):
356
377
:returns: Boolean statement of ownership
357
378
:rtype: bool
358
379
"""
359
- if data_key .key_provider == self .key_provider :
360
- return True
361
- return False
380
+ return data_key .key_provider == self .key_provider
362
381
363
382
def master_keys_for_encryption (self , encryption_context , plaintext_rostream , plaintext_length = None ):
364
383
"""Returns self and a list containing self, to match the format of output for a Master Key Provider.
0 commit comments