From 26fc28838aab0edea2f7908c842137350ae1cb04 Mon Sep 17 00:00:00 2001 From: sannya-singal Date: Sat, 2 Aug 2025 15:14:10 +0530 Subject: [PATCH 1/5] KMS: add support for import of external HMAC keys --- .../localstack/services/kms/models.py | 8 +- tests/aws/services/kms/test_kms.py | 48 ++++++++++ tests/aws/services/kms/test_kms.snapshot.json | 96 +++++++++++++++++++ .../aws/services/kms/test_kms.validation.json | 9 ++ 4 files changed, 160 insertions(+), 1 deletion(-) diff --git a/localstack-core/localstack/services/kms/models.py b/localstack-core/localstack/services/kms/models.py index 3479e309d4903..31719834c19a9 100644 --- a/localstack-core/localstack/services/kms/models.py +++ b/localstack-core/localstack/services/kms/models.py @@ -251,7 +251,13 @@ def __init__(self, key_spec: str, key_material: Optional[bytes] = None): self._serialize_key(key) def load_key_material(self, material: bytes): - if self.key_spec == "SYMMETRIC_DEFAULT": + if self.key_spec in [ + KeySpec.SYMMETRIC_DEFAULT, + KeySpec.HMAC_224, + KeySpec.HMAC_256, + KeySpec.HMAC_384, + KeySpec.HMAC_512, + ]: self.key_material = material else: key = crypto_serialization.load_der_private_key(material, password=None) diff --git a/tests/aws/services/kms/test_kms.py b/tests/aws/services/kms/test_kms.py index bd8a33d929471..53a3adfd97337 100644 --- a/tests/aws/services/kms/test_kms.py +++ b/tests/aws/services/kms/test_kms.py @@ -1194,6 +1194,54 @@ def test_list_aliases_of_key(self, kms_create_key, kms_create_alias, aws_client) assert _get_alias(aws_client.kms, alias_name, aliased_key_id) is not None assert _get_alias(aws_client.kms, alias_name, comparison_key_id) is None + @markers.aws.validated + def test_import_key_hmac(self, kms_create_key, aws_client, snapshot): + snapshot.add_transformer(snapshot.transform.key_value("Description")) + key = kms_create_key(Origin="EXTERNAL", KeySpec="HMAC_512", KeyUsage="GENERATE_VERIFY_MAC") + key_id = key["KeyId"] + + plaintext = os.urandom(64) + + params = aws_client.kms.get_parameters_for_import( + KeyId=key_id, WrappingAlgorithm="RSAES_OAEP_SHA_256", WrappingKeySpec="RSA_4096" + ) + + public_key = load_der_public_key(params["PublicKey"]) + encrypted_key = public_key.encrypt( + plaintext, + padding.OAEP( + mgf=padding.MGF1(algorithm=hashes.SHA256()), algorithm=hashes.SHA256(), label=None + ), + ) + describe_key_before_import = aws_client.kms.describe_key(KeyId=key_id) + snapshot.match("describe-key-before-import", describe_key_before_import) + + aws_client.kms.import_key_material( + KeyId=key_id, + ImportToken=params["ImportToken"], + EncryptedKeyMaterial=encrypted_key, + ExpirationModel="KEY_MATERIAL_DOES_NOT_EXPIRE", + ) + describe_key_after_import = aws_client.kms.describe_key(KeyId=key_id) + snapshot.match("describe-key-after-import", describe_key_after_import) + + # Generate and verify MAC + message = b"test-mac-message" + generate_mac = aws_client.kms.generate_mac( + KeyId=key_id, Message=message, MacAlgorithm="HMAC_SHA_512" + ) + snapshot.match("generate-mac-response", generate_mac) + + verify_mac = aws_client.kms.verify_mac( + KeyId=key_id, Message=message, Mac=generate_mac["Mac"], MacAlgorithm="HMAC_SHA_512" + ) + snapshot.match("verify-mac-response", verify_mac) + assert verify_mac["MacValid"] + + aws_client.kms.delete_imported_key_material(KeyId=key_id) + describe_key_after_deleted_import = aws_client.kms.describe_key(KeyId=key_id) + snapshot.match("describe-key-after-deleted-import", describe_key_after_deleted_import) + @markers.aws.validated def test_all_types_of_key_id_can_be_used_for_encryption( self, kms_create_key, kms_create_alias, aws_client diff --git a/tests/aws/services/kms/test_kms.snapshot.json b/tests/aws/services/kms/test_kms.snapshot.json index 14caa75229d16..eff490d51c94e 100644 --- a/tests/aws/services/kms/test_kms.snapshot.json +++ b/tests/aws/services/kms/test_kms.snapshot.json @@ -2427,5 +2427,101 @@ } } } + }, + "tests/aws/services/kms/test_kms.py::TestKMS::test_import_key_hmac": { + "recorded-date": "02-08-2025, 09:37:57", + "recorded-content": { + "describe-key-before-import": { + "KeyMetadata": { + "AWSAccountId": "111111111111", + "Arn": "arn::kms::111111111111:key/", + "CreationDate": "datetime", + "CustomerMasterKeySpec": "HMAC_512", + "Description": "", + "Enabled": false, + "KeyId": "", + "KeyManager": "CUSTOMER", + "KeySpec": "HMAC_512", + "KeyState": "PendingImport", + "KeyUsage": "GENERATE_VERIFY_MAC", + "MacAlgorithms": [ + "HMAC_SHA_512" + ], + "MultiRegion": false, + "Origin": "EXTERNAL" + }, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "describe-key-after-import": { + "KeyMetadata": { + "AWSAccountId": "111111111111", + "Arn": "arn::kms::111111111111:key/", + "CreationDate": "datetime", + "CustomerMasterKeySpec": "HMAC_512", + "Description": "", + "Enabled": true, + "ExpirationModel": "KEY_MATERIAL_DOES_NOT_EXPIRE", + "KeyId": "", + "KeyManager": "CUSTOMER", + "KeySpec": "HMAC_512", + "KeyState": "Enabled", + "KeyUsage": "GENERATE_VERIFY_MAC", + "MacAlgorithms": [ + "HMAC_SHA_512" + ], + "MultiRegion": false, + "Origin": "EXTERNAL" + }, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "generate-mac-response": { + "KeyId": "arn::kms::111111111111:key/", + "Mac": "", + "MacAlgorithm": "HMAC_SHA_512", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "verify-mac-response": { + "KeyId": "arn::kms::111111111111:key/", + "MacAlgorithm": "HMAC_SHA_512", + "MacValid": true, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "describe-key-after-deleted-import": { + "KeyMetadata": { + "AWSAccountId": "111111111111", + "Arn": "arn::kms::111111111111:key/", + "CreationDate": "datetime", + "CustomerMasterKeySpec": "HMAC_512", + "Description": "", + "Enabled": false, + "KeyId": "", + "KeyManager": "CUSTOMER", + "KeySpec": "HMAC_512", + "KeyState": "PendingImport", + "KeyUsage": "GENERATE_VERIFY_MAC", + "MacAlgorithms": [ + "HMAC_SHA_512" + ], + "MultiRegion": false, + "Origin": "EXTERNAL" + }, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + } + } } } diff --git a/tests/aws/services/kms/test_kms.validation.json b/tests/aws/services/kms/test_kms.validation.json index 53acbdfce27e2..27b6b1c6bfb26 100644 --- a/tests/aws/services/kms/test_kms.validation.json +++ b/tests/aws/services/kms/test_kms.validation.json @@ -161,6 +161,15 @@ "tests/aws/services/kms/test_kms.py::TestKMS::test_import_key_asymmetric": { "last_validated_date": "2024-04-11T15:53:35+00:00" }, + "tests/aws/services/kms/test_kms.py::TestKMS::test_import_key_hmac": { + "last_validated_date": "2025-08-02T09:37:57+00:00", + "durations_in_seconds": { + "setup": 1.3, + "call": 3.51, + "teardown": 0.31, + "total": 5.12 + } + }, "tests/aws/services/kms/test_kms.py::TestKMS::test_import_key_rsa_aes_wrap_sha256": { "last_validated_date": "2025-07-22T06:11:13+00:00", "durations_in_seconds": { From d7ea73a1e2a41cd0d1d097247e2d1fc08fe0f9d0 Mon Sep 17 00:00:00 2001 From: sannya-singal Date: Mon, 4 Aug 2025 11:06:13 +0530 Subject: [PATCH 2/5] add tests to validate imported ecc keys --- tests/aws/services/kms/test_kms.py | 173 ++++- tests/aws/services/kms/test_kms.snapshot.json | 680 +++++++++++++++++- .../aws/services/kms/test_kms.validation.json | 73 +- 3 files changed, 912 insertions(+), 14 deletions(-) diff --git a/tests/aws/services/kms/test_kms.py b/tests/aws/services/kms/test_kms.py index 53a3adfd97337..3e2bd9a9d6f14 100644 --- a/tests/aws/services/kms/test_kms.py +++ b/tests/aws/services/kms/test_kms.py @@ -15,6 +15,13 @@ from cryptography.hazmat.primitives.keywrap import aes_key_wrap_with_padding from cryptography.hazmat.primitives.serialization import load_der_public_key +from localstack.aws.api.kms import ( + AlgorithmSpec, + KeySpec, + MacAlgorithmSpec, + SigningAlgorithmSpec, + WrappingKeySpec, +) from localstack.services.kms.models import ( HEADER_LEN, IV_LEN, @@ -29,6 +36,14 @@ from localstack.utils.strings import short_uid, to_str from localstack.utils.sync import poll_condition +# Map HMAC key specs with expected byte lengths and mac algo +HMAC_KEY_SPECS = [ + (KeySpec.HMAC_224, 28, MacAlgorithmSpec.HMAC_SHA_224), + (KeySpec.HMAC_256, 32, MacAlgorithmSpec.HMAC_SHA_256), + (KeySpec.HMAC_384, 48, MacAlgorithmSpec.HMAC_SHA_384), + (KeySpec.HMAC_512, 64, MacAlgorithmSpec.HMAC_SHA_512), +] + def create_tags(**kwargs): return [{"TagKey": key, "TagValue": value} for key, value in kwargs.items()] @@ -1195,12 +1210,158 @@ def test_list_aliases_of_key(self, kms_create_key, kms_create_alias, aws_client) assert _get_alias(aws_client.kms, alias_name, comparison_key_id) is None @markers.aws.validated - def test_import_key_hmac(self, kms_create_key, aws_client, snapshot): - snapshot.add_transformer(snapshot.transform.key_value("Description")) - key = kms_create_key(Origin="EXTERNAL", KeySpec="HMAC_512", KeyUsage="GENERATE_VERIFY_MAC") + @pytest.mark.parametrize( + "key_spec, curve, signing_algorithm, wrapping_key_spec, wrapping_algorithm, oaep_hash", + [ + ( + KeySpec.ECC_NIST_P256, + ec.SECP256R1(), + SigningAlgorithmSpec.ECDSA_SHA_256, + WrappingKeySpec.RSA_2048, + AlgorithmSpec.RSAES_OAEP_SHA_1, + hashes.SHA1(), + ), + ( + KeySpec.ECC_NIST_P384, + ec.SECP384R1(), + SigningAlgorithmSpec.ECDSA_SHA_384, + WrappingKeySpec.RSA_2048, + AlgorithmSpec.RSAES_OAEP_SHA_1, + hashes.SHA1(), + ), + ( + KeySpec.ECC_NIST_P521, + ec.SECP521R1(), + SigningAlgorithmSpec.ECDSA_SHA_512, + WrappingKeySpec.RSA_4096, + AlgorithmSpec.RSAES_OAEP_SHA_256, + hashes.SHA256(), + ), + ( + KeySpec.ECC_SECG_P256K1, + ec.SECP256K1(), + SigningAlgorithmSpec.ECDSA_SHA_256, + WrappingKeySpec.RSA_2048, + AlgorithmSpec.RSAES_OAEP_SHA_1, + hashes.SHA1(), + ), + ], + ids=[ + KeySpec.ECC_NIST_P256, + KeySpec.ECC_NIST_P384, + KeySpec.ECC_NIST_P521, + KeySpec.ECC_SECG_P256K1, + ], + ) + def test_import_key_ecc_keys( + self, + key_spec, + curve, + signing_algorithm, + wrapping_key_spec, + wrapping_algorithm, + oaep_hash, + kms_create_key, + aws_client, + snapshot, + ): + key = kms_create_key( + Origin="EXTERNAL", + KeySpec=key_spec, + KeyUsage="SIGN_VERIFY", + Description="test ecc key import", + ) + key_id = key["KeyId"] + + ecc_key = ec.generate_private_key(curve) + raw_private_key = ecc_key.private_bytes( + serialization.Encoding.DER, + serialization.PrivateFormat.PKCS8, + serialization.NoEncryption(), + ) + raw_public_key = ecc_key.public_key().public_bytes( + serialization.Encoding.DER, + serialization.PublicFormat.SubjectPublicKeyInfo, + ) + + import_params = aws_client.kms.get_parameters_for_import( + KeyId=key_id, + WrappingAlgorithm=wrapping_algorithm, + WrappingKeySpec=wrapping_key_spec, + ) + + public_key = load_der_public_key(import_params["PublicKey"]) + encrypted_key = public_key.encrypt( + raw_private_key, + padding.OAEP( + mgf=padding.MGF1(algorithm=oaep_hash), + algorithm=oaep_hash, + label=None, + ), + ) + + describe_before = aws_client.kms.describe_key(KeyId=key_id) + snapshot.match("describe-key-before-import", describe_before) + + aws_client.kms.import_key_material( + KeyId=key_id, + ImportToken=import_params["ImportToken"], + EncryptedKeyMaterial=encrypted_key, + ExpirationModel="KEY_MATERIAL_DOES_NOT_EXPIRE", + ) + + describe_after = aws_client.kms.describe_key(KeyId=key_id) + snapshot.match("describe-key-after-import", describe_after) + + get_public_key_after_import = aws_client.kms.get_public_key(KeyId=key_id) + assert get_public_key_after_import["PublicKey"] == raw_public_key + + message = b"test sign verify 123 !%$@ 1234567890" + sign_result = aws_client.kms.sign( + KeyId=key_id, + Message=message, + MessageType="RAW", + SigningAlgorithm=signing_algorithm, + ) + snapshot.match("sign-result", sign_result) + + verify_result = aws_client.kms.verify( + KeyId=key_id, + Message=message, + MessageType="RAW", + SigningAlgorithm=signing_algorithm, + Signature=sign_result["Signature"], + ) + snapshot.match("verify-result", verify_result) + assert verify_result["SignatureValid"] + + aws_client.kms.delete_imported_key_material(KeyId=key_id) + describe_deleted = aws_client.kms.describe_key(KeyId=key_id) + snapshot.match("describe-key-after-deleted-import", describe_deleted) + + @markers.aws.validated + @pytest.mark.parametrize( + "key_spec, key_length, mac_algo", + [ + (KeySpec.HMAC_224, 28, MacAlgorithmSpec.HMAC_SHA_224), + (KeySpec.HMAC_256, 32, MacAlgorithmSpec.HMAC_SHA_256), + (KeySpec.HMAC_384, 48, MacAlgorithmSpec.HMAC_SHA_384), + (KeySpec.HMAC_512, 64, MacAlgorithmSpec.HMAC_SHA_512), + ], + ids=[KeySpec.HMAC_224, KeySpec.HMAC_256, KeySpec.HMAC_384, KeySpec.HMAC_512], + ) + def test_import_key_hmac_keys( + self, key_spec, key_length, mac_algo, kms_create_key, aws_client, snapshot + ): + key = kms_create_key( + Origin="EXTERNAL", + KeySpec=key_spec, + KeyUsage="GENERATE_VERIFY_MAC", + Description="test import hmac key", + ) key_id = key["KeyId"] - plaintext = os.urandom(64) + plaintext = os.urandom(key_length) params = aws_client.kms.get_parameters_for_import( KeyId=key_id, WrappingAlgorithm="RSAES_OAEP_SHA_256", WrappingKeySpec="RSA_4096" @@ -1228,12 +1389,12 @@ def test_import_key_hmac(self, kms_create_key, aws_client, snapshot): # Generate and verify MAC message = b"test-mac-message" generate_mac = aws_client.kms.generate_mac( - KeyId=key_id, Message=message, MacAlgorithm="HMAC_SHA_512" + KeyId=key_id, Message=message, MacAlgorithm=mac_algo ) snapshot.match("generate-mac-response", generate_mac) verify_mac = aws_client.kms.verify_mac( - KeyId=key_id, Message=message, Mac=generate_mac["Mac"], MacAlgorithm="HMAC_SHA_512" + KeyId=key_id, Message=message, Mac=generate_mac["Mac"], MacAlgorithm=mac_algo ) snapshot.match("verify-mac-response", verify_mac) assert verify_mac["MacValid"] diff --git a/tests/aws/services/kms/test_kms.snapshot.json b/tests/aws/services/kms/test_kms.snapshot.json index eff490d51c94e..44155d3f21f7b 100644 --- a/tests/aws/services/kms/test_kms.snapshot.json +++ b/tests/aws/services/kms/test_kms.snapshot.json @@ -2430,6 +2430,680 @@ }, "tests/aws/services/kms/test_kms.py::TestKMS::test_import_key_hmac": { "recorded-date": "02-08-2025, 09:37:57", + "tests/aws/services/kms/test_kms.py::TestKMS::test_import_key_ecc_keys[ECC_NIST_P256]": { + "recorded-date": "04-08-2025, 05:34:34", + "recorded-content": { + "describe-key-before-import": { + "KeyMetadata": { + "AWSAccountId": "111111111111", + "Arn": "arn::kms::111111111111:key/", + "CreationDate": "datetime", + "CustomerMasterKeySpec": "ECC_NIST_P256", + "Description": "test ecc key import", + "Enabled": false, + "KeyId": "", + "KeyManager": "CUSTOMER", + "KeySpec": "ECC_NIST_P256", + "KeyState": "PendingImport", + "KeyUsage": "SIGN_VERIFY", + "MultiRegion": false, + "Origin": "EXTERNAL", + "SigningAlgorithms": [ + "ECDSA_SHA_256" + ] + }, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "describe-key-after-import": { + "KeyMetadata": { + "AWSAccountId": "111111111111", + "Arn": "arn::kms::111111111111:key/", + "CreationDate": "datetime", + "CustomerMasterKeySpec": "ECC_NIST_P256", + "Description": "test ecc key import", + "Enabled": true, + "ExpirationModel": "KEY_MATERIAL_DOES_NOT_EXPIRE", + "KeyId": "", + "KeyManager": "CUSTOMER", + "KeySpec": "ECC_NIST_P256", + "KeyState": "Enabled", + "KeyUsage": "SIGN_VERIFY", + "MultiRegion": false, + "Origin": "EXTERNAL", + "SigningAlgorithms": [ + "ECDSA_SHA_256" + ] + }, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "sign-result": { + "KeyId": "arn::kms::111111111111:key/", + "Signature": "", + "SigningAlgorithm": "ECDSA_SHA_256", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "verify-result": { + "KeyId": "arn::kms::111111111111:key/", + "SignatureValid": true, + "SigningAlgorithm": "ECDSA_SHA_256", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "describe-key-after-deleted-import": { + "KeyMetadata": { + "AWSAccountId": "111111111111", + "Arn": "arn::kms::111111111111:key/", + "CreationDate": "datetime", + "CustomerMasterKeySpec": "ECC_NIST_P256", + "Description": "test ecc key import", + "Enabled": false, + "KeyId": "", + "KeyManager": "CUSTOMER", + "KeySpec": "ECC_NIST_P256", + "KeyState": "PendingImport", + "KeyUsage": "SIGN_VERIFY", + "MultiRegion": false, + "Origin": "EXTERNAL", + "SigningAlgorithms": [ + "ECDSA_SHA_256" + ] + }, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + } + } + }, + "tests/aws/services/kms/test_kms.py::TestKMS::test_import_key_ecc_keys[ECC_NIST_P384]": { + "recorded-date": "04-08-2025, 05:34:37", + "recorded-content": { + "describe-key-before-import": { + "KeyMetadata": { + "AWSAccountId": "111111111111", + "Arn": "arn::kms::111111111111:key/", + "CreationDate": "datetime", + "CustomerMasterKeySpec": "ECC_NIST_P384", + "Description": "test ecc key import", + "Enabled": false, + "KeyId": "", + "KeyManager": "CUSTOMER", + "KeySpec": "ECC_NIST_P384", + "KeyState": "PendingImport", + "KeyUsage": "SIGN_VERIFY", + "MultiRegion": false, + "Origin": "EXTERNAL", + "SigningAlgorithms": [ + "ECDSA_SHA_384" + ] + }, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "describe-key-after-import": { + "KeyMetadata": { + "AWSAccountId": "111111111111", + "Arn": "arn::kms::111111111111:key/", + "CreationDate": "datetime", + "CustomerMasterKeySpec": "ECC_NIST_P384", + "Description": "test ecc key import", + "Enabled": true, + "ExpirationModel": "KEY_MATERIAL_DOES_NOT_EXPIRE", + "KeyId": "", + "KeyManager": "CUSTOMER", + "KeySpec": "ECC_NIST_P384", + "KeyState": "Enabled", + "KeyUsage": "SIGN_VERIFY", + "MultiRegion": false, + "Origin": "EXTERNAL", + "SigningAlgorithms": [ + "ECDSA_SHA_384" + ] + }, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "sign-result": { + "KeyId": "arn::kms::111111111111:key/", + "Signature": "", + "SigningAlgorithm": "ECDSA_SHA_384", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "verify-result": { + "KeyId": "arn::kms::111111111111:key/", + "SignatureValid": true, + "SigningAlgorithm": "ECDSA_SHA_384", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "describe-key-after-deleted-import": { + "KeyMetadata": { + "AWSAccountId": "111111111111", + "Arn": "arn::kms::111111111111:key/", + "CreationDate": "datetime", + "CustomerMasterKeySpec": "ECC_NIST_P384", + "Description": "test ecc key import", + "Enabled": false, + "KeyId": "", + "KeyManager": "CUSTOMER", + "KeySpec": "ECC_NIST_P384", + "KeyState": "PendingImport", + "KeyUsage": "SIGN_VERIFY", + "MultiRegion": false, + "Origin": "EXTERNAL", + "SigningAlgorithms": [ + "ECDSA_SHA_384" + ] + }, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + } + } + }, + "tests/aws/services/kms/test_kms.py::TestKMS::test_import_key_ecc_keys[ECC_SECG_P256K1]": { + "recorded-date": "04-08-2025, 05:34:44", + "recorded-content": { + "describe-key-before-import": { + "KeyMetadata": { + "AWSAccountId": "111111111111", + "Arn": "arn::kms::111111111111:key/", + "CreationDate": "datetime", + "CustomerMasterKeySpec": "ECC_SECG_P256K1", + "Description": "test ecc key import", + "Enabled": false, + "KeyId": "", + "KeyManager": "CUSTOMER", + "KeySpec": "ECC_SECG_P256K1", + "KeyState": "PendingImport", + "KeyUsage": "SIGN_VERIFY", + "MultiRegion": false, + "Origin": "EXTERNAL", + "SigningAlgorithms": [ + "ECDSA_SHA_256" + ] + }, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "describe-key-after-import": { + "KeyMetadata": { + "AWSAccountId": "111111111111", + "Arn": "arn::kms::111111111111:key/", + "CreationDate": "datetime", + "CustomerMasterKeySpec": "ECC_SECG_P256K1", + "Description": "test ecc key import", + "Enabled": true, + "ExpirationModel": "KEY_MATERIAL_DOES_NOT_EXPIRE", + "KeyId": "", + "KeyManager": "CUSTOMER", + "KeySpec": "ECC_SECG_P256K1", + "KeyState": "Enabled", + "KeyUsage": "SIGN_VERIFY", + "MultiRegion": false, + "Origin": "EXTERNAL", + "SigningAlgorithms": [ + "ECDSA_SHA_256" + ] + }, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "sign-result": { + "KeyId": "arn::kms::111111111111:key/", + "Signature": "", + "SigningAlgorithm": "ECDSA_SHA_256", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "verify-result": { + "KeyId": "arn::kms::111111111111:key/", + "SignatureValid": true, + "SigningAlgorithm": "ECDSA_SHA_256", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "describe-key-after-deleted-import": { + "KeyMetadata": { + "AWSAccountId": "111111111111", + "Arn": "arn::kms::111111111111:key/", + "CreationDate": "datetime", + "CustomerMasterKeySpec": "ECC_SECG_P256K1", + "Description": "test ecc key import", + "Enabled": false, + "KeyId": "", + "KeyManager": "CUSTOMER", + "KeySpec": "ECC_SECG_P256K1", + "KeyState": "PendingImport", + "KeyUsage": "SIGN_VERIFY", + "MultiRegion": false, + "Origin": "EXTERNAL", + "SigningAlgorithms": [ + "ECDSA_SHA_256" + ] + }, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + } + } + }, + "tests/aws/services/kms/test_kms.py::TestKMS::test_import_key_ecc_keys[ECC_NIST_P521]": { + "recorded-date": "04-08-2025, 05:34:41", + "recorded-content": { + "describe-key-before-import": { + "KeyMetadata": { + "AWSAccountId": "111111111111", + "Arn": "arn::kms::111111111111:key/", + "CreationDate": "datetime", + "CustomerMasterKeySpec": "ECC_NIST_P521", + "Description": "test ecc key import", + "Enabled": false, + "KeyId": "", + "KeyManager": "CUSTOMER", + "KeySpec": "ECC_NIST_P521", + "KeyState": "PendingImport", + "KeyUsage": "SIGN_VERIFY", + "MultiRegion": false, + "Origin": "EXTERNAL", + "SigningAlgorithms": [ + "ECDSA_SHA_512" + ] + }, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "describe-key-after-import": { + "KeyMetadata": { + "AWSAccountId": "111111111111", + "Arn": "arn::kms::111111111111:key/", + "CreationDate": "datetime", + "CustomerMasterKeySpec": "ECC_NIST_P521", + "Description": "test ecc key import", + "Enabled": true, + "ExpirationModel": "KEY_MATERIAL_DOES_NOT_EXPIRE", + "KeyId": "", + "KeyManager": "CUSTOMER", + "KeySpec": "ECC_NIST_P521", + "KeyState": "Enabled", + "KeyUsage": "SIGN_VERIFY", + "MultiRegion": false, + "Origin": "EXTERNAL", + "SigningAlgorithms": [ + "ECDSA_SHA_512" + ] + }, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "sign-result": { + "KeyId": "arn::kms::111111111111:key/", + "Signature": "", + "SigningAlgorithm": "ECDSA_SHA_512", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "verify-result": { + "KeyId": "arn::kms::111111111111:key/", + "SignatureValid": true, + "SigningAlgorithm": "ECDSA_SHA_512", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "describe-key-after-deleted-import": { + "KeyMetadata": { + "AWSAccountId": "111111111111", + "Arn": "arn::kms::111111111111:key/", + "CreationDate": "datetime", + "CustomerMasterKeySpec": "ECC_NIST_P521", + "Description": "test ecc key import", + "Enabled": false, + "KeyId": "", + "KeyManager": "CUSTOMER", + "KeySpec": "ECC_NIST_P521", + "KeyState": "PendingImport", + "KeyUsage": "SIGN_VERIFY", + "MultiRegion": false, + "Origin": "EXTERNAL", + "SigningAlgorithms": [ + "ECDSA_SHA_512" + ] + }, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + } + } + }, + "tests/aws/services/kms/test_kms.py::TestKMS::test_import_key_hmac_keys[HMAC_224]": { + "recorded-date": "04-08-2025, 05:34:11", + "recorded-content": { + "describe-key-before-import": { + "KeyMetadata": { + "AWSAccountId": "111111111111", + "Arn": "arn::kms::111111111111:key/", + "CreationDate": "datetime", + "CustomerMasterKeySpec": "HMAC_224", + "Description": "test import hmac key", + "Enabled": false, + "KeyId": "", + "KeyManager": "CUSTOMER", + "KeySpec": "HMAC_224", + "KeyState": "PendingImport", + "KeyUsage": "GENERATE_VERIFY_MAC", + "MacAlgorithms": [ + "HMAC_SHA_224" + ], + "MultiRegion": false, + "Origin": "EXTERNAL" + }, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "describe-key-after-import": { + "KeyMetadata": { + "AWSAccountId": "111111111111", + "Arn": "arn::kms::111111111111:key/", + "CreationDate": "datetime", + "CustomerMasterKeySpec": "HMAC_224", + "Description": "test import hmac key", + "Enabled": true, + "ExpirationModel": "KEY_MATERIAL_DOES_NOT_EXPIRE", + "KeyId": "", + "KeyManager": "CUSTOMER", + "KeySpec": "HMAC_224", + "KeyState": "Enabled", + "KeyUsage": "GENERATE_VERIFY_MAC", + "MacAlgorithms": [ + "HMAC_SHA_224" + ], + "MultiRegion": false, + "Origin": "EXTERNAL" + }, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "generate-mac-response": { + "KeyId": "arn::kms::111111111111:key/", + "Mac": "", + "MacAlgorithm": "HMAC_SHA_224", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "verify-mac-response": { + "KeyId": "arn::kms::111111111111:key/", + "MacAlgorithm": "HMAC_SHA_224", + "MacValid": true, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "describe-key-after-deleted-import": { + "KeyMetadata": { + "AWSAccountId": "111111111111", + "Arn": "arn::kms::111111111111:key/", + "CreationDate": "datetime", + "CustomerMasterKeySpec": "HMAC_224", + "Description": "test import hmac key", + "Enabled": false, + "KeyId": "", + "KeyManager": "CUSTOMER", + "KeySpec": "HMAC_224", + "KeyState": "PendingImport", + "KeyUsage": "GENERATE_VERIFY_MAC", + "MacAlgorithms": [ + "HMAC_SHA_224" + ], + "MultiRegion": false, + "Origin": "EXTERNAL" + }, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + } + } + }, + "tests/aws/services/kms/test_kms.py::TestKMS::test_import_key_hmac_keys[HMAC_256]": { + "recorded-date": "04-08-2025, 05:34:14", + "recorded-content": { + "describe-key-before-import": { + "KeyMetadata": { + "AWSAccountId": "111111111111", + "Arn": "arn::kms::111111111111:key/", + "CreationDate": "datetime", + "CustomerMasterKeySpec": "HMAC_256", + "Description": "test import hmac key", + "Enabled": false, + "KeyId": "", + "KeyManager": "CUSTOMER", + "KeySpec": "HMAC_256", + "KeyState": "PendingImport", + "KeyUsage": "GENERATE_VERIFY_MAC", + "MacAlgorithms": [ + "HMAC_SHA_256" + ], + "MultiRegion": false, + "Origin": "EXTERNAL" + }, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "describe-key-after-import": { + "KeyMetadata": { + "AWSAccountId": "111111111111", + "Arn": "arn::kms::111111111111:key/", + "CreationDate": "datetime", + "CustomerMasterKeySpec": "HMAC_256", + "Description": "test import hmac key", + "Enabled": true, + "ExpirationModel": "KEY_MATERIAL_DOES_NOT_EXPIRE", + "KeyId": "", + "KeyManager": "CUSTOMER", + "KeySpec": "HMAC_256", + "KeyState": "Enabled", + "KeyUsage": "GENERATE_VERIFY_MAC", + "MacAlgorithms": [ + "HMAC_SHA_256" + ], + "MultiRegion": false, + "Origin": "EXTERNAL" + }, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "generate-mac-response": { + "KeyId": "arn::kms::111111111111:key/", + "Mac": "", + "MacAlgorithm": "HMAC_SHA_256", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "verify-mac-response": { + "KeyId": "arn::kms::111111111111:key/", + "MacAlgorithm": "HMAC_SHA_256", + "MacValid": true, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "describe-key-after-deleted-import": { + "KeyMetadata": { + "AWSAccountId": "111111111111", + "Arn": "arn::kms::111111111111:key/", + "CreationDate": "datetime", + "CustomerMasterKeySpec": "HMAC_256", + "Description": "test import hmac key", + "Enabled": false, + "KeyId": "", + "KeyManager": "CUSTOMER", + "KeySpec": "HMAC_256", + "KeyState": "PendingImport", + "KeyUsage": "GENERATE_VERIFY_MAC", + "MacAlgorithms": [ + "HMAC_SHA_256" + ], + "MultiRegion": false, + "Origin": "EXTERNAL" + }, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + } + } + }, + "tests/aws/services/kms/test_kms.py::TestKMS::test_import_key_hmac_keys[HMAC_384]": { + "recorded-date": "04-08-2025, 05:34:17", + "recorded-content": { + "describe-key-before-import": { + "KeyMetadata": { + "AWSAccountId": "111111111111", + "Arn": "arn::kms::111111111111:key/", + "CreationDate": "datetime", + "CustomerMasterKeySpec": "HMAC_384", + "Description": "test import hmac key", + "Enabled": false, + "KeyId": "", + "KeyManager": "CUSTOMER", + "KeySpec": "HMAC_384", + "KeyState": "PendingImport", + "KeyUsage": "GENERATE_VERIFY_MAC", + "MacAlgorithms": [ + "HMAC_SHA_384" + ], + "MultiRegion": false, + "Origin": "EXTERNAL" + }, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "describe-key-after-import": { + "KeyMetadata": { + "AWSAccountId": "111111111111", + "Arn": "arn::kms::111111111111:key/", + "CreationDate": "datetime", + "CustomerMasterKeySpec": "HMAC_384", + "Description": "test import hmac key", + "Enabled": true, + "ExpirationModel": "KEY_MATERIAL_DOES_NOT_EXPIRE", + "KeyId": "", + "KeyManager": "CUSTOMER", + "KeySpec": "HMAC_384", + "KeyState": "Enabled", + "KeyUsage": "GENERATE_VERIFY_MAC", + "MacAlgorithms": [ + "HMAC_SHA_384" + ], + "MultiRegion": false, + "Origin": "EXTERNAL" + }, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "generate-mac-response": { + "KeyId": "arn::kms::111111111111:key/", + "Mac": "", + "MacAlgorithm": "HMAC_SHA_384", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "verify-mac-response": { + "KeyId": "arn::kms::111111111111:key/", + "MacAlgorithm": "HMAC_SHA_384", + "MacValid": true, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + }, + "describe-key-after-deleted-import": { + "KeyMetadata": { + "AWSAccountId": "111111111111", + "Arn": "arn::kms::111111111111:key/", + "CreationDate": "datetime", + "CustomerMasterKeySpec": "HMAC_384", + "Description": "test import hmac key", + "Enabled": false, + "KeyId": "", + "KeyManager": "CUSTOMER", + "KeySpec": "HMAC_384", + "KeyState": "PendingImport", + "KeyUsage": "GENERATE_VERIFY_MAC", + "MacAlgorithms": [ + "HMAC_SHA_384" + ], + "MultiRegion": false, + "Origin": "EXTERNAL" + }, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + } + } + }, + "tests/aws/services/kms/test_kms.py::TestKMS::test_import_key_hmac_keys[HMAC_512]": { + "recorded-date": "04-08-2025, 05:34:21", "recorded-content": { "describe-key-before-import": { "KeyMetadata": { @@ -2437,7 +3111,7 @@ "Arn": "arn::kms::111111111111:key/", "CreationDate": "datetime", "CustomerMasterKeySpec": "HMAC_512", - "Description": "", + "Description": "test import hmac key", "Enabled": false, "KeyId": "", "KeyManager": "CUSTOMER", @@ -2461,7 +3135,7 @@ "Arn": "arn::kms::111111111111:key/", "CreationDate": "datetime", "CustomerMasterKeySpec": "HMAC_512", - "Description": "", + "Description": "test import hmac key", "Enabled": true, "ExpirationModel": "KEY_MATERIAL_DOES_NOT_EXPIRE", "KeyId": "", @@ -2504,7 +3178,7 @@ "Arn": "arn::kms::111111111111:key/", "CreationDate": "datetime", "CustomerMasterKeySpec": "HMAC_512", - "Description": "", + "Description": "test import hmac key", "Enabled": false, "KeyId": "", "KeyManager": "CUSTOMER", diff --git a/tests/aws/services/kms/test_kms.validation.json b/tests/aws/services/kms/test_kms.validation.json index 27b6b1c6bfb26..0fd0a6cc3e914 100644 --- a/tests/aws/services/kms/test_kms.validation.json +++ b/tests/aws/services/kms/test_kms.validation.json @@ -161,13 +161,76 @@ "tests/aws/services/kms/test_kms.py::TestKMS::test_import_key_asymmetric": { "last_validated_date": "2024-04-11T15:53:35+00:00" }, - "tests/aws/services/kms/test_kms.py::TestKMS::test_import_key_hmac": { - "last_validated_date": "2025-08-02T09:37:57+00:00", + "tests/aws/services/kms/test_kms.py::TestKMS::test_import_key_ecc_keys[ECC_NIST_P256]": { + "last_validated_date": "2025-08-04T05:34:34+00:00", "durations_in_seconds": { - "setup": 1.3, - "call": 3.51, + "setup": 1.31, + "call": 3.75, "teardown": 0.31, - "total": 5.12 + "total": 5.37 + } + }, + "tests/aws/services/kms/test_kms.py::TestKMS::test_import_key_ecc_keys[ECC_NIST_P384]": { + "last_validated_date": "2025-08-04T05:34:37+00:00", + "durations_in_seconds": { + "setup": 0.0, + "call": 3.11, + "teardown": 0.33, + "total": 3.44 + } + }, + "tests/aws/services/kms/test_kms.py::TestKMS::test_import_key_ecc_keys[ECC_NIST_P521]": { + "last_validated_date": "2025-08-04T05:34:41+00:00", + "durations_in_seconds": { + "setup": 0.01, + "call": 3.16, + "teardown": 0.31, + "total": 3.48 + } + }, + "tests/aws/services/kms/test_kms.py::TestKMS::test_import_key_ecc_keys[ECC_SECG_P256K1]": { + "last_validated_date": "2025-08-04T05:34:44+00:00", + "durations_in_seconds": { + "setup": 0.0, + "call": 3.2, + "teardown": 0.31, + "total": 3.51 + } + }, + "tests/aws/services/kms/test_kms.py::TestKMS::test_import_key_hmac_keys[HMAC_224]": { + "last_validated_date": "2025-08-04T05:34:11+00:00", + "durations_in_seconds": { + "setup": 1.9, + "call": 3.59, + "teardown": 0.31, + "total": 5.8 + } + }, + "tests/aws/services/kms/test_kms.py::TestKMS::test_import_key_hmac_keys[HMAC_256]": { + "last_validated_date": "2025-08-04T05:34:14+00:00", + "durations_in_seconds": { + "setup": 0.0, + "call": 2.74, + "teardown": 0.31, + "total": 3.05 + } + }, + "tests/aws/services/kms/test_kms.py::TestKMS::test_import_key_hmac_keys[HMAC_384]": { + "last_validated_date": "2025-08-04T05:34:17+00:00", + "durations_in_seconds": { + "setup": 0.0, + "call": 2.77, + "teardown": 0.31, + "total": 3.08 + } + }, + "tests/aws/services/kms/test_kms.py::TestKMS::test_import_key_hmac_keys[HMAC_512]": { + "last_validated_date": "2025-08-04T05:34:21+00:00", + "durations_in_seconds": { + "setup": 0.0, + "call": 2.89, + "teardown": 0.31, + "total": 3.2 } }, "tests/aws/services/kms/test_kms.py::TestKMS::test_import_key_rsa_aes_wrap_sha256": { From a55cb9a9034dc24b8f9eb3cae35b6600e30e9e0d Mon Sep 17 00:00:00 2001 From: sannya-singal Date: Mon, 4 Aug 2025 13:43:21 +0530 Subject: [PATCH 3/5] code cleanup and fix lint --- tests/aws/services/kms/test_kms.py | 68 +++++++------------ tests/aws/services/kms/test_kms.snapshot.json | 16 ++--- .../aws/services/kms/test_kms.validation.json | 68 +++++++++---------- 3 files changed, 66 insertions(+), 86 deletions(-) diff --git a/tests/aws/services/kms/test_kms.py b/tests/aws/services/kms/test_kms.py index 3e2bd9a9d6f14..46b9bf534bd41 100644 --- a/tests/aws/services/kms/test_kms.py +++ b/tests/aws/services/kms/test_kms.py @@ -15,13 +15,6 @@ from cryptography.hazmat.primitives.keywrap import aes_key_wrap_with_padding from cryptography.hazmat.primitives.serialization import load_der_public_key -from localstack.aws.api.kms import ( - AlgorithmSpec, - KeySpec, - MacAlgorithmSpec, - SigningAlgorithmSpec, - WrappingKeySpec, -) from localstack.services.kms.models import ( HEADER_LEN, IV_LEN, @@ -36,14 +29,6 @@ from localstack.utils.strings import short_uid, to_str from localstack.utils.sync import poll_condition -# Map HMAC key specs with expected byte lengths and mac algo -HMAC_KEY_SPECS = [ - (KeySpec.HMAC_224, 28, MacAlgorithmSpec.HMAC_SHA_224), - (KeySpec.HMAC_256, 32, MacAlgorithmSpec.HMAC_SHA_256), - (KeySpec.HMAC_384, 48, MacAlgorithmSpec.HMAC_SHA_384), - (KeySpec.HMAC_512, 64, MacAlgorithmSpec.HMAC_SHA_512), -] - def create_tags(**kwargs): return [{"TagKey": key, "TagValue": value} for key, value in kwargs.items()] @@ -1211,56 +1196,51 @@ def test_list_aliases_of_key(self, kms_create_key, kms_create_alias, aws_client) @markers.aws.validated @pytest.mark.parametrize( - "key_spec, curve, signing_algorithm, wrapping_key_spec, wrapping_algorithm, oaep_hash", + "key_spec, curve, oaep_hash, signing_algorithm, wrapping_key_spec, wrapping_algorithm", [ ( - KeySpec.ECC_NIST_P256, + "ECC_NIST_P256", ec.SECP256R1(), - SigningAlgorithmSpec.ECDSA_SHA_256, - WrappingKeySpec.RSA_2048, - AlgorithmSpec.RSAES_OAEP_SHA_1, hashes.SHA1(), + "ECDSA_SHA_256", + "RSA_2048", + "RSAES_OAEP_SHA_1", ), ( - KeySpec.ECC_NIST_P384, + "ECC_NIST_P384", ec.SECP384R1(), - SigningAlgorithmSpec.ECDSA_SHA_384, - WrappingKeySpec.RSA_2048, - AlgorithmSpec.RSAES_OAEP_SHA_1, hashes.SHA1(), + "ECDSA_SHA_384", + "RSA_2048", + "RSAES_OAEP_SHA_1", ), ( - KeySpec.ECC_NIST_P521, + "ECC_NIST_P521", ec.SECP521R1(), - SigningAlgorithmSpec.ECDSA_SHA_512, - WrappingKeySpec.RSA_4096, - AlgorithmSpec.RSAES_OAEP_SHA_256, hashes.SHA256(), + "ECDSA_SHA_512", + "RSA_4096", + "RSAES_OAEP_SHA_256", ), ( - KeySpec.ECC_SECG_P256K1, + "ECC_SECG_P256K1", ec.SECP256K1(), - SigningAlgorithmSpec.ECDSA_SHA_256, - WrappingKeySpec.RSA_2048, - AlgorithmSpec.RSAES_OAEP_SHA_1, hashes.SHA1(), + "ECDSA_SHA_256", + "RSA_2048", + "RSAES_OAEP_SHA_1", ), ], - ids=[ - KeySpec.ECC_NIST_P256, - KeySpec.ECC_NIST_P384, - KeySpec.ECC_NIST_P521, - KeySpec.ECC_SECG_P256K1, - ], + ids=["ECC_NIST_P256", "ECC_NIST_P384", "ECC_NIST_P521", "ECC_SECG_P256K1"], ) def test_import_key_ecc_keys( self, key_spec, curve, + oaep_hash, signing_algorithm, wrapping_key_spec, wrapping_algorithm, - oaep_hash, kms_create_key, aws_client, snapshot, @@ -1343,12 +1323,12 @@ def test_import_key_ecc_keys( @pytest.mark.parametrize( "key_spec, key_length, mac_algo", [ - (KeySpec.HMAC_224, 28, MacAlgorithmSpec.HMAC_SHA_224), - (KeySpec.HMAC_256, 32, MacAlgorithmSpec.HMAC_SHA_256), - (KeySpec.HMAC_384, 48, MacAlgorithmSpec.HMAC_SHA_384), - (KeySpec.HMAC_512, 64, MacAlgorithmSpec.HMAC_SHA_512), + ("HMAC_224", 28, "HMAC_SHA_224"), + ("HMAC_256", 32, "HMAC_SHA_256"), + ("HMAC_384", 48, "HMAC_SHA_384"), + ("HMAC_512", 64, "HMAC_SHA_512"), ], - ids=[KeySpec.HMAC_224, KeySpec.HMAC_256, KeySpec.HMAC_384, KeySpec.HMAC_512], + ids=["HMAC_224", "HMAC_256", "HMAC_384", "HMAC_512"], ) def test_import_key_hmac_keys( self, key_spec, key_length, mac_algo, kms_create_key, aws_client, snapshot diff --git a/tests/aws/services/kms/test_kms.snapshot.json b/tests/aws/services/kms/test_kms.snapshot.json index 44155d3f21f7b..16fd6d89b132b 100644 --- a/tests/aws/services/kms/test_kms.snapshot.json +++ b/tests/aws/services/kms/test_kms.snapshot.json @@ -2431,7 +2431,7 @@ "tests/aws/services/kms/test_kms.py::TestKMS::test_import_key_hmac": { "recorded-date": "02-08-2025, 09:37:57", "tests/aws/services/kms/test_kms.py::TestKMS::test_import_key_ecc_keys[ECC_NIST_P256]": { - "recorded-date": "04-08-2025, 05:34:34", + "recorded-date": "04-08-2025, 08:10:22", "recorded-content": { "describe-key-before-import": { "KeyMetadata": { @@ -2527,7 +2527,7 @@ } }, "tests/aws/services/kms/test_kms.py::TestKMS::test_import_key_ecc_keys[ECC_NIST_P384]": { - "recorded-date": "04-08-2025, 05:34:37", + "recorded-date": "04-08-2025, 08:10:26", "recorded-content": { "describe-key-before-import": { "KeyMetadata": { @@ -2623,7 +2623,7 @@ } }, "tests/aws/services/kms/test_kms.py::TestKMS::test_import_key_ecc_keys[ECC_SECG_P256K1]": { - "recorded-date": "04-08-2025, 05:34:44", + "recorded-date": "04-08-2025, 08:10:33", "recorded-content": { "describe-key-before-import": { "KeyMetadata": { @@ -2719,7 +2719,7 @@ } }, "tests/aws/services/kms/test_kms.py::TestKMS::test_import_key_ecc_keys[ECC_NIST_P521]": { - "recorded-date": "04-08-2025, 05:34:41", + "recorded-date": "04-08-2025, 08:10:29", "recorded-content": { "describe-key-before-import": { "KeyMetadata": { @@ -2815,7 +2815,7 @@ } }, "tests/aws/services/kms/test_kms.py::TestKMS::test_import_key_hmac_keys[HMAC_224]": { - "recorded-date": "04-08-2025, 05:34:11", + "recorded-date": "04-08-2025, 08:11:28", "recorded-content": { "describe-key-before-import": { "KeyMetadata": { @@ -2911,7 +2911,7 @@ } }, "tests/aws/services/kms/test_kms.py::TestKMS::test_import_key_hmac_keys[HMAC_256]": { - "recorded-date": "04-08-2025, 05:34:14", + "recorded-date": "04-08-2025, 08:11:32", "recorded-content": { "describe-key-before-import": { "KeyMetadata": { @@ -3007,7 +3007,7 @@ } }, "tests/aws/services/kms/test_kms.py::TestKMS::test_import_key_hmac_keys[HMAC_384]": { - "recorded-date": "04-08-2025, 05:34:17", + "recorded-date": "04-08-2025, 08:11:35", "recorded-content": { "describe-key-before-import": { "KeyMetadata": { @@ -3103,7 +3103,7 @@ } }, "tests/aws/services/kms/test_kms.py::TestKMS::test_import_key_hmac_keys[HMAC_512]": { - "recorded-date": "04-08-2025, 05:34:21", + "recorded-date": "04-08-2025, 08:11:38", "recorded-content": { "describe-key-before-import": { "KeyMetadata": { diff --git a/tests/aws/services/kms/test_kms.validation.json b/tests/aws/services/kms/test_kms.validation.json index 0fd0a6cc3e914..7d53da7de6f49 100644 --- a/tests/aws/services/kms/test_kms.validation.json +++ b/tests/aws/services/kms/test_kms.validation.json @@ -162,75 +162,75 @@ "last_validated_date": "2024-04-11T15:53:35+00:00" }, "tests/aws/services/kms/test_kms.py::TestKMS::test_import_key_ecc_keys[ECC_NIST_P256]": { - "last_validated_date": "2025-08-04T05:34:34+00:00", + "last_validated_date": "2025-08-04T08:10:22+00:00", "durations_in_seconds": { - "setup": 1.31, - "call": 3.75, - "teardown": 0.31, - "total": 5.37 + "setup": 1.37, + "call": 4.01, + "teardown": 0.32, + "total": 5.7 } }, "tests/aws/services/kms/test_kms.py::TestKMS::test_import_key_ecc_keys[ECC_NIST_P384]": { - "last_validated_date": "2025-08-04T05:34:37+00:00", + "last_validated_date": "2025-08-04T08:10:26+00:00", "durations_in_seconds": { "setup": 0.0, - "call": 3.11, - "teardown": 0.33, - "total": 3.44 + "call": 3.15, + "teardown": 0.31, + "total": 3.46 } }, "tests/aws/services/kms/test_kms.py::TestKMS::test_import_key_ecc_keys[ECC_NIST_P521]": { - "last_validated_date": "2025-08-04T05:34:41+00:00", + "last_validated_date": "2025-08-04T08:10:29+00:00", "durations_in_seconds": { - "setup": 0.01, - "call": 3.16, + "setup": 0.0, + "call": 3.18, "teardown": 0.31, - "total": 3.48 + "total": 3.49 } }, "tests/aws/services/kms/test_kms.py::TestKMS::test_import_key_ecc_keys[ECC_SECG_P256K1]": { - "last_validated_date": "2025-08-04T05:34:44+00:00", + "last_validated_date": "2025-08-04T08:10:33+00:00", "durations_in_seconds": { "setup": 0.0, - "call": 3.2, - "teardown": 0.31, - "total": 3.51 + "call": 3.28, + "teardown": 0.32, + "total": 3.6 } }, "tests/aws/services/kms/test_kms.py::TestKMS::test_import_key_hmac_keys[HMAC_224]": { - "last_validated_date": "2025-08-04T05:34:11+00:00", + "last_validated_date": "2025-08-04T08:11:28+00:00", "durations_in_seconds": { - "setup": 1.9, - "call": 3.59, - "teardown": 0.31, - "total": 5.8 + "setup": 1.33, + "call": 3.61, + "teardown": 0.32, + "total": 5.26 } }, "tests/aws/services/kms/test_kms.py::TestKMS::test_import_key_hmac_keys[HMAC_256]": { - "last_validated_date": "2025-08-04T05:34:14+00:00", + "last_validated_date": "2025-08-04T08:11:32+00:00", "durations_in_seconds": { "setup": 0.0, - "call": 2.74, - "teardown": 0.31, - "total": 3.05 + "call": 2.85, + "teardown": 0.32, + "total": 3.17 } }, "tests/aws/services/kms/test_kms.py::TestKMS::test_import_key_hmac_keys[HMAC_384]": { - "last_validated_date": "2025-08-04T05:34:17+00:00", + "last_validated_date": "2025-08-04T08:11:35+00:00", "durations_in_seconds": { "setup": 0.0, - "call": 2.77, - "teardown": 0.31, - "total": 3.08 + "call": 2.89, + "teardown": 0.32, + "total": 3.21 } }, "tests/aws/services/kms/test_kms.py::TestKMS::test_import_key_hmac_keys[HMAC_512]": { - "last_validated_date": "2025-08-04T05:34:21+00:00", + "last_validated_date": "2025-08-04T08:11:38+00:00", "durations_in_seconds": { "setup": 0.0, - "call": 2.89, - "teardown": 0.31, - "total": 3.2 + "call": 2.92, + "teardown": 0.32, + "total": 3.24 } }, "tests/aws/services/kms/test_kms.py::TestKMS::test_import_key_rsa_aes_wrap_sha256": { From a212c1f3948a7a12482fd1ca9353c6039251087b Mon Sep 17 00:00:00 2001 From: sannya-singal Date: Tue, 5 Aug 2025 11:40:57 +0530 Subject: [PATCH 4/5] re run tests --- tests/aws/services/kms/test_kms.py | 378 ++++++++++++++--------------- 1 file changed, 189 insertions(+), 189 deletions(-) diff --git a/tests/aws/services/kms/test_kms.py b/tests/aws/services/kms/test_kms.py index 46b9bf534bd41..97943728ce9b5 100644 --- a/tests/aws/services/kms/test_kms.py +++ b/tests/aws/services/kms/test_kms.py @@ -1194,195 +1194,6 @@ def test_list_aliases_of_key(self, kms_create_key, kms_create_alias, aws_client) assert _get_alias(aws_client.kms, alias_name, aliased_key_id) is not None assert _get_alias(aws_client.kms, alias_name, comparison_key_id) is None - @markers.aws.validated - @pytest.mark.parametrize( - "key_spec, curve, oaep_hash, signing_algorithm, wrapping_key_spec, wrapping_algorithm", - [ - ( - "ECC_NIST_P256", - ec.SECP256R1(), - hashes.SHA1(), - "ECDSA_SHA_256", - "RSA_2048", - "RSAES_OAEP_SHA_1", - ), - ( - "ECC_NIST_P384", - ec.SECP384R1(), - hashes.SHA1(), - "ECDSA_SHA_384", - "RSA_2048", - "RSAES_OAEP_SHA_1", - ), - ( - "ECC_NIST_P521", - ec.SECP521R1(), - hashes.SHA256(), - "ECDSA_SHA_512", - "RSA_4096", - "RSAES_OAEP_SHA_256", - ), - ( - "ECC_SECG_P256K1", - ec.SECP256K1(), - hashes.SHA1(), - "ECDSA_SHA_256", - "RSA_2048", - "RSAES_OAEP_SHA_1", - ), - ], - ids=["ECC_NIST_P256", "ECC_NIST_P384", "ECC_NIST_P521", "ECC_SECG_P256K1"], - ) - def test_import_key_ecc_keys( - self, - key_spec, - curve, - oaep_hash, - signing_algorithm, - wrapping_key_spec, - wrapping_algorithm, - kms_create_key, - aws_client, - snapshot, - ): - key = kms_create_key( - Origin="EXTERNAL", - KeySpec=key_spec, - KeyUsage="SIGN_VERIFY", - Description="test ecc key import", - ) - key_id = key["KeyId"] - - ecc_key = ec.generate_private_key(curve) - raw_private_key = ecc_key.private_bytes( - serialization.Encoding.DER, - serialization.PrivateFormat.PKCS8, - serialization.NoEncryption(), - ) - raw_public_key = ecc_key.public_key().public_bytes( - serialization.Encoding.DER, - serialization.PublicFormat.SubjectPublicKeyInfo, - ) - - import_params = aws_client.kms.get_parameters_for_import( - KeyId=key_id, - WrappingAlgorithm=wrapping_algorithm, - WrappingKeySpec=wrapping_key_spec, - ) - - public_key = load_der_public_key(import_params["PublicKey"]) - encrypted_key = public_key.encrypt( - raw_private_key, - padding.OAEP( - mgf=padding.MGF1(algorithm=oaep_hash), - algorithm=oaep_hash, - label=None, - ), - ) - - describe_before = aws_client.kms.describe_key(KeyId=key_id) - snapshot.match("describe-key-before-import", describe_before) - - aws_client.kms.import_key_material( - KeyId=key_id, - ImportToken=import_params["ImportToken"], - EncryptedKeyMaterial=encrypted_key, - ExpirationModel="KEY_MATERIAL_DOES_NOT_EXPIRE", - ) - - describe_after = aws_client.kms.describe_key(KeyId=key_id) - snapshot.match("describe-key-after-import", describe_after) - - get_public_key_after_import = aws_client.kms.get_public_key(KeyId=key_id) - assert get_public_key_after_import["PublicKey"] == raw_public_key - - message = b"test sign verify 123 !%$@ 1234567890" - sign_result = aws_client.kms.sign( - KeyId=key_id, - Message=message, - MessageType="RAW", - SigningAlgorithm=signing_algorithm, - ) - snapshot.match("sign-result", sign_result) - - verify_result = aws_client.kms.verify( - KeyId=key_id, - Message=message, - MessageType="RAW", - SigningAlgorithm=signing_algorithm, - Signature=sign_result["Signature"], - ) - snapshot.match("verify-result", verify_result) - assert verify_result["SignatureValid"] - - aws_client.kms.delete_imported_key_material(KeyId=key_id) - describe_deleted = aws_client.kms.describe_key(KeyId=key_id) - snapshot.match("describe-key-after-deleted-import", describe_deleted) - - @markers.aws.validated - @pytest.mark.parametrize( - "key_spec, key_length, mac_algo", - [ - ("HMAC_224", 28, "HMAC_SHA_224"), - ("HMAC_256", 32, "HMAC_SHA_256"), - ("HMAC_384", 48, "HMAC_SHA_384"), - ("HMAC_512", 64, "HMAC_SHA_512"), - ], - ids=["HMAC_224", "HMAC_256", "HMAC_384", "HMAC_512"], - ) - def test_import_key_hmac_keys( - self, key_spec, key_length, mac_algo, kms_create_key, aws_client, snapshot - ): - key = kms_create_key( - Origin="EXTERNAL", - KeySpec=key_spec, - KeyUsage="GENERATE_VERIFY_MAC", - Description="test import hmac key", - ) - key_id = key["KeyId"] - - plaintext = os.urandom(key_length) - - params = aws_client.kms.get_parameters_for_import( - KeyId=key_id, WrappingAlgorithm="RSAES_OAEP_SHA_256", WrappingKeySpec="RSA_4096" - ) - - public_key = load_der_public_key(params["PublicKey"]) - encrypted_key = public_key.encrypt( - plaintext, - padding.OAEP( - mgf=padding.MGF1(algorithm=hashes.SHA256()), algorithm=hashes.SHA256(), label=None - ), - ) - describe_key_before_import = aws_client.kms.describe_key(KeyId=key_id) - snapshot.match("describe-key-before-import", describe_key_before_import) - - aws_client.kms.import_key_material( - KeyId=key_id, - ImportToken=params["ImportToken"], - EncryptedKeyMaterial=encrypted_key, - ExpirationModel="KEY_MATERIAL_DOES_NOT_EXPIRE", - ) - describe_key_after_import = aws_client.kms.describe_key(KeyId=key_id) - snapshot.match("describe-key-after-import", describe_key_after_import) - - # Generate and verify MAC - message = b"test-mac-message" - generate_mac = aws_client.kms.generate_mac( - KeyId=key_id, Message=message, MacAlgorithm=mac_algo - ) - snapshot.match("generate-mac-response", generate_mac) - - verify_mac = aws_client.kms.verify_mac( - KeyId=key_id, Message=message, Mac=generate_mac["Mac"], MacAlgorithm=mac_algo - ) - snapshot.match("verify-mac-response", verify_mac) - assert verify_mac["MacValid"] - - aws_client.kms.delete_imported_key_material(KeyId=key_id) - describe_key_after_deleted_import = aws_client.kms.describe_key(KeyId=key_id) - snapshot.match("describe-key-after-deleted-import", describe_key_after_deleted_import) - @markers.aws.validated def test_all_types_of_key_id_can_be_used_for_encryption( self, kms_create_key, kms_create_alias, aws_client @@ -1891,6 +1702,195 @@ def test_hmac_create_key_invalid_operations(self, kms_create_key, snapshot, regi ) snapshot.match("create-hmac-key-invalid-key-usage", e.value.response) + @markers.aws.validated + @pytest.mark.parametrize( + "key_spec, curve, oaep_hash, signing_algorithm, wrapping_key_spec, wrapping_algorithm", + [ + ( + "ECC_NIST_P256", + ec.SECP256R1(), + hashes.SHA1(), + "ECDSA_SHA_256", + "RSA_2048", + "RSAES_OAEP_SHA_1", + ), + ( + "ECC_NIST_P384", + ec.SECP384R1(), + hashes.SHA1(), + "ECDSA_SHA_384", + "RSA_2048", + "RSAES_OAEP_SHA_1", + ), + ( + "ECC_NIST_P521", + ec.SECP521R1(), + hashes.SHA256(), + "ECDSA_SHA_512", + "RSA_4096", + "RSAES_OAEP_SHA_256", + ), + ( + "ECC_SECG_P256K1", + ec.SECP256K1(), + hashes.SHA1(), + "ECDSA_SHA_256", + "RSA_2048", + "RSAES_OAEP_SHA_1", + ), + ], + ids=["ECC_NIST_P256", "ECC_NIST_P384", "ECC_NIST_P521", "ECC_SECG_P256K1"], + ) + def test_import_key_ecc_keys( + self, + key_spec, + curve, + oaep_hash, + signing_algorithm, + wrapping_key_spec, + wrapping_algorithm, + kms_create_key, + aws_client, + snapshot, + ): + key = kms_create_key( + Origin="EXTERNAL", + KeySpec=key_spec, + KeyUsage="SIGN_VERIFY", + Description="test ecc key import", + ) + key_id = key["KeyId"] + + ecc_key = ec.generate_private_key(curve) + raw_private_key = ecc_key.private_bytes( + serialization.Encoding.DER, + serialization.PrivateFormat.PKCS8, + serialization.NoEncryption(), + ) + raw_public_key = ecc_key.public_key().public_bytes( + serialization.Encoding.DER, + serialization.PublicFormat.SubjectPublicKeyInfo, + ) + + import_params = aws_client.kms.get_parameters_for_import( + KeyId=key_id, + WrappingAlgorithm=wrapping_algorithm, + WrappingKeySpec=wrapping_key_spec, + ) + + public_key = load_der_public_key(import_params["PublicKey"]) + encrypted_key = public_key.encrypt( + raw_private_key, + padding.OAEP( + mgf=padding.MGF1(algorithm=oaep_hash), + algorithm=oaep_hash, + label=None, + ), + ) + + describe_before = aws_client.kms.describe_key(KeyId=key_id) + snapshot.match("describe-key-before-import", describe_before) + + aws_client.kms.import_key_material( + KeyId=key_id, + ImportToken=import_params["ImportToken"], + EncryptedKeyMaterial=encrypted_key, + ExpirationModel="KEY_MATERIAL_DOES_NOT_EXPIRE", + ) + + describe_after = aws_client.kms.describe_key(KeyId=key_id) + snapshot.match("describe-key-after-import", describe_after) + + get_public_key_after_import = aws_client.kms.get_public_key(KeyId=key_id) + assert get_public_key_after_import["PublicKey"] == raw_public_key + + message = b"test sign verify 123 !%$@ 1234567890" + sign_result = aws_client.kms.sign( + KeyId=key_id, + Message=message, + MessageType="RAW", + SigningAlgorithm=signing_algorithm, + ) + snapshot.match("sign-result", sign_result) + + verify_result = aws_client.kms.verify( + KeyId=key_id, + Message=message, + MessageType="RAW", + SigningAlgorithm=signing_algorithm, + Signature=sign_result["Signature"], + ) + snapshot.match("verify-result", verify_result) + assert verify_result["SignatureValid"] + + aws_client.kms.delete_imported_key_material(KeyId=key_id) + describe_deleted = aws_client.kms.describe_key(KeyId=key_id) + snapshot.match("describe-key-after-deleted-import", describe_deleted) + + @markers.aws.validated + @pytest.mark.parametrize( + "key_spec, key_length, mac_algo", + [ + ("HMAC_224", 28, "HMAC_SHA_224"), + ("HMAC_256", 32, "HMAC_SHA_256"), + ("HMAC_384", 48, "HMAC_SHA_384"), + ("HMAC_512", 64, "HMAC_SHA_512"), + ], + ids=["HMAC_224", "HMAC_256", "HMAC_384", "HMAC_512"], + ) + def test_import_key_hmac_keys( + self, key_spec, key_length, mac_algo, kms_create_key, aws_client, snapshot + ): + key = kms_create_key( + Origin="EXTERNAL", + KeySpec=key_spec, + KeyUsage="GENERATE_VERIFY_MAC", + Description="test import hmac key", + ) + key_id = key["KeyId"] + + plaintext = os.urandom(key_length) + + params = aws_client.kms.get_parameters_for_import( + KeyId=key_id, WrappingAlgorithm="RSAES_OAEP_SHA_256", WrappingKeySpec="RSA_4096" + ) + + public_key = load_der_public_key(params["PublicKey"]) + encrypted_key = public_key.encrypt( + plaintext, + padding.OAEP( + mgf=padding.MGF1(algorithm=hashes.SHA256()), algorithm=hashes.SHA256(), label=None + ), + ) + describe_key_before_import = aws_client.kms.describe_key(KeyId=key_id) + snapshot.match("describe-key-before-import", describe_key_before_import) + + aws_client.kms.import_key_material( + KeyId=key_id, + ImportToken=params["ImportToken"], + EncryptedKeyMaterial=encrypted_key, + ExpirationModel="KEY_MATERIAL_DOES_NOT_EXPIRE", + ) + describe_key_after_import = aws_client.kms.describe_key(KeyId=key_id) + snapshot.match("describe-key-after-import", describe_key_after_import) + + # Generate and verify MAC + message = b"test-mac-message" + generate_mac = aws_client.kms.generate_mac( + KeyId=key_id, Message=message, MacAlgorithm=mac_algo + ) + snapshot.match("generate-mac-response", generate_mac) + + verify_mac = aws_client.kms.verify_mac( + KeyId=key_id, Message=message, Mac=generate_mac["Mac"], MacAlgorithm=mac_algo + ) + snapshot.match("verify-mac-response", verify_mac) + assert verify_mac["MacValid"] + + aws_client.kms.delete_imported_key_material(KeyId=key_id) + describe_key_after_deleted_import = aws_client.kms.describe_key(KeyId=key_id) + snapshot.match("describe-key-after-deleted-import", describe_key_after_deleted_import) + @markers.aws.validated @pytest.mark.parametrize( "key_spec,mac_algo", From 875f43296055a205dd42a31280f25a6437462bdf Mon Sep 17 00:00:00 2001 From: sannya-singal Date: Wed, 6 Aug 2025 11:38:54 +0530 Subject: [PATCH 5/5] rebasing --- tests/aws/services/kms/test_kms.snapshot.json | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/aws/services/kms/test_kms.snapshot.json b/tests/aws/services/kms/test_kms.snapshot.json index 16fd6d89b132b..93c67bca92401 100644 --- a/tests/aws/services/kms/test_kms.snapshot.json +++ b/tests/aws/services/kms/test_kms.snapshot.json @@ -2428,8 +2428,6 @@ } } }, - "tests/aws/services/kms/test_kms.py::TestKMS::test_import_key_hmac": { - "recorded-date": "02-08-2025, 09:37:57", "tests/aws/services/kms/test_kms.py::TestKMS::test_import_key_ecc_keys[ECC_NIST_P256]": { "recorded-date": "04-08-2025, 08:10:22", "recorded-content": {