41
41
_LOGGER = logging .getLogger (__name__ )
42
42
43
43
44
- def generate_data_key (
44
+ def _generate_data_key (
45
45
encryption_materials , # type: EncryptionMaterials
46
46
key_provider , # type: MasterKeyInfo
47
47
):
@@ -80,20 +80,39 @@ def generate_data_key(
80
80
81
81
@attr .s
82
82
class RawAESKeyring (Keyring ):
83
- """Public class for Raw AES Keyring.
83
+ """Generate an instance of Raw AES Keyring which encrypts using AES-GCM algorithm using wrapping key provided as a
84
+ byte array
84
85
85
86
:param str key_namespace: String defining the keyring.
86
87
:param bytes key_name: Key ID
87
88
:param bytes wrapping_key: Encryption key with which to wrap plaintext data key.
88
89
:param wrapping_algorithm: Wrapping Algorithm with which to wrap plaintext data key.
89
90
:type wrapping_algorithm: WrappingAlgorithm
91
+
92
+ .. note::
93
+ Only one wrapping key can be specified in a Raw AES Keyring
90
94
"""
91
95
92
96
key_namespace = attr .ib (validator = instance_of (six .string_types ))
93
97
key_name = attr .ib (validator = instance_of (six .binary_type ))
94
98
_wrapping_key = attr .ib (repr = False , validator = instance_of (six .binary_type ))
95
99
_wrapping_algorithm = attr .ib (repr = False , validator = instance_of (WrappingAlgorithm ))
96
100
101
+ def __attrs_post_init__ (self ):
102
+ # type: () -> None
103
+ """Prepares initial values not handled by attrs."""
104
+ self ._key_provider = MasterKeyInfo (provider_id = self .key_namespace , key_info = self .key_name )
105
+
106
+ self ._wrapping_key_structure = WrappingKey (
107
+ wrapping_algorithm = self ._wrapping_algorithm ,
108
+ wrapping_key = self ._wrapping_key ,
109
+ wrapping_key_type = EncryptionKeyType .SYMMETRIC ,
110
+ )
111
+
112
+ self ._key_info_prefix = self ._get_key_info_prefix (
113
+ key_namespace = self .key_namespace , key_name = self .key_name , wrapping_key = self ._wrapping_key_structure
114
+ )
115
+
97
116
@staticmethod
98
117
def _get_key_info_prefix (key_namespace , key_name , wrapping_key ):
99
118
# type: (str, bytes, WrappingKey) -> six.binary_type
@@ -111,21 +130,6 @@ def _get_key_info_prefix(key_namespace, key_name, wrapping_key):
111
130
)
112
131
return key_info_prefix
113
132
114
- def __attrs_post_init__ (self ):
115
- # type: () -> None
116
- """Prepares initial values not handled by attrs."""
117
- self ._key_provider = MasterKeyInfo (provider_id = self .key_namespace , key_info = self .key_name )
118
-
119
- self ._wrapping_key_structure = WrappingKey (
120
- wrapping_algorithm = self ._wrapping_algorithm ,
121
- wrapping_key = self ._wrapping_key ,
122
- wrapping_key_type = EncryptionKeyType .SYMMETRIC ,
123
- )
124
-
125
- self ._key_info_prefix = self ._get_key_info_prefix (
126
- key_namespace = self .key_namespace , key_name = self .key_name , wrapping_key = self ._wrapping_key_structure
127
- )
128
-
129
133
def on_encrypt (self , encryption_materials ):
130
134
# type: (EncryptionMaterials) -> EncryptionMaterials
131
135
"""Generate a data key if not present and encrypt it using any available wrapping key
@@ -136,26 +140,16 @@ def on_encrypt(self, encryption_materials):
136
140
:rtype: aws_encryption_sdk.materials_managers.EncryptionMaterials
137
141
"""
138
142
if encryption_materials .data_encryption_key is None :
139
- plaintext_generated = generate_data_key (
140
- encryption_materials = encryption_materials , key_provider = self ._key_provider
141
- )
142
-
143
- # Check if data key exists
144
- if not plaintext_generated or plaintext_generated is None :
145
- raise GenerateKeyError ("Unable to generate data encryption key." )
146
-
147
- # Encrypt data key
148
- encrypted_wrapped_key = self ._wrapping_key_structure .encrypt (
149
- plaintext_data_key = encryption_materials .data_encryption_key .data_key ,
150
- encryption_context = encryption_materials .encryption_context ,
151
- )
152
-
153
- # Check if encryption is successful
154
- if encrypted_wrapped_key is None :
155
- return encryption_materials
143
+ _generate_data_key (encryption_materials = encryption_materials , key_provider = self ._key_provider )
156
144
157
- # EncryptedData to EncryptedDataKey
158
145
try :
146
+ # Encrypt data key
147
+ encrypted_wrapped_key = self ._wrapping_key_structure .encrypt (
148
+ plaintext_data_key = encryption_materials .data_encryption_key .data_key ,
149
+ encryption_context = encryption_materials .encryption_context ,
150
+ )
151
+
152
+ # EncryptedData to EncryptedDataKey
159
153
encrypted_data_key = serialize_wrapped_key (
160
154
key_provider = self ._key_provider ,
161
155
wrapping_algorithm = self ._wrapping_algorithm ,
@@ -227,29 +221,30 @@ def on_decrypt(self, decryption_materials, encrypted_data_keys):
227
221
)
228
222
229
223
# Update decryption materials
230
- data_encryption_key = RawDataKey (
231
- key_provider = MasterKeyInfo (provider_id = self ._key_provider .provider_id , key_info = self .key_name ),
232
- data_key = plaintext_data_key ,
233
- )
224
+ data_encryption_key = RawDataKey (key_provider = self ._key_provider , data_key = plaintext_data_key )
234
225
decryption_materials .add_data_encryption_key (data_encryption_key , keyring_trace )
235
226
236
227
return decryption_materials
237
228
238
229
239
230
@attr .s
240
231
class RawRSAKeyring (Keyring ):
241
- """Public class for Raw RSA Keyring.
232
+ """Generate an instance of Raw RSA Keyring which performs asymmetric encryption and decryption using public
233
+ and private keys provided
242
234
243
235
:param str key_namespace: String defining the keyring ID
244
236
:param bytes key_name: Key ID
245
- :param _private_wrapping_key : Private encryption key with which to wrap plaintext data key (optional)
246
- :type _private_wrapping_key : RSAPrivateKey
247
- :param _public_wrapping_key : Public encryption key with which to wrap plaintext data key (optional)
248
- :type _public_wrapping_key : RSAPublicKey
237
+ :param private_wrapping_key : Private encryption key with which to wrap plaintext data key (optional)
238
+ :type private_wrapping_key : RSAPrivateKey
239
+ :param public_wrapping_key : Public encryption key with which to wrap plaintext data key (optional)
240
+ :type public_wrapping_key : RSAPublicKey
249
241
:param wrapping_algorithm: Wrapping Algorithm with which to wrap plaintext data key
250
242
:type wrapping_algorithm: WrappingAlgorithm
251
243
:param key_provider: Complete information about the key in the keyring
252
244
:type key_provider: MasterKeyInfo
245
+
246
+ .. note::
247
+ At least one of public wrapping key or private wrapping key must be provided.
253
248
"""
254
249
255
250
key_namespace = attr .ib (validator = instance_of (six .string_types ))
@@ -258,6 +253,17 @@ class RawRSAKeyring(Keyring):
258
253
_private_wrapping_key = attr .ib (default = None , repr = False , validator = optional (instance_of (rsa .RSAPrivateKey )))
259
254
_public_wrapping_key = attr .ib (default = None , repr = False , validator = optional (instance_of (rsa .RSAPublicKey )))
260
255
256
+ def __attrs_post_init__ (self ):
257
+ # type: () -> None
258
+ """Prepares initial values not handled by attrs."""
259
+ self ._key_provider = MasterKeyInfo (provider_id = self .key_namespace , key_info = self .key_name )
260
+
261
+ if self ._public_wrapping_key is None and self ._private_wrapping_key is None :
262
+ raise TypeError ("At least one of public key or private key must be provided." )
263
+
264
+ if self ._private_wrapping_key is not None and self ._public_wrapping_key is None :
265
+ self ._public_wrapping_key = self ._private_wrapping_key .public_key ()
266
+
261
267
@classmethod
262
268
def from_pem_encoding (
263
269
cls ,
@@ -269,7 +275,7 @@ def from_pem_encoding(
269
275
password = None , # type: bytes
270
276
):
271
277
# type: (...) -> RawRSAKeyring
272
- """Generate a raw RSA keyring using a key with PEM Encoding
278
+ """Generate a Raw RSA keyring using PEM Encoded public and private keys
273
279
274
280
:param str key_namespace: String defining the keyring ID
275
281
:param bytes key_name: Key ID
@@ -308,7 +314,7 @@ def from_der_encoding(
308
314
private_encoded_key = None , # type: bytes
309
315
password = None , # type: bytes
310
316
):
311
- """Generate a raw RSA keyring using a key with DER Encoding
317
+ """Generate a raw RSA keyring using DER Encoded public and private keys
312
318
313
319
:param str key_namespace: String defining the keyring ID
314
320
:param bytes key_name: Key ID
@@ -337,17 +343,6 @@ def from_der_encoding(
337
343
public_wrapping_key = loaded_public_wrapping_key ,
338
344
)
339
345
340
- def __attrs_post_init__ (self ):
341
- # type: () -> None
342
- """Prepares initial values not handled by attrs."""
343
- self ._key_provider = MasterKeyInfo (provider_id = self .key_namespace , key_info = self .key_name )
344
-
345
- if self ._public_wrapping_key is None and self ._private_wrapping_key is None :
346
- raise TypeError ("At least one of public key or private key must be provided." )
347
-
348
- if self ._private_wrapping_key is not None :
349
- self ._public_wrapping_key = self ._private_wrapping_key .public_key ()
350
-
351
346
def on_encrypt (self , encryption_materials ):
352
347
# type: (EncryptionMaterials) -> EncryptionMaterials
353
348
"""Generate a data key if not present and encrypt it using any available wrapping key.
@@ -358,19 +353,13 @@ def on_encrypt(self, encryption_materials):
358
353
:rtype: aws_encryption_sdk.materials_managers.EncryptionMaterials
359
354
"""
360
355
if encryption_materials .data_encryption_key is None :
361
- plaintext_generated = generate_data_key (
362
- encryption_materials = encryption_materials , key_provider = self ._key_provider
363
- )
364
-
365
- # Check if data key exists
366
- if not plaintext_generated or plaintext_generated is None :
367
- raise GenerateKeyError ("Unable to generate data encryption key." )
356
+ _generate_data_key (encryption_materials = encryption_materials , key_provider = self ._key_provider )
368
357
369
358
if self ._public_wrapping_key is None :
370
359
return encryption_materials
371
360
372
- # Encrypt data key
373
361
try :
362
+ # Encrypt data key
374
363
encrypted_wrapped_key = EncryptedData (
375
364
iv = None ,
376
365
ciphertext = self ._public_wrapping_key .encrypt (
@@ -379,19 +368,19 @@ def on_encrypt(self, encryption_materials):
379
368
),
380
369
tag = None ,
381
370
)
371
+
372
+ # EncryptedData to EncryptedDataKey
373
+ encrypted_data_key = serialize_wrapped_key (
374
+ key_provider = self ._key_provider ,
375
+ wrapping_algorithm = self ._wrapping_algorithm ,
376
+ wrapping_key_id = self .key_name ,
377
+ encrypted_wrapped_key = encrypted_wrapped_key ,
378
+ )
382
379
except Exception : # pylint: disable=broad-except
383
380
error_message = "Raw RSA Keyring unable to encrypt data key"
384
381
_LOGGER .exception (error_message )
385
382
return encryption_materials
386
383
387
- # EncryptedData to EncryptedDataKey
388
- encrypted_data_key = serialize_wrapped_key (
389
- key_provider = self ._key_provider ,
390
- wrapping_algorithm = self ._wrapping_algorithm ,
391
- wrapping_key_id = self .key_name ,
392
- encrypted_wrapped_key = encrypted_wrapped_key ,
393
- )
394
-
395
384
# Update Keyring Trace
396
385
keyring_trace = KeyringTrace (
397
386
wrapping_key = encrypted_data_key .key_provider , flags = {KeyringTraceFlag .WRAPPING_KEY_ENCRYPTED_DATA_KEY }
@@ -441,10 +430,7 @@ def on_decrypt(self, decryption_materials, encrypted_data_keys):
441
430
)
442
431
443
432
# Update decryption materials
444
- data_encryption_key = RawDataKey (
445
- key_provider = MasterKeyInfo (provider_id = self ._key_provider .provider_id , key_info = self .key_name ),
446
- data_key = plaintext_data_key ,
447
- )
433
+ data_encryption_key = RawDataKey (key_provider = self ._key_provider , data_key = plaintext_data_key )
448
434
decryption_materials .add_data_encryption_key (data_encryption_key , keyring_trace )
449
435
450
436
return decryption_materials
0 commit comments