2019-09-13 21:08:26 +00:00
# -*- coding: utf-8 -*-
2015-06-30 09:44:39 +00:00
from __future__ import unicode_literals
2019-08-27 20:42:36 +00:00
from datetime import date
from datetime import datetime
from dateutil . tz import tzutc
import base64
import os
import re
2017-03-15 03:42:47 +00:00
import boto3
2015-06-30 09:44:39 +00:00
import boto . kms
2019-04-26 19:52:24 +00:00
import botocore . exceptions
2019-09-13 21:08:26 +00:00
import six
2019-08-27 20:42:36 +00:00
import sure # noqa
2015-06-30 09:44:39 +00:00
from boto . exception import JSONResponseError
2015-07-22 15:42:26 +00:00
from boto . kms . exceptions import AlreadyExistsException , NotFoundException
2019-08-27 20:42:36 +00:00
from freezegun import freeze_time
from nose . tools import assert_raises
from parameterized import parameterized
2019-04-26 19:52:24 +00:00
from moto . kms . exceptions import NotFoundException as MotoNotFoundException
2017-03-15 03:42:47 +00:00
from moto import mock_kms , mock_kms_deprecated
2019-08-27 20:42:36 +00:00
PLAINTEXT_VECTORS = (
( b " some encodeable plaintext " , ) ,
( b " some unencodeable plaintext \xec \x8a \xcf \xb6 r \xe9 \xb5 \xeb \xff \xa2 3 \x16 " , ) ,
2019-10-31 15:44:26 +00:00
( " some unicode characters ø˚∆øˆˆ∆ßçøˆˆçßøˆ¨¥ " , ) ,
2019-08-27 20:42:36 +00:00
)
2015-06-30 09:44:39 +00:00
2017-02-24 02:37:43 +00:00
2019-09-13 21:08:26 +00:00
def _get_encoded_value ( plaintext ) :
if isinstance ( plaintext , six . binary_type ) :
return plaintext
return plaintext . encode ( " utf-8 " )
2019-07-25 02:15:43 +00:00
@mock_kms
2015-06-30 09:44:39 +00:00
def test_create_key ( ) :
2019-08-27 20:42:36 +00:00
conn = boto3 . client ( " kms " , region_name = " us-east-1 " )
2019-05-21 16:46:22 +00:00
with freeze_time ( " 2015-01-01 00:00:00 " ) :
2019-08-27 20:42:36 +00:00
key = conn . create_key (
Policy = " my policy " ,
Description = " my key " ,
KeyUsage = " ENCRYPT_DECRYPT " ,
Tags = [ { " TagKey " : " project " , " TagValue " : " moto " } ] ,
)
2015-06-30 09:44:39 +00:00
2020-01-31 16:16:42 +00:00
key [ " KeyMetadata " ] [ " Arn " ] . should . equal (
" arn:aws:kms:us-east-1:123456789012:key/ {} " . format (
key [ " KeyMetadata " ] [ " KeyId " ]
)
)
key [ " KeyMetadata " ] [ " AWSAccountId " ] . should . equal ( " 123456789012 " )
key [ " KeyMetadata " ] [ " CreationDate " ] . should . be . a ( datetime )
key [ " KeyMetadata " ] [ " CustomerMasterKeySpec " ] . should . equal ( " SYMMETRIC_DEFAULT " )
2019-08-27 20:42:36 +00:00
key [ " KeyMetadata " ] [ " Description " ] . should . equal ( " my key " )
2020-01-31 16:16:42 +00:00
key [ " KeyMetadata " ] [ " Enabled " ] . should . be . ok
key [ " KeyMetadata " ] [ " EncryptionAlgorithms " ] . should . equal ( [ " SYMMETRIC_DEFAULT " ] )
key [ " KeyMetadata " ] [ " KeyId " ] . should_not . be . empty
key [ " KeyMetadata " ] [ " KeyManager " ] . should . equal ( " CUSTOMER " )
key [ " KeyMetadata " ] [ " KeyState " ] . should . equal ( " Enabled " )
2019-08-27 20:42:36 +00:00
key [ " KeyMetadata " ] [ " KeyUsage " ] . should . equal ( " ENCRYPT_DECRYPT " )
2020-01-31 16:16:42 +00:00
key [ " KeyMetadata " ] [ " Origin " ] . should . equal ( " AWS_KMS " )
key [ " KeyMetadata " ] . should_not . have . key ( " SigningAlgorithms " )
2015-06-30 09:44:39 +00:00
2017-02-16 03:35:45 +00:00
@mock_kms_deprecated
2015-06-30 09:44:39 +00:00
def test_describe_key ( ) :
conn = boto . kms . connect_to_region ( " us-west-2 " )
2019-10-31 15:44:26 +00:00
key = conn . create_key (
policy = " my policy " , description = " my key " , key_usage = " ENCRYPT_DECRYPT "
)
2019-08-27 20:42:36 +00:00
key_id = key [ " KeyMetadata " ] [ " KeyId " ]
2015-06-30 09:44:39 +00:00
key = conn . describe_key ( key_id )
2019-08-27 20:42:36 +00:00
key [ " KeyMetadata " ] [ " Description " ] . should . equal ( " my key " )
key [ " KeyMetadata " ] [ " KeyUsage " ] . should . equal ( " ENCRYPT_DECRYPT " )
2015-06-30 09:44:39 +00:00
2017-02-16 03:35:45 +00:00
@mock_kms_deprecated
2016-10-02 14:33:59 +00:00
def test_describe_key_via_alias ( ) :
conn = boto . kms . connect_to_region ( " us-west-2 " )
2019-10-31 15:44:26 +00:00
key = conn . create_key (
policy = " my policy " , description = " my key " , key_usage = " ENCRYPT_DECRYPT "
)
conn . create_alias (
alias_name = " alias/my-key-alias " , target_key_id = key [ " KeyMetadata " ] [ " KeyId " ]
)
2016-10-02 14:33:59 +00:00
2019-08-27 20:42:36 +00:00
alias_key = conn . describe_key ( " alias/my-key-alias " )
alias_key [ " KeyMetadata " ] [ " Description " ] . should . equal ( " my key " )
alias_key [ " KeyMetadata " ] [ " KeyUsage " ] . should . equal ( " ENCRYPT_DECRYPT " )
alias_key [ " KeyMetadata " ] [ " Arn " ] . should . equal ( key [ " KeyMetadata " ] [ " Arn " ] )
2016-10-02 14:33:59 +00:00
2017-02-16 03:35:45 +00:00
@mock_kms_deprecated
2016-10-02 14:33:59 +00:00
def test_describe_key_via_alias_not_found ( ) :
conn = boto . kms . connect_to_region ( " us-west-2 " )
2019-10-31 15:44:26 +00:00
key = conn . create_key (
policy = " my policy " , description = " my key " , key_usage = " ENCRYPT_DECRYPT "
)
conn . create_alias (
alias_name = " alias/my-key-alias " , target_key_id = key [ " KeyMetadata " ] [ " KeyId " ]
)
2016-10-02 14:33:59 +00:00
2019-10-31 15:44:26 +00:00
conn . describe_key . when . called_with ( " alias/not-found-alias " ) . should . throw (
NotFoundException
)
2016-10-02 14:33:59 +00:00
2019-10-31 15:44:26 +00:00
@parameterized (
(
2019-09-13 20:01:55 +00:00
( " alias/does-not-exist " , ) ,
( " arn:aws:kms:us-east-1:012345678912:alias/does-not-exist " , ) ,
( " invalid " , ) ,
2019-10-31 15:44:26 +00:00
)
)
2019-09-13 20:01:55 +00:00
@mock_kms
def test_describe_key_via_alias_invalid_alias ( key_id ) :
client = boto3 . client ( " kms " , region_name = " us-east-1 " )
client . create_key ( Description = " key " )
with assert_raises ( client . exceptions . NotFoundException ) :
client . describe_key ( KeyId = key_id )
2017-02-16 03:35:45 +00:00
@mock_kms_deprecated
2016-10-02 14:33:59 +00:00
def test_describe_key_via_arn ( ) :
conn = boto . kms . connect_to_region ( " us-west-2 " )
2019-10-31 15:44:26 +00:00
key = conn . create_key (
policy = " my policy " , description = " my key " , key_usage = " ENCRYPT_DECRYPT "
)
2019-08-27 20:42:36 +00:00
arn = key [ " KeyMetadata " ] [ " Arn " ]
2016-10-02 14:33:59 +00:00
the_key = conn . describe_key ( arn )
2019-08-27 20:42:36 +00:00
the_key [ " KeyMetadata " ] [ " Description " ] . should . equal ( " my key " )
the_key [ " KeyMetadata " ] [ " KeyUsage " ] . should . equal ( " ENCRYPT_DECRYPT " )
the_key [ " KeyMetadata " ] [ " KeyId " ] . should . equal ( key [ " KeyMetadata " ] [ " KeyId " ] )
2016-10-02 14:33:59 +00:00
2017-02-16 03:35:45 +00:00
@mock_kms_deprecated
2015-06-30 09:44:39 +00:00
def test_describe_missing_key ( ) :
conn = boto . kms . connect_to_region ( " us-west-2 " )
2019-08-28 06:55:08 +00:00
conn . describe_key . when . called_with ( " not-a-key " ) . should . throw ( NotFoundException )
2015-06-30 09:44:39 +00:00
2017-02-16 03:35:45 +00:00
@mock_kms_deprecated
2015-06-30 09:44:39 +00:00
def test_list_keys ( ) :
conn = boto . kms . connect_to_region ( " us-west-2 " )
2019-10-31 15:44:26 +00:00
conn . create_key (
policy = " my policy " , description = " my key1 " , key_usage = " ENCRYPT_DECRYPT "
)
conn . create_key (
policy = " my policy " , description = " my key2 " , key_usage = " ENCRYPT_DECRYPT "
)
2015-06-30 09:44:39 +00:00
keys = conn . list_keys ( )
2019-08-27 20:42:36 +00:00
keys [ " Keys " ] . should . have . length_of ( 2 )
2015-07-22 15:42:26 +00:00
2017-02-16 03:35:45 +00:00
@mock_kms_deprecated
2015-11-24 23:44:55 +00:00
def test_enable_key_rotation ( ) :
conn = boto . kms . connect_to_region ( " us-west-2 " )
2019-10-31 15:44:26 +00:00
key = conn . create_key (
policy = " my policy " , description = " my key " , key_usage = " ENCRYPT_DECRYPT "
)
2019-08-27 20:42:36 +00:00
key_id = key [ " KeyMetadata " ] [ " KeyId " ]
2015-11-24 23:44:55 +00:00
conn . enable_key_rotation ( key_id )
2019-08-27 20:42:36 +00:00
conn . get_key_rotation_status ( key_id ) [ " KeyRotationEnabled " ] . should . equal ( True )
2017-02-24 02:37:43 +00:00
2015-11-24 23:44:55 +00:00
2017-02-16 03:35:45 +00:00
@mock_kms_deprecated
2016-10-02 14:33:59 +00:00
def test_enable_key_rotation_via_arn ( ) :
conn = boto . kms . connect_to_region ( " us-west-2 " )
2019-10-31 15:44:26 +00:00
key = conn . create_key (
policy = " my policy " , description = " my key " , key_usage = " ENCRYPT_DECRYPT "
)
2019-08-27 20:42:36 +00:00
key_id = key [ " KeyMetadata " ] [ " Arn " ]
2016-10-02 14:33:59 +00:00
conn . enable_key_rotation ( key_id )
2019-08-27 20:42:36 +00:00
conn . get_key_rotation_status ( key_id ) [ " KeyRotationEnabled " ] . should . equal ( True )
2016-10-02 14:33:59 +00:00
2015-11-24 23:44:55 +00:00
2017-02-16 03:35:45 +00:00
@mock_kms_deprecated
2015-11-24 23:44:55 +00:00
def test_enable_key_rotation_with_missing_key ( ) :
conn = boto . kms . connect_to_region ( " us-west-2 " )
2019-10-31 15:44:26 +00:00
conn . enable_key_rotation . when . called_with ( " not-a-key " ) . should . throw (
NotFoundException
)
2015-11-24 23:44:55 +00:00
2017-02-16 03:35:45 +00:00
@mock_kms_deprecated
2016-10-02 14:33:59 +00:00
def test_enable_key_rotation_with_alias_name_should_fail ( ) :
conn = boto . kms . connect_to_region ( " us-west-2 " )
2019-10-31 15:44:26 +00:00
key = conn . create_key (
policy = " my policy " , description = " my key " , key_usage = " ENCRYPT_DECRYPT "
)
conn . create_alias (
alias_name = " alias/my-key-alias " , target_key_id = key [ " KeyMetadata " ] [ " KeyId " ]
)
2016-10-02 14:33:59 +00:00
2019-08-27 20:42:36 +00:00
alias_key = conn . describe_key ( " alias/my-key-alias " )
alias_key [ " KeyMetadata " ] [ " Arn " ] . should . equal ( key [ " KeyMetadata " ] [ " Arn " ] )
2016-10-02 14:33:59 +00:00
2019-10-31 15:44:26 +00:00
conn . enable_key_rotation . when . called_with ( " alias/my-alias " ) . should . throw (
NotFoundException
)
2016-10-02 14:33:59 +00:00
2017-02-16 03:35:45 +00:00
@mock_kms_deprecated
2015-11-24 23:44:55 +00:00
def test_disable_key_rotation ( ) :
conn = boto . kms . connect_to_region ( " us-west-2 " )
2019-10-31 15:44:26 +00:00
key = conn . create_key (
policy = " my policy " , description = " my key " , key_usage = " ENCRYPT_DECRYPT "
)
2019-08-27 20:42:36 +00:00
key_id = key [ " KeyMetadata " ] [ " KeyId " ]
2015-11-24 23:44:55 +00:00
conn . enable_key_rotation ( key_id )
2019-08-27 20:42:36 +00:00
conn . get_key_rotation_status ( key_id ) [ " KeyRotationEnabled " ] . should . equal ( True )
2015-11-24 23:44:55 +00:00
conn . disable_key_rotation ( key_id )
2019-08-27 20:42:36 +00:00
conn . get_key_rotation_status ( key_id ) [ " KeyRotationEnabled " ] . should . equal ( False )
2015-11-24 23:44:55 +00:00
2017-02-16 03:35:45 +00:00
@mock_kms_deprecated
2019-08-27 20:42:36 +00:00
def test_generate_data_key ( ) :
2017-02-10 03:36:24 +00:00
conn = boto . kms . connect_to_region ( " us-west-2 " )
2019-10-31 15:44:26 +00:00
key = conn . create_key (
policy = " my policy " , description = " my key " , key_usage = " ENCRYPT_DECRYPT "
)
2019-08-27 20:42:36 +00:00
key_id = key [ " KeyMetadata " ] [ " KeyId " ]
key_arn = key [ " KeyMetadata " ] [ " Arn " ]
response = conn . generate_data_key ( key_id = key_id , number_of_bytes = 32 )
# CiphertextBlob must NOT be base64-encoded
with assert_raises ( Exception ) :
base64 . b64decode ( response [ " CiphertextBlob " ] , validate = True )
# Plaintext must NOT be base64-encoded
with assert_raises ( Exception ) :
base64 . b64decode ( response [ " Plaintext " ] , validate = True )
response [ " KeyId " ] . should . equal ( key_arn )
@mock_kms
def test_boto3_generate_data_key ( ) :
kms = boto3 . client ( " kms " , region_name = " us-west-2 " )
key = kms . create_key ( )
key_id = key [ " KeyMetadata " ] [ " KeyId " ]
key_arn = key [ " KeyMetadata " ] [ " Arn " ]
response = kms . generate_data_key ( KeyId = key_id , NumberOfBytes = 32 )
# CiphertextBlob must NOT be base64-encoded
with assert_raises ( Exception ) :
base64 . b64decode ( response [ " CiphertextBlob " ] , validate = True )
# Plaintext must NOT be base64-encoded
with assert_raises ( Exception ) :
base64 . b64decode ( response [ " Plaintext " ] , validate = True )
response [ " KeyId " ] . should . equal ( key_arn )
2017-02-10 03:36:24 +00:00
2019-08-27 20:42:36 +00:00
@parameterized ( PLAINTEXT_VECTORS )
2019-09-13 20:32:19 +00:00
@mock_kms
2019-08-27 20:42:36 +00:00
def test_encrypt ( plaintext ) :
2019-09-13 20:32:19 +00:00
client = boto3 . client ( " kms " , region_name = " us-west-2 " )
2019-08-27 20:42:36 +00:00
2019-09-13 20:32:19 +00:00
key = client . create_key ( Description = " key " )
2019-08-27 20:42:36 +00:00
key_id = key [ " KeyMetadata " ] [ " KeyId " ]
key_arn = key [ " KeyMetadata " ] [ " Arn " ]
2019-09-13 20:32:19 +00:00
response = client . encrypt ( KeyId = key_id , Plaintext = plaintext )
2019-08-27 20:42:36 +00:00
response [ " CiphertextBlob " ] . should_not . equal ( plaintext )
# CiphertextBlob must NOT be base64-encoded
with assert_raises ( Exception ) :
base64 . b64decode ( response [ " CiphertextBlob " ] , validate = True )
response [ " KeyId " ] . should . equal ( key_arn )
@parameterized ( PLAINTEXT_VECTORS )
2019-09-13 20:32:19 +00:00
@mock_kms
2019-08-27 20:42:36 +00:00
def test_decrypt ( plaintext ) :
2019-09-13 20:32:19 +00:00
client = boto3 . client ( " kms " , region_name = " us-west-2 " )
2019-08-27 20:42:36 +00:00
2019-09-13 20:32:19 +00:00
key = client . create_key ( Description = " key " )
2019-08-27 20:42:36 +00:00
key_id = key [ " KeyMetadata " ] [ " KeyId " ]
key_arn = key [ " KeyMetadata " ] [ " Arn " ]
2019-09-13 20:32:19 +00:00
encrypt_response = client . encrypt ( KeyId = key_id , Plaintext = plaintext )
2019-08-27 20:42:36 +00:00
2019-09-13 20:32:19 +00:00
client . create_key ( Description = " key " )
2019-08-27 20:42:36 +00:00
# CiphertextBlob must NOT be base64-encoded
with assert_raises ( Exception ) :
base64 . b64decode ( encrypt_response [ " CiphertextBlob " ] , validate = True )
2019-09-13 20:32:19 +00:00
decrypt_response = client . decrypt ( CiphertextBlob = encrypt_response [ " CiphertextBlob " ] )
2019-08-27 20:42:36 +00:00
# Plaintext must NOT be base64-encoded
with assert_raises ( Exception ) :
base64 . b64decode ( decrypt_response [ " Plaintext " ] , validate = True )
2019-09-13 21:08:26 +00:00
decrypt_response [ " Plaintext " ] . should . equal ( _get_encoded_value ( plaintext ) )
2019-08-27 20:42:36 +00:00
decrypt_response [ " KeyId " ] . should . equal ( key_arn )
2016-10-12 18:47:38 +00:00
2017-02-16 03:35:45 +00:00
@mock_kms_deprecated
2015-11-24 23:44:55 +00:00
def test_disable_key_rotation_with_missing_key ( ) :
conn = boto . kms . connect_to_region ( " us-west-2 " )
2019-10-31 15:44:26 +00:00
conn . disable_key_rotation . when . called_with ( " not-a-key " ) . should . throw (
NotFoundException
)
2015-11-24 23:44:55 +00:00
2017-02-16 03:35:45 +00:00
@mock_kms_deprecated
2015-11-24 23:44:55 +00:00
def test_get_key_rotation_status_with_missing_key ( ) :
conn = boto . kms . connect_to_region ( " us-west-2 " )
2019-10-31 15:44:26 +00:00
conn . get_key_rotation_status . when . called_with ( " not-a-key " ) . should . throw (
NotFoundException
)
2015-11-24 23:44:55 +00:00
2017-02-16 03:35:45 +00:00
@mock_kms_deprecated
2015-11-24 23:44:55 +00:00
def test_get_key_rotation_status ( ) :
conn = boto . kms . connect_to_region ( " us-west-2 " )
2019-10-31 15:44:26 +00:00
key = conn . create_key (
policy = " my policy " , description = " my key " , key_usage = " ENCRYPT_DECRYPT "
)
2019-08-27 20:42:36 +00:00
key_id = key [ " KeyMetadata " ] [ " KeyId " ]
2015-11-24 23:44:55 +00:00
2019-08-27 20:42:36 +00:00
conn . get_key_rotation_status ( key_id ) [ " KeyRotationEnabled " ] . should . equal ( False )
2015-11-24 23:44:55 +00:00
2017-02-16 03:35:45 +00:00
@mock_kms_deprecated
2015-11-24 23:44:55 +00:00
def test_create_key_defaults_key_rotation ( ) :
conn = boto . kms . connect_to_region ( " us-west-2 " )
2019-10-31 15:44:26 +00:00
key = conn . create_key (
policy = " my policy " , description = " my key " , key_usage = " ENCRYPT_DECRYPT "
)
2019-08-27 20:42:36 +00:00
key_id = key [ " KeyMetadata " ] [ " KeyId " ]
2015-11-24 23:44:55 +00:00
2019-08-27 20:42:36 +00:00
conn . get_key_rotation_status ( key_id ) [ " KeyRotationEnabled " ] . should . equal ( False )
2015-11-24 23:44:55 +00:00
2017-02-16 03:35:45 +00:00
@mock_kms_deprecated
2015-11-25 19:50:55 +00:00
def test_get_key_policy ( ) :
2019-08-27 20:42:36 +00:00
conn = boto . kms . connect_to_region ( " us-west-2 " )
2015-11-25 19:50:55 +00:00
2019-10-31 15:44:26 +00:00
key = conn . create_key (
policy = " my policy " , description = " my key1 " , key_usage = " ENCRYPT_DECRYPT "
)
2019-08-27 20:42:36 +00:00
key_id = key [ " KeyMetadata " ] [ " KeyId " ]
2015-11-25 19:50:55 +00:00
2019-08-27 20:42:36 +00:00
policy = conn . get_key_policy ( key_id , " default " )
policy [ " Policy " ] . should . equal ( " my policy " )
2015-11-25 19:50:55 +00:00
2017-02-24 02:37:43 +00:00
2017-02-16 03:35:45 +00:00
@mock_kms_deprecated
2016-10-02 14:33:59 +00:00
def test_get_key_policy_via_arn ( ) :
2019-08-27 20:42:36 +00:00
conn = boto . kms . connect_to_region ( " us-west-2 " )
2016-10-02 14:33:59 +00:00
2019-10-31 15:44:26 +00:00
key = conn . create_key (
policy = " my policy " , description = " my key1 " , key_usage = " ENCRYPT_DECRYPT "
)
2019-08-27 20:42:36 +00:00
policy = conn . get_key_policy ( key [ " KeyMetadata " ] [ " Arn " ] , " default " )
2016-10-02 14:33:59 +00:00
2019-08-27 20:42:36 +00:00
policy [ " Policy " ] . should . equal ( " my policy " )
2015-11-25 19:50:55 +00:00
2017-02-24 02:37:43 +00:00
2017-02-16 03:35:45 +00:00
@mock_kms_deprecated
2015-11-25 19:50:55 +00:00
def test_put_key_policy ( ) :
2019-08-27 20:42:36 +00:00
conn = boto . kms . connect_to_region ( " us-west-2 " )
2015-11-25 19:50:55 +00:00
2019-10-31 15:44:26 +00:00
key = conn . create_key (
policy = " my policy " , description = " my key1 " , key_usage = " ENCRYPT_DECRYPT "
)
2019-08-27 20:42:36 +00:00
key_id = key [ " KeyMetadata " ] [ " KeyId " ]
2015-11-25 19:50:55 +00:00
2019-08-27 20:42:36 +00:00
conn . put_key_policy ( key_id , " default " , " new policy " )
policy = conn . get_key_policy ( key_id , " default " )
policy [ " Policy " ] . should . equal ( " new policy " )
2015-11-25 19:50:55 +00:00
2017-02-16 03:35:45 +00:00
@mock_kms_deprecated
2016-10-02 14:33:59 +00:00
def test_put_key_policy_via_arn ( ) :
2019-08-27 20:42:36 +00:00
conn = boto . kms . connect_to_region ( " us-west-2 " )
2016-10-02 14:33:59 +00:00
2019-10-31 15:44:26 +00:00
key = conn . create_key (
policy = " my policy " , description = " my key1 " , key_usage = " ENCRYPT_DECRYPT "
)
2019-08-27 20:42:36 +00:00
key_id = key [ " KeyMetadata " ] [ " Arn " ]
2016-10-02 14:33:59 +00:00
2019-08-27 20:42:36 +00:00
conn . put_key_policy ( key_id , " default " , " new policy " )
policy = conn . get_key_policy ( key_id , " default " )
policy [ " Policy " ] . should . equal ( " new policy " )
2016-10-02 14:33:59 +00:00
2017-02-16 03:35:45 +00:00
@mock_kms_deprecated
2016-10-02 14:33:59 +00:00
def test_put_key_policy_via_alias_should_not_update ( ) :
2019-08-27 20:42:36 +00:00
conn = boto . kms . connect_to_region ( " us-west-2 " )
2016-10-02 14:33:59 +00:00
2019-10-31 15:44:26 +00:00
key = conn . create_key (
policy = " my policy " , description = " my key1 " , key_usage = " ENCRYPT_DECRYPT "
)
conn . create_alias (
alias_name = " alias/my-key-alias " , target_key_id = key [ " KeyMetadata " ] [ " KeyId " ]
)
2016-10-02 14:33:59 +00:00
2019-10-31 15:44:26 +00:00
conn . put_key_policy . when . called_with (
" alias/my-key-alias " , " default " , " new policy "
) . should . throw ( NotFoundException )
2016-10-02 14:33:59 +00:00
2019-08-27 20:42:36 +00:00
policy = conn . get_key_policy ( key [ " KeyMetadata " ] [ " KeyId " ] , " default " )
policy [ " Policy " ] . should . equal ( " my policy " )
2016-10-02 14:33:59 +00:00
2017-02-16 03:35:45 +00:00
@mock_kms_deprecated
2016-10-02 14:33:59 +00:00
def test_put_key_policy ( ) :
2019-08-27 20:42:36 +00:00
conn = boto . kms . connect_to_region ( " us-west-2 " )
2016-10-02 14:33:59 +00:00
2019-10-31 15:44:26 +00:00
key = conn . create_key (
policy = " my policy " , description = " my key1 " , key_usage = " ENCRYPT_DECRYPT "
)
2019-08-27 20:42:36 +00:00
conn . put_key_policy ( key [ " KeyMetadata " ] [ " Arn " ] , " default " , " new policy " )
2016-10-02 14:33:59 +00:00
2019-08-27 20:42:36 +00:00
policy = conn . get_key_policy ( key [ " KeyMetadata " ] [ " KeyId " ] , " default " )
policy [ " Policy " ] . should . equal ( " new policy " )
2016-10-02 14:33:59 +00:00
2017-02-16 03:35:45 +00:00
@mock_kms_deprecated
2015-11-25 19:50:55 +00:00
def test_list_key_policies ( ) :
2019-08-27 20:42:36 +00:00
conn = boto . kms . connect_to_region ( " us-west-2 " )
2015-11-25 19:50:55 +00:00
2019-10-31 15:44:26 +00:00
key = conn . create_key (
policy = " my policy " , description = " my key1 " , key_usage = " ENCRYPT_DECRYPT "
)
2019-08-27 20:42:36 +00:00
key_id = key [ " KeyMetadata " ] [ " KeyId " ]
2015-11-25 19:50:55 +00:00
policies = conn . list_key_policies ( key_id )
2019-08-27 20:42:36 +00:00
policies [ " PolicyNames " ] . should . equal ( [ " default " ] )
2015-11-25 19:50:55 +00:00
2017-02-16 03:35:45 +00:00
@mock_kms_deprecated
2015-07-22 15:42:26 +00:00
def test__create_alias__returns_none_if_correct ( ) :
kms = boto . connect_kms ( )
create_resp = kms . create_key ( )
2019-08-27 20:42:36 +00:00
key_id = create_resp [ " KeyMetadata " ] [ " KeyId " ]
2015-07-22 15:42:26 +00:00
2019-08-27 20:42:36 +00:00
resp = kms . create_alias ( " alias/my-alias " , key_id )
2015-07-22 15:42:26 +00:00
resp . should . be . none
2017-02-16 03:35:45 +00:00
@mock_kms_deprecated
2015-07-22 15:42:26 +00:00
def test__create_alias__raises_if_reserved_alias ( ) :
kms = boto . connect_kms ( )
create_resp = kms . create_key ( )
2019-08-27 20:42:36 +00:00
key_id = create_resp [ " KeyMetadata " ] [ " KeyId " ]
2015-07-22 15:42:26 +00:00
2019-10-31 15:44:26 +00:00
reserved_aliases = [
" alias/aws/ebs " ,
" alias/aws/s3 " ,
" alias/aws/redshift " ,
" alias/aws/rds " ,
]
2015-07-22 15:42:26 +00:00
for alias_name in reserved_aliases :
with assert_raises ( JSONResponseError ) as err :
kms . create_alias ( alias_name , key_id )
ex = err . exception
ex . error_message . should . be . none
2019-08-27 20:42:36 +00:00
ex . error_code . should . equal ( " NotAuthorizedException " )
ex . body . should . equal ( { " __type " : " NotAuthorizedException " } )
ex . reason . should . equal ( " Bad Request " )
2015-07-22 15:42:26 +00:00
ex . status . should . equal ( 400 )
2017-02-16 03:35:45 +00:00
@mock_kms_deprecated
2015-07-22 15:42:26 +00:00
def test__create_alias__can_create_multiple_aliases_for_same_key_id ( ) :
kms = boto . connect_kms ( )
create_resp = kms . create_key ( )
2019-08-27 20:42:36 +00:00
key_id = create_resp [ " KeyMetadata " ] [ " KeyId " ]
2015-07-22 15:42:26 +00:00
2019-08-27 20:42:36 +00:00
kms . create_alias ( " alias/my-alias3 " , key_id ) . should . be . none
kms . create_alias ( " alias/my-alias4 " , key_id ) . should . be . none
kms . create_alias ( " alias/my-alias5 " , key_id ) . should . be . none
2015-07-22 15:42:26 +00:00
2017-02-16 03:35:45 +00:00
@mock_kms_deprecated
2015-07-22 15:42:26 +00:00
def test__create_alias__raises_if_wrong_prefix ( ) :
kms = boto . connect_kms ( )
create_resp = kms . create_key ( )
2019-08-27 20:42:36 +00:00
key_id = create_resp [ " KeyMetadata " ] [ " KeyId " ]
2015-07-22 15:42:26 +00:00
with assert_raises ( JSONResponseError ) as err :
2019-08-27 20:42:36 +00:00
kms . create_alias ( " wrongprefix/my-alias " , key_id )
2015-07-22 15:42:26 +00:00
ex = err . exception
2019-08-27 20:42:36 +00:00
ex . error_message . should . equal ( " Invalid identifier " )
ex . error_code . should . equal ( " ValidationException " )
2019-10-31 15:44:26 +00:00
ex . body . should . equal (
{ " message " : " Invalid identifier " , " __type " : " ValidationException " }
)
2019-08-27 20:42:36 +00:00
ex . reason . should . equal ( " Bad Request " )
2015-07-22 15:42:26 +00:00
ex . status . should . equal ( 400 )
2017-02-16 03:35:45 +00:00
@mock_kms_deprecated
2015-07-22 15:42:26 +00:00
def test__create_alias__raises_if_duplicate ( ) :
2019-08-27 20:42:36 +00:00
region = " us-west-2 "
2015-07-22 15:42:26 +00:00
kms = boto . kms . connect_to_region ( region )
create_resp = kms . create_key ( )
2019-08-27 20:42:36 +00:00
key_id = create_resp [ " KeyMetadata " ] [ " KeyId " ]
alias = " alias/my-alias "
2015-07-22 15:42:26 +00:00
kms . create_alias ( alias , key_id )
with assert_raises ( AlreadyExistsException ) as err :
kms . create_alias ( alias , key_id )
ex = err . exception
2019-08-27 20:42:36 +00:00
ex . error_message . should . match (
2019-10-31 15:44:26 +00:00
r " An alias with the name arn:aws:kms: {region} : \ d {{ 12}}: {alias} already exists " . format (
* * locals ( )
)
2019-08-27 20:42:36 +00:00
)
2015-07-22 15:42:26 +00:00
ex . error_code . should . be . none
ex . box_usage . should . be . none
ex . request_id . should . be . none
2019-08-27 20:42:36 +00:00
ex . body [ " message " ] . should . match (
2019-10-31 15:44:26 +00:00
r " An alias with the name arn:aws:kms: {region} : \ d {{ 12}}: {alias} already exists " . format (
* * locals ( )
)
2019-08-27 20:42:36 +00:00
)
ex . body [ " __type " ] . should . equal ( " AlreadyExistsException " )
ex . reason . should . equal ( " Bad Request " )
2015-07-22 15:42:26 +00:00
ex . status . should . equal ( 400 )
2017-02-16 03:35:45 +00:00
@mock_kms_deprecated
2015-07-22 15:42:26 +00:00
def test__create_alias__raises_if_alias_has_restricted_characters ( ) :
kms = boto . connect_kms ( )
create_resp = kms . create_key ( )
2019-08-27 20:42:36 +00:00
key_id = create_resp [ " KeyMetadata " ] [ " KeyId " ]
2015-07-22 15:42:26 +00:00
2019-10-31 15:44:26 +00:00
alias_names_with_restricted_characters = [
" alias/my-alias! " ,
" alias/my-alias$ " ,
" alias/my-alias@ " ,
]
2015-07-22 15:42:26 +00:00
for alias_name in alias_names_with_restricted_characters :
with assert_raises ( JSONResponseError ) as err :
kms . create_alias ( alias_name , key_id )
ex = err . exception
2019-08-27 20:42:36 +00:00
ex . body [ " __type " ] . should . equal ( " ValidationException " )
ex . body [ " message " ] . should . equal (
" 1 validation error detected: Value ' {alias_name} ' at ' aliasName ' failed to satisfy constraint: Member must satisfy regular expression pattern: ^[a-zA-Z0-9:/_-]+$ " . format (
* * locals ( )
)
)
ex . error_code . should . equal ( " ValidationException " )
2017-02-24 02:37:43 +00:00
ex . message . should . equal (
2019-08-27 20:42:36 +00:00
" 1 validation error detected: Value ' {alias_name} ' at ' aliasName ' failed to satisfy constraint: Member must satisfy regular expression pattern: ^[a-zA-Z0-9:/_-]+$ " . format (
* * locals ( )
)
)
ex . reason . should . equal ( " Bad Request " )
2015-07-22 15:42:26 +00:00
ex . status . should . equal ( 400 )
2017-02-16 03:35:45 +00:00
@mock_kms_deprecated
2015-07-22 15:42:26 +00:00
def test__create_alias__raises_if_alias_has_colon_character ( ) :
2017-02-24 02:37:43 +00:00
# For some reason, colons are not accepted for an alias, even though they
# are accepted by regex ^[a-zA-Z0-9:/_-]+$
2015-07-22 15:42:26 +00:00
kms = boto . connect_kms ( )
create_resp = kms . create_key ( )
2019-08-27 20:42:36 +00:00
key_id = create_resp [ " KeyMetadata " ] [ " KeyId " ]
2015-07-22 15:42:26 +00:00
2019-08-27 20:42:36 +00:00
alias_names_with_restricted_characters = [ " alias/my:alias " ]
2015-07-22 15:42:26 +00:00
for alias_name in alias_names_with_restricted_characters :
with assert_raises ( JSONResponseError ) as err :
kms . create_alias ( alias_name , key_id )
ex = err . exception
2019-08-27 20:42:36 +00:00
ex . body [ " __type " ] . should . equal ( " ValidationException " )
2019-10-31 15:44:26 +00:00
ex . body [ " message " ] . should . equal (
" {alias_name} contains invalid characters for an alias " . format ( * * locals ( ) )
)
2019-08-27 20:42:36 +00:00
ex . error_code . should . equal ( " ValidationException " )
2019-10-31 15:44:26 +00:00
ex . message . should . equal (
" {alias_name} contains invalid characters for an alias " . format ( * * locals ( ) )
)
2019-08-27 20:42:36 +00:00
ex . reason . should . equal ( " Bad Request " )
2015-07-22 15:42:26 +00:00
ex . status . should . equal ( 400 )
2019-10-31 15:44:26 +00:00
@parameterized ( ( ( " alias/my-alias_/ " , ) , ( " alias/my_alias-/ " , ) ) )
2017-02-16 03:35:45 +00:00
@mock_kms_deprecated
2019-08-28 06:52:44 +00:00
def test__create_alias__accepted_characters ( alias_name ) :
2015-07-22 15:42:26 +00:00
kms = boto . connect_kms ( )
create_resp = kms . create_key ( )
2019-08-27 20:42:36 +00:00
key_id = create_resp [ " KeyMetadata " ] [ " KeyId " ]
2015-07-22 15:42:26 +00:00
2019-08-28 06:52:44 +00:00
kms . create_alias ( alias_name , key_id )
2015-07-22 15:42:26 +00:00
2017-02-16 03:35:45 +00:00
@mock_kms_deprecated
2015-07-22 15:42:26 +00:00
def test__create_alias__raises_if_target_key_id_is_existing_alias ( ) :
kms = boto . connect_kms ( )
create_resp = kms . create_key ( )
2019-08-27 20:42:36 +00:00
key_id = create_resp [ " KeyMetadata " ] [ " KeyId " ]
alias = " alias/my-alias "
2015-07-22 15:42:26 +00:00
kms . create_alias ( alias , key_id )
with assert_raises ( JSONResponseError ) as err :
kms . create_alias ( alias , alias )
ex = err . exception
2019-08-27 20:42:36 +00:00
ex . body [ " __type " ] . should . equal ( " ValidationException " )
ex . body [ " message " ] . should . equal ( " Aliases must refer to keys. Not aliases " )
ex . error_code . should . equal ( " ValidationException " )
ex . message . should . equal ( " Aliases must refer to keys. Not aliases " )
ex . reason . should . equal ( " Bad Request " )
2015-07-22 15:42:26 +00:00
ex . status . should . equal ( 400 )
2017-02-16 03:35:45 +00:00
@mock_kms_deprecated
2015-07-22 15:42:26 +00:00
def test__delete_alias ( ) :
kms = boto . connect_kms ( )
create_resp = kms . create_key ( )
2019-08-27 20:42:36 +00:00
key_id = create_resp [ " KeyMetadata " ] [ " KeyId " ]
alias = " alias/my-alias "
2015-07-22 15:42:26 +00:00
2017-11-27 10:36:25 +00:00
# added another alias here to make sure that the deletion of the alias can
# be done when there are multiple existing aliases.
another_create_resp = kms . create_key ( )
2019-08-27 20:42:36 +00:00
another_key_id = create_resp [ " KeyMetadata " ] [ " KeyId " ]
another_alias = " alias/another-alias "
2017-11-27 10:36:25 +00:00
2015-07-22 15:42:26 +00:00
kms . create_alias ( alias , key_id )
2017-11-27 10:36:25 +00:00
kms . create_alias ( another_alias , another_key_id )
2015-07-22 15:42:26 +00:00
resp = kms . delete_alias ( alias )
resp . should . be . none
# we can create the alias again, since it has been deleted
kms . create_alias ( alias , key_id )
2017-02-16 03:35:45 +00:00
@mock_kms_deprecated
2015-07-22 15:42:26 +00:00
def test__delete_alias__raises_if_wrong_prefix ( ) :
kms = boto . connect_kms ( )
with assert_raises ( JSONResponseError ) as err :
2019-08-27 20:42:36 +00:00
kms . delete_alias ( " wrongprefix/my-alias " )
2015-07-22 15:42:26 +00:00
ex = err . exception
2019-08-27 20:42:36 +00:00
ex . body [ " __type " ] . should . equal ( " ValidationException " )
ex . body [ " message " ] . should . equal ( " Invalid identifier " )
ex . error_code . should . equal ( " ValidationException " )
ex . message . should . equal ( " Invalid identifier " )
ex . reason . should . equal ( " Bad Request " )
2015-07-22 15:42:26 +00:00
ex . status . should . equal ( 400 )
2017-02-16 03:35:45 +00:00
@mock_kms_deprecated
2015-07-22 15:42:26 +00:00
def test__delete_alias__raises_if_alias_is_not_found ( ) :
2019-08-27 20:42:36 +00:00
region = " us-west-2 "
2015-07-22 15:42:26 +00:00
kms = boto . kms . connect_to_region ( region )
2019-08-27 20:42:36 +00:00
alias_name = " alias/unexisting-alias "
2015-07-22 15:42:26 +00:00
with assert_raises ( NotFoundException ) as err :
kms . delete_alias ( alias_name )
2019-08-28 06:52:44 +00:00
expected_message_match = r " Alias arn:aws:kms: {region} :[0-9] {{ 12}}: {alias_name} is not found. " . format (
2019-10-31 15:44:26 +00:00
region = region , alias_name = alias_name
2019-08-28 06:52:44 +00:00
)
2015-07-22 15:42:26 +00:00
ex = err . exception
2019-08-27 20:42:36 +00:00
ex . body [ " __type " ] . should . equal ( " NotFoundException " )
2019-08-28 06:52:44 +00:00
ex . body [ " message " ] . should . match ( expected_message_match )
2015-07-22 15:42:26 +00:00
ex . box_usage . should . be . none
ex . error_code . should . be . none
2019-08-28 06:52:44 +00:00
ex . message . should . match ( expected_message_match )
2019-08-27 20:42:36 +00:00
ex . reason . should . equal ( " Bad Request " )
2015-07-22 15:42:26 +00:00
ex . request_id . should . be . none
ex . status . should . equal ( 400 )
2017-02-16 03:35:45 +00:00
@mock_kms_deprecated
2015-07-22 15:42:26 +00:00
def test__list_aliases ( ) :
region = " eu-west-1 "
kms = boto . kms . connect_to_region ( region )
create_resp = kms . create_key ( )
2019-08-27 20:42:36 +00:00
key_id = create_resp [ " KeyMetadata " ] [ " KeyId " ]
kms . create_alias ( " alias/my-alias1 " , key_id )
kms . create_alias ( " alias/my-alias2 " , key_id )
kms . create_alias ( " alias/my-alias3 " , key_id )
2015-07-22 15:42:26 +00:00
resp = kms . list_aliases ( )
2019-08-27 20:42:36 +00:00
resp [ " Truncated " ] . should . be . false
2015-07-22 15:42:26 +00:00
2019-08-27 20:42:36 +00:00
aliases = resp [ " Aliases " ]
2015-07-22 15:42:26 +00:00
def has_correct_arn ( alias_obj ) :
2019-08-27 20:42:36 +00:00
alias_name = alias_obj [ " AliasName " ]
alias_arn = alias_obj [ " AliasArn " ]
return re . match (
2019-10-31 15:44:26 +00:00
r " arn:aws:kms: {region} : \ d {{ 12}}: {alias_name} " . format (
region = region , alias_name = alias_name
) ,
alias_arn ,
2019-08-27 20:42:36 +00:00
)
len (
2019-10-31 15:44:26 +00:00
[
alias
for alias in aliases
if has_correct_arn ( alias ) and " alias/aws/ebs " == alias [ " AliasName " ]
]
) . should . equal ( 1 )
len (
[
alias
for alias in aliases
if has_correct_arn ( alias ) and " alias/aws/rds " == alias [ " AliasName " ]
]
) . should . equal ( 1 )
len (
[
alias
for alias in aliases
if has_correct_arn ( alias ) and " alias/aws/redshift " == alias [ " AliasName " ]
]
) . should . equal ( 1 )
len (
[
alias
for alias in aliases
if has_correct_arn ( alias ) and " alias/aws/s3 " == alias [ " AliasName " ]
]
2019-08-27 20:42:36 +00:00
) . should . equal ( 1 )
len (
2019-10-31 15:44:26 +00:00
[
alias
for alias in aliases
if has_correct_arn ( alias ) and " alias/my-alias1 " == alias [ " AliasName " ]
]
2019-08-27 20:42:36 +00:00
) . should . equal ( 1 )
len (
2019-10-31 15:44:26 +00:00
[
alias
for alias in aliases
if has_correct_arn ( alias ) and " alias/my-alias2 " == alias [ " AliasName " ]
]
2019-08-27 20:42:36 +00:00
) . should . equal ( 1 )
2019-10-31 15:44:26 +00:00
len (
[
alias
for alias in aliases
if " TargetKeyId " in alias and key_id == alias [ " TargetKeyId " ]
]
) . should . equal ( 3 )
2015-07-22 15:42:26 +00:00
len ( aliases ) . should . equal ( 7 )
2015-11-24 23:44:55 +00:00
2019-10-31 15:44:26 +00:00
@parameterized (
(
2019-08-28 06:52:44 +00:00
( " not-a-uuid " , ) ,
( " alias/DoesNotExist " , ) ,
( " arn:aws:kms:us-east-1:012345678912:alias/DoesNotExist " , ) ,
( " d25652e4-d2d2-49f7-929a-671ccda580c6 " , ) ,
2019-10-31 15:44:26 +00:00
(
" arn:aws:kms:us-east-1:012345678912:key/d25652e4-d2d2-49f7-929a-671ccda580c6 " ,
) ,
)
)
2019-08-28 06:52:44 +00:00
@mock_kms
def test_invalid_key_ids ( key_id ) :
client = boto3 . client ( " kms " , region_name = " us-east-1 " )
2015-11-24 23:44:55 +00:00
2019-08-28 06:52:44 +00:00
with assert_raises ( client . exceptions . NotFoundException ) :
client . generate_data_key ( KeyId = key_id , NumberOfBytes = 5 )
2015-11-25 19:50:55 +00:00
2017-02-16 03:35:45 +00:00
@mock_kms_deprecated
2015-11-25 19:50:55 +00:00
def test__assert_default_policy ( ) :
from moto . kms . responses import _assert_default_policy
2019-10-31 15:44:26 +00:00
_assert_default_policy . when . called_with ( " not-default " ) . should . throw (
MotoNotFoundException
)
_assert_default_policy . when . called_with ( " default " ) . should_not . throw (
MotoNotFoundException
)
2017-03-15 03:42:47 +00:00
2019-08-27 20:42:36 +00:00
@parameterized ( PLAINTEXT_VECTORS )
2017-03-15 03:42:47 +00:00
@mock_kms
2019-08-27 20:42:36 +00:00
def test_kms_encrypt_boto3 ( 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 )
2017-03-15 03:42:47 +00:00
2019-08-27 20:42:36 +00:00
response = client . decrypt ( CiphertextBlob = response [ " CiphertextBlob " ] )
2019-09-13 21:08:26 +00:00
response [ " Plaintext " ] . should . equal ( _get_encoded_value ( plaintext ) )
2018-10-05 20:55:47 +00:00
@mock_kms
def test_disable_key ( ) :
2019-08-27 20:42:36 +00:00
client = boto3 . client ( " kms " , region_name = " us-east-1 " )
key = client . create_key ( Description = " disable-key " )
client . disable_key ( KeyId = key [ " KeyMetadata " ] [ " KeyId " ] )
2018-10-05 20:55:47 +00:00
2019-08-27 20:42:36 +00:00
result = client . describe_key ( KeyId = key [ " KeyMetadata " ] [ " KeyId " ] )
2018-10-05 20:55:47 +00:00
assert result [ " KeyMetadata " ] [ " Enabled " ] == False
2019-08-27 20:42:36 +00:00
assert result [ " KeyMetadata " ] [ " KeyState " ] == " Disabled "
2018-10-05 20:55:47 +00:00
@mock_kms
def test_enable_key ( ) :
2019-08-27 20:42:36 +00:00
client = boto3 . client ( " kms " , region_name = " us-east-1 " )
key = client . create_key ( Description = " enable-key " )
client . disable_key ( KeyId = key [ " KeyMetadata " ] [ " KeyId " ] )
client . enable_key ( KeyId = key [ " KeyMetadata " ] [ " KeyId " ] )
2018-10-05 20:55:47 +00:00
2019-08-27 20:42:36 +00:00
result = client . describe_key ( KeyId = key [ " KeyMetadata " ] [ " KeyId " ] )
2018-10-05 20:55:47 +00:00
assert result [ " KeyMetadata " ] [ " Enabled " ] == True
2019-08-27 20:42:36 +00:00
assert result [ " KeyMetadata " ] [ " KeyState " ] == " Enabled "
2018-10-05 20:55:47 +00:00
@mock_kms
def test_schedule_key_deletion ( ) :
2019-08-27 20:42:36 +00:00
client = boto3 . client ( " kms " , region_name = " us-east-1 " )
key = client . create_key ( Description = " schedule-key-deletion " )
if os . environ . get ( " TEST_SERVER_MODE " , " false " ) . lower ( ) == " false " :
2018-10-08 13:29:21 +00:00
with freeze_time ( " 2015-01-01 12:00:00 " ) :
2019-08-27 20:42:36 +00:00
response = client . schedule_key_deletion ( KeyId = key [ " KeyMetadata " ] [ " KeyId " ] )
assert response [ " KeyId " ] == key [ " KeyMetadata " ] [ " KeyId " ]
2019-10-31 15:44:26 +00:00
assert response [ " DeletionDate " ] == datetime (
2015 , 1 , 31 , 12 , 0 , tzinfo = tzutc ( )
)
2018-10-08 13:29:21 +00:00
else :
# Can't manipulate time in server mode
2019-08-27 20:42:36 +00:00
response = client . schedule_key_deletion ( KeyId = key [ " KeyMetadata " ] [ " KeyId " ] )
assert response [ " KeyId " ] == key [ " KeyMetadata " ] [ " KeyId " ]
2018-10-05 20:55:47 +00:00
2019-08-27 20:42:36 +00:00
result = client . describe_key ( KeyId = key [ " KeyMetadata " ] [ " KeyId " ] )
2018-10-05 20:55:47 +00:00
assert result [ " KeyMetadata " ] [ " Enabled " ] == False
2019-08-27 20:42:36 +00:00
assert result [ " KeyMetadata " ] [ " KeyState " ] == " PendingDeletion "
assert " DeletionDate " in result [ " KeyMetadata " ]
2018-10-05 20:55:47 +00:00
@mock_kms
def test_schedule_key_deletion_custom ( ) :
2019-08-27 20:42:36 +00:00
client = boto3 . client ( " kms " , region_name = " us-east-1 " )
key = client . create_key ( Description = " schedule-key-deletion " )
if os . environ . get ( " TEST_SERVER_MODE " , " false " ) . lower ( ) == " false " :
2018-10-08 13:29:21 +00:00
with freeze_time ( " 2015-01-01 12:00:00 " ) :
2019-10-31 15:44:26 +00:00
response = client . schedule_key_deletion (
KeyId = key [ " KeyMetadata " ] [ " KeyId " ] , PendingWindowInDays = 7
)
2019-08-27 20:42:36 +00:00
assert response [ " KeyId " ] == key [ " KeyMetadata " ] [ " KeyId " ]
2019-10-31 15:44:26 +00:00
assert response [ " DeletionDate " ] == datetime (
2015 , 1 , 8 , 12 , 0 , tzinfo = tzutc ( )
)
2018-10-08 13:29:21 +00:00
else :
# Can't manipulate time in server mode
2019-10-31 15:44:26 +00:00
response = client . schedule_key_deletion (
KeyId = key [ " KeyMetadata " ] [ " KeyId " ] , PendingWindowInDays = 7
)
2019-08-27 20:42:36 +00:00
assert response [ " KeyId " ] == key [ " KeyMetadata " ] [ " KeyId " ]
2018-10-05 20:55:47 +00:00
2019-08-27 20:42:36 +00:00
result = client . describe_key ( KeyId = key [ " KeyMetadata " ] [ " KeyId " ] )
2018-10-05 20:55:47 +00:00
assert result [ " KeyMetadata " ] [ " Enabled " ] == False
2019-08-27 20:42:36 +00:00
assert result [ " KeyMetadata " ] [ " KeyState " ] == " PendingDeletion "
assert " DeletionDate " in result [ " KeyMetadata " ]
2018-10-05 20:55:47 +00:00
@mock_kms
def test_cancel_key_deletion ( ) :
2019-08-27 20:42:36 +00:00
client = boto3 . client ( " kms " , region_name = " us-east-1 " )
key = client . create_key ( Description = " cancel-key-deletion " )
client . schedule_key_deletion ( KeyId = key [ " KeyMetadata " ] [ " KeyId " ] )
response = client . cancel_key_deletion ( KeyId = key [ " KeyMetadata " ] [ " KeyId " ] )
assert response [ " KeyId " ] == key [ " KeyMetadata " ] [ " KeyId " ]
2018-10-05 20:55:47 +00:00
2019-08-27 20:42:36 +00:00
result = client . describe_key ( KeyId = key [ " KeyMetadata " ] [ " KeyId " ] )
2018-10-05 20:55:47 +00:00
assert result [ " KeyMetadata " ] [ " Enabled " ] == False
2019-08-27 20:42:36 +00:00
assert result [ " KeyMetadata " ] [ " KeyState " ] == " Disabled "
assert " DeletionDate " not in result [ " KeyMetadata " ]
2019-02-16 15:27:23 +00:00
@mock_kms
def test_update_key_description ( ) :
2019-08-27 20:42:36 +00:00
client = boto3 . client ( " kms " , region_name = " us-east-1 " )
key = client . create_key ( Description = " old_description " )
key_id = key [ " KeyMetadata " ] [ " KeyId " ]
2019-02-16 15:27:23 +00:00
2019-08-27 20:42:36 +00:00
result = client . update_key_description ( KeyId = key_id , Description = " new_description " )
assert " ResponseMetadata " in result
2019-02-16 15:27:23 +00:00
@mock_kms
def test_tag_resource ( ) :
2019-08-27 20:42:36 +00:00
client = boto3 . client ( " kms " , region_name = " us-east-1 " )
key = client . create_key ( Description = " cancel-key-deletion " )
response = client . schedule_key_deletion ( KeyId = key [ " KeyMetadata " ] [ " KeyId " ] )
2019-02-16 15:27:23 +00:00
2019-08-27 20:42:36 +00:00
keyid = response [ " KeyId " ]
2019-10-31 15:44:26 +00:00
response = client . tag_resource (
KeyId = keyid , Tags = [ { " TagKey " : " string " , " TagValue " : " string " } ]
)
2019-02-16 15:27:23 +00:00
# Shouldn't have any data, just header
assert len ( response . keys ( ) ) == 1
@mock_kms
def test_list_resource_tags ( ) :
2019-08-27 20:42:36 +00:00
client = boto3 . client ( " kms " , region_name = " us-east-1 " )
key = client . create_key ( Description = " cancel-key-deletion " )
response = client . schedule_key_deletion ( KeyId = key [ " KeyMetadata " ] [ " KeyId " ] )
2019-02-16 15:27:23 +00:00
2019-08-27 20:42:36 +00:00
keyid = response [ " KeyId " ]
2019-10-31 15:44:26 +00:00
response = client . tag_resource (
KeyId = keyid , Tags = [ { " TagKey " : " string " , " TagValue " : " string " } ]
)
2019-02-16 15:27:23 +00:00
response = client . list_resource_tags ( KeyId = keyid )
2019-08-27 20:42:36 +00:00
assert response [ " Tags " ] [ 0 ] [ " TagKey " ] == " string "
assert response [ " Tags " ] [ 0 ] [ " TagValue " ] == " string "
2019-04-26 19:52:24 +00:00
2019-10-31 15:44:26 +00:00
@parameterized (
(
2019-08-27 20:57:50 +00:00
( dict ( KeySpec = " AES_256 " ) , 32 ) ,
( dict ( KeySpec = " AES_128 " ) , 16 ) ,
( dict ( NumberOfBytes = 64 ) , 64 ) ,
2019-08-28 06:52:44 +00:00
( dict ( NumberOfBytes = 1 ) , 1 ) ,
( dict ( NumberOfBytes = 1024 ) , 1024 ) ,
2019-10-31 15:44:26 +00:00
)
)
2019-04-26 19:52:24 +00:00
@mock_kms
2019-08-27 20:57:50 +00:00
def test_generate_data_key_sizes ( kwargs , expected_key_length ) :
2019-08-27 20:42:36 +00:00
client = boto3 . client ( " kms " , region_name = " us-east-1 " )
key = client . create_key ( Description = " generate-data-key-size " )
2019-04-26 19:52:24 +00:00
2019-08-27 20:57:50 +00:00
response = client . generate_data_key ( KeyId = key [ " KeyMetadata " ] [ " KeyId " ] , * * kwargs )
2019-04-26 19:52:24 +00:00
2019-08-27 20:57:50 +00:00
assert len ( response [ " Plaintext " ] ) == expected_key_length
2019-04-26 19:52:24 +00:00
@mock_kms
def test_generate_data_key_decrypt ( ) :
2019-08-27 20:42:36 +00:00
client = boto3 . client ( " kms " , region_name = " us-east-1 " )
key = client . create_key ( Description = " generate-data-key-decrypt " )
2019-04-26 19:52:24 +00:00
2019-10-31 15:44:26 +00:00
resp1 = client . generate_data_key (
KeyId = key [ " KeyMetadata " ] [ " KeyId " ] , KeySpec = " AES_256 "
)
2019-08-27 20:42:36 +00:00
resp2 = client . decrypt ( CiphertextBlob = resp1 [ " CiphertextBlob " ] )
2019-04-26 19:52:24 +00:00
2019-08-27 20:42:36 +00:00
assert resp1 [ " Plaintext " ] == resp2 [ " Plaintext " ]
2019-04-26 19:52:24 +00:00
2019-10-31 15:44:26 +00:00
@parameterized (
(
2019-08-27 20:57:50 +00:00
( dict ( KeySpec = " AES_257 " ) , ) ,
( dict ( KeySpec = " AES_128 " , NumberOfBytes = 16 ) , ) ,
( dict ( NumberOfBytes = 2048 ) , ) ,
2019-08-28 06:52:44 +00:00
( dict ( NumberOfBytes = 0 ) , ) ,
2019-08-27 20:57:50 +00:00
( dict ( ) , ) ,
2019-10-31 15:44:26 +00:00
)
)
2019-04-26 19:52:24 +00:00
@mock_kms
2019-08-27 20:57:50 +00:00
def test_generate_data_key_invalid_size_params ( kwargs ) :
2019-08-27 20:42:36 +00:00
client = boto3 . client ( " kms " , region_name = " us-east-1 " )
key = client . create_key ( Description = " generate-data-key-size " )
2019-04-26 19:52:24 +00:00
2019-10-31 15:44:26 +00:00
with assert_raises (
( botocore . exceptions . ClientError , botocore . exceptions . ParamValidationError )
) as err :
2019-08-27 20:57:50 +00:00
client . generate_data_key ( KeyId = key [ " KeyMetadata " ] [ " KeyId " ] , * * kwargs )
2019-04-26 19:52:24 +00:00
2019-10-31 15:44:26 +00:00
@parameterized (
(
2019-08-28 06:52:44 +00:00
( " alias/DoesNotExist " , ) ,
( " arn:aws:kms:us-east-1:012345678912:alias/DoesNotExist " , ) ,
( " d25652e4-d2d2-49f7-929a-671ccda580c6 " , ) ,
2019-10-31 15:44:26 +00:00
(
" arn:aws:kms:us-east-1:012345678912:key/d25652e4-d2d2-49f7-929a-671ccda580c6 " ,
) ,
)
)
2019-04-26 19:52:24 +00:00
@mock_kms
2019-08-28 06:52:44 +00:00
def test_generate_data_key_invalid_key ( key_id ) :
2019-08-27 20:42:36 +00:00
client = boto3 . client ( " kms " , region_name = " us-east-1 " )
2019-04-26 19:52:24 +00:00
with assert_raises ( client . exceptions . NotFoundException ) :
2019-08-28 06:52:44 +00:00
client . generate_data_key ( KeyId = key_id , KeySpec = " AES_256 " )
2019-04-26 19:52:24 +00:00
2019-08-28 06:52:44 +00:00
2019-10-31 15:44:26 +00:00
@parameterized (
(
2019-08-28 06:52:44 +00:00
( " alias/DoesExist " , False ) ,
( " arn:aws:kms:us-east-1:012345678912:alias/DoesExist " , False ) ,
( " " , True ) ,
( " arn:aws:kms:us-east-1:012345678912:key/ " , True ) ,
2019-10-31 15:44:26 +00:00
)
)
2019-08-28 06:52:44 +00:00
@mock_kms
def test_generate_data_key_all_valid_key_ids ( prefix , append_key_id ) :
client = boto3 . client ( " kms " , region_name = " us-east-1 " )
key = client . create_key ( )
key_id = key [ " KeyMetadata " ] [ " KeyId " ]
client . create_alias ( AliasName = " alias/DoesExist " , TargetKeyId = key_id )
target_id = prefix
if append_key_id :
target_id + = key_id
client . generate_data_key ( KeyId = key_id , NumberOfBytes = 32 )
2019-04-26 19:52:24 +00:00
@mock_kms
def test_generate_data_key_without_plaintext_decrypt ( ) :
2019-08-27 20:42:36 +00:00
client = boto3 . client ( " kms " , region_name = " us-east-1 " )
key = client . create_key ( Description = " generate-data-key-decrypt " )
2019-04-26 19:52:24 +00:00
2019-10-31 15:44:26 +00:00
resp1 = client . generate_data_key_without_plaintext (
KeyId = key [ " KeyMetadata " ] [ " KeyId " ] , KeySpec = " AES_256 "
)
2019-04-26 19:52:24 +00:00
2019-08-27 20:42:36 +00:00
assert " Plaintext " not in resp1
2019-04-26 19:52:24 +00:00
2019-08-28 03:24:57 +00:00
@parameterized ( 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 (
2019-10-31 15:44:26 +00:00
KeyId = key_1_id , Plaintext = plaintext , EncryptionContext = { " encryption " : " context " }
2019-08-28 03:24:57 +00:00
)
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 assert_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 " } ,
)
2019-09-13 21:08:26 +00:00
decrypt_response_1 [ " Plaintext " ] . should . equal ( _get_encoded_value ( plaintext ) )
2019-08-28 03:24:57 +00:00
decrypt_response_1 [ " KeyId " ] . should . equal ( key_1_arn )
decrypt_response_2 = client . decrypt (
CiphertextBlob = re_encrypt_response [ " CiphertextBlob " ] ,
EncryptionContext = { " another " : " context " } ,
)
2019-09-13 21:08:26 +00:00
decrypt_response_2 [ " Plaintext " ] . should . equal ( _get_encoded_value ( plaintext ) )
2019-08-28 03:24:57 +00:00
decrypt_response_2 [ " KeyId " ] . should . equal ( key_2_arn )
decrypt_response_1 [ " Plaintext " ] . should . equal ( decrypt_response_2 [ " Plaintext " ] )
2019-08-28 03:49:47 +00:00
@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 " ]
2019-10-31 15:44:26 +00:00
encrypt_response = client . encrypt ( KeyId = key_id , Plaintext = b " some plaintext " )
2019-08-28 03:49:47 +00:00
with assert_raises ( client . exceptions . NotFoundException ) :
client . re_encrypt (
CiphertextBlob = encrypt_response [ " CiphertextBlob " ] ,
2019-08-28 06:52:44 +00:00
DestinationKeyId = " alias/DoesNotExist " ,
2019-08-28 03:49:47 +00:00
)
2019-08-28 06:52:44 +00:00
@parameterized ( ( ( 12 , ) , ( 44 , ) , ( 91 , ) , ( 1 , ) , ( 1024 , ) ) )
2019-08-28 03:55:58 +00:00
@mock_kms
def test_generate_random ( number_of_bytes ) :
client = boto3 . client ( " kms " , region_name = " us-west-2 " )
response = client . generate_random ( NumberOfBytes = number_of_bytes )
response [ " Plaintext " ] . should . be . a ( bytes )
len ( response [ " Plaintext " ] ) . should . equal ( number_of_bytes )
2019-10-31 15:44:26 +00:00
@parameterized (
(
2019-09-13 20:19:11 +00:00
( 2048 , botocore . exceptions . ClientError ) ,
( 1025 , botocore . exceptions . ClientError ) ,
( 0 , botocore . exceptions . ParamValidationError ) ,
( - 1 , botocore . exceptions . ParamValidationError ) ,
2019-10-31 15:44:26 +00:00
( - 1024 , botocore . exceptions . ParamValidationError ) ,
)
)
2019-09-13 20:19:11 +00:00
@mock_kms
def test_generate_random_invalid_number_of_bytes ( number_of_bytes , error_type ) :
client = boto3 . client ( " kms " , region_name = " us-west-2 " )
with assert_raises ( error_type ) :
client . generate_random ( NumberOfBytes = number_of_bytes )
2019-04-26 19:52:24 +00:00
@mock_kms
def test_enable_key_rotation_key_not_found ( ) :
2019-08-27 20:42:36 +00:00
client = boto3 . client ( " kms " , region_name = " us-east-1 " )
2019-04-26 19:52:24 +00:00
with assert_raises ( client . exceptions . NotFoundException ) :
2019-08-27 20:42:36 +00:00
client . enable_key_rotation ( KeyId = " 12366f9b-1230-123d-123e-123e6ae60c02 " )
2019-04-26 19:52:24 +00:00
@mock_kms
def test_disable_key_rotation_key_not_found ( ) :
2019-08-27 20:42:36 +00:00
client = boto3 . client ( " kms " , region_name = " us-east-1 " )
2019-04-26 19:52:24 +00:00
with assert_raises ( client . exceptions . NotFoundException ) :
2019-08-27 20:42:36 +00:00
client . disable_key_rotation ( KeyId = " 12366f9b-1230-123d-123e-123e6ae60c02 " )
2019-04-26 19:52:24 +00:00
@mock_kms
def test_enable_key_key_not_found ( ) :
2019-08-27 20:42:36 +00:00
client = boto3 . client ( " kms " , region_name = " us-east-1 " )
2019-04-26 19:52:24 +00:00
with assert_raises ( client . exceptions . NotFoundException ) :
2019-08-27 20:42:36 +00:00
client . enable_key ( KeyId = " 12366f9b-1230-123d-123e-123e6ae60c02 " )
2019-04-26 19:52:24 +00:00
@mock_kms
def test_disable_key_key_not_found ( ) :
2019-08-27 20:42:36 +00:00
client = boto3 . client ( " kms " , region_name = " us-east-1 " )
2019-04-26 19:52:24 +00:00
with assert_raises ( client . exceptions . NotFoundException ) :
2019-08-27 20:42:36 +00:00
client . disable_key ( KeyId = " 12366f9b-1230-123d-123e-123e6ae60c02 " )
2019-04-26 19:52:24 +00:00
@mock_kms
def test_cancel_key_deletion_key_not_found ( ) :
2019-08-27 20:42:36 +00:00
client = boto3 . client ( " kms " , region_name = " us-east-1 " )
2019-04-26 19:52:24 +00:00
with assert_raises ( client . exceptions . NotFoundException ) :
2019-08-27 20:42:36 +00:00
client . cancel_key_deletion ( KeyId = " 12366f9b-1230-123d-123e-123e6ae60c02 " )
2019-04-26 19:52:24 +00:00
@mock_kms
def test_schedule_key_deletion_key_not_found ( ) :
2019-08-27 20:42:36 +00:00
client = boto3 . client ( " kms " , region_name = " us-east-1 " )
2019-04-26 19:52:24 +00:00
with assert_raises ( client . exceptions . NotFoundException ) :
2019-08-27 20:42:36 +00:00
client . schedule_key_deletion ( KeyId = " 12366f9b-1230-123d-123e-123e6ae60c02 " )
2019-04-26 19:52:24 +00:00
@mock_kms
def test_get_key_rotation_status_key_not_found ( ) :
2019-08-27 20:42:36 +00:00
client = boto3 . client ( " kms " , region_name = " us-east-1 " )
2019-04-26 19:52:24 +00:00
with assert_raises ( client . exceptions . NotFoundException ) :
2019-08-27 20:42:36 +00:00
client . get_key_rotation_status ( KeyId = " 12366f9b-1230-123d-123e-123e6ae60c02 " )
2019-04-26 19:52:24 +00:00
@mock_kms
def test_get_key_policy_key_not_found ( ) :
2019-08-27 20:42:36 +00:00
client = boto3 . client ( " kms " , region_name = " us-east-1 " )
2019-04-26 19:52:24 +00:00
with assert_raises ( client . exceptions . NotFoundException ) :
2019-10-31 15:44:26 +00:00
client . get_key_policy (
KeyId = " 12366f9b-1230-123d-123e-123e6ae60c02 " , PolicyName = " default "
)
2019-04-26 19:52:24 +00:00
@mock_kms
def test_list_key_policies_key_not_found ( ) :
2019-08-27 20:42:36 +00:00
client = boto3 . client ( " kms " , region_name = " us-east-1 " )
2019-04-26 19:52:24 +00:00
with assert_raises ( client . exceptions . NotFoundException ) :
2019-08-27 20:42:36 +00:00
client . list_key_policies ( KeyId = " 12366f9b-1230-123d-123e-123e6ae60c02 " )
2019-04-26 19:52:24 +00:00
@mock_kms
def test_put_key_policy_key_not_found ( ) :
2019-08-27 20:42:36 +00:00
client = boto3 . client ( " kms " , region_name = " us-east-1 " )
2019-04-26 19:52:24 +00:00
with assert_raises ( client . exceptions . NotFoundException ) :
2019-10-31 15:44:26 +00:00
client . put_key_policy (
KeyId = " 00000000-0000-0000-0000-000000000000 " ,
PolicyName = " default " ,
Policy = " new policy " ,
)