Skip to content

Commit 7bd0df4

Browse files
authored
don't block ec/ed keys from_cryptography_key() (#1096)
* don't block ec/ed keys from_cryptography_key() * clean up test comments * properly describe test
1 parent db9aed3 commit 7bd0df4

File tree

2 files changed

+51
-17
lines changed

2 files changed

+51
-17
lines changed

src/OpenSSL/crypto.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,13 @@
55
from functools import partial
66

77
from cryptography import utils, x509
8-
from cryptography.hazmat.primitives.asymmetric import dsa, rsa
8+
from cryptography.hazmat.primitives.asymmetric import (
9+
dsa,
10+
ec,
11+
ed25519,
12+
ed448,
13+
rsa,
14+
)
915

1016
from OpenSSL._util import (
1117
ffi as _ffi,
@@ -254,6 +260,9 @@ def from_cryptography_key(cls, crypto_key):
254260
rsa.RSAPrivateKey,
255261
dsa.DSAPublicKey,
256262
dsa.DSAPrivateKey,
263+
ec.EllipticCurvePrivateKey,
264+
ed25519.Ed25519PrivateKey,
265+
ed448.Ed448PrivateKey,
257266
),
258267
):
259268
raise TypeError("Unsupported key type")
@@ -351,7 +360,7 @@ def check(self):
351360
raise TypeError("public key only")
352361

353362
if _lib.EVP_PKEY_type(self.type()) != _lib.EVP_PKEY_RSA:
354-
raise TypeError("key type unsupported")
363+
raise TypeError("Only RSA keys can currently be checked.")
355364

356365
rsa = _lib.EVP_PKEY_get1_RSA(self._pkey)
357366
rsa = _ffi.gc(rsa, _lib.RSA_free)

tests/test_crypto.py

Lines changed: 40 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
from cryptography import x509
1818
from cryptography.hazmat.primitives import serialization
19-
from cryptography.hazmat.primitives.asymmetric import rsa
19+
from cryptography.hazmat.primitives.asymmetric import ec, ed25519, ed448, rsa
2020

2121
import flaky
2222

@@ -782,6 +782,21 @@ def normalize_privatekey_pem(pem):
782782
-----END RSA PRIVATE KEY-----
783783
"""
784784

785+
ed25519_private_key_pem = b"""-----BEGIN PRIVATE KEY-----
786+
MC4CAQAwBQYDK2VwBCIEIKlxBbhVsSURoLTmsu9uTqYH6oF7zpxmp1ZQCAPhDmI2
787+
-----END PRIVATE KEY-----
788+
"""
789+
790+
ed448_private_key_pem = b"""-----BEGIN PRIVATE KEY-----
791+
MEcCAQAwBQYDK2VxBDsEOcqZ7a3k6JwrJbYO8CNTPT/d7dlWCo5vCf0EYDj79ZvA\nhD8u9EPHlYJw5Y8ZQdH4WmVEfpKA23xkdQ==
792+
-----END PRIVATE KEY-----
793+
"""
794+
795+
x25519_private_key_pem = b"""-----BEGIN PRIVATE KEY-----
796+
MC4CAQAwBQYDK2VuBCIEIPAjVfPNTm25VxtBRg+JjjFx9tA3M8aaBdVhjb92iBts
797+
-----END PRIVATE KEY-----
798+
"""
799+
785800

786801
@pytest.fixture
787802
def x509_data():
@@ -1012,15 +1027,35 @@ class TestPKey:
10121027
Tests for `OpenSSL.crypto.PKey`.
10131028
"""
10141029

1015-
def test_convert_from_cryptography_private_key(self):
1030+
@pytest.mark.parametrize(
1031+
("key_string", "key_type"),
1032+
[
1033+
(intermediate_key_pem, rsa.RSAPrivateKey),
1034+
(ec_private_key_pem, ec.EllipticCurvePrivateKey),
1035+
(ed25519_private_key_pem, ed25519.Ed25519PrivateKey),
1036+
(ed448_private_key_pem, ed448.Ed448PrivateKey),
1037+
],
1038+
)
1039+
def test_convert_roundtrip_cryptography_private_key(
1040+
self, key_string, key_type
1041+
):
10161042
"""
10171043
PKey.from_cryptography_key creates a proper private PKey.
1044+
PKey.to_cryptography_key creates a proper cryptography private key.
10181045
"""
1019-
key = serialization.load_pem_private_key(intermediate_key_pem, None)
1046+
key = serialization.load_pem_private_key(key_string, None)
10201047
pkey = PKey.from_cryptography_key(key)
10211048

10221049
assert isinstance(pkey, PKey)
1023-
assert pkey.bits() == key.key_size
1050+
parsed_key = pkey.to_cryptography_key()
1051+
assert isinstance(parsed_key, key_type)
1052+
assert parsed_key.public_key().public_bytes(
1053+
serialization.Encoding.PEM,
1054+
serialization.PublicFormat.SubjectPublicKeyInfo,
1055+
) == key.public_key().public_bytes(
1056+
serialization.Encoding.PEM,
1057+
serialization.PublicFormat.SubjectPublicKeyInfo,
1058+
)
10241059
assert pkey._only_public is False
10251060
assert pkey._initialized is True
10261061

@@ -1040,7 +1075,7 @@ def test_convert_from_cryptography_unsupported_type(self):
10401075
"""
10411076
PKey.from_cryptography_key raises TypeError with an unsupported type.
10421077
"""
1043-
key = serialization.load_pem_private_key(ec_private_key_pem, None)
1078+
key = serialization.load_pem_private_key(x25519_private_key_pem, None)
10441079
with pytest.raises(TypeError):
10451080
PKey.from_cryptography_key(key)
10461081

@@ -1054,16 +1089,6 @@ def test_convert_public_pkey_to_cryptography_key(self):
10541089
assert isinstance(key, rsa.RSAPublicKey)
10551090
assert pkey.bits() == key.key_size
10561091

1057-
def test_convert_private_pkey_to_cryptography_key(self):
1058-
"""
1059-
PKey.to_cryptography_key creates a proper cryptography private key.
1060-
"""
1061-
pkey = load_privatekey(FILETYPE_PEM, root_key_pem)
1062-
key = pkey.to_cryptography_key()
1063-
1064-
assert isinstance(key, rsa.RSAPrivateKey)
1065-
assert pkey.bits() == key.key_size
1066-
10671092
def test_type(self):
10681093
"""
10691094
`PKey` can be used to create instances of that type.

0 commit comments

Comments
 (0)