Skip to content

Commit 6ffc135

Browse files
authored
feat: refactor raw RSA keyrings configuration per #257 (#260)
* feat: refactor raw RSA keyrings configuration per #257 * fix: raw RSA keyring must raise an error on encrypt if public key is not available * docs: fix links in examples readme
1 parent 6136620 commit 6ffc135

File tree

8 files changed

+193
-105
lines changed

8 files changed

+193
-105
lines changed

examples/README.md

+4-4
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,9 @@ We start with AWS KMS examples, then show how to use other wrapping keys.
4949
* [with keyrings](./src/keyring/raw_aes/raw_aes.py)
5050
* [with master key providers](./src/master_key_provider/raw_aes/raw_aes.py)
5151
* How to use a raw RSA wrapping key
52-
* [with keyrings](./src/keyring/raw_rsa/private_key_only.py)
52+
* [with keyrings](./src/keyring/raw_rsa/keypair.py)
5353
* How to use a raw RSA wrapping key when the key is PEM or DER encoded
54-
* [with keyrings](./src/keyring/raw_rsa/private_key_only_from_pem.py)
54+
* [with keyrings](./src/keyring/raw_rsa/keypair_from_pem.py)
5555
* [with master key providers](./src/master_key_provider/raw_rsa/private_key_only_from_pem.py)
5656
* How to encrypt with a raw RSA public key wrapping key without access to the private key
5757
* [with keyrings](./src/keyring/raw_rsa/public_private_key_separate.py)
@@ -62,9 +62,9 @@ We start with AWS KMS examples, then show how to use other wrapping keys.
6262
* How to reuse data keys across multiple messages
6363
* [with the caching cryptographic materials manager](./src/crypto_materials_manager/caching/simple_cache.py)
6464
* How to restrict algorithm suites
65-
* [with a custom cryptographic materials manager](src/crypto_materials_manager/custom/algorithm_suite_enforcement.py)
65+
* [with a custom cryptographic materials manager](./src/crypto_materials_manager/custom/algorithm_suite_enforcement.py)
6666
* How to require encryption context fields
67-
* [with a custom cryptographic materials manager](src/crypto_materials_manager/custom/requiring_encryption_context_fields.py)
67+
* [with a custom cryptographic materials manager](./src/crypto_materials_manager/custom/requiring_encryption_context_fields.py)
6868

6969
### Keyrings
7070

examples/src/keyring/raw_rsa/private_key_only.py renamed to examples/src/keyring/raw_rsa/keypair.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
22
# SPDX-License-Identifier: Apache-2.0
33
"""
4-
This examples shows how to configure and use a raw RSA keyring using a pre-loaded RSA private key.
4+
This examples shows how to configure and use a raw RSA keyring using a pre-loaded RSA keypair.
55
66
If your RSA key is in PEM or DER format,
77
see the ``keyring/raw_rsa/private_key_only_from_pem`` example.
@@ -55,6 +55,7 @@ def run(source_plaintext):
5555
key_namespace="some managed raw keys",
5656
key_name=b"my RSA wrapping key",
5757
private_wrapping_key=private_key,
58+
public_wrapping_key=private_key.public_key(),
5859
# The wrapping algorithm tells the raw RSA keyring
5960
# how to use your wrapping key to encrypt data keys.
6061
#

examples/src/keyring/raw_rsa/private_key_only_from_pem.py renamed to examples/src/keyring/raw_rsa/keypair_from_pem.py

+6-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"""
44
When you store RSA keys, you have to serialize them somehow.
55
6-
This example shows how to configure and use a raw RSA keyring using a PEM-encoded RSA private key.
6+
This example shows how to configure and use a raw RSA keyring using a PEM-encoded RSA keypair.
77
88
The most commonly used encodings for RSA keys tend to be PEM and DER.
99
The raw RSA keyring supports loading both public and private keys from these encodings.
@@ -47,13 +47,16 @@ def run(source_plaintext):
4747
# https://crypto.stanford.edu/~dabo/pubs/papers/RSA-survey.pdf
4848
private_key = rsa.generate_private_key(public_exponent=65537, key_size=4096, backend=default_backend())
4949

50-
# Serialize the RSA private key to PEM encoding.
50+
# Serialize the RSA keypair to PEM encoding.
5151
# This or DER encoding is likely to be what you get from your key management system in practice.
5252
private_key_pem = private_key.private_bytes(
5353
encoding=serialization.Encoding.PEM,
5454
format=serialization.PrivateFormat.PKCS8,
5555
encryption_algorithm=serialization.NoEncryption(),
5656
)
57+
public_key_pem = private_key.public_key().public_bytes(
58+
encoding=serialization.Encoding.PEM, format=serialization.PublicFormat.SubjectPublicKeyInfo,
59+
)
5760

5861
# Create the keyring that determines how your data keys are protected.
5962
#
@@ -68,6 +71,7 @@ def run(source_plaintext):
6871
key_namespace="some managed raw keys",
6972
key_name=b"my RSA wrapping key",
7073
private_encoded_key=private_key_pem,
74+
public_encoded_key=public_key_pem,
7175
# The wrapping algorithm tells the raw RSA keyring
7276
# how to use your wrapping key to encrypt data keys.
7377
#

src/aws_encryption_sdk/keyrings/raw.py

+9-6
Original file line numberDiff line numberDiff line change
@@ -283,8 +283,12 @@ def __attrs_post_init__(self):
283283
if self._public_wrapping_key is None and self._private_wrapping_key is None:
284284
raise TypeError("At least one of public key or private key must be provided.")
285285

286-
if self._private_wrapping_key is not None and self._public_wrapping_key is None:
287-
self._public_wrapping_key = self._private_wrapping_key.public_key()
286+
if self._public_wrapping_key is not None and self._private_wrapping_key is not None:
287+
derived_public_key = self._private_wrapping_key.public_key()
288+
# We cannot compare the public key objects directly.
289+
# Instead, extract their numbers and compare those.
290+
if derived_public_key.public_numbers() != self._public_wrapping_key.public_numbers():
291+
raise ValueError("Private and public wrapping keys MUST be from the same keypair.")
288292

289293
@classmethod
290294
def from_pem_encoding(
@@ -375,13 +379,12 @@ def on_encrypt(self, encryption_materials):
375379
"""
376380
new_materials = encryption_materials
377381

382+
if self._public_wrapping_key is None:
383+
raise EncryptKeyError("A public key is required to encrypt")
384+
378385
if new_materials.data_encryption_key is None:
379386
new_materials = _generate_data_key(encryption_materials=new_materials, key_provider=self._key_provider)
380387

381-
if self._public_wrapping_key is None:
382-
# This should be impossible, but just in case, give a useful error message.
383-
raise EncryptKeyError("Raw RSA keyring unable to encrypt data key: no public key available")
384-
385388
try:
386389
# Encrypt data key
387390
encrypted_wrapped_key = EncryptedData(

test/functional/keyrings/raw/test_raw_rsa.py

+128-52
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
from cryptography.hazmat.primitives import serialization
1818
from cryptography.hazmat.primitives.asymmetric import rsa
1919

20+
from aws_encryption_sdk.exceptions import EncryptKeyError
2021
from aws_encryption_sdk.identifiers import (
2122
Algorithm,
2223
EncryptionKeyType,
@@ -42,79 +43,41 @@
4243
_BACKEND = default_backend()
4344

4445
_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()
4547

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(
7949
encoding=serialization.Encoding.PEM,
8050
format=serialization.PrivateFormat.TraditionalOpenSSL,
8151
encryption_algorithm=serialization.NoEncryption(),
8252
)
53+
_PUBLIC_WRAPPING_KEY_PEM = _PUBLIC_WRAPPING_KEY.public_bytes(
54+
encoding=serialization.Encoding.PEM, format=serialization.PublicFormat.SubjectPublicKeyInfo
55+
)
8356

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(
8760
encoding=serialization.Encoding.PEM,
8861
format=serialization.PrivateFormat.PKCS8,
8962
encryption_algorithm=serialization.BestAvailableEncryption(b"mypassword"),
9063
)
9164

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
9766

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(
10168
encoding=serialization.Encoding.DER,
10269
format=serialization.PrivateFormat.TraditionalOpenSSL,
10370
encryption_algorithm=serialization.NoEncryption(),
10471
)
10572

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(
10974
encoding=serialization.Encoding.DER,
11075
format=serialization.PrivateFormat.PKCS8,
11176
encryption_algorithm=serialization.BestAvailableEncryption(b"mypassword"),
11277
)
11378

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
11881
)
11982

12083

@@ -148,18 +111,21 @@ def sample_raw_rsa_keyring_using_different_wrapping_algorithm():
148111
key_name=_KEY_ID,
149112
wrapping_algorithm=alg,
150113
private_wrapping_key=_PRIVATE_WRAPPING_KEY,
114+
public_wrapping_key=_PUBLIC_WRAPPING_KEY,
151115
)
152116
pem_and_der_encoded_raw_rsa_keyring = [
153117
RawRSAKeyring.from_pem_encoding(
154118
key_namespace=_PROVIDER_ID,
155119
key_name=_KEY_ID,
156120
private_encoded_key=_RAW_RSA_PRIVATE_KEY_PEM_ENCODED_WITHOUT_PASSWORD,
121+
public_encoded_key=_RAW_RSA_PUBLIC_KEY_PEM_ENCODED,
157122
wrapping_algorithm=_WRAPPING_ALGORITHM,
158123
),
159124
RawRSAKeyring.from_pem_encoding(
160125
key_namespace=_PROVIDER_ID,
161126
key_name=_KEY_ID,
162127
private_encoded_key=_RAW_RSA_PRIVATE_KEY_PEM_ENCODED_WITH_PASSWORD,
128+
public_encoded_key=_RAW_RSA_PUBLIC_KEY_PEM_ENCODED,
163129
password=b"mypassword",
164130
wrapping_algorithm=_WRAPPING_ALGORITHM,
165131
),
@@ -173,20 +139,21 @@ def sample_raw_rsa_keyring_using_different_wrapping_algorithm():
173139
key_namespace=_PROVIDER_ID,
174140
key_name=_KEY_ID,
175141
private_encoded_key=_RAW_RSA_PRIVATE_KEY_DER_ENCODED_WITHOUT_PASSWORD,
142+
public_encoded_key=_RAW_RSA_PUBLIC_KEY_DER_ENCODED,
176143
wrapping_algorithm=_WRAPPING_ALGORITHM,
177144
),
178145
RawRSAKeyring.from_der_encoding(
179146
key_namespace=_PROVIDER_ID,
180147
key_name=_KEY_ID,
181148
private_encoded_key=_RAW_RSA_PRIVATE_KEY_DER_ENCODED_WITH_PASSWORD,
149+
public_encoded_key=_RAW_RSA_PUBLIC_KEY_DER_ENCODED,
182150
password=b"mypassword",
183151
wrapping_algorithm=_WRAPPING_ALGORITHM,
184152
),
185153
RawRSAKeyring.from_der_encoding(
186154
key_namespace=_PROVIDER_ID,
187155
key_name=_KEY_ID,
188156
public_encoded_key=_RAW_RSA_PUBLIC_KEY_DER_ENCODED,
189-
password=b"mypassword",
190157
wrapping_algorithm=_WRAPPING_ALGORITHM,
191158
),
192159
]
@@ -227,6 +194,7 @@ def test_raw_master_key_decrypts_what_raw_keyring_encrypts(encryption_materials_
227194
key_name=_KEY_ID,
228195
wrapping_algorithm=_WRAPPING_ALGORITHM,
229196
private_encoded_key=_PRIVATE_WRAPPING_KEY_PEM,
197+
public_encoded_key=_PUBLIC_WRAPPING_KEY_PEM,
230198
)
231199

232200
# Creating an instance of a raw master key
@@ -272,6 +240,7 @@ def test_raw_keyring_decrypts_what_raw_master_key_encrypts(encryption_materials_
272240
key_name=_KEY_ID,
273241
wrapping_algorithm=_WRAPPING_ALGORITHM,
274242
private_encoded_key=_PRIVATE_WRAPPING_KEY_PEM,
243+
public_encoded_key=_PUBLIC_WRAPPING_KEY_PEM,
275244
)
276245

277246
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_
295264
)
296265

297266
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

Comments
 (0)