@@ -82,6 +82,29 @@ class KeyInfo(object):
82
82
algorithm = attr .ib (validator = attr .validators .instance_of (six .string_types ))
83
83
length = attr .ib (validator = attr .validators .instance_of (six .integer_types ))
84
84
85
+ @classmethod
86
+ def from_description (cls , description , default_key_length = None ):
87
+ # type: (Text) -> KeyInfo
88
+ """Load key info from key info description.
89
+
90
+ :param str description: Key info description
91
+ :param int default_key_length: Key length to use if not found in description
92
+ """
93
+ description_parts = description .split ('/' , 1 )
94
+ algorithm = description_parts [0 ]
95
+ try :
96
+ key_length = int (description_parts [1 ])
97
+ except IndexError :
98
+ if default_key_length is None :
99
+ raise ValueError (
100
+ 'Description "{}" does not contain key length and no default key length is provided' .format (
101
+ description
102
+ )
103
+ )
104
+
105
+ key_length = default_key_length
106
+ return cls (description , algorithm , key_length )
107
+
85
108
@classmethod
86
109
def from_material_description (cls , material_description , description_key , default_algorithm , default_key_length ):
87
110
# type: (Dict[Text, Text], Text, Text, int) -> KeyInfo
@@ -90,18 +113,12 @@ def from_material_description(cls, material_description, description_key, defaul
90
113
:param dict material_description: Material description to read
91
114
:param str description_key: Material description key containing desired key info description
92
115
:param str default_algorithm: Algorithm name to use if not found in material description
93
- :param int default_key_length: Key length to use if not found in material description
116
+ :param int default_key_length: Key length to use if not found in key info description
94
117
:returns: Key info loaded from material description, with defaults applied if necessary
95
118
:rtype: dynamodb_encryption_sdk.material_providers.aws_kms.KeyInfo
96
119
"""
97
120
description = material_description .get (description_key , default_algorithm )
98
- description_parts = description .split ('/' , 1 )
99
- algorithm = description_parts [0 ]
100
- try :
101
- key_length = int (description_parts [1 ])
102
- except IndexError :
103
- key_length = default_key_length
104
- return cls (description , algorithm , key_length )
121
+ return cls .from_description (description , default_key_length )
105
122
106
123
107
124
@attr .s
@@ -234,7 +251,7 @@ def _attribute_to_value(self, attribute):
234
251
attribute_type , attribute_value = list (attribute .items ())[0 ]
235
252
if attribute_type == 'B' :
236
253
return base64 .b64encode (attribute_value .value ).decode (TEXT_ENCODING )
237
- if attribute_type == 'S' :
254
+ if attribute_type in ( 'S' , 'N' ) :
238
255
return attribute_value
239
256
raise ValueError ('Attribute of type "{}" cannot be used in KMS encryption context.' .format (attribute_type ))
240
257
@@ -255,14 +272,22 @@ def _kms_encryption_context(self, encryption_context, encryption_description, si
255
272
}
256
273
257
274
if encryption_context .partition_key_name is not None :
258
- partition_key_attribute = encryption_context .attributes .get (encryption_context .partition_key_name )
259
- kms_encryption_context [encryption_context .partition_key_name ] = self ._attribute_to_value (
260
- partition_key_attribute
261
- )
275
+ try :
276
+ partition_key_attribute = encryption_context .attributes [encryption_context .partition_key_name ]
277
+ except KeyError :
278
+ pass
279
+ else :
280
+ kms_encryption_context [encryption_context .partition_key_name ] = self ._attribute_to_value (
281
+ partition_key_attribute
282
+ )
262
283
263
284
if encryption_context .sort_key_name is not None :
264
- sort_key_attribute = encryption_context .attributes .get (encryption_context .sort_key_name )
265
- kms_encryption_context [encryption_context .sort_key_name ] = self ._attribute_to_value (sort_key_attribute )
285
+ try :
286
+ sort_key_attribute = encryption_context .attributes [encryption_context .sort_key_name ]
287
+ except KeyError :
288
+ pass
289
+ else :
290
+ kms_encryption_context [encryption_context .sort_key_name ] = self ._attribute_to_value (sort_key_attribute )
266
291
267
292
if encryption_context .table_name is not None :
268
293
kms_encryption_context [_TABLE_NAME_EC_KEY ] = encryption_context .table_name
0 commit comments