Skip to content

Commit 5de76e5

Browse files
authored
Merge pull request #107 from mattsb42-aws/handlers
Test vector handler updates
2 parents fd07fbb + 67bf9f9 commit 5de76e5

File tree

6 files changed

+4323
-4420
lines changed

6 files changed

+4323
-4420
lines changed

test_vector_handlers/src/awses_test_vectors/internal/mypy_types.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
MANIFEST_VERSION = Dict[str, Union[str, int]]
3434

3535
AWS_KMS_KEY_SPEC = Dict[str, Union[bool, str]]
36-
MANUAL_KEY_SPEC = Dict[str, Union[bool, str, int, Iterable[str]]]
36+
MANUAL_KEY_SPEC = Dict[str, Union[bool, str, int]]
3737
KEY_SPEC = Union[AWS_KMS_KEY_SPEC, MANUAL_KEY_SPEC]
3838
KEYS_MANIFEST = Dict[str, Union[MANIFEST_VERSION, Iterable[KEY_SPEC]]]
3939

test_vector_handlers/src/awses_test_vectors/manifests/full_message/encrypt.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,4 @@ def run_and_write_to_dir(self, target_directory, json_indent=None):
238238
keys_uri="file://keys.json", keys=self.keys, test_scenarios=test_scenarios
239239
)
240240

241-
root_writer(
242-
"manifest.json", json.dumps(decrypt_manifest.manifest_spec, indent=json_indent).encode(ENCODING)
243-
)
241+
root_writer("manifest.json", json.dumps(decrypt_manifest.manifest_spec, indent=json_indent).encode(ENCODING))

test_vector_handlers/src/awses_test_vectors/manifests/keys.py

Lines changed: 18 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,7 @@
2222

2323
from awses_test_vectors.internal.aws_kms import arn_from_key_id
2424
from awses_test_vectors.internal.defaults import ENCODING
25-
from awses_test_vectors.internal.util import (
26-
dictionary_validator,
27-
iterable_validator,
28-
membership_validator,
29-
validate_manifest_type,
30-
)
25+
from awses_test_vectors.internal.util import dictionary_validator, membership_validator, validate_manifest_type
3126

3227
try: # Python 3.5.0 and 3.5.1 have incompatible typing modules
3328
from typing import cast, Dict, Iterable, Optional # noqa pylint: disable=unused-import
@@ -42,7 +37,7 @@
4237
# We only actually need these imports when running the mypy checks
4338
pass
4439

45-
SUPPORTED_VERSIONS = (1,)
40+
SUPPORTED_VERSIONS = (3,)
4641
KEY_TYPES = ("symmetric", "private", "public")
4742
KEY_ENCODINGS = ("base64", "pem")
4843
KEY_ALGORITHMS = ("aes", "rsa")
@@ -60,14 +55,16 @@ class KeySpec(object):
6055

6156
encrypt = attr.ib(validator=attr.validators.instance_of(bool))
6257
decrypt = attr.ib(validator=attr.validators.instance_of(bool))
58+
key_id = attr.ib(validator=attr.validators.instance_of(six.string_types))
6359

64-
def __init__(self, encrypt, decrypt): # noqa=D107
65-
# type: (bool, bool) -> None
60+
def __init__(self, encrypt, decrypt, key_id): # noqa=D107
61+
# type: (bool, bool, str) -> None
6662
# Workaround pending resolution of attrs/mypy interaction.
6763
# https://github.com/python/mypy/issues/2088
6864
# https://github.com/python-attrs/attrs/issues/215
6965
self.encrypt = encrypt
7066
self.decrypt = decrypt
67+
self.key_id = key_id
7168
attr.validate(self)
7269

7370

@@ -84,16 +81,14 @@ class AwsKmsKeySpec(KeySpec):
8481
# pylint: disable=too-few-public-methods
8582

8683
type_name = attr.ib(validator=membership_validator(("aws-kms",)))
87-
key_id = attr.ib(validator=attr.validators.instance_of(six.string_types))
8884

8985
def __init__(self, encrypt, decrypt, type_name, key_id): # noqa=D107
9086
# type: (bool, bool, str, str) -> None
9187
# Workaround pending resolution of attrs/mypy interaction.
9288
# https://github.com/python/mypy/issues/2088
9389
# https://github.com/python-attrs/attrs/issues/215
9490
self.type_name = type_name
95-
self.key_id = key_id
96-
super(AwsKmsKeySpec, self).__init__(encrypt, decrypt)
91+
super(AwsKmsKeySpec, self).__init__(encrypt, decrypt, key_id)
9792

9893
@property
9994
def manifest_spec(self):
@@ -117,35 +112,32 @@ class ManualKeySpec(KeySpec):
117112
118113
Allowed values described in AWS Crypto Tools Test Vector Framework feature #0002 Keys Manifest.
119114
115+
:param str key_id: Master key ID
120116
:param bool encrypt: Key can be used to encrypt
121117
:param bool decrypt: Key can be used to decrypt
122118
:param str algorithm: Algorithm to use with key
123119
:param str type_name: Key type
124120
:param int bits: Key length in bits
125121
:param str encoding: Encoding used to encode key material
126-
:param material: Raw material encoded, then split into lines separated by ``line_separator``
127-
:type material: list of str
128-
:param str line_separator: Character with which to separate members of ``material``
129-
before decoding (optional: default is empty string)
122+
:param str material: Raw material encoded
130123
"""
131124

132125
algorithm = attr.ib(validator=membership_validator(KEY_ALGORITHMS))
133126
type_name = attr.ib(validator=membership_validator(KEY_TYPES))
134127
bits = attr.ib(validator=attr.validators.instance_of(int))
135128
encoding = attr.ib(validator=membership_validator(KEY_ENCODINGS))
136-
material = attr.ib(validator=iterable_validator(list, six.string_types))
137-
line_separator = attr.ib(default="", validator=attr.validators.instance_of(six.string_types))
129+
material = attr.ib(validator=attr.validators.instance_of(six.string_types))
138130

139131
def __init__(
140132
self,
133+
key_id, # type: str
141134
encrypt, # type: bool
142135
decrypt, # type: bool
143136
algorithm, # type: str
144137
type_name, # type: str
145138
bits, # type: int
146139
encoding, # type: str
147140
material, # type: Iterable[str]
148-
line_separator="", # type: Optional[str]
149141
): # noqa=D107
150142
# type: (...) -> None
151143
# Workaround pending resolution of attrs/mypy interaction.
@@ -156,8 +148,7 @@ def __init__(
156148
self.bits = bits
157149
self.encoding = encoding
158150
self.material = material
159-
self.line_separator = line_separator
160-
super(ManualKeySpec, self).__init__(encrypt, decrypt)
151+
super(ManualKeySpec, self).__init__(encrypt, decrypt, key_id)
161152

162153
@property
163154
def raw_material(self):
@@ -167,7 +158,7 @@ def raw_material(self):
167158
:return: Binary key material
168159
:rtype: bytes
169160
"""
170-
raw_material = self.line_separator.join(self.material).encode(ENCODING)
161+
raw_material = self.material.encode(ENCODING)
171162
if self.encoding == "base64":
172163
return base64.b64decode(raw_material)
173164

@@ -188,8 +179,8 @@ def manifest_spec(self):
188179
"type": self.type_name,
189180
"bits": self.bits,
190181
"encoding": self.encoding,
191-
"line-separator": self.line_separator,
192182
"material": self.material,
183+
"key-id": self.key_id,
193184
}
194185

195186

@@ -201,6 +192,7 @@ def key_from_manifest_spec(key_spec):
201192
:return: Loaded key
202193
:rtype: KeySpec
203194
"""
195+
key_id = key_spec["key-id"] # type: str
204196
decrypt = key_spec["decrypt"] # type: bool
205197
encrypt = key_spec["encrypt"] # type: bool
206198
type_name = key_spec["type"] # type: str
@@ -211,16 +203,15 @@ def key_from_manifest_spec(key_spec):
211203
algorithm = key_spec["algorithm"] # type: str
212204
bits = key_spec["bits"] # type: int
213205
encoding = key_spec["encoding"] # type: str
214-
line_separator = key_spec.get("line-separator", "") # type: str
215-
material = key_spec["material"] # type: Iterable[str]
206+
material = key_spec["material"] # type: str
216207
return ManualKeySpec(
208+
key_id=key_id,
217209
encrypt=encrypt,
218210
decrypt=decrypt,
219211
type_name=type_name,
220212
algorithm=algorithm,
221213
bits=bits,
222214
encoding=encoding,
223-
line_separator=line_separator,
224215
material=material,
225216
)
226217

@@ -242,7 +233,7 @@ class KeysManifest(object):
242233
@classmethod
243234
def from_manifest_spec(cls, raw_manifest):
244235
# type: (KEYS_MANIFEST) -> KeysManifest
245-
""""""
236+
"""Load from a JSON keys manifest."""
246237
manifest_version = raw_manifest["manifest"] # type: MANIFEST_VERSION
247238
validate_manifest_type(
248239
type_name=cls.type_name, manifest_version=manifest_version, supported_versions=SUPPORTED_VERSIONS

test_vector_handlers/src/awses_test_vectors/manifests/master_key.py

Lines changed: 17 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,17 @@
5050
"rsa/pkcs1": WrappingAlgorithm.RSA_PKCS1,
5151
"rsa/oaep-mgf1/sha1": WrappingAlgorithm.RSA_OAEP_SHA1_MGF1,
5252
"rsa/oaep-mgf1/sha256": WrappingAlgorithm.RSA_OAEP_SHA256_MGF1,
53-
# \/ not yet implemented \/
54-
# 'rsa/oaep-mgf1/sha384': WrappingAlgorithm.RSA_OAEP_SHA384_MGF1,
55-
# 'rsa/oaep-mgf1/sha512': WrappingAlgorithm.RSA_OAEP_SHA512_MGF1,
5653
}
57-
_NOT_YET_IMPLEMENTED = {"rsa/oaep-mgf1/sha384", "rsa/oaep-mgf1/sha512"}
54+
try:
55+
_RAW_WRAPPING_KEY_ALGORITHMS.update(
56+
{
57+
"rsa/oaep-mgf1/sha384": WrappingAlgorithm.RSA_OAEP_SHA384_MGF1,
58+
"rsa/oaep-mgf1/sha512": WrappingAlgorithm.RSA_OAEP_SHA512_MGF1,
59+
}
60+
)
61+
_NOT_YET_IMPLEMENTED = {}
62+
except AttributeError:
63+
_NOT_YET_IMPLEMENTED = {"rsa/oaep-mgf1/sha384", "rsa/oaep-mgf1/sha512"}
5864
_RAW_ENCRYPTION_KEY_TYPE = {
5965
"symmetric": EncryptionKeyType.SYMMETRIC,
6066
"private": EncryptionKeyType.PRIVATE,
@@ -68,18 +74,16 @@ class MasterKeySpec(object):
6874
6975
Described in AWS Crypto Tools Test Vector Framework features #0003 and #0004.
7076
71-
:param str type_name:
72-
:param str key_name:
73-
:param str key_id:
74-
:param str provider_id:
75-
:param str encryption_algorithm:
76-
:param str padding_algorithm:
77-
:param str padding_hash:
77+
:param str type_name: Master key type name
78+
:param str key_name: Name of key in keys spec
79+
:param str provider_id: Master key provider ID
80+
:param str encryption_algorithm: Wrapping key encryption algorithm (required for raw master keys)
81+
:param str padding_algorithm: Wrapping key padding algorithm (required for raw master keys)
82+
:param str padding_hash: Wrapping key padding hash (required for raw master keys)
7883
"""
7984

8085
type_name = attr.ib(validator=membership_validator(KNOWN_TYPES))
8186
key_name = attr.ib(validator=attr.validators.instance_of(six.string_types))
82-
key_id = attr.ib(validator=attr.validators.optional(attr.validators.instance_of(six.string_types)))
8387
provider_id = attr.ib(validator=attr.validators.optional(attr.validators.instance_of(six.string_types)))
8488
encryption_algorithm = attr.ib(validator=attr.validators.optional(membership_validator(KNOWN_ALGORITHMS)))
8589
padding_algorithm = attr.ib(validator=attr.validators.optional(membership_validator(KNOWN_PADDING)))
@@ -113,7 +117,6 @@ def from_scenario(cls, spec):
113117
return cls(
114118
type_name=spec["type"],
115119
key_name=spec["key"],
116-
key_id=spec.get("key-id"),
117120
provider_id=spec.get("provider-id"),
118121
encryption_algorithm=spec.get("encryption-algorithm"),
119122
padding_algorithm=spec.get("padding-algorithm"),
@@ -166,19 +169,6 @@ def _wrapping_key(self, key_spec):
166169
key_type = _RAW_ENCRYPTION_KEY_TYPE[key_spec.type_name]
167170
return WrappingKey(wrapping_algorithm=algorithm, wrapping_key=material, wrapping_key_type=key_type)
168171

169-
def _raw_key_id(self):
170-
# type: () -> str
171-
"""Determine the key ID value if this is a raw master key.
172-
173-
:returns: Correct key ID
174-
:rtype: str
175-
:raises TypeError: if this is not a raw master key specification
176-
"""
177-
if not self.type_name == "raw":
178-
raise TypeError("This is not a raw master key")
179-
180-
return self.key_id if self.key_id is not None else self.key_name
181-
182172
def _raw_master_key_from_spec(self, key_spec):
183173
# type: (KeySpec) -> RawMasterKey
184174
"""Build a raw master key using this specification.
@@ -192,8 +182,7 @@ def _raw_master_key_from_spec(self, key_spec):
192182
raise TypeError("This is not a raw master key")
193183

194184
wrapping_key = self._wrapping_key(key_spec)
195-
key_id = self._raw_key_id()
196-
return RawMasterKey(provider_id=self.provider_id, key_id=key_id, wrapping_key=wrapping_key)
185+
return RawMasterKey(provider_id=self.provider_id, key_id=key_spec.key_id, wrapping_key=wrapping_key)
197186

198187
def _kms_master_key_from_spec(self, key_spec):
199188
# type: (KeySpec) -> KMSMasterKey
@@ -207,9 +196,6 @@ def _kms_master_key_from_spec(self, key_spec):
207196
if not self.type_name == "aws-kms":
208197
raise TypeError("This is not an AWS KMS master key")
209198

210-
if self.key_id is not None and self.key_id != key_spec.key_id:
211-
raise ValueError("AWS KMS key IDs must match between master key spec and key spec")
212-
213199
return KMS_MASTER_KEY_PROVIDER.master_key(key_id=key_spec.key_id)
214200

215201
_MASTER_KEY_LOADERS = {"aws-kms": _kms_master_key_from_spec, "raw": _raw_master_key_from_spec}
@@ -237,7 +223,6 @@ def scenario_spec(self):
237223
if self.type_name != "aws-kms":
238224
spec.update(
239225
{
240-
"key-id": self.key_id,
241226
"provider-id": self.provider_id,
242227
"encryption-algorithm": self.encryption_algorithm,
243228
"padding-algorithm": self.padding_algorithm,

0 commit comments

Comments
 (0)