Skip to content

Commit b0cb4b4

Browse files
authored
Deprecate passing PKey instances to use_privatekey (#1348)
Allow passing cryptography keys instead. Refs #1321
1 parent 0eaef1c commit b0cb4b4

File tree

4 files changed

+45
-9
lines changed

4 files changed

+45
-9
lines changed

CHANGELOG.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ Deprecations:
1616
- Deprecated ``OpenSSL.rand`` - callers should use ``os.urandom()`` instead.
1717
- Deprecated ``OpenSSL.crypto.get_elliptic_curves`` and ``OpenSSL.crypto.get_elliptic_curve``, as well as passing the reult of them to ``OpenSSL.SSL.Context.set_tmp_ecdh``, users should instead pass curves from ``cryptography``.
1818
- Deprecated passing ``X509`` objects to ``OpenSSL.SSL.Context.use_certificate``, ``OpenSSL.SSL.Connection.use_certificate``, ``OpenSSL.SSL.Context.add_extra_chain_cert``, and ``OpenSSL.SSL.Context.add_client_ca``, users should instead pass ``cryptography.x509.Certificate`` instances. This is in preparation for deprecating pyOpenSSL's ``X509`` entirely.
19+
- Deprecated passing ``PKey`` objects to ``OpenSSL.SSL.Context.use_privatekey`` and ``OpenSSL.SSL.Connection.use_privatekey``, users should instead pass ``cryptography`` priate key instances. This is in preparation for deprecating pyOpenSSL's ``PKey`` entirely.
1920

2021
Changes:
2122
^^^^^^^^

src/OpenSSL/SSL.py

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
X509Store,
4747
_EllipticCurve,
4848
_PassphraseHelper,
49+
_PrivateKey,
4950
)
5051

5152
__all__ = [
@@ -1204,7 +1205,7 @@ def use_privatekey_file(
12041205
if not use_result:
12051206
self._raise_passphrase_exception()
12061207

1207-
def use_privatekey(self, pkey: PKey) -> None:
1208+
def use_privatekey(self, pkey: _PrivateKey | PKey) -> None:
12081209
"""
12091210
Load a private key from a PKey object
12101211
@@ -1213,7 +1214,16 @@ def use_privatekey(self, pkey: PKey) -> None:
12131214
"""
12141215
# Mirrored at Connection.use_privatekey
12151216
if not isinstance(pkey, PKey):
1216-
raise TypeError("pkey must be a PKey instance")
1217+
pkey = PKey.from_cryptography_key(pkey)
1218+
else:
1219+
warnings.warn(
1220+
(
1221+
"Passing pyOpenSSL PKey objects is deprecated. You "
1222+
"should use a cryptography private key instead."
1223+
),
1224+
DeprecationWarning,
1225+
stacklevel=2,
1226+
)
12171227

12181228
use_result = _lib.SSL_CTX_use_PrivateKey(self._context, pkey._pkey)
12191229
if not use_result:
@@ -2070,7 +2080,7 @@ def use_certificate(self, cert: X509 | x509.Certificate) -> None:
20702080
if not use_result:
20712081
_raise_current_error()
20722082

2073-
def use_privatekey(self, pkey: PKey) -> None:
2083+
def use_privatekey(self, pkey: _PrivateKey | PKey) -> None:
20742084
"""
20752085
Load a private key from a PKey object
20762086
@@ -2079,7 +2089,16 @@ def use_privatekey(self, pkey: PKey) -> None:
20792089
"""
20802090
# Mirrored from Context.use_privatekey
20812091
if not isinstance(pkey, PKey):
2082-
raise TypeError("pkey must be a PKey instance")
2092+
pkey = PKey.from_cryptography_key(pkey)
2093+
else:
2094+
warnings.warn(
2095+
(
2096+
"Passing pyOpenSSL PKey objects is deprecated. You "
2097+
"should use a cryptography private key instead."
2098+
),
2099+
DeprecationWarning,
2100+
stacklevel=2,
2101+
)
20832102

20842103
use_result = _lib.SSL_use_PrivateKey(self._ssl, pkey._pkey)
20852104
if not use_result:

src/OpenSSL/crypto.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -84,18 +84,21 @@
8484
]
8585

8686

87-
_Key = Union[
87+
_PrivateKey = Union[
8888
dsa.DSAPrivateKey,
89-
dsa.DSAPublicKey,
9089
ec.EllipticCurvePrivateKey,
91-
ec.EllipticCurvePublicKey,
9290
ed25519.Ed25519PrivateKey,
93-
ed25519.Ed25519PublicKey,
9491
ed448.Ed448PrivateKey,
95-
ed448.Ed448PublicKey,
9692
rsa.RSAPrivateKey,
93+
]
94+
_PublicKey = Union[
95+
dsa.DSAPublicKey,
96+
ec.EllipticCurvePublicKey,
97+
ed25519.Ed25519PublicKey,
98+
ed448.Ed448PublicKey,
9799
rsa.RSAPublicKey,
98100
]
101+
_Key = Union[_PrivateKey, _PublicKey]
99102
StrOrBytesPath = Union[str, bytes, PathLike]
100103
PassphraseCallableT = Union[bytes, Callable[..., bytes]]
101104

tests/test_ssl.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -727,6 +727,11 @@ def test_check_privatekey_valid(self):
727727
context.use_certificate(cert)
728728
assert None is context.check_privatekey()
729729

730+
context = Context(SSLv23_METHOD)
731+
context.use_privatekey(key.to_cryptography_key())
732+
context.use_certificate(cert)
733+
assert None is context.check_privatekey()
734+
730735
def test_check_privatekey_invalid(self):
731736
"""
732737
`Context.check_privatekey` raises `Error` if the `Context` instance
@@ -741,6 +746,12 @@ def test_check_privatekey_invalid(self):
741746
with pytest.raises(Error):
742747
context.check_privatekey()
743748

749+
context = Context(SSLv23_METHOD)
750+
context.use_privatekey(key.to_cryptography_key())
751+
context.use_certificate(cert)
752+
with pytest.raises(Error):
753+
context.check_privatekey()
754+
744755
def test_app_data(self):
745756
"""
746757
`Context.set_app_data` stores an object for later retrieval
@@ -2163,6 +2174,8 @@ def test_use_privatekey(self, ctx_or_conn):
21632174
with pytest.raises(TypeError):
21642175
ctx_or_conn.use_privatekey("")
21652176

2177+
ctx_or_conn.use_privatekey(key.to_cryptography_key())
2178+
21662179
def test_use_privatekey_wrong_key(self, ctx_or_conn):
21672180
"""
21682181
`use_privatekey` raises `OpenSSL.SSL.Error` when passed a

0 commit comments

Comments
 (0)