| 
									
										
										
										
											2021-10-18 19:44:29 +00:00
										 |  |  | import sure  # noqa # pylint: disable=unused-import | 
					
						
							| 
									
										
										
										
											2020-10-06 07:54:49 +02:00
										 |  |  | import pytest | 
					
						
							| 
									
										
										
										
											2019-08-26 23:24:31 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | from moto.kms.exceptions import ( | 
					
						
							|  |  |  |     AccessDeniedException, | 
					
						
							|  |  |  |     InvalidCiphertextException, | 
					
						
							|  |  |  |     NotFoundException, | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  | ) | 
					
						
							| 
									
										
										
										
											2019-08-26 23:24:31 -07:00
										 |  |  | from moto.kms.models import Key | 
					
						
							|  |  |  | from moto.kms.utils import ( | 
					
						
							|  |  |  |     _deserialize_ciphertext_blob, | 
					
						
							| 
									
										
										
										
											2019-08-26 23:29:30 -07:00
										 |  |  |     _serialize_ciphertext_blob, | 
					
						
							| 
									
										
										
										
											2019-08-26 23:24:31 -07:00
										 |  |  |     _serialize_encryption_context, | 
					
						
							| 
									
										
										
										
											2019-08-26 23:29:30 -07:00
										 |  |  |     generate_data_key, | 
					
						
							|  |  |  |     generate_master_key, | 
					
						
							|  |  |  |     MASTER_KEY_LEN, | 
					
						
							| 
									
										
										
										
											2019-08-26 23:24:31 -07:00
										 |  |  |     encrypt, | 
					
						
							|  |  |  |     decrypt, | 
					
						
							|  |  |  |     Ciphertext, | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-11 15:54:01 +00:00
										 |  |  | ENCRYPTION_CONTEXT_VECTORS = [ | 
					
						
							| 
									
										
										
										
											2019-08-26 23:24:31 -07:00
										 |  |  |     ( | 
					
						
							|  |  |  |         {"this": "is", "an": "encryption", "context": "example"}, | 
					
						
							|  |  |  |         b"an" b"encryption" b"context" b"example" b"this" b"is", | 
					
						
							|  |  |  |     ), | 
					
						
							|  |  |  |     ( | 
					
						
							|  |  |  |         {"a_this": "one", "b_is": "actually", "c_in": "order"}, | 
					
						
							|  |  |  |         b"a_this" b"one" b"b_is" b"actually" b"c_in" b"order", | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     ), | 
					
						
							| 
									
										
										
										
											2020-11-11 15:54:01 +00:00
										 |  |  | ] | 
					
						
							|  |  |  | CIPHERTEXT_BLOB_VECTORS = [ | 
					
						
							| 
									
										
										
										
											2019-08-26 23:24:31 -07:00
										 |  |  |     ( | 
					
						
							|  |  |  |         Ciphertext( | 
					
						
							|  |  |  |             key_id="d25652e4-d2d2-49f7-929a-671ccda580c6", | 
					
						
							|  |  |  |             iv=b"123456789012", | 
					
						
							|  |  |  |             ciphertext=b"some ciphertext", | 
					
						
							|  |  |  |             tag=b"1234567890123456", | 
					
						
							|  |  |  |         ), | 
					
						
							|  |  |  |         b"d25652e4-d2d2-49f7-929a-671ccda580c6" | 
					
						
							|  |  |  |         b"123456789012" | 
					
						
							|  |  |  |         b"1234567890123456" | 
					
						
							|  |  |  |         b"some ciphertext", | 
					
						
							|  |  |  |     ), | 
					
						
							|  |  |  |     ( | 
					
						
							|  |  |  |         Ciphertext( | 
					
						
							|  |  |  |             key_id="d25652e4-d2d2-49f7-929a-671ccda580c6", | 
					
						
							|  |  |  |             iv=b"123456789012", | 
					
						
							|  |  |  |             ciphertext=b"some ciphertext that is much longer now", | 
					
						
							|  |  |  |             tag=b"1234567890123456", | 
					
						
							|  |  |  |         ), | 
					
						
							|  |  |  |         b"d25652e4-d2d2-49f7-929a-671ccda580c6" | 
					
						
							|  |  |  |         b"123456789012" | 
					
						
							|  |  |  |         b"1234567890123456" | 
					
						
							|  |  |  |         b"some ciphertext that is much longer now", | 
					
						
							|  |  |  |     ), | 
					
						
							| 
									
										
										
										
											2020-11-11 15:54:01 +00:00
										 |  |  | ] | 
					
						
							| 
									
										
										
										
											2019-08-26 23:24:31 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-26 23:29:30 -07:00
										 |  |  | def test_generate_data_key(): | 
					
						
							|  |  |  |     test = generate_data_key(123) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     test.should.be.a(bytes) | 
					
						
							|  |  |  |     len(test).should.equal(123) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def test_generate_master_key(): | 
					
						
							|  |  |  |     test = generate_master_key() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     test.should.be.a(bytes) | 
					
						
							|  |  |  |     len(test).should.equal(MASTER_KEY_LEN) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-11 15:54:01 +00:00
										 |  |  | @pytest.mark.parametrize("raw,serialized", ENCRYPTION_CONTEXT_VECTORS) | 
					
						
							| 
									
										
										
										
											2019-08-26 23:24:31 -07:00
										 |  |  | def test_serialize_encryption_context(raw, serialized): | 
					
						
							|  |  |  |     test = _serialize_encryption_context(raw) | 
					
						
							|  |  |  |     test.should.equal(serialized) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-11 15:54:01 +00:00
										 |  |  | @pytest.mark.parametrize("raw,_serialized", CIPHERTEXT_BLOB_VECTORS) | 
					
						
							| 
									
										
										
										
											2019-08-26 23:24:31 -07:00
										 |  |  | def test_cycle_ciphertext_blob(raw, _serialized): | 
					
						
							|  |  |  |     test_serialized = _serialize_ciphertext_blob(raw) | 
					
						
							|  |  |  |     test_deserialized = _deserialize_ciphertext_blob(test_serialized) | 
					
						
							|  |  |  |     test_deserialized.should.equal(raw) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-11 15:54:01 +00:00
										 |  |  | @pytest.mark.parametrize("raw,serialized", CIPHERTEXT_BLOB_VECTORS) | 
					
						
							| 
									
										
										
										
											2019-08-26 23:24:31 -07:00
										 |  |  | def test_serialize_ciphertext_blob(raw, serialized): | 
					
						
							|  |  |  |     test = _serialize_ciphertext_blob(raw) | 
					
						
							|  |  |  |     test.should.equal(serialized) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-11 15:54:01 +00:00
										 |  |  | @pytest.mark.parametrize("raw,serialized", CIPHERTEXT_BLOB_VECTORS) | 
					
						
							| 
									
										
										
										
											2019-08-26 23:24:31 -07:00
										 |  |  | def test_deserialize_ciphertext_blob(raw, serialized): | 
					
						
							|  |  |  |     test = _deserialize_ciphertext_blob(serialized) | 
					
						
							|  |  |  |     test.should.equal(raw) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-11 15:55:37 +00:00
										 |  |  | @pytest.mark.parametrize( | 
					
						
							|  |  |  |     "encryption_context", [ec[0] for ec in ENCRYPTION_CONTEXT_VECTORS] | 
					
						
							|  |  |  | ) | 
					
						
							| 
									
										
										
										
											2019-08-26 23:24:31 -07:00
										 |  |  | def test_encrypt_decrypt_cycle(encryption_context): | 
					
						
							|  |  |  |     plaintext = b"some secret plaintext" | 
					
						
							| 
									
										
										
										
											2022-08-13 09:49:43 +00:00
										 |  |  |     master_key = Key("nop", "nop", "nop", "nop", "nop", "nop") | 
					
						
							| 
									
										
										
										
											2019-08-26 23:24:31 -07:00
										 |  |  |     master_key_map = {master_key.id: master_key} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ciphertext_blob = encrypt( | 
					
						
							|  |  |  |         master_keys=master_key_map, | 
					
						
							|  |  |  |         key_id=master_key.id, | 
					
						
							|  |  |  |         plaintext=plaintext, | 
					
						
							|  |  |  |         encryption_context=encryption_context, | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     ciphertext_blob.should_not.equal(plaintext) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     decrypted, decrypting_key_id = decrypt( | 
					
						
							|  |  |  |         master_keys=master_key_map, | 
					
						
							|  |  |  |         ciphertext_blob=ciphertext_blob, | 
					
						
							|  |  |  |         encryption_context=encryption_context, | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     decrypted.should.equal(plaintext) | 
					
						
							|  |  |  |     decrypting_key_id.should.equal(master_key.id) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def test_encrypt_unknown_key_id(): | 
					
						
							| 
									
										
										
										
											2020-10-06 07:54:49 +02:00
										 |  |  |     with pytest.raises(NotFoundException): | 
					
						
							| 
									
										
										
										
											2019-08-27 13:42:36 -07:00
										 |  |  |         encrypt( | 
					
						
							|  |  |  |             master_keys={}, | 
					
						
							|  |  |  |             key_id="anything", | 
					
						
							|  |  |  |             plaintext=b"secrets", | 
					
						
							|  |  |  |             encryption_context={}, | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2019-08-26 23:24:31 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def test_decrypt_invalid_ciphertext_format(): | 
					
						
							| 
									
										
										
										
											2022-08-13 09:49:43 +00:00
										 |  |  |     master_key = Key("nop", "nop", "nop", "nop", "nop", "nop") | 
					
						
							| 
									
										
										
										
											2019-08-26 23:24:31 -07:00
										 |  |  |     master_key_map = {master_key.id: master_key} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 07:54:49 +02:00
										 |  |  |     with pytest.raises(InvalidCiphertextException): | 
					
						
							| 
									
										
										
										
											2019-08-27 13:42:36 -07:00
										 |  |  |         decrypt(master_keys=master_key_map, ciphertext_blob=b"", encryption_context={}) | 
					
						
							| 
									
										
										
										
											2019-08-26 23:24:31 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def test_decrypt_unknwown_key_id(): | 
					
						
							|  |  |  |     ciphertext_blob = ( | 
					
						
							|  |  |  |         b"d25652e4-d2d2-49f7-929a-671ccda580c6" | 
					
						
							|  |  |  |         b"123456789012" | 
					
						
							|  |  |  |         b"1234567890123456" | 
					
						
							|  |  |  |         b"some ciphertext" | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     ) | 
					
						
							| 
									
										
										
										
											2019-08-26 23:24:31 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 07:54:49 +02:00
										 |  |  |     with pytest.raises(AccessDeniedException): | 
					
						
							| 
									
										
										
										
											2019-08-27 13:42:36 -07:00
										 |  |  |         decrypt(master_keys={}, ciphertext_blob=ciphertext_blob, encryption_context={}) | 
					
						
							| 
									
										
										
										
											2019-08-26 23:24:31 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def test_decrypt_invalid_ciphertext(): | 
					
						
							| 
									
										
										
										
											2022-08-13 09:49:43 +00:00
										 |  |  |     master_key = Key("nop", "nop", "nop", "nop", "nop", "nop") | 
					
						
							| 
									
										
										
										
											2019-08-26 23:24:31 -07:00
										 |  |  |     master_key_map = {master_key.id: master_key} | 
					
						
							|  |  |  |     ciphertext_blob = ( | 
					
						
							|  |  |  |         master_key.id.encode("utf-8") + b"123456789012" | 
					
						
							|  |  |  |         b"1234567890123456" | 
					
						
							|  |  |  |         b"some ciphertext" | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     ) | 
					
						
							| 
									
										
										
										
											2019-08-26 23:24:31 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 07:54:49 +02:00
										 |  |  |     with pytest.raises(InvalidCiphertextException): | 
					
						
							| 
									
										
										
										
											2019-08-27 13:42:36 -07:00
										 |  |  |         decrypt( | 
					
						
							|  |  |  |             master_keys=master_key_map, | 
					
						
							|  |  |  |             ciphertext_blob=ciphertext_blob, | 
					
						
							|  |  |  |             encryption_context={}, | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2019-08-26 23:24:31 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def test_decrypt_invalid_encryption_context(): | 
					
						
							|  |  |  |     plaintext = b"some secret plaintext" | 
					
						
							| 
									
										
										
										
											2022-08-13 09:49:43 +00:00
										 |  |  |     master_key = Key("nop", "nop", "nop", "nop", "nop", "nop") | 
					
						
							| 
									
										
										
										
											2019-08-26 23:24:31 -07:00
										 |  |  |     master_key_map = {master_key.id: master_key} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ciphertext_blob = encrypt( | 
					
						
							|  |  |  |         master_keys=master_key_map, | 
					
						
							|  |  |  |         key_id=master_key.id, | 
					
						
							|  |  |  |         plaintext=plaintext, | 
					
						
							|  |  |  |         encryption_context={"some": "encryption", "context": "here"}, | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 07:54:49 +02:00
										 |  |  |     with pytest.raises(InvalidCiphertextException): | 
					
						
							| 
									
										
										
										
											2019-08-27 13:42:36 -07:00
										 |  |  |         decrypt( | 
					
						
							|  |  |  |             master_keys=master_key_map, | 
					
						
							|  |  |  |             ciphertext_blob=ciphertext_blob, | 
					
						
							|  |  |  |             encryption_context={}, | 
					
						
							|  |  |  |         ) |