KMS: encrypt() should allow an alias as argument (#5959)
This commit is contained in:
parent
7816b191b8
commit
11e2120046
@ -363,7 +363,7 @@ class KmsBackend(BaseBackend):
|
|||||||
key_id = self.get_alias_name(key_id)
|
key_id = self.get_alias_name(key_id)
|
||||||
key_id = self.get_key_id(key_id)
|
key_id = self.get_key_id(key_id)
|
||||||
if key_id.startswith("alias/"):
|
if key_id.startswith("alias/"):
|
||||||
key_id = self.get_key_id_from_alias(key_id)
|
key_id = self.get_key_id(self.get_key_id_from_alias(key_id))
|
||||||
return key_id
|
return key_id
|
||||||
|
|
||||||
def alias_exists(self, alias_name):
|
def alias_exists(self, alias_name):
|
||||||
|
@ -43,19 +43,6 @@ def test_create_key_without_description():
|
|||||||
metadata.should.have.key("Description").equal("")
|
metadata.should.have.key("Description").equal("")
|
||||||
|
|
||||||
|
|
||||||
@mock_kms
|
|
||||||
def test_create_key_with_empty_content():
|
|
||||||
client_kms = boto3.client("kms", region_name="ap-northeast-1")
|
|
||||||
metadata = client_kms.create_key(Policy="my policy")["KeyMetadata"]
|
|
||||||
with pytest.raises(ClientError) as exc:
|
|
||||||
client_kms.encrypt(KeyId=metadata["KeyId"], Plaintext="")
|
|
||||||
err = exc.value.response["Error"]
|
|
||||||
err["Code"].should.equal("ValidationException")
|
|
||||||
err["Message"].should.equal(
|
|
||||||
"1 validation error detected: Value at 'plaintext' failed to satisfy constraint: Member must have length greater than or equal to 1"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@mock_kms
|
@mock_kms
|
||||||
def test_create_key():
|
def test_create_key():
|
||||||
conn = boto3.client("kms", region_name="us-east-1")
|
conn = boto3.client("kms", region_name="us-east-1")
|
||||||
@ -377,51 +364,6 @@ def test_generate_data_key():
|
|||||||
response["KeyId"].should.equal(key_arn)
|
response["KeyId"].should.equal(key_arn)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("plaintext", PLAINTEXT_VECTORS)
|
|
||||||
@mock_kms
|
|
||||||
def test_encrypt(plaintext):
|
|
||||||
client = boto3.client("kms", region_name="us-west-2")
|
|
||||||
|
|
||||||
key = client.create_key(Description="key")
|
|
||||||
key_id = key["KeyMetadata"]["KeyId"]
|
|
||||||
key_arn = key["KeyMetadata"]["Arn"]
|
|
||||||
|
|
||||||
response = client.encrypt(KeyId=key_id, Plaintext=plaintext)
|
|
||||||
response["CiphertextBlob"].should_not.equal(plaintext)
|
|
||||||
|
|
||||||
# CiphertextBlob must NOT be base64-encoded
|
|
||||||
with pytest.raises(Exception):
|
|
||||||
base64.b64decode(response["CiphertextBlob"], validate=True)
|
|
||||||
|
|
||||||
response["KeyId"].should.equal(key_arn)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("plaintext", PLAINTEXT_VECTORS)
|
|
||||||
@mock_kms
|
|
||||||
def test_decrypt(plaintext):
|
|
||||||
client = boto3.client("kms", region_name="us-west-2")
|
|
||||||
|
|
||||||
key = client.create_key(Description="key")
|
|
||||||
key_id = key["KeyMetadata"]["KeyId"]
|
|
||||||
key_arn = key["KeyMetadata"]["Arn"]
|
|
||||||
|
|
||||||
encrypt_response = client.encrypt(KeyId=key_id, Plaintext=plaintext)
|
|
||||||
|
|
||||||
client.create_key(Description="key")
|
|
||||||
# CiphertextBlob must NOT be base64-encoded
|
|
||||||
with pytest.raises(Exception):
|
|
||||||
base64.b64decode(encrypt_response["CiphertextBlob"], validate=True)
|
|
||||||
|
|
||||||
decrypt_response = client.decrypt(CiphertextBlob=encrypt_response["CiphertextBlob"])
|
|
||||||
|
|
||||||
# Plaintext must NOT be base64-encoded
|
|
||||||
with pytest.raises(Exception):
|
|
||||||
base64.b64decode(decrypt_response["Plaintext"], validate=True)
|
|
||||||
|
|
||||||
decrypt_response["Plaintext"].should.equal(_get_encoded_value(plaintext))
|
|
||||||
decrypt_response["KeyId"].should.equal(key_arn)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"key_id",
|
"key_id",
|
||||||
[
|
[
|
||||||
@ -440,17 +382,6 @@ def test_invalid_key_ids(key_id):
|
|||||||
client.generate_data_key(KeyId=key_id, NumberOfBytes=5)
|
client.generate_data_key(KeyId=key_id, NumberOfBytes=5)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("plaintext", PLAINTEXT_VECTORS)
|
|
||||||
@mock_kms
|
|
||||||
def test_kms_encrypt(plaintext):
|
|
||||||
client = boto3.client("kms", region_name="us-east-1")
|
|
||||||
key = client.create_key(Description="key")
|
|
||||||
response = client.encrypt(KeyId=key["KeyMetadata"]["KeyId"], Plaintext=plaintext)
|
|
||||||
|
|
||||||
response = client.decrypt(CiphertextBlob=response["CiphertextBlob"])
|
|
||||||
response["Plaintext"].should.equal(_get_encoded_value(plaintext))
|
|
||||||
|
|
||||||
|
|
||||||
@mock_kms
|
@mock_kms
|
||||||
def test_disable_key():
|
def test_disable_key():
|
||||||
client = boto3.client("kms", region_name="us-east-1")
|
client = boto3.client("kms", region_name="us-east-1")
|
||||||
@ -738,69 +669,6 @@ def test_generate_data_key_without_plaintext_decrypt():
|
|||||||
assert "Plaintext" not in resp1
|
assert "Plaintext" not in resp1
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("plaintext", PLAINTEXT_VECTORS)
|
|
||||||
@mock_kms
|
|
||||||
def test_re_encrypt_decrypt(plaintext):
|
|
||||||
client = boto3.client("kms", region_name="us-west-2")
|
|
||||||
|
|
||||||
key_1 = client.create_key(Description="key 1")
|
|
||||||
key_1_id = key_1["KeyMetadata"]["KeyId"]
|
|
||||||
key_1_arn = key_1["KeyMetadata"]["Arn"]
|
|
||||||
key_2 = client.create_key(Description="key 2")
|
|
||||||
key_2_id = key_2["KeyMetadata"]["KeyId"]
|
|
||||||
key_2_arn = key_2["KeyMetadata"]["Arn"]
|
|
||||||
|
|
||||||
encrypt_response = client.encrypt(
|
|
||||||
KeyId=key_1_id, Plaintext=plaintext, EncryptionContext={"encryption": "context"}
|
|
||||||
)
|
|
||||||
|
|
||||||
re_encrypt_response = client.re_encrypt(
|
|
||||||
CiphertextBlob=encrypt_response["CiphertextBlob"],
|
|
||||||
SourceEncryptionContext={"encryption": "context"},
|
|
||||||
DestinationKeyId=key_2_id,
|
|
||||||
DestinationEncryptionContext={"another": "context"},
|
|
||||||
)
|
|
||||||
|
|
||||||
# CiphertextBlob must NOT be base64-encoded
|
|
||||||
with pytest.raises(Exception):
|
|
||||||
base64.b64decode(re_encrypt_response["CiphertextBlob"], validate=True)
|
|
||||||
|
|
||||||
re_encrypt_response["SourceKeyId"].should.equal(key_1_arn)
|
|
||||||
re_encrypt_response["KeyId"].should.equal(key_2_arn)
|
|
||||||
|
|
||||||
decrypt_response_1 = client.decrypt(
|
|
||||||
CiphertextBlob=encrypt_response["CiphertextBlob"],
|
|
||||||
EncryptionContext={"encryption": "context"},
|
|
||||||
)
|
|
||||||
decrypt_response_1["Plaintext"].should.equal(_get_encoded_value(plaintext))
|
|
||||||
decrypt_response_1["KeyId"].should.equal(key_1_arn)
|
|
||||||
|
|
||||||
decrypt_response_2 = client.decrypt(
|
|
||||||
CiphertextBlob=re_encrypt_response["CiphertextBlob"],
|
|
||||||
EncryptionContext={"another": "context"},
|
|
||||||
)
|
|
||||||
decrypt_response_2["Plaintext"].should.equal(_get_encoded_value(plaintext))
|
|
||||||
decrypt_response_2["KeyId"].should.equal(key_2_arn)
|
|
||||||
|
|
||||||
decrypt_response_1["Plaintext"].should.equal(decrypt_response_2["Plaintext"])
|
|
||||||
|
|
||||||
|
|
||||||
@mock_kms
|
|
||||||
def test_re_encrypt_to_invalid_destination():
|
|
||||||
client = boto3.client("kms", region_name="us-west-2")
|
|
||||||
|
|
||||||
key = client.create_key(Description="key 1")
|
|
||||||
key_id = key["KeyMetadata"]["KeyId"]
|
|
||||||
|
|
||||||
encrypt_response = client.encrypt(KeyId=key_id, Plaintext=b"some plaintext")
|
|
||||||
|
|
||||||
with pytest.raises(client.exceptions.NotFoundException):
|
|
||||||
client.re_encrypt(
|
|
||||||
CiphertextBlob=encrypt_response["CiphertextBlob"],
|
|
||||||
DestinationKeyId="alias/DoesNotExist",
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("number_of_bytes", [12, 44, 91, 1, 1024])
|
@pytest.mark.parametrize("number_of_bytes", [12, 44, 91, 1, 1024])
|
||||||
@mock_kms
|
@mock_kms
|
||||||
def test_generate_random(number_of_bytes):
|
def test_generate_random(number_of_bytes):
|
||||||
|
176
tests/test_kms/test_kms_encrypt.py
Normal file
176
tests/test_kms/test_kms_encrypt.py
Normal file
@ -0,0 +1,176 @@
|
|||||||
|
import base64
|
||||||
|
|
||||||
|
import boto3
|
||||||
|
import sure # noqa # pylint: disable=unused-import
|
||||||
|
from botocore.exceptions import ClientError
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from moto import mock_kms
|
||||||
|
from .test_kms_boto3 import PLAINTEXT_VECTORS, _get_encoded_value
|
||||||
|
|
||||||
|
|
||||||
|
@mock_kms
|
||||||
|
def test_create_key_with_empty_content():
|
||||||
|
client_kms = boto3.client("kms", region_name="ap-northeast-1")
|
||||||
|
metadata = client_kms.create_key(Policy="my policy")["KeyMetadata"]
|
||||||
|
with pytest.raises(ClientError) as exc:
|
||||||
|
client_kms.encrypt(KeyId=metadata["KeyId"], Plaintext="")
|
||||||
|
err = exc.value.response["Error"]
|
||||||
|
err["Code"].should.equal("ValidationException")
|
||||||
|
err["Message"].should.equal(
|
||||||
|
"1 validation error detected: Value at 'plaintext' failed to satisfy constraint: Member must have length greater than or equal to 1"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("plaintext", PLAINTEXT_VECTORS)
|
||||||
|
@mock_kms
|
||||||
|
def test_encrypt(plaintext):
|
||||||
|
client = boto3.client("kms", region_name="us-west-2")
|
||||||
|
|
||||||
|
key = client.create_key(Description="key")
|
||||||
|
key_id = key["KeyMetadata"]["KeyId"]
|
||||||
|
key_arn = key["KeyMetadata"]["Arn"]
|
||||||
|
|
||||||
|
response = client.encrypt(KeyId=key_id, Plaintext=plaintext)
|
||||||
|
response["CiphertextBlob"].should_not.equal(plaintext)
|
||||||
|
|
||||||
|
# CiphertextBlob must NOT be base64-encoded
|
||||||
|
with pytest.raises(Exception):
|
||||||
|
base64.b64decode(response["CiphertextBlob"], validate=True)
|
||||||
|
|
||||||
|
response["KeyId"].should.equal(key_arn)
|
||||||
|
|
||||||
|
|
||||||
|
@mock_kms
|
||||||
|
def test_encrypt_using_alias_name():
|
||||||
|
kms = boto3.client("kms", region_name="us-east-1")
|
||||||
|
key_details = kms.create_key()
|
||||||
|
key_alias = "alias/examplekey"
|
||||||
|
kms.create_alias(AliasName=key_alias, TargetKeyId=key_details["KeyMetadata"]["Arn"])
|
||||||
|
|
||||||
|
# Just ensure that they do not throw an error, i.e. verify that it's possible to call this method using the Alias
|
||||||
|
resp = kms.encrypt(KeyId=key_alias, Plaintext="hello")
|
||||||
|
kms.decrypt(CiphertextBlob=resp["CiphertextBlob"])
|
||||||
|
|
||||||
|
|
||||||
|
@mock_kms
|
||||||
|
def test_encrypt_using_alias_arn():
|
||||||
|
kms = boto3.client("kms", region_name="us-east-1")
|
||||||
|
key_details = kms.create_key()
|
||||||
|
key_alias = "alias/examplekey"
|
||||||
|
kms.create_alias(AliasName=key_alias, TargetKeyId=key_details["KeyMetadata"]["Arn"])
|
||||||
|
|
||||||
|
aliases = kms.list_aliases(KeyId=key_details["KeyMetadata"]["Arn"])["Aliases"]
|
||||||
|
my_alias = [a for a in aliases if a["AliasName"] == key_alias][0]
|
||||||
|
|
||||||
|
kms.encrypt(KeyId=my_alias["AliasArn"], Plaintext="hello")
|
||||||
|
|
||||||
|
|
||||||
|
@mock_kms
|
||||||
|
def test_encrypt_using_key_arn():
|
||||||
|
kms = boto3.client("kms", region_name="us-east-1")
|
||||||
|
key_details = kms.create_key()
|
||||||
|
key_alias = "alias/examplekey"
|
||||||
|
kms.create_alias(AliasName=key_alias, TargetKeyId=key_details["KeyMetadata"]["Arn"])
|
||||||
|
|
||||||
|
kms.encrypt(KeyId=key_details["KeyMetadata"]["Arn"], Plaintext="hello")
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("plaintext", PLAINTEXT_VECTORS)
|
||||||
|
@mock_kms
|
||||||
|
def test_decrypt(plaintext):
|
||||||
|
client = boto3.client("kms", region_name="us-west-2")
|
||||||
|
|
||||||
|
key = client.create_key(Description="key")
|
||||||
|
key_id = key["KeyMetadata"]["KeyId"]
|
||||||
|
key_arn = key["KeyMetadata"]["Arn"]
|
||||||
|
|
||||||
|
encrypt_response = client.encrypt(KeyId=key_id, Plaintext=plaintext)
|
||||||
|
|
||||||
|
client.create_key(Description="key")
|
||||||
|
# CiphertextBlob must NOT be base64-encoded
|
||||||
|
with pytest.raises(Exception):
|
||||||
|
base64.b64decode(encrypt_response["CiphertextBlob"], validate=True)
|
||||||
|
|
||||||
|
decrypt_response = client.decrypt(CiphertextBlob=encrypt_response["CiphertextBlob"])
|
||||||
|
|
||||||
|
# Plaintext must NOT be base64-encoded
|
||||||
|
with pytest.raises(Exception):
|
||||||
|
base64.b64decode(decrypt_response["Plaintext"], validate=True)
|
||||||
|
|
||||||
|
decrypt_response["Plaintext"].should.equal(_get_encoded_value(plaintext))
|
||||||
|
decrypt_response["KeyId"].should.equal(key_arn)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("plaintext", PLAINTEXT_VECTORS)
|
||||||
|
@mock_kms
|
||||||
|
def test_kms_encrypt(plaintext):
|
||||||
|
client = boto3.client("kms", region_name="us-east-1")
|
||||||
|
key = client.create_key(Description="key")
|
||||||
|
response = client.encrypt(KeyId=key["KeyMetadata"]["KeyId"], Plaintext=plaintext)
|
||||||
|
|
||||||
|
response = client.decrypt(CiphertextBlob=response["CiphertextBlob"])
|
||||||
|
response["Plaintext"].should.equal(_get_encoded_value(plaintext))
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("plaintext", PLAINTEXT_VECTORS)
|
||||||
|
@mock_kms
|
||||||
|
def test_re_encrypt_decrypt(plaintext):
|
||||||
|
client = boto3.client("kms", region_name="us-west-2")
|
||||||
|
|
||||||
|
key_1 = client.create_key(Description="key 1")
|
||||||
|
key_1_id = key_1["KeyMetadata"]["KeyId"]
|
||||||
|
key_1_arn = key_1["KeyMetadata"]["Arn"]
|
||||||
|
key_2 = client.create_key(Description="key 2")
|
||||||
|
key_2_id = key_2["KeyMetadata"]["KeyId"]
|
||||||
|
key_2_arn = key_2["KeyMetadata"]["Arn"]
|
||||||
|
|
||||||
|
encrypt_response = client.encrypt(
|
||||||
|
KeyId=key_1_id, Plaintext=plaintext, EncryptionContext={"encryption": "context"}
|
||||||
|
)
|
||||||
|
|
||||||
|
re_encrypt_response = client.re_encrypt(
|
||||||
|
CiphertextBlob=encrypt_response["CiphertextBlob"],
|
||||||
|
SourceEncryptionContext={"encryption": "context"},
|
||||||
|
DestinationKeyId=key_2_id,
|
||||||
|
DestinationEncryptionContext={"another": "context"},
|
||||||
|
)
|
||||||
|
|
||||||
|
# CiphertextBlob must NOT be base64-encoded
|
||||||
|
with pytest.raises(Exception):
|
||||||
|
base64.b64decode(re_encrypt_response["CiphertextBlob"], validate=True)
|
||||||
|
|
||||||
|
re_encrypt_response["SourceKeyId"].should.equal(key_1_arn)
|
||||||
|
re_encrypt_response["KeyId"].should.equal(key_2_arn)
|
||||||
|
|
||||||
|
decrypt_response_1 = client.decrypt(
|
||||||
|
CiphertextBlob=encrypt_response["CiphertextBlob"],
|
||||||
|
EncryptionContext={"encryption": "context"},
|
||||||
|
)
|
||||||
|
decrypt_response_1["Plaintext"].should.equal(_get_encoded_value(plaintext))
|
||||||
|
decrypt_response_1["KeyId"].should.equal(key_1_arn)
|
||||||
|
|
||||||
|
decrypt_response_2 = client.decrypt(
|
||||||
|
CiphertextBlob=re_encrypt_response["CiphertextBlob"],
|
||||||
|
EncryptionContext={"another": "context"},
|
||||||
|
)
|
||||||
|
decrypt_response_2["Plaintext"].should.equal(_get_encoded_value(plaintext))
|
||||||
|
decrypt_response_2["KeyId"].should.equal(key_2_arn)
|
||||||
|
|
||||||
|
decrypt_response_1["Plaintext"].should.equal(decrypt_response_2["Plaintext"])
|
||||||
|
|
||||||
|
|
||||||
|
@mock_kms
|
||||||
|
def test_re_encrypt_to_invalid_destination():
|
||||||
|
client = boto3.client("kms", region_name="us-west-2")
|
||||||
|
|
||||||
|
key = client.create_key(Description="key 1")
|
||||||
|
key_id = key["KeyMetadata"]["KeyId"]
|
||||||
|
|
||||||
|
encrypt_response = client.encrypt(KeyId=key_id, Plaintext=b"some plaintext")
|
||||||
|
|
||||||
|
with pytest.raises(client.exceptions.NotFoundException):
|
||||||
|
client.re_encrypt(
|
||||||
|
CiphertextBlob=encrypt_response["CiphertextBlob"],
|
||||||
|
DestinationKeyId="alias/DoesNotExist",
|
||||||
|
)
|
Loading…
x
Reference in New Issue
Block a user