Skip to content

Commit 7302775

Browse files
committed
add is_complete properties to EncryptionMaterials and DecryptionMaterials
1 parent 4f95e53 commit 7302775

File tree

2 files changed

+101
-0
lines changed

2 files changed

+101
-0
lines changed

src/aws_encryption_sdk/materials_managers/__init__.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,9 @@ def __init__(
223223
if data_encryption_key is None and encrypted_data_keys is not None:
224224
raise TypeError("encrypted_data_keys cannot be provided without data_encryption_key")
225225

226+
if encrypted_data_keys is None:
227+
encrypted_data_keys = []
228+
226229
super(EncryptionMaterials, self).__init__(
227230
algorithm=algorithm,
228231
encryption_context=encryption_context,
@@ -242,6 +245,24 @@ def encrypted_data_keys(self):
242245
"""
243246
return frozenset(self._encrypted_data_keys)
244247

248+
@property
249+
def is_complete(self):
250+
# type: () -> bool
251+
"""Determine whether these materials are sufficiently complete for use as decryption materials.
252+
253+
:rtype: bool
254+
"""
255+
if self.data_encryption_key is None:
256+
return False
257+
258+
if not self.encrypted_data_keys:
259+
return False
260+
261+
if self.algorithm.signing_algorithm_info is not None and self.signing_key is None:
262+
return False
263+
264+
return True
265+
245266
def add_data_encryption_key(self, data_encryption_key, keyring_trace):
246267
# type: (Union[DataKey, RawDataKey], KeyringTrace) -> None
247268
"""Add a plaintext data encryption key.
@@ -380,6 +401,24 @@ def __init__(
380401
self._setattr("verification_key", verification_key)
381402
attr.validate(self)
382403

404+
@property
405+
def is_complete(self):
406+
# type: () -> bool
407+
"""Determine whether these materials are sufficiently complete for use as decryption materials.
408+
409+
:rtype: bool
410+
"""
411+
if None in (self.algorithm, self.encryption_context):
412+
return False
413+
414+
if self.data_encryption_key is None:
415+
return False
416+
417+
if self.algorithm.signing_algorithm_info is not None and self.verification_key is None:
418+
return False
419+
420+
return True
421+
383422
@property
384423
def data_key(self):
385424
# type: () -> RawDataKey

test/unit/test_material_managers.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,13 +215,32 @@ def test_immutable_keyring_trace(material_class):
215215
materials.keyring_trace.append(42)
216216

217217

218+
@pytest.mark.parametrize("material_class", (CryptographicMaterials, EncryptionMaterials, DecryptionMaterials))
219+
def test_empty_keyring_trace(material_class):
220+
materials = material_class(**_copy_and_update_kwargs(material_class.__name__, dict(keyring_trace=_REMOVE)))
221+
222+
trace = materials.keyring_trace
223+
224+
assert isinstance(trace, tuple)
225+
assert not trace
226+
227+
218228
def test_immutable_encrypted_data_keys():
219229
materials = EncryptionMaterials(**_VALID_KWARGS["EncryptionMaterials"])
220230

221231
with pytest.raises(AttributeError):
222232
materials.encrypted_data_keys.add(42)
223233

224234

235+
def test_empty_encrypted_data_keys():
236+
materials = EncryptionMaterials(**_copy_and_update_kwargs("EncryptionMaterials", dict(encrypted_data_keys=_REMOVE)))
237+
238+
edks = materials.encrypted_data_keys
239+
240+
assert isinstance(edks, frozenset)
241+
assert not edks
242+
243+
225244
@pytest.mark.parametrize(
226245
"material_class, flag",
227246
(
@@ -415,3 +434,46 @@ def test_add_verification_key_fail(mod_kwargs, verification_key, exception_type,
415434
materials.add_verification_key(verification_key=verification_key)
416435

417436
excinfo.match(exception_message)
437+
438+
439+
def test_decryption_materials_is_complete():
440+
materials = DecryptionMaterials(**_copy_and_update_kwargs("DecryptionMaterials", {}))
441+
442+
assert materials.is_complete
443+
444+
445+
@pytest.mark.parametrize(
446+
"mod_kwargs",
447+
(
448+
dict(algorithm=_REMOVE),
449+
dict(encryption_context=_REMOVE),
450+
dict(data_encryption_key=_REMOVE, data_key=_REMOVE),
451+
dict(verification_key=_REMOVE),
452+
),
453+
)
454+
def test_decryption_materials_is_not_complete(mod_kwargs):
455+
kwargs = _copy_and_update_kwargs("DecryptionMaterials", mod_kwargs)
456+
materials = DecryptionMaterials(**kwargs)
457+
458+
assert not materials.is_complete
459+
460+
461+
def test_encryption_materials_is_complete():
462+
materials = EncryptionMaterials(**_copy_and_update_kwargs("EncryptionMaterials", {}))
463+
464+
assert materials.is_complete
465+
466+
467+
@pytest.mark.parametrize(
468+
"mod_kwargs",
469+
(
470+
dict(data_encryption_key=_REMOVE, encrypted_data_keys=_REMOVE),
471+
dict(encrypted_data_keys=_REMOVE),
472+
dict(signing_key=_REMOVE),
473+
),
474+
)
475+
def test_encryption_materials_is_not_complete(mod_kwargs):
476+
kwargs = _copy_and_update_kwargs("EncryptionMaterials", mod_kwargs)
477+
materials = EncryptionMaterials(**kwargs)
478+
479+
assert not materials.is_complete

0 commit comments

Comments
 (0)