KMS: Validate key specs (#6630)

* validate key specs

* fix failed tests

* add unittests

* fix typo

---------

Co-authored-by: Akira Noda <akira.noda@onecareer.com>
This commit is contained in:
Akira Noda 2023-08-19 19:53:54 +09:00 committed by GitHub
parent c072bac9ee
commit 27f025320a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 52 additions and 1 deletions

View File

@ -22,6 +22,7 @@ from .utils import (
generate_key_id,
generate_master_key,
generate_private_key,
KeySpec,
)
@ -302,6 +303,8 @@ class KmsBackend(BaseBackend):
- The resource is set to "*"
- The Action matches `describe_key`
"""
if key_spec:
self.__ensure_valid_key_spec(key_spec)
key = Key(
policy,
key_usage,
@ -615,6 +618,16 @@ class KmsBackend(BaseBackend):
)
)
def __ensure_valid_key_spec(self, key_spec: str) -> None:
if key_spec not in KeySpec.key_specs():
raise ValidationException(
(
"1 validation error detected: Value '{key_spec}' at 'KeySpec' failed "
"to satisfy constraint: Member must satisfy enum value set: "
"{valid_key_specs}"
).format(key_spec=key_spec, valid_key_specs=KeySpec.key_specs())
)
def sign(
self, key_id: str, message: bytes, signing_algorithm: str
) -> Tuple[str, bytes, str]:

View File

@ -1,5 +1,6 @@
from collections import namedtuple
from typing import Any, Dict, Tuple
from typing import Any, Dict, Tuple, List
from enum import Enum
import io
import os
import struct
@ -48,6 +49,28 @@ RESERVED_ALIASE_TARGET_KEY_IDS = {
RESERVED_ALIASES = list(RESERVED_ALIASE_TARGET_KEY_IDS.keys())
class KeySpec(str, Enum):
# Asymmetric key specs
RSA_2048 = "RSA_2048"
RSA_3072 = "RSA_3072"
RSA_4096 = "RSA_4096"
ECC_NIST_P256 = "ECC_NIST_P256"
ECC_SECG_P256K1 = "ECC_SECG_P256K1"
ECC_NIST_P384 = "ECC_NIST_P384"
ECC_NIST_P512 = "ECC_NIST_P521"
SM2 = "SM2" # China Regions only
# Symmetric key specs
SYMMETRIC_DEFAULT = "SYMMETRIC_DEFAULT"
HMAC_224 = "HMAC_224"
HMAC_256 = "HMAC_256"
HMAC_284 = "HMAC_384"
HMAC_512 = "HMAC_512"
@classmethod
def key_specs(self) -> List[str]:
return sorted([item.value for item in KeySpec])
def generate_key_id(multi_region: bool = False) -> str:
key = str(mock_random.uuid4())
# https://docs.aws.amazon.com/kms/latest/developerguide/multi-region-keys-overview.html

View File

@ -42,6 +42,21 @@ def test_create_key_without_description():
assert metadata["Description"] == ""
@mock_kms
def test_create_key_with_invalid_key_spec():
conn = boto3.client("kms", region_name="us-east-1")
unsupported_key_spec = "NotSupportedKeySpec"
with pytest.raises(ClientError) as ex:
conn.create_key(Policy="my policy", KeySpec=unsupported_key_spec)
err = ex.value.response["Error"]
assert err["Code"] == "ValidationException"
assert err["Message"] == (
"1 validation error detected: Value '{key_spec}' at 'KeySpec' failed "
"to satisfy constraint: Member must satisfy enum value set: "
"['ECC_NIST_P256', 'ECC_NIST_P384', 'ECC_NIST_P521', 'ECC_SECG_P256K1', 'HMAC_224', 'HMAC_256', 'HMAC_384', 'HMAC_512', 'RSA_2048', 'RSA_3072', 'RSA_4096', 'SM2', 'SYMMETRIC_DEFAULT']"
).format(key_spec=unsupported_key_spec)
@mock_kms
def test_create_key():
conn = boto3.client("kms", region_name="us-east-1")