diff --git a/setup.py b/setup.py index fa546359..19b83b68 100644 --- a/setup.py +++ b/setup.py @@ -95,6 +95,10 @@ def find_meta(meta): package_dir={"": "src"}, install_requires=[ "cryptography>=41.0.5,<45", + ( + "typing-extensions>=4.9; " + "python_version < '3.13' and python_version >= '3.8'" + ), ], extras_require={ "test": ["pytest-rerunfailures", "pretend", "pytest>=3.0.1"], diff --git a/src/OpenSSL/crypto.py b/src/OpenSSL/crypto.py index e7ae772c..366007e8 100644 --- a/src/OpenSSL/crypto.py +++ b/src/OpenSSL/crypto.py @@ -3,6 +3,7 @@ import calendar import datetime import functools +import sys import typing import warnings from base64 import b16encode @@ -14,6 +15,16 @@ Union, ) +if sys.version_info >= (3, 13): + from warnings import deprecated +elif sys.version_info < (3, 8): + _T = typing.TypeVar("T") + + def deprecated(msg: str, **kwargs: object) -> Callable[[_T], _T]: + return lambda f: f +else: + from typing_extensions import deprecated + from cryptography import utils, x509 from cryptography.hazmat.primitives.asymmetric import ( dsa, @@ -529,6 +540,10 @@ def _to_EC_KEY(self) -> Any: return _ffi.gc(key, _lib.EC_KEY_free) +@deprecated( + "get_elliptic_curves is deprecated. You should use the APIs in " + "cryptography instead." +) def get_elliptic_curves() -> set[_EllipticCurve]: """ Return a set of objects representing the elliptic curves supported in the @@ -544,20 +559,10 @@ def get_elliptic_curves() -> set[_EllipticCurve]: return _EllipticCurve._get_elliptic_curves(_lib) -_get_elliptic_curves_internal = get_elliptic_curves - -utils.deprecated( - get_elliptic_curves, - __name__, - ( - "get_elliptic_curves is deprecated. You should use the APIs in " - "cryptography instead." - ), - DeprecationWarning, - name="get_elliptic_curves", +@deprecated( + "get_elliptic_curve is deprecated. You should use the APIs in " + "cryptography instead." ) - - def get_elliptic_curve(name: str) -> _EllipticCurve: """ Return a single curve object selected by name. @@ -570,24 +575,12 @@ def get_elliptic_curve(name: str) -> _EllipticCurve: If the named curve is not supported then :py:class:`ValueError` is raised. """ - for curve in _get_elliptic_curves_internal(): + for curve in get_elliptic_curves(): if curve.name == name: return curve raise ValueError("unknown curve name", name) -utils.deprecated( - get_elliptic_curve, - __name__, - ( - "get_elliptic_curve is deprecated. You should use the APIs in " - "cryptography instead." - ), - DeprecationWarning, - name="get_elliptic_curve", -) - - @functools.total_ordering class X509Name: """ @@ -783,6 +776,10 @@ def get_components(self) -> list[tuple[bytes, bytes]]: return result +@deprecated( + "X509Extension support in pyOpenSSL is deprecated. You should use the " + "APIs in cryptography." +) class X509Extension: """ An X.509 v3 certificate extension. @@ -953,19 +950,10 @@ def get_data(self) -> bytes: return _ffi.buffer(char_result, result_length)[:] -_X509ExtensionInternal = X509Extension -utils.deprecated( - X509Extension, - __name__, - ( - "X509Extension support in pyOpenSSL is deprecated. You should use the " - "APIs in cryptography." - ), - DeprecationWarning, - name="X509Extension", +@deprecated( + "CSR support in pyOpenSSL is deprecated. You should use the APIs " + "in cryptography." ) - - class X509Req: """ An X.509 certificate signing requests. @@ -1091,9 +1079,7 @@ def get_subject(self) -> X509Name: return name - def add_extensions( - self, extensions: Iterable[_X509ExtensionInternal] - ) -> None: + def add_extensions(self, extensions: Iterable[X509Extension]) -> None: """ Add extensions to the certificate signing request. @@ -1117,7 +1103,7 @@ def add_extensions( stack = _ffi.gc(stack, _lib.sk_X509_EXTENSION_free) for ext in extensions: - if not isinstance(ext, _X509ExtensionInternal): + if not isinstance(ext, X509Extension): raise ValueError("One of the elements is not an X509Extension") # TODO push can fail (here and elsewhere) @@ -1126,7 +1112,7 @@ def add_extensions( add_result = _lib.X509_REQ_add_extensions(self._req, stack) _openssl_assert(add_result == 1) - def get_extensions(self) -> list[_X509ExtensionInternal]: + def get_extensions(self) -> list[X509Extension]: """ Get X.509 extensions in the certificate signing request. @@ -1156,7 +1142,7 @@ def get_extensions(self) -> list[_X509ExtensionInternal]: ) for i in range(_lib.sk_X509_EXTENSION_num(native_exts_obj)): - ext = _X509ExtensionInternal.__new__(_X509ExtensionInternal) + ext = X509Extension.__new__(X509Extension) extension = _lib.X509_EXTENSION_dup( _lib.sk_X509_EXTENSION_value(native_exts_obj, i) ) @@ -1210,20 +1196,6 @@ def verify(self, pkey: PKey) -> bool: return result -_X509ReqInternal = X509Req - -utils.deprecated( - X509Req, - __name__, - ( - "CSR support in pyOpenSSL is deprecated. You should use the APIs " - "in cryptography." - ), - DeprecationWarning, - name="X509Req", -) - - class X509: """ An X.509 certificate. @@ -1655,9 +1627,7 @@ def get_extension_count(self) -> int: """ return _lib.X509_get_ext_count(self._x509) - def add_extensions( - self, extensions: Iterable[_X509ExtensionInternal] - ) -> None: + def add_extensions(self, extensions: Iterable[X509Extension]) -> None: """ Add extensions to the certificate. @@ -1676,13 +1646,13 @@ def add_extensions( ) for ext in extensions: - if not isinstance(ext, _X509ExtensionInternal): + if not isinstance(ext, X509Extension): raise ValueError("One of the elements is not an X509Extension") add_result = _lib.X509_add_ext(self._x509, ext._extension, -1) _openssl_assert(add_result == 1) - def get_extension(self, index: int) -> _X509ExtensionInternal: + def get_extension(self, index: int) -> X509Extension: """ Get a specific extension of the certificate by index. @@ -1706,7 +1676,7 @@ def get_extension(self, index: int) -> _X509ExtensionInternal: stacklevel=2, ) - ext = _X509ExtensionInternal.__new__(_X509ExtensionInternal) + ext = X509Extension.__new__(X509Extension) ext._extension = _lib.X509_get_ext(self._x509, index) if ext._extension == _ffi.NULL: raise IndexError("extension index out of bounds") @@ -2461,7 +2431,7 @@ def load_certificate_request(type: int, buffer: bytes) -> X509Req: _openssl_assert(req != _ffi.NULL) - x509req = _X509ReqInternal.__new__(_X509ReqInternal) + x509req = X509Req.__new__(X509Req) x509req._req = _ffi.gc(req, _lib.X509_REQ_free) return x509req diff --git a/tests/test_crypto.py b/tests/test_crypto.py index 4c67682d..7b07b441 100644 --- a/tests/test_crypto.py +++ b/tests/test_crypto.py @@ -36,6 +36,7 @@ X509, Error, PKey, + X509Extension, X509Name, X509Req, X509Store, @@ -57,11 +58,6 @@ load_publickey, ) -with pytest.warns(DeprecationWarning): - from OpenSSL.crypto import ( - X509Extension, - ) - from .util import ( NON_ASCII, )