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:
		
							parent
							
								
									c072bac9ee
								
							
						
					
					
						commit
						27f025320a
					
				@ -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]:
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
 | 
			
		||||
@ -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")
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user