17
17
from cryptography .hazmat .primitives import serialization
18
18
from cryptography .hazmat .primitives .asymmetric import rsa
19
19
20
+ from aws_encryption_sdk .exceptions import EncryptKeyError
20
21
from aws_encryption_sdk .identifiers import (
21
22
Algorithm ,
22
23
EncryptionKeyType ,
42
43
_BACKEND = default_backend ()
43
44
44
45
_PRIVATE_WRAPPING_KEY = rsa .generate_private_key (public_exponent = _PUBLIC_EXPONENT , key_size = _KEY_SIZE , backend = _BACKEND )
46
+ _PUBLIC_WRAPPING_KEY = _PRIVATE_WRAPPING_KEY .public_key ()
45
47
46
- _PRIVATE_WRAPPING_KEY_PEM = (
47
- b"-----BEGIN RSA PRIVATE KEY-----\n "
48
- b"MIIEowIBAAKCAQEAo8uCyhiO4JUGZV+rtNq5DBA9Lm4xkw5kTA3v6EPybs8bVXL2\n "
49
- b"ZE6jkbo+xT4Jg/bKzUpnp1fE+T1ruGPtsPdoEmhY/P64LDNIs3sRq5U4QV9IETU1\n "
50
- b"vIcbNNkgGhRjV8J87YNY0tV0H7tuWuZRpqnS+gjV6V9lUMkbvjMCc5IBqQc3heut\n "
51
- b"/+fH4JwpGlGxOVXI8QAapnSy1XpCr3+PT29kydVJnIMuAoFrurojRpOQbOuVvhtA\n "
52
- b"gARhst1Ji4nfROGYkj6eZhvkz2Bkud4/+3lGvVU5LO1vD8oY7WoGtpin3h50VcWe\n "
53
- b"aBT4kejx4s9/G9C4R24lTH09J9HO2UUsuCqZYQIDAQABAoIBAQCfC90bCk+qaWqF\n "
54
- b"gymC+qOWwCn4bM28gswHQb1D5r6AtKBRD8mKywVvWs7azguFVV3Fi8sspkBA2FBC\n "
55
- b"At5p6ULoJOTL/TauzLl6djVJTCMM701WUDm2r+ZOIctXJ5bzP4n5Q4I7b0NMEL7u\n "
56
- b"ixib4elYGr5D1vrVQAKtZHCr8gmkqyx8Mz7wkJepzBP9EeVzETCHsmiQDd5WYlO1\n "
57
- b"C2IQYgw6MJzgM4entJ0V/GPytkodblGY95ORVK7ZhyNtda+r5BZ6/jeMW+hA3VoK\n "
58
- b"tHSWjHt06ueVCCieZIATmYzBNt+zEz5UA2l7ksg3eWfVORJQS7a6Ef4VvbJLM9Ca\n "
59
- b"m1kdsjelAoGBANKgvRf39i3bSuvm5VoyJuqinSb/23IH3Zo7XOZ5G164vh49E9Cq\n "
60
- b"dOXXVxox74ppj/kbGUoOk+AvaB48zzfzNvac0a7lRHExykPH2kVrI/NwH/1OcT/x\n "
61
- b"2e2DnFYocXcb4gbdZQ+m6X3zkxOYcONRzPVW1uMrFTWHcJveMUm4PGx7AoGBAMcU\n "
62
- b"IRvrT6ye5se0s27gHnPweV+3xjsNtXZcK82N7duXyHmNjxrwOAv0SOhUmTkRXArM\n "
63
- b"6aN5D8vyZBSWma2TgUKwpQYFTI+4Sp7sdkkyojGAEixJ+c5TZJNxZFrUe0FwAoic\n "
64
- b"c2kb7ntaiEj5G+qHvykJJro5hy6uLnjiMVbAiJDTAoGAKb67241EmHAXGEwp9sdr\n "
65
- b"2SMjnIAnQSF39UKAthkYqJxa6elXDQtLoeYdGE7/V+J2K3wIdhoPiuY6b4vD0iX9\n "
66
- b"JcGM+WntN7YTjX2FsC588JmvbWfnoDHR7HYiPR1E58N597xXdFOzgUgORVr4PMWQ\n "
67
- b"pqtwaZO3X2WZlvrhr+e46hMCgYBfdIdrm6jYXFjL6RkgUNZJQUTxYGzsY+ZemlNm\n "
68
- b"fGdQo7a8kePMRuKY2MkcnXPaqTg49YgRmjq4z8CtHokRcWjJUWnPOTs8rmEZUshk\n "
69
- b"0KJ0mbQdCFt/Uv0mtXgpFTkEZ3DPkDTGcV4oR4CRfOCl0/EU/A5VvL/U4i/mRo7h\n "
70
- b"ye+xgQKBgD58b+9z+PR5LAJm1tZHIwb4tnyczP28PzwknxFd2qylR4ZNgvAUqGtU\n "
71
- b"xvpUDpzMioz6zUH9YV43YNtt+5Xnzkqj+u9Mr27/H2v9XPwORGfwQ5XPwRJz/2oC\n "
72
- b"EnPmP1SZoY9lXKUpQXHXSpDZ2rE2Klt3RHMUMHt8Zpy36E8Vwx8o\n "
73
- b"-----END RSA PRIVATE KEY-----\n "
74
- )
75
-
76
- _RAW_RSA_PRIVATE_KEY_PEM_ENCODED_WITHOUT_PASSWORD = rsa .generate_private_key (
77
- public_exponent = _PUBLIC_EXPONENT , key_size = _KEY_SIZE , backend = _BACKEND
78
- ).private_bytes (
48
+ _PRIVATE_WRAPPING_KEY_PEM = _PRIVATE_WRAPPING_KEY .private_bytes (
79
49
encoding = serialization .Encoding .PEM ,
80
50
format = serialization .PrivateFormat .TraditionalOpenSSL ,
81
51
encryption_algorithm = serialization .NoEncryption (),
82
52
)
53
+ _PUBLIC_WRAPPING_KEY_PEM = _PUBLIC_WRAPPING_KEY .public_bytes (
54
+ encoding = serialization .Encoding .PEM , format = serialization .PublicFormat .SubjectPublicKeyInfo
55
+ )
83
56
84
- _RAW_RSA_PRIVATE_KEY_PEM_ENCODED_WITH_PASSWORD = rsa . generate_private_key (
85
- public_exponent = _PUBLIC_EXPONENT , key_size = _KEY_SIZE , backend = _BACKEND
86
- ) .private_bytes (
57
+ _RAW_RSA_PRIVATE_KEY_PEM_ENCODED_WITHOUT_PASSWORD = _PRIVATE_WRAPPING_KEY_PEM
58
+
59
+ _RAW_RSA_PRIVATE_KEY_PEM_ENCODED_WITH_PASSWORD = _PRIVATE_WRAPPING_KEY .private_bytes (
87
60
encoding = serialization .Encoding .PEM ,
88
61
format = serialization .PrivateFormat .PKCS8 ,
89
62
encryption_algorithm = serialization .BestAvailableEncryption (b"mypassword" ),
90
63
)
91
64
92
- _RAW_RSA_PUBLIC_KEY_PEM_ENCODED = (
93
- rsa .generate_private_key (public_exponent = _PUBLIC_EXPONENT , key_size = _KEY_SIZE , backend = _BACKEND )
94
- .public_key ()
95
- .public_bytes (encoding = serialization .Encoding .PEM , format = serialization .PublicFormat .SubjectPublicKeyInfo )
96
- )
65
+ _RAW_RSA_PUBLIC_KEY_PEM_ENCODED = _PUBLIC_WRAPPING_KEY_PEM
97
66
98
- _RAW_RSA_PRIVATE_KEY_DER_ENCODED_WITHOUT_PASSWORD = rsa .generate_private_key (
99
- public_exponent = _PUBLIC_EXPONENT , key_size = _KEY_SIZE , backend = _BACKEND
100
- ).private_bytes (
67
+ _RAW_RSA_PRIVATE_KEY_DER_ENCODED_WITHOUT_PASSWORD = _PRIVATE_WRAPPING_KEY .private_bytes (
101
68
encoding = serialization .Encoding .DER ,
102
69
format = serialization .PrivateFormat .TraditionalOpenSSL ,
103
70
encryption_algorithm = serialization .NoEncryption (),
104
71
)
105
72
106
- _RAW_RSA_PRIVATE_KEY_DER_ENCODED_WITH_PASSWORD = rsa .generate_private_key (
107
- public_exponent = _PUBLIC_EXPONENT , key_size = _KEY_SIZE , backend = _BACKEND
108
- ).private_bytes (
73
+ _RAW_RSA_PRIVATE_KEY_DER_ENCODED_WITH_PASSWORD = _PRIVATE_WRAPPING_KEY .private_bytes (
109
74
encoding = serialization .Encoding .DER ,
110
75
format = serialization .PrivateFormat .PKCS8 ,
111
76
encryption_algorithm = serialization .BestAvailableEncryption (b"mypassword" ),
112
77
)
113
78
114
- _RAW_RSA_PUBLIC_KEY_DER_ENCODED = (
115
- rsa .generate_private_key (public_exponent = _PUBLIC_EXPONENT , key_size = _KEY_SIZE , backend = _BACKEND )
116
- .public_key ()
117
- .public_bytes (encoding = serialization .Encoding .DER , format = serialization .PublicFormat .SubjectPublicKeyInfo )
79
+ _RAW_RSA_PUBLIC_KEY_DER_ENCODED = _PUBLIC_WRAPPING_KEY .public_bytes (
80
+ encoding = serialization .Encoding .DER , format = serialization .PublicFormat .SubjectPublicKeyInfo
118
81
)
119
82
120
83
@@ -148,18 +111,21 @@ def sample_raw_rsa_keyring_using_different_wrapping_algorithm():
148
111
key_name = _KEY_ID ,
149
112
wrapping_algorithm = alg ,
150
113
private_wrapping_key = _PRIVATE_WRAPPING_KEY ,
114
+ public_wrapping_key = _PUBLIC_WRAPPING_KEY ,
151
115
)
152
116
pem_and_der_encoded_raw_rsa_keyring = [
153
117
RawRSAKeyring .from_pem_encoding (
154
118
key_namespace = _PROVIDER_ID ,
155
119
key_name = _KEY_ID ,
156
120
private_encoded_key = _RAW_RSA_PRIVATE_KEY_PEM_ENCODED_WITHOUT_PASSWORD ,
121
+ public_encoded_key = _RAW_RSA_PUBLIC_KEY_PEM_ENCODED ,
157
122
wrapping_algorithm = _WRAPPING_ALGORITHM ,
158
123
),
159
124
RawRSAKeyring .from_pem_encoding (
160
125
key_namespace = _PROVIDER_ID ,
161
126
key_name = _KEY_ID ,
162
127
private_encoded_key = _RAW_RSA_PRIVATE_KEY_PEM_ENCODED_WITH_PASSWORD ,
128
+ public_encoded_key = _RAW_RSA_PUBLIC_KEY_PEM_ENCODED ,
163
129
password = b"mypassword" ,
164
130
wrapping_algorithm = _WRAPPING_ALGORITHM ,
165
131
),
@@ -173,20 +139,21 @@ def sample_raw_rsa_keyring_using_different_wrapping_algorithm():
173
139
key_namespace = _PROVIDER_ID ,
174
140
key_name = _KEY_ID ,
175
141
private_encoded_key = _RAW_RSA_PRIVATE_KEY_DER_ENCODED_WITHOUT_PASSWORD ,
142
+ public_encoded_key = _RAW_RSA_PUBLIC_KEY_DER_ENCODED ,
176
143
wrapping_algorithm = _WRAPPING_ALGORITHM ,
177
144
),
178
145
RawRSAKeyring .from_der_encoding (
179
146
key_namespace = _PROVIDER_ID ,
180
147
key_name = _KEY_ID ,
181
148
private_encoded_key = _RAW_RSA_PRIVATE_KEY_DER_ENCODED_WITH_PASSWORD ,
149
+ public_encoded_key = _RAW_RSA_PUBLIC_KEY_DER_ENCODED ,
182
150
password = b"mypassword" ,
183
151
wrapping_algorithm = _WRAPPING_ALGORITHM ,
184
152
),
185
153
RawRSAKeyring .from_der_encoding (
186
154
key_namespace = _PROVIDER_ID ,
187
155
key_name = _KEY_ID ,
188
156
public_encoded_key = _RAW_RSA_PUBLIC_KEY_DER_ENCODED ,
189
- password = b"mypassword" ,
190
157
wrapping_algorithm = _WRAPPING_ALGORITHM ,
191
158
),
192
159
]
@@ -227,6 +194,7 @@ def test_raw_master_key_decrypts_what_raw_keyring_encrypts(encryption_materials_
227
194
key_name = _KEY_ID ,
228
195
wrapping_algorithm = _WRAPPING_ALGORITHM ,
229
196
private_encoded_key = _PRIVATE_WRAPPING_KEY_PEM ,
197
+ public_encoded_key = _PUBLIC_WRAPPING_KEY_PEM ,
230
198
)
231
199
232
200
# Creating an instance of a raw master key
@@ -272,6 +240,7 @@ def test_raw_keyring_decrypts_what_raw_master_key_encrypts(encryption_materials_
272
240
key_name = _KEY_ID ,
273
241
wrapping_algorithm = _WRAPPING_ALGORITHM ,
274
242
private_encoded_key = _PRIVATE_WRAPPING_KEY_PEM ,
243
+ public_encoded_key = _PUBLIC_WRAPPING_KEY_PEM ,
275
244
)
276
245
277
246
raw_mkp_generated_data_key = test_raw_master_key .generate_data_key (
@@ -295,3 +264,110 @@ def test_raw_keyring_decrypts_what_raw_master_key_encrypts(encryption_materials_
295
264
)
296
265
297
266
assert raw_mkp_generated_data_key .data_key == decryption_materials .data_encryption_key .data_key
267
+
268
+
269
+ def test_public_key_only_can_encrypt ():
270
+ test_keyring = RawRSAKeyring (
271
+ key_namespace = _PROVIDER_ID ,
272
+ key_name = _KEY_ID ,
273
+ wrapping_algorithm = _WRAPPING_ALGORITHM ,
274
+ public_wrapping_key = _PUBLIC_WRAPPING_KEY ,
275
+ )
276
+ initial_materials = EncryptionMaterials (
277
+ algorithm = Algorithm .AES_256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384 , encryption_context = _ENCRYPTION_CONTEXT
278
+ )
279
+
280
+ test_materials = test_keyring .on_encrypt (initial_materials )
281
+
282
+ assert test_materials is not initial_materials
283
+ assert test_materials .data_encryption_key is not None
284
+ assert test_materials .encrypted_data_keys
285
+
286
+
287
+ def test_public_key_only_cannot_decrypt ():
288
+ test_keyring = RawRSAKeyring (
289
+ key_namespace = _PROVIDER_ID ,
290
+ key_name = _KEY_ID ,
291
+ wrapping_algorithm = _WRAPPING_ALGORITHM ,
292
+ public_wrapping_key = _PUBLIC_WRAPPING_KEY ,
293
+ )
294
+ initial_materials = EncryptionMaterials (
295
+ algorithm = Algorithm .AES_256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384 , encryption_context = _ENCRYPTION_CONTEXT
296
+ )
297
+
298
+ encryption_materials = test_keyring .on_encrypt (initial_materials )
299
+
300
+ initial_decryption_materials = DecryptionMaterials (
301
+ algorithm = Algorithm .AES_192_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384 , encryption_context = _ENCRYPTION_CONTEXT
302
+ )
303
+
304
+ test_materials = test_keyring .on_decrypt (
305
+ decryption_materials = initial_decryption_materials , encrypted_data_keys = encryption_materials .encrypted_data_keys
306
+ )
307
+
308
+ assert test_materials is initial_decryption_materials
309
+
310
+
311
+ def test_private_key_can_decrypt ():
312
+ complete_keyring = RawRSAKeyring (
313
+ key_namespace = _PROVIDER_ID ,
314
+ key_name = _KEY_ID ,
315
+ wrapping_algorithm = _WRAPPING_ALGORITHM ,
316
+ private_wrapping_key = _PRIVATE_WRAPPING_KEY ,
317
+ public_wrapping_key = _PUBLIC_WRAPPING_KEY ,
318
+ )
319
+ test_keyring = RawRSAKeyring (
320
+ key_namespace = _PROVIDER_ID ,
321
+ key_name = _KEY_ID ,
322
+ wrapping_algorithm = _WRAPPING_ALGORITHM ,
323
+ private_wrapping_key = _PRIVATE_WRAPPING_KEY ,
324
+ )
325
+ initial_materials = EncryptionMaterials (
326
+ algorithm = Algorithm .AES_256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384 , encryption_context = _ENCRYPTION_CONTEXT
327
+ )
328
+
329
+ encryption_materials = complete_keyring .on_encrypt (initial_materials )
330
+
331
+ initial_decryption_materials = DecryptionMaterials (
332
+ algorithm = Algorithm .AES_256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384 , encryption_context = _ENCRYPTION_CONTEXT
333
+ )
334
+
335
+ test_materials = test_keyring .on_decrypt (
336
+ decryption_materials = initial_decryption_materials , encrypted_data_keys = encryption_materials .encrypted_data_keys
337
+ )
338
+
339
+ assert test_materials is not initial_decryption_materials
340
+ assert test_materials .data_encryption_key is not None
341
+
342
+
343
+ def test_private_key_cannot_encrypt ():
344
+ test_keyring = RawRSAKeyring (
345
+ key_namespace = _PROVIDER_ID ,
346
+ key_name = _KEY_ID ,
347
+ wrapping_algorithm = _WRAPPING_ALGORITHM ,
348
+ private_wrapping_key = _PRIVATE_WRAPPING_KEY ,
349
+ )
350
+ initial_materials = EncryptionMaterials (
351
+ algorithm = Algorithm .AES_256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384 , encryption_context = _ENCRYPTION_CONTEXT
352
+ )
353
+
354
+ with pytest .raises (EncryptKeyError ) as excinfo :
355
+ test_keyring .on_encrypt (initial_materials )
356
+
357
+ excinfo .match ("A public key is required to encrypt" )
358
+
359
+
360
+ def test_keypair_must_match ():
361
+ wrapping_key_a = rsa .generate_private_key (public_exponent = _PUBLIC_EXPONENT , key_size = _KEY_SIZE , backend = _BACKEND )
362
+ wrapping_key_b = rsa .generate_private_key (public_exponent = _PUBLIC_EXPONENT , key_size = _KEY_SIZE , backend = _BACKEND )
363
+
364
+ with pytest .raises (ValueError ) as excinfo :
365
+ RawRSAKeyring (
366
+ key_namespace = _PROVIDER_ID ,
367
+ key_name = _KEY_ID ,
368
+ wrapping_algorithm = _WRAPPING_ALGORITHM ,
369
+ private_wrapping_key = wrapping_key_a ,
370
+ public_wrapping_key = wrapping_key_b .public_key (),
371
+ )
372
+
373
+ excinfo .match ("Private and public wrapping keys MUST be from the same keypair." )
0 commit comments