Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-pyOpenSSL for
openSUSE:Factory checked in at 2026-06-16 18:29:14
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-pyOpenSSL (Old)
and /work/SRC/openSUSE:Factory/.python-pyOpenSSL.new.1981 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-pyOpenSSL"
Tue Jun 16 18:29:14 2026 rev:66 rq:1359292 version:26.3.0
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-pyOpenSSL/python-pyOpenSSL.changes
2026-05-12 19:25:57.405317786 +0200
+++
/work/SRC/openSUSE:Factory/.python-pyOpenSSL.new.1981/python-pyOpenSSL.changes
2026-06-16 18:29:16.933224938 +0200
@@ -1,0 +2,42 @@
+Sun Jun 14 09:18:38 UTC 2026 - Dirk Müller <[email protected]>
+
+- update to 26.3.0:
+ * Dropped support for Python 3.8.
+ * The minimum cryptography version is now 49.0.0.
+ * Removed deprecated OpenSSL.crypto.X509Req,
+ OpenSSL.crypto.dump_certificate_request, and
+ OpenSSL.crypto.load_certificate_request. cryptography.x509
+ should be used instead.
+ * OpenSSL.SSL.Connection.set_session now raises ValueError if
+ the Session was obtained from a Connection that was using a
+ different Context than this one. OpenSSL requires (but does
+ not verify) that sessions only be re-used with a compatible
+ SSL_CTX, so this contract is now enforced.
+ * Deprecated OpenSSL.crypto.PKey.generate_key and
+ OpenSSL.crypto.PKey.check. The key generation and loading
+ APIs in cryptography should be used instead.
+ * Deprecated OpenSSL.crypto.dump_privatekey. The serialization
+ APIs on cryptography private key types should be used
+ instead.
+ * Deprecated all the mutable APIs on OpenSSL.crypto.X509:
+ set_version, set_pubkey, sign, set_serial_number,
+ gmtime_adj_notAfter, gmtime_adj_notBefore, set_notBefore,
+ set_notAfter, set_issuer, and set_subject.
+ cryptography.x509.CertificateBuilder should be used instead.
+ * Deprecated OpenSSL.SSL.Context.set_passwd_cb. Users should
+ decrypt and load their private keys themselves, with
+ cryptography's key loading APIs, and then call
+ OpenSSL.SSL.Context.use_privatekey.
+ * Deprecated OpenSSL.crypto.X509Name, as well as the remaining
+ APIs that consume or return it:
+ OpenSSL.crypto.X509.get_issuer,
+ OpenSSL.crypto.X509.get_subject, and
+ OpenSSL.SSL.Context.set_client_ca_list. The APIs in
+ cryptography.x509 should be used instead.
+ * OpenSSL.SSL.Connection.get_client_ca_list now takes an
+ as_cryptography keyword-argument. When True is passed then
+ cryptography.x509.Name are returned, instead of
+ OpenSSL.crypto.X509Name. In the future, passing False (the
+ default) will be deprecated.
+
+-------------------------------------------------------------------
Old:
----
pyopenssl-26.2.0.tar.gz
New:
----
pyopenssl-26.3.0.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-pyOpenSSL.spec ++++++
--- /var/tmp/diff_new_pack.J9pXL8/_old 2026-06-16 18:29:17.601253071 +0200
+++ /var/tmp/diff_new_pack.J9pXL8/_new 2026-06-16 18:29:17.605253240 +0200
@@ -26,7 +26,7 @@
%endif
%{?sle15_python_module_pythons}
Name: python-pyOpenSSL%{psuffix}
-Version: 26.2.0
+Version: 26.3.0
Release: 0
Summary: Python wrapper module around the OpenSSL library
License: Apache-2.0
@@ -35,14 +35,14 @@
# PATCH-FIX-UPSTREAM skip-networked-test.patch gh#pyca/pyopenssl#68
[email protected]
# Mark tests requiring network access
Patch0: skip-networked-test.patch
-BuildRequires: %{python_module base >= 3.8}
+BuildRequires: %{python_module base >= 3.9}
BuildRequires: %{python_module cffi}
BuildRequires: %{python_module pip}
BuildRequires: %{python_module setuptools}
BuildRequires: fdupes
BuildRequires: python-rpm-macros
Requires: python-cffi
-Requires: (python-cryptography >= 46.0.0 with python-cryptography < 49)
+Requires: (python-cryptography >= 49.0.0 with python-cryptography < 50)
%if %{python_version_nodots} < 313
Requires: python-typing-extensions >= 4.9
%endif
@@ -51,7 +51,7 @@
%if %{without test}
BuildArch: noarch
%else
-BuildRequires: %{python_module cryptography >= 46.0.0 with
%python-cryptography < 49}
+BuildRequires: %{python_module cryptography >= 49.0.0 with
%python-cryptography < 50}
BuildRequires: %{python_module pretend}
BuildRequires: %{python_module pyOpenSSL >= %version}
BuildRequires: %{python_module pytest >= 3.0.1}
++++++ pyopenssl-26.2.0.tar.gz -> pyopenssl-26.3.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pyopenssl-26.2.0/CHANGELOG.rst
new/pyopenssl-26.3.0/CHANGELOG.rst
--- old/pyopenssl-26.2.0/CHANGELOG.rst 2026-05-05 01:05:30.000000000 +0200
+++ new/pyopenssl-26.3.0/CHANGELOG.rst 2026-06-12 22:27:26.000000000 +0200
@@ -4,6 +4,32 @@
Versions are year-based with a strict backward-compatibility policy.
The third digit is only for regressions.
+26.3.0 (2026-06-12)
+-------------------
+
+Backward-incompatible changes:
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+- Dropped support for Python 3.8.
+- The minimum ``cryptography`` version is now 49.0.0.
+- Removed deprecated ``OpenSSL.crypto.X509Req``,
``OpenSSL.crypto.dump_certificate_request``, and
``OpenSSL.crypto.load_certificate_request``. ``cryptography.x509`` should be
used instead.
+- ``OpenSSL.SSL.Connection.set_session`` now raises ``ValueError`` if the
``Session`` was obtained from a ``Connection`` that was using a different
``Context`` than this one. OpenSSL requires (but does not verify) that sessions
only be re-used with a compatible ``SSL_CTX``, so this contract is now enforced.
+
+Deprecations:
+^^^^^^^^^^^^^
+
+- Deprecated ``OpenSSL.crypto.PKey.generate_key`` and
``OpenSSL.crypto.PKey.check``. The key generation and loading APIs in
``cryptography`` should be used instead.
+- Deprecated ``OpenSSL.crypto.dump_privatekey``. The serialization APIs on
``cryptography`` private key types should be used instead.
+- Deprecated all the mutable APIs on ``OpenSSL.crypto.X509``: ``set_version``,
``set_pubkey``, ``sign``, ``set_serial_number``, ``gmtime_adj_notAfter``,
``gmtime_adj_notBefore``, ``set_notBefore``, ``set_notAfter``, ``set_issuer``,
and ``set_subject``. ``cryptography.x509.CertificateBuilder`` should be used
instead.
+- Deprecated ``OpenSSL.SSL.Context.set_passwd_cb``. Users should decrypt and
load their private keys themselves, with ``cryptography``'s key loading APIs,
and then call ``OpenSSL.SSL.Context.use_privatekey``.
+- Deprecated ``OpenSSL.crypto.X509Name``, as well as the remaining APIs that
consume or return it: ``OpenSSL.crypto.X509.get_issuer``,
``OpenSSL.crypto.X509.get_subject``, and
``OpenSSL.SSL.Context.set_client_ca_list``. The APIs in ``cryptography.x509``
should be used instead.
+
+Changes:
+^^^^^^^^
+
+- ``OpenSSL.SSL.Connection.get_client_ca_list`` now takes an
``as_cryptography`` keyword-argument. When ``True`` is passed then
``cryptography.x509.Name`` are returned, instead of
``OpenSSL.crypto.X509Name``. In the future, passing ``False`` (the default)
will be deprecated.
+
+
26.2.0 (2026-05-04)
-------------------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pyopenssl-26.2.0/PKG-INFO
new/pyopenssl-26.3.0/PKG-INFO
--- old/pyopenssl-26.2.0/PKG-INFO 2026-05-05 01:05:34.877339600 +0200
+++ new/pyopenssl-26.3.0/PKG-INFO 2026-06-12 22:27:29.249154800 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 2.4
Name: pyOpenSSL
-Version: 26.2.0
+Version: 26.3.0
Summary: Python wrapper module around the OpenSSL library
Home-page: https://pyopenssl.org/
Author: The pyOpenSSL developers
@@ -14,7 +14,6 @@
Classifier: Operating System :: Microsoft :: Windows
Classifier: Operating System :: POSIX
Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
@@ -25,10 +24,10 @@
Classifier: Topic :: Security :: Cryptography
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: System :: Networking
-Requires-Python: >=3.8
+Requires-Python: >=3.9
License-File: LICENSE
-Requires-Dist: cryptography<49,>=46.0.0
-Requires-Dist: typing-extensions>=4.9; python_version < "3.13" and
python_version >= "3.8"
+Requires-Dist: cryptography<50,>=49.0.0
+Requires-Dist: typing-extensions>=4.9; python_version < "3.13"
Provides-Extra: test
Requires-Dist: pytest-rerunfailures; extra == "test"
Requires-Dist: pretend; extra == "test"
@@ -96,6 +95,32 @@
Release Information
===================
+26.3.0 (2026-06-12)
+-------------------
+
+Backward-incompatible changes:
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+- Dropped support for Python 3.8.
+- The minimum ``cryptography`` version is now 49.0.0.
+- Removed deprecated ``OpenSSL.crypto.X509Req``,
``OpenSSL.crypto.dump_certificate_request``, and
``OpenSSL.crypto.load_certificate_request``. ``cryptography.x509`` should be
used instead.
+- ``OpenSSL.SSL.Connection.set_session`` now raises ``ValueError`` if the
``Session`` was obtained from a ``Connection`` that was using a different
``Context`` than this one. OpenSSL requires (but does not verify) that sessions
only be re-used with a compatible ``SSL_CTX``, so this contract is now enforced.
+
+Deprecations:
+^^^^^^^^^^^^^
+
+- Deprecated ``OpenSSL.crypto.PKey.generate_key`` and
``OpenSSL.crypto.PKey.check``. The key generation and loading APIs in
``cryptography`` should be used instead.
+- Deprecated ``OpenSSL.crypto.dump_privatekey``. The serialization APIs on
``cryptography`` private key types should be used instead.
+- Deprecated all the mutable APIs on ``OpenSSL.crypto.X509``: ``set_version``,
``set_pubkey``, ``sign``, ``set_serial_number``, ``gmtime_adj_notAfter``,
``gmtime_adj_notBefore``, ``set_notBefore``, ``set_notAfter``, ``set_issuer``,
and ``set_subject``. ``cryptography.x509.CertificateBuilder`` should be used
instead.
+- Deprecated ``OpenSSL.SSL.Context.set_passwd_cb``. Users should decrypt and
load their private keys themselves, with ``cryptography``'s key loading APIs,
and then call ``OpenSSL.SSL.Context.use_privatekey``.
+- Deprecated ``OpenSSL.crypto.X509Name``, as well as the remaining APIs that
consume or return it: ``OpenSSL.crypto.X509.get_issuer``,
``OpenSSL.crypto.X509.get_subject``, and
``OpenSSL.SSL.Context.set_client_ca_list``. The APIs in ``cryptography.x509``
should be used instead.
+
+Changes:
+^^^^^^^^
+
+- ``OpenSSL.SSL.Connection.get_client_ca_list`` now takes an
``as_cryptography`` keyword-argument. When ``True`` is passed then
``cryptography.x509.Name`` are returned, instead of
``OpenSSL.crypto.X509Name``. In the future, passing ``False`` (the default)
will be deprecated.
+
+
26.2.0 (2026-05-04)
-------------------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pyopenssl-26.2.0/doc/api/crypto.rst
new/pyopenssl-26.3.0/doc/api/crypto.rst
--- old/pyopenssl-26.2.0/doc/api/crypto.rst 2026-05-05 01:05:30.000000000
+0200
+++ new/pyopenssl-26.3.0/doc/api/crypto.rst 2026-06-12 22:27:26.000000000
+0200
@@ -12,7 +12,7 @@
`pyca/cryptography`_ is likely a better choice than using this module.
It contains a complete set of cryptographic primitives as well as a
significantly better and more powerful X509 API.
- If necessary you can convert to and from cryptography objects using the
``to_cryptography`` and ``from_cryptography`` methods on ``X509``, ``X509Req``,
``CRL``, and ``PKey``.
+ If necessary you can convert to and from cryptography objects using the
``to_cryptography`` and ``from_cryptography`` methods on ``X509``, ``CRL``, and
``PKey``.
Elliptic curves
@@ -42,13 +42,6 @@
.. autofunction:: load_certificate
-Certificate signing requests
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. autofunction:: dump_certificate_request
-
-.. autofunction:: load_certificate_request
-
Private keys
~~~~~~~~~~~~
@@ -82,16 +75,6 @@
:special-members:
:exclude-members: __repr__, __getattr__, __weakref__
-.. _openssl-x509req:
-
-X509Req objects
----------------
-
-.. autoclass:: X509Req
- :members:
- :special-members:
- :exclude-members: __weakref__
-
.. _openssl-x509store:
X509Store objects
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pyopenssl-26.2.0/doc/introduction.rst
new/pyopenssl-26.3.0/doc/introduction.rst
--- old/pyopenssl-26.2.0/doc/introduction.rst 2026-05-05 01:05:30.000000000
+0200
+++ new/pyopenssl-26.3.0/doc/introduction.rst 2026-06-12 22:27:26.000000000
+0200
@@ -14,7 +14,7 @@
Later it was maintained by `Jean-Paul Calderone`_ who among other things
managed to make pyOpenSSL a pure Python project which the current maintainers
are *very* grateful for.
Over the time the standard library's ``ssl`` module improved, never reaching
the completeness of pyOpenSSL's API coverage.
-pyOpenSSL remains the only choice for full-featured TLS code in Python
versions 3.8+ and PyPy_.
+pyOpenSSL remains the only choice for full-featured TLS code in Python
versions 3.9+ and PyPy_.
Development
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pyopenssl-26.2.0/noxfile.py
new/pyopenssl-26.3.0/noxfile.py
--- old/pyopenssl-26.2.0/noxfile.py 2026-05-05 01:05:30.000000000 +0200
+++ new/pyopenssl-26.3.0/noxfile.py 2026-06-12 22:27:26.000000000 +0200
@@ -3,7 +3,7 @@
nox.options.reuse_existing_virtualenvs = True
nox.options.default_venv_backend = "uv|virtualenv"
-MINIMUM_CRYPTOGRAPHY_VERSION = "46.0.0"
+MINIMUM_CRYPTOGRAPHY_VERSION = "49.0.0"
@nox.session
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pyopenssl-26.2.0/setup.py
new/pyopenssl-26.3.0/setup.py
--- old/pyopenssl-26.2.0/setup.py 2026-05-05 01:05:30.000000000 +0200
+++ new/pyopenssl-26.3.0/setup.py 2026-06-12 22:27:26.000000000 +0200
@@ -77,7 +77,6 @@
"Operating System :: Microsoft :: Windows",
"Operating System :: POSIX",
"Programming Language :: Python :: 3",
- "Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
@@ -89,15 +88,12 @@
"Topic :: Software Development :: Libraries :: Python Modules",
"Topic :: System :: Networking",
],
- python_requires=">=3.8",
+ python_requires=">=3.9",
packages=find_packages(where="src"),
package_dir={"": "src"},
install_requires=[
- "cryptography>=46.0.0,<49",
- (
- "typing-extensions>=4.9; "
- "python_version < '3.13' and python_version >= '3.8'"
- ),
+ "cryptography>=49.0.0,<50",
+ "typing-extensions>=4.9; python_version < '3.13'",
],
extras_require={
"test": ["pytest-rerunfailures", "pretend", "pytest>=3.0.1"],
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pyopenssl-26.2.0/src/OpenSSL/SSL.py
new/pyopenssl-26.3.0/src/OpenSSL/SSL.py
--- old/pyopenssl-26.2.0/src/OpenSSL/SSL.py 2026-05-05 01:05:30.000000000
+0200
+++ new/pyopenssl-26.3.0/src/OpenSSL/SSL.py 2026-06-12 22:27:26.000000000
+0200
@@ -13,6 +13,11 @@
from typing import Any, Callable, Optional, TypeVar
from weakref import WeakValueDictionary
+if sys.version_info >= (3, 13):
+ from warnings import deprecated
+else:
+ from typing_extensions import deprecated
+
from cryptography import x509
from cryptography.hazmat.primitives.asymmetric import ec
@@ -847,6 +852,11 @@
"""
_session: Any
+ # The Context the Connection this Session came from was using. OpenSSL
+ # requires that a session only be re-used with a compatible SSL_CTX, but
+ # doesn't verify it, so we pin the Context here and enforce identity in
+ # Connection.set_session.
+ _context: Context
F = TypeVar("F", bound=Callable[..., Any])
@@ -1016,6 +1026,11 @@
FILETYPE_PEM, wrapper, more_args=True, truncate=True
)
+ @deprecated(
+ "Context.set_passwd_cb is deprecated. You should decrypt and load "
+ "your private key yourself, with cryptography's key loading APIs, "
+ "and then use Context.use_privatekey instead."
+ )
@_require_not_used
def set_passwd_cb(
self,
@@ -1527,6 +1542,10 @@
_lib.SSL_CTX_set_ciphersuites(self._context, ciphersuites) == 1
)
+ @deprecated(
+ "Context.set_client_ca_list is deprecated. X509Name support in "
+ "pyOpenSSL is deprecated."
+ )
@_require_not_used
def set_client_ca_list(
self, certificate_authorities: Sequence[X509Name]
@@ -2628,10 +2647,30 @@
ciphers.append(_ffi.string(result).decode("utf-8"))
return ciphers
- def get_client_ca_list(self) -> list[X509Name]:
+ @typing.overload
+ def get_client_ca_list(
+ self, *, as_cryptography: typing.Literal[True]
+ ) -> list[x509.Name]:
+ pass
+
+ @typing.overload
+ def get_client_ca_list(
+ self, *, as_cryptography: typing.Literal[False] = False
+ ) -> list[X509Name]:
+ pass
+
+ def get_client_ca_list(
+ self,
+ *,
+ as_cryptography: typing.Literal[True] | typing.Literal[False] = False,
+ ) -> list[X509Name] | list[x509.Name]:
"""
Get CAs whose certificates are suggested for client authentication.
+ :param bool as_cryptography: Controls whether a list of
+ ``cryptography.x509.Name`` or ``OpenSSL.crypto.X509Name``
+ objects should be returned.
+
:return: If this is a server connection, the list of certificate
authorities that will be sent or has been sent to the client, as
controlled by this :class:`Connection`'s :class:`Context`.
@@ -2646,13 +2685,28 @@
# TODO: This is untested.
return []
+ if as_cryptography:
+ names = []
+ for i in range(_lib.sk_X509_NAME_num(ca_names)):
+ name = _lib.sk_X509_NAME_value(ca_names, i)
+ result_buffer = _ffi.new("unsigned char**")
+ encode_result = _lib.i2d_X509_NAME(name, result_buffer)
+ _openssl_assert(encode_result >= 0)
+ der = _ffi.buffer(result_buffer[0], encode_result)[:]
+ _lib.OPENSSL_free(result_buffer[0])
+
+ names.append(x509.Name.from_bytes(der))
+ return names
+
result = []
for i in range(_lib.sk_X509_NAME_num(ca_names)):
name = _lib.sk_X509_NAME_value(ca_names, i)
copy = _lib.X509_NAME_dup(name)
_openssl_assert(copy != _ffi.NULL)
- pyname = X509Name.__new__(X509Name)
+ # Bypass X509Name.__new__, which warns that X509Name is
+ # deprecated -- this method is not itself deprecated.
+ pyname = object.__new__(X509Name)
pyname._name = _ffi.gc(copy, _lib.X509_NAME_free)
result.append(pyname)
return result
@@ -3032,12 +3086,18 @@
pysession = Session.__new__(Session)
pysession._session = _ffi.gc(session, _lib.SSL_SESSION_free)
+ pysession._context = self._context
return pysession
def set_session(self, session: Session) -> None:
"""
Set the session to be used when the TLS/SSL connection is established.
+ The session must have been obtained, via :meth:`get_session`, from a
+ :class:`Connection` that was using the same :class:`Context` as this
+ one. OpenSSL requires (but does not verify) that sessions only be
+ re-used with a compatible ``SSL_CTX``, so this is enforced here.
+
:param session: A Session instance representing the session to use.
:returns: None
@@ -3046,6 +3106,12 @@
if not isinstance(session, Session):
raise TypeError("session must be a Session instance")
+ if session._context is not self._context:
+ raise ValueError(
+ "session must have been created by a Connection using the "
+ "same Context as this one"
+ )
+
result = _lib.SSL_set_session(self._ssl, session._session)
_openssl_assert(result == 1)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pyopenssl-26.2.0/src/OpenSSL/_util.py
new/pyopenssl-26.3.0/src/OpenSSL/_util.py
--- old/pyopenssl-26.2.0/src/OpenSSL/_util.py 2026-05-05 01:05:30.000000000
+0200
+++ new/pyopenssl-26.3.0/src/OpenSSL/_util.py 2026-06-12 22:27:26.000000000
+0200
@@ -7,10 +7,7 @@
from cryptography.hazmat.bindings.openssl.binding import Binding
-if sys.version_info >= (3, 9):
- StrOrBytesPath = Union[str, bytes, os.PathLike[str], os.PathLike[bytes]]
-else:
- StrOrBytesPath = Union[str, bytes, os.PathLike]
+StrOrBytesPath = Union[str, bytes, os.PathLike[str], os.PathLike[bytes]]
binding = Binding()
ffi = binding.ffi
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pyopenssl-26.2.0/src/OpenSSL/crypto.py
new/pyopenssl-26.3.0/src/OpenSSL/crypto.py
--- old/pyopenssl-26.2.0/src/OpenSSL/crypto.py 2026-05-05 01:05:30.000000000
+0200
+++ new/pyopenssl-26.3.0/src/OpenSSL/crypto.py 2026-06-12 22:27:26.000000000
+0200
@@ -16,11 +16,6 @@
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
@@ -63,19 +58,16 @@
"Error",
"PKey",
"X509Name",
- "X509Req",
"X509Store",
"X509StoreContext",
"X509StoreContextError",
"X509StoreFlags",
"dump_certificate",
- "dump_certificate_request",
"dump_privatekey",
"dump_publickey",
"get_elliptic_curve",
"get_elliptic_curves",
"load_certificate",
- "load_certificate_request",
"load_privatekey",
"load_publickey",
]
@@ -275,7 +267,7 @@
der = dump_publickey(FILETYPE_ASN1, self)
return typing.cast(_Key, load_der_public_key(der))
else:
- der = dump_privatekey(FILETYPE_ASN1, self)
+ der = _dump_privatekey_internal(FILETYPE_ASN1, self)
return typing.cast(_Key, load_der_private_key(der, password=None))
@classmethod
@@ -336,6 +328,10 @@
)
return load_privatekey(FILETYPE_ASN1, der)
+ @deprecated(
+ "PKey.generate_key is deprecated. You should use the key "
+ "generation APIs in cryptography instead."
+ )
def generate_key(self, type: int, bits: int) -> None:
"""
Generate a key pair of the given type, with the given number of bits.
@@ -392,6 +388,10 @@
self._initialized = True
+ @deprecated(
+ "PKey.check is deprecated. You should use the APIs in "
+ "cryptography instead."
+ )
def check(self) -> bool:
"""
Check the consistency of an RSA private key.
@@ -579,6 +579,10 @@
raise ValueError("unknown curve name", name)
+@deprecated(
+ "X509Name support in pyOpenSSL is deprecated. You should use the "
+ "APIs in cryptography."
+)
@functools.total_ordering
class X509Name:
"""
@@ -774,181 +778,6 @@
return result
-@deprecated(
- "CSR support in pyOpenSSL is deprecated. You should use the APIs "
- "in cryptography."
-)
-class X509Req:
- """
- An X.509 certificate signing requests.
-
- .. deprecated:: 24.2.0
- Use `cryptography.x509.CertificateSigningRequest` instead.
- """
-
- def __init__(self) -> None:
- req = _lib.X509_REQ_new()
- self._req = _ffi.gc(req, _lib.X509_REQ_free)
- # Default to version 0.
- self.set_version(0)
-
- def to_cryptography(self) -> x509.CertificateSigningRequest:
- """
- Export as a ``cryptography`` certificate signing request.
-
- :rtype: ``cryptography.x509.CertificateSigningRequest``
-
- .. versionadded:: 17.1.0
- """
- from cryptography.x509 import load_der_x509_csr
-
- der = _dump_certificate_request_internal(FILETYPE_ASN1, self)
-
- return load_der_x509_csr(der)
-
- @classmethod
- def from_cryptography(
- cls, crypto_req: x509.CertificateSigningRequest
- ) -> X509Req:
- """
- Construct based on a ``cryptography`` *crypto_req*.
-
- :param crypto_req: A ``cryptography`` X.509 certificate signing request
- :type crypto_req: ``cryptography.x509.CertificateSigningRequest``
-
- :rtype: X509Req
-
- .. versionadded:: 17.1.0
- """
- if not isinstance(crypto_req, x509.CertificateSigningRequest):
- raise TypeError("Must be a certificate signing request")
-
- from cryptography.hazmat.primitives.serialization import Encoding
-
- der = crypto_req.public_bytes(Encoding.DER)
- return _load_certificate_request_internal(FILETYPE_ASN1, der)
-
- def set_pubkey(self, pkey: PKey) -> None:
- """
- Set the public key of the certificate signing request.
-
- :param pkey: The public key to use.
- :type pkey: :py:class:`PKey`
-
- :return: ``None``
- """
- set_result = _lib.X509_REQ_set_pubkey(self._req, pkey._pkey)
- _openssl_assert(set_result == 1)
-
- def get_pubkey(self) -> PKey:
- """
- Get the public key of the certificate signing request.
-
- :return: The public key.
- :rtype: :py:class:`PKey`
- """
- pkey = PKey.__new__(PKey)
- pkey._pkey = _lib.X509_REQ_get_pubkey(self._req)
- _openssl_assert(pkey._pkey != _ffi.NULL)
- pkey._pkey = _ffi.gc(pkey._pkey, _lib.EVP_PKEY_free)
- pkey._only_public = True
- return pkey
-
- def set_version(self, version: int) -> None:
- """
- Set the version subfield (RFC 2986, section 4.1) of the certificate
- request.
-
- :param int version: The version number.
- :return: ``None``
- """
- if not isinstance(version, int):
- raise TypeError("version must be an int")
- if version != 0:
- raise ValueError(
- "Invalid version. The only valid version for X509Req is 0."
- )
- set_result = _lib.X509_REQ_set_version(self._req, version)
- _openssl_assert(set_result == 1)
-
- def get_version(self) -> int:
- """
- Get the version subfield (RFC 2459, section 4.1.2.1) of the certificate
- request.
-
- :return: The value of the version subfield.
- :rtype: :py:class:`int`
- """
- return _lib.X509_REQ_get_version(self._req)
-
- def get_subject(self) -> X509Name:
- """
- Return the subject of this certificate signing request.
-
- This creates a new :class:`X509Name` that wraps the underlying subject
- name field on the certificate signing request. Modifying it will modify
- the underlying signing request, and will have the effect of modifying
- any other :class:`X509Name` that refers to this subject.
-
- :return: The subject of this certificate signing request.
- :rtype: :class:`X509Name`
- """
- name = X509Name.__new__(X509Name)
- name._name = _lib.X509_REQ_get_subject_name(self._req)
- _openssl_assert(name._name != _ffi.NULL)
-
- # The name is owned by the X509Req structure. As long as the X509Name
- # Python object is alive, keep the X509Req Python object alive.
- name._owner = self
-
- return name
-
- def sign(self, pkey: PKey, digest: str) -> None:
- """
- Sign the certificate signing request with this key and digest type.
-
- :param pkey: The key pair to sign with.
- :type pkey: :py:class:`PKey`
- :param digest: The name of the message digest to use for the signature,
- e.g. :py:data:`"sha256"`.
- :type digest: :py:class:`str`
- :return: ``None``
- """
- if pkey._only_public:
- raise ValueError("Key has only public part")
-
- if not pkey._initialized:
- raise ValueError("Key is uninitialized")
-
- digest_obj = _lib.EVP_get_digestbyname(_byte_string(digest))
- if digest_obj == _ffi.NULL:
- raise ValueError("No such digest method")
-
- sign_result = _lib.X509_REQ_sign(self._req, pkey._pkey, digest_obj)
- _openssl_assert(sign_result > 0)
-
- def verify(self, pkey: PKey) -> bool:
- """
- Verifies the signature on this certificate signing request.
-
- :param PKey key: A public key.
-
- :return: ``True`` if the signature is correct.
- :rtype: bool
-
- :raises OpenSSL.crypto.Error: If the signature is invalid or there is a
- problem verifying the signature.
- """
- if not isinstance(pkey, PKey):
- raise TypeError("pkey must be a PKey instance")
-
- result = _lib.X509_REQ_verify(self._req, pkey._pkey)
- if result <= 0:
- _raise_current_error()
-
- return result
-
-
class X509:
"""
An X.509 certificate.
@@ -1003,6 +832,10 @@
der = crypto_cert.public_bytes(Encoding.DER)
return load_certificate(FILETYPE_ASN1, der)
+ @deprecated(
+ "X509.set_version is deprecated. You should use "
+ "cryptography's CertificateBuilder instead."
+ )
def set_version(self, version: int) -> None:
"""
Set the version number of the certificate. Note that the
@@ -1042,6 +875,10 @@
pkey._only_public = True
return pkey
+ @deprecated(
+ "X509.set_pubkey is deprecated. You should use "
+ "cryptography's CertificateBuilder instead."
+ )
def set_pubkey(self, pkey: PKey) -> None:
"""
Set the public key of the certificate.
@@ -1057,6 +894,10 @@
set_result = _lib.X509_set_pubkey(self._x509, pkey._pkey)
_openssl_assert(set_result == 1)
+ @deprecated(
+ "X509.sign is deprecated. You should use "
+ "cryptography's CertificateBuilder instead."
+ )
def sign(self, pkey: PKey, digest: str) -> None:
"""
Sign the certificate with this key and digest type.
@@ -1144,6 +985,10 @@
"""
return _lib.X509_subject_name_hash(self._x509)
+ @deprecated(
+ "X509.set_serial_number is deprecated. You should use "
+ "cryptography's CertificateBuilder instead."
+ )
def set_serial_number(self, serial: int) -> None:
"""
Set the serial number of the certificate.
@@ -1192,6 +1037,10 @@
finally:
_lib.BN_free(bignum_serial)
+ @deprecated(
+ "X509.gmtime_adj_notAfter is deprecated. You should use "
+ "cryptography's CertificateBuilder instead."
+ )
def gmtime_adj_notAfter(self, amount: int) -> None:
"""
Adjust the time stamp on which the certificate stops being valid.
@@ -1206,6 +1055,10 @@
notAfter = _lib.X509_getm_notAfter(self._x509)
_lib.X509_gmtime_adj(notAfter, amount)
+ @deprecated(
+ "X509.gmtime_adj_notBefore is deprecated. You should use "
+ "cryptography's CertificateBuilder instead."
+ )
def gmtime_adj_notBefore(self, amount: int) -> None:
"""
Adjust the timestamp on which the certificate starts being valid.
@@ -1257,6 +1110,10 @@
) -> None:
return _set_asn1_time(which(self._x509), when)
+ @deprecated(
+ "X509.set_notBefore is deprecated. You should use "
+ "cryptography's CertificateBuilder instead."
+ )
def set_notBefore(self, when: bytes) -> None:
"""
Set the timestamp at which the certificate starts being valid.
@@ -1283,6 +1140,10 @@
"""
return self._get_boundary_time(_lib.X509_getm_notAfter)
+ @deprecated(
+ "X509.set_notAfter is deprecated. You should use "
+ "cryptography's CertificateBuilder instead."
+ )
def set_notAfter(self, when: bytes) -> None:
"""
Set the timestamp at which the certificate stops being valid.
@@ -1297,7 +1158,9 @@
return self._set_boundary_time(_lib.X509_getm_notAfter, when)
def _get_name(self, which: Any) -> X509Name:
- name = X509Name.__new__(X509Name)
+ # Bypass X509Name.__new__, which warns that X509Name is deprecated;
+ # callers that should warn are decorated individually.
+ name = object.__new__(X509Name)
name._name = which(self._x509)
_openssl_assert(name._name != _ffi.NULL)
@@ -1313,6 +1176,10 @@
set_result = which(self._x509, name._name)
_openssl_assert(set_result == 1)
+ @deprecated(
+ "X509.get_issuer is deprecated. You should use "
+ "cryptography's X.509 APIs instead."
+ )
def get_issuer(self) -> X509Name:
"""
Return the issuer of this certificate.
@@ -1329,6 +1196,10 @@
self._issuer_invalidator.add(name)
return name
+ @deprecated(
+ "X509.set_issuer is deprecated. You should use "
+ "cryptography's CertificateBuilder instead."
+ )
def set_issuer(self, issuer: X509Name) -> None:
"""
Set the issuer of this certificate.
@@ -1341,6 +1212,10 @@
self._set_name(_lib.X509_set_issuer_name, issuer)
self._issuer_invalidator.clear()
+ @deprecated(
+ "X509.get_subject is deprecated. You should use "
+ "cryptography's X.509 APIs instead."
+ )
def get_subject(self) -> X509Name:
"""
Return the subject of this certificate.
@@ -1357,6 +1232,10 @@
self._subject_invalidator.add(name)
return name
+ @deprecated(
+ "X509.set_subject is deprecated. You should use "
+ "cryptography's CertificateBuilder instead."
+ )
def set_subject(self, subject: X509Name) -> None:
"""
Set the subject of this certificate.
@@ -1851,6 +1730,10 @@
:return: The buffer with the dumped key in
:rtype: bytes
+
+ .. deprecated:: 26.3.0
+ Use the serialization APIs on ``cryptography`` private key types
+ instead.
"""
bio = _new_mem_buf()
@@ -1900,6 +1783,20 @@
return _bio_to_string(bio)
+_dump_privatekey_internal = dump_privatekey
+
+utils.deprecated(
+ dump_privatekey,
+ __name__,
+ (
+ "dump_privatekey is deprecated. You should use the APIs in "
+ "cryptography."
+ ),
+ DeprecationWarning,
+ name="dump_privatekey",
+)
+
+
class _PassphraseHelper:
def __init__(
self,
@@ -2051,95 +1948,3 @@
pkey = PKey.__new__(PKey)
pkey._pkey = _ffi.gc(evp_pkey, _lib.EVP_PKEY_free)
return pkey
-
-
-def dump_certificate_request(type: int, req: X509Req) -> bytes:
- """
- Dump the certificate request *req* into a buffer string encoded with the
- type *type*.
-
- :param type: The file type (one of FILETYPE_PEM, FILETYPE_ASN1)
- :param req: The certificate request to dump
- :return: The buffer with the dumped certificate request in
-
-
- .. deprecated:: 24.2.0
- Use `cryptography.x509.CertificateSigningRequest` instead.
- """
- bio = _new_mem_buf()
-
- if type == FILETYPE_PEM:
- result_code = _lib.PEM_write_bio_X509_REQ(bio, req._req)
- elif type == FILETYPE_ASN1:
- result_code = _lib.i2d_X509_REQ_bio(bio, req._req)
- elif type == FILETYPE_TEXT:
- result_code = _lib.X509_REQ_print_ex(bio, req._req, 0, 0)
- else:
- raise ValueError(
- "type argument must be FILETYPE_PEM, FILETYPE_ASN1, or "
- "FILETYPE_TEXT"
- )
-
- _openssl_assert(result_code != 0)
-
- return _bio_to_string(bio)
-
-
-_dump_certificate_request_internal = dump_certificate_request
-
-utils.deprecated(
- dump_certificate_request,
- __name__,
- (
- "CSR support in pyOpenSSL is deprecated. You should use the APIs "
- "in cryptography."
- ),
- DeprecationWarning,
- name="dump_certificate_request",
-)
-
-
-def load_certificate_request(type: int, buffer: bytes) -> X509Req:
- """
- Load a certificate request (X509Req) from the string *buffer* encoded with
- the type *type*.
-
- :param type: The file type (one of FILETYPE_PEM, FILETYPE_ASN1)
- :param buffer: The buffer the certificate request is stored in
- :return: The X509Req object
-
- .. deprecated:: 24.2.0
- Use `cryptography.x509.load_der_x509_csr` or
- `cryptography.x509.load_pem_x509_csr` instead.
- """
- if isinstance(buffer, str):
- buffer = buffer.encode("ascii")
-
- bio = _new_mem_buf(buffer)
-
- if type == FILETYPE_PEM:
- req = _lib.PEM_read_bio_X509_REQ(bio, _ffi.NULL, _ffi.NULL, _ffi.NULL)
- elif type == FILETYPE_ASN1:
- req = _lib.d2i_X509_REQ_bio(bio, _ffi.NULL)
- else:
- raise ValueError("type argument must be FILETYPE_PEM or FILETYPE_ASN1")
-
- _openssl_assert(req != _ffi.NULL)
-
- x509req = X509Req.__new__(X509Req)
- x509req._req = _ffi.gc(req, _lib.X509_REQ_free)
- return x509req
-
-
-_load_certificate_request_internal = load_certificate_request
-
-utils.deprecated(
- load_certificate_request,
- __name__,
- (
- "CSR support in pyOpenSSL is deprecated. You should use the APIs "
- "in cryptography."
- ),
- DeprecationWarning,
- name="load_certificate_request",
-)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pyopenssl-26.2.0/src/OpenSSL/version.py
new/pyopenssl-26.3.0/src/OpenSSL/version.py
--- old/pyopenssl-26.2.0/src/OpenSSL/version.py 2026-05-05 01:05:30.000000000
+0200
+++ new/pyopenssl-26.3.0/src/OpenSSL/version.py 2026-06-12 22:27:26.000000000
+0200
@@ -17,7 +17,7 @@
"__version__",
]
-__version__ = "26.2.0"
+__version__ = "26.3.0"
__title__ = "pyOpenSSL"
__uri__ = "https://pyopenssl.org/"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pyopenssl-26.2.0/src/pyOpenSSL.egg-info/PKG-INFO
new/pyopenssl-26.3.0/src/pyOpenSSL.egg-info/PKG-INFO
--- old/pyopenssl-26.2.0/src/pyOpenSSL.egg-info/PKG-INFO 2026-05-05
01:05:34.000000000 +0200
+++ new/pyopenssl-26.3.0/src/pyOpenSSL.egg-info/PKG-INFO 2026-06-12
22:27:29.000000000 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 2.4
Name: pyOpenSSL
-Version: 26.2.0
+Version: 26.3.0
Summary: Python wrapper module around the OpenSSL library
Home-page: https://pyopenssl.org/
Author: The pyOpenSSL developers
@@ -14,7 +14,6 @@
Classifier: Operating System :: Microsoft :: Windows
Classifier: Operating System :: POSIX
Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
@@ -25,10 +24,10 @@
Classifier: Topic :: Security :: Cryptography
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: System :: Networking
-Requires-Python: >=3.8
+Requires-Python: >=3.9
License-File: LICENSE
-Requires-Dist: cryptography<49,>=46.0.0
-Requires-Dist: typing-extensions>=4.9; python_version < "3.13" and
python_version >= "3.8"
+Requires-Dist: cryptography<50,>=49.0.0
+Requires-Dist: typing-extensions>=4.9; python_version < "3.13"
Provides-Extra: test
Requires-Dist: pytest-rerunfailures; extra == "test"
Requires-Dist: pretend; extra == "test"
@@ -96,6 +95,32 @@
Release Information
===================
+26.3.0 (2026-06-12)
+-------------------
+
+Backward-incompatible changes:
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+- Dropped support for Python 3.8.
+- The minimum ``cryptography`` version is now 49.0.0.
+- Removed deprecated ``OpenSSL.crypto.X509Req``,
``OpenSSL.crypto.dump_certificate_request``, and
``OpenSSL.crypto.load_certificate_request``. ``cryptography.x509`` should be
used instead.
+- ``OpenSSL.SSL.Connection.set_session`` now raises ``ValueError`` if the
``Session`` was obtained from a ``Connection`` that was using a different
``Context`` than this one. OpenSSL requires (but does not verify) that sessions
only be re-used with a compatible ``SSL_CTX``, so this contract is now enforced.
+
+Deprecations:
+^^^^^^^^^^^^^
+
+- Deprecated ``OpenSSL.crypto.PKey.generate_key`` and
``OpenSSL.crypto.PKey.check``. The key generation and loading APIs in
``cryptography`` should be used instead.
+- Deprecated ``OpenSSL.crypto.dump_privatekey``. The serialization APIs on
``cryptography`` private key types should be used instead.
+- Deprecated all the mutable APIs on ``OpenSSL.crypto.X509``: ``set_version``,
``set_pubkey``, ``sign``, ``set_serial_number``, ``gmtime_adj_notAfter``,
``gmtime_adj_notBefore``, ``set_notBefore``, ``set_notAfter``, ``set_issuer``,
and ``set_subject``. ``cryptography.x509.CertificateBuilder`` should be used
instead.
+- Deprecated ``OpenSSL.SSL.Context.set_passwd_cb``. Users should decrypt and
load their private keys themselves, with ``cryptography``'s key loading APIs,
and then call ``OpenSSL.SSL.Context.use_privatekey``.
+- Deprecated ``OpenSSL.crypto.X509Name``, as well as the remaining APIs that
consume or return it: ``OpenSSL.crypto.X509.get_issuer``,
``OpenSSL.crypto.X509.get_subject``, and
``OpenSSL.SSL.Context.set_client_ca_list``. The APIs in ``cryptography.x509``
should be used instead.
+
+Changes:
+^^^^^^^^
+
+- ``OpenSSL.SSL.Connection.get_client_ca_list`` now takes an
``as_cryptography`` keyword-argument. When ``True`` is passed then
``cryptography.x509.Name`` are returned, instead of
``OpenSSL.crypto.X509Name``. In the future, passing ``False`` (the default)
will be deprecated.
+
+
26.2.0 (2026-05-04)
-------------------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pyopenssl-26.2.0/src/pyOpenSSL.egg-info/requires.txt
new/pyopenssl-26.3.0/src/pyOpenSSL.egg-info/requires.txt
--- old/pyopenssl-26.2.0/src/pyOpenSSL.egg-info/requires.txt 2026-05-05
01:05:34.000000000 +0200
+++ new/pyopenssl-26.3.0/src/pyOpenSSL.egg-info/requires.txt 2026-06-12
22:27:29.000000000 +0200
@@ -1,6 +1,6 @@
-cryptography<49,>=46.0.0
+cryptography<50,>=49.0.0
-[:python_version < "3.13" and python_version >= "3.8"]
+[:python_version < "3.13"]
typing-extensions>=4.9
[docs]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pyopenssl-26.2.0/tests/test_crypto.py
new/pyopenssl-26.3.0/tests/test_crypto.py
--- old/pyopenssl-26.2.0/tests/test_crypto.py 2026-05-05 01:05:30.000000000
+0200
+++ new/pyopenssl-26.3.0/tests/test_crypto.py 2026-06-12 22:27:26.000000000
+0200
@@ -37,7 +37,6 @@
Error,
PKey,
X509Name,
- X509Req,
X509Store,
X509StoreContext,
X509StoreContextError,
@@ -46,13 +45,11 @@
_Key,
_PrivateKey,
dump_certificate,
- dump_certificate_request,
dump_privatekey,
dump_publickey,
get_elliptic_curve,
get_elliptic_curves,
load_certificate,
- load_certificate_request,
load_privatekey,
load_publickey,
)
@@ -491,19 +488,6 @@
"""
)
-cleartextCertificateRequestPEM = b"""-----BEGIN CERTIFICATE REQUEST-----
-MIIBnjCCAQcCAQAwXjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAklMMRAwDgYDVQQH
-EwdDaGljYWdvMRcwFQYDVQQKEw5NeSBDb21wYW55IEx0ZDEXMBUGA1UEAxMORnJl
-ZGVyaWNrIERlYW4wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANp6Y17WzKSw
-BsUWkXdqg6tnXy8H8hA1msCMWpc+/2KJ4mbv5NyD6UD+/SqagQqulPbF/DFea9nA
-E0zhmHJELcM8gUTIlXv/cgDWnmK4xj8YkjVUiCdqKRAKeuzLG1pGmwwF5lGeJpXN
-xQn5ecR0UYSOWj6TTGXB9VyUMQzCClcBAgMBAAGgADANBgkqhkiG9w0BAQUFAAOB
-gQAAJGuF/R/GGbeC7FbFW+aJgr9ee0Xbl6nlhu7pTe67k+iiKT2dsl2ti68MVTnu
-Vrb3HUNqOkiwsJf6kCtq5oPn3QVYzTa76Dt2y3Rtzv6boRSlmlfrgS92GNma8JfR
-oICQk3nAudi6zl1Dix3BCv1pUp5KMtGn3MeDEi6QFGy2rA==
------END CERTIFICATE REQUEST-----
-"""
-
encryptedPrivateKeyPEM = b"""-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,9573604A18579E9E
@@ -805,13 +789,10 @@
# Basic setup stuff to generate a certificate
pkey = PKey()
pkey.generate_key(TYPE_RSA, 2048)
- req = X509Req()
- req.set_pubkey(pkey)
- # Authority good you have.
- req.get_subject().commonName = "Yoda root CA"
x509 = X509()
subject = x509.get_subject()
- subject.commonName = req.get_subject().commonName
+ # Authority good you have.
+ subject.commonName = "Yoda root CA"
x509.set_issuer(subject)
x509.set_pubkey(pkey)
now = datetime.now()
@@ -1391,170 +1372,6 @@
setattr(name, "O", b"x" * 512)
-class TestX509Req:
- """
- Tests for `OpenSSL.crypto.X509Req`.
- """
-
- def test_sign_with_ungenerated(self) -> None:
- """
- `X509Req.sign` raises `ValueError` when passed a `PKey` with no parts.
- """
- request = X509Req()
- key = PKey()
- with pytest.raises(ValueError):
- request.sign(key, GOOD_DIGEST)
-
- def test_sign_with_public_key(self) -> None:
- """
- `X509Req.sign` raises `ValueError` when passed a `PKey` with no private
- part as the signing key.
- """
- request = X509Req()
- key = PKey()
- key.generate_key(TYPE_RSA, 2048)
- request.set_pubkey(key)
- pub = request.get_pubkey()
- with pytest.raises(ValueError):
- request.sign(pub, GOOD_DIGEST)
-
- def test_sign_with_unknown_digest(self) -> None:
- """
- `X509Req.sign` raises `ValueError` when passed a digest name which is
- not known.
- """
- request = X509Req()
- key = PKey()
- key.generate_key(TYPE_RSA, 2048)
- with pytest.raises(ValueError):
- request.sign(key, BAD_DIGEST)
-
- def test_sign(self) -> None:
- """
- `X509Req.sign` succeeds when passed a private key object and a
- valid digest function. `X509Req.verify` can be used to check
- the signature.
- """
- request = X509Req()
- key = PKey()
- key.generate_key(TYPE_RSA, 2048)
- request.set_pubkey(key)
- request.sign(key, GOOD_DIGEST)
- # If the type has a verify method, cover that too.
- if getattr(request, "verify", None) is not None:
- pub = request.get_pubkey()
- assert request.verify(pub)
- # Make another key that won't verify.
- key = PKey()
- key.generate_key(TYPE_RSA, 2048)
- with pytest.raises(Error):
- request.verify(key)
-
- def test_construction(self) -> None:
- """
- `X509Req` takes no arguments and returns an `X509Req` instance.
- """
- request = X509Req()
- assert isinstance(request, X509Req)
-
- def test_version(self) -> None:
- """
- `X509Req.set_version` sets the X.509 version of the certificate
- request. `X509Req.get_version` returns the X.509 version of the
- certificate request. The only defined version is 0.
- """
- request = X509Req()
- assert request.get_version() == 0
- request.set_version(0)
- assert request.get_version() == 0
-
- def test_version_wrong_args(self) -> None:
- """
- `X509Req.set_version` raises `TypeError` if called with a non-`int`
- argument.
- """
- request = X509Req()
- with pytest.raises(TypeError):
- request.set_version("foo") # type: ignore[arg-type]
- with pytest.raises(ValueError):
- request.set_version(2)
-
- def test_get_subject(self) -> None:
- """
- `X509Req.get_subject` returns an `X509Name` for the subject of the
- request and which is valid even after the request object is
- otherwise dead.
- """
- request = X509Req()
- subject = request.get_subject()
- assert isinstance(subject, X509Name)
- subject.commonName = "foo"
- assert request.get_subject().commonName == "foo"
- del request
- subject.commonName = "bar"
- assert subject.commonName == "bar"
-
- def test_verify_wrong_args(self) -> None:
- """
- `X509Req.verify` raises `TypeError` if passed anything other than a
- `PKey` instance as its single argument.
- """
- request = X509Req()
- with pytest.raises(TypeError):
- request.verify(object()) # type: ignore[arg-type]
-
- def test_verify_uninitialized_key(self) -> None:
- """
- `X509Req.verify` raises `OpenSSL.crypto.Error` if called with a
- `OpenSSL.crypto.PKey` which contains no key data.
- """
- request = X509Req()
- pkey = PKey()
- with pytest.raises(Error):
- request.verify(pkey)
-
- def test_verify_wrong_key(self) -> None:
- """
- `X509Req.verify` raises `OpenSSL.crypto.Error` if called with a
- `OpenSSL.crypto.PKey` which does not represent the public part of the
- key which signed the request.
- """
- request = X509Req()
- pkey = load_privatekey(FILETYPE_PEM, root_key_pem)
- request.set_pubkey(pkey)
- request.sign(pkey, GOOD_DIGEST)
- another_pkey = load_privatekey(FILETYPE_PEM, client_key_pem)
- with pytest.raises(Error):
- request.verify(another_pkey)
-
- def test_verify_success(self) -> None:
- """
- `X509Req.verify` returns `True` if called with a `OpenSSL.crypto.PKey`
- which represents the public part of the key which signed the request.
- """
- request = X509Req()
- pkey = load_privatekey(FILETYPE_PEM, root_key_pem)
- request.set_pubkey(pkey)
- request.sign(pkey, GOOD_DIGEST)
- assert request.verify(pkey)
-
- def test_convert_from_cryptography(self) -> None:
- crypto_req = x509.load_pem_x509_csr(cleartextCertificateRequestPEM)
- req = X509Req.from_cryptography(crypto_req)
- assert isinstance(req, X509Req)
-
- def test_convert_from_cryptography_unsupported_type(self) -> None:
- with pytest.raises(TypeError):
- X509Req.from_cryptography(object()) # type: ignore[arg-type]
-
- def test_convert_to_cryptography_key(self) -> None:
- req = load_certificate_request(
- FILETYPE_PEM, cleartextCertificateRequestPEM
- )
- crypto_req = req.to_cryptography()
- assert isinstance(crypto_req, x509.CertificateSigningRequest)
-
-
class TestX509:
"""
Tests for `OpenSSL.crypto.X509`.
@@ -1598,8 +1415,7 @@
def test_sign(self) -> None:
"""
`X509.sign` succeeds when passed a private key object and a
- valid digest function. `X509Req.verify` can be used to check
- the signature.
+ valid digest function.
"""
cert = X509()
key = PKey()
@@ -2528,26 +2344,6 @@
with pytest.raises(ValueError):
dump_publickey(FILETYPE_TEXT, key)
- def test_dump_certificate_request(self) -> None:
- """
- `dump_certificate_request` writes a PEM, DER, and text.
- """
- req = load_certificate_request(
- FILETYPE_PEM, cleartextCertificateRequestPEM
- )
- dumped_pem = dump_certificate_request(FILETYPE_PEM, req)
- assert dumped_pem == cleartextCertificateRequestPEM
- dumped_der = dump_certificate_request(FILETYPE_ASN1, req)
- good_der = _runopenssl(dumped_pem, b"req", b"-outform", b"DER")
- assert dumped_der == good_der
- req2 = load_certificate_request(FILETYPE_ASN1, dumped_der)
- dumped_pem2 = dump_certificate_request(FILETYPE_PEM, req2)
- assert dumped_pem2 == cleartextCertificateRequestPEM
- dumped_text = dump_certificate_request(FILETYPE_TEXT, req)
- assert len(dumped_text) > 500
- with pytest.raises(ValueError):
- dump_certificate_request(100, req)
-
def test_dump_privatekey_passphrase_callback(self) -> None:
"""
`dump_privatekey` writes an encrypted PEM when given a callback
@@ -2636,17 +2432,15 @@
class TestLoadCertificate:
"""
- Tests for `load_certificate_request`.
+ Tests for `load_certificate`.
"""
def test_bad_file_type(self) -> None:
"""
- If the file type passed to `load_certificate_request` is neither
+ If the file type passed to `load_certificate` is neither
`FILETYPE_PEM` nor `FILETYPE_ASN1` then `ValueError` is raised.
"""
with pytest.raises(ValueError):
- load_certificate_request(object(), b"") # type: ignore[arg-type]
- with pytest.raises(ValueError):
load_certificate(object(), b"") # type: ignore[arg-type]
def test_bad_certificate(self) -> None:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pyopenssl-26.2.0/tests/test_ssl.py
new/pyopenssl-26.3.0/tests/test_ssl.py
--- old/pyopenssl-26.2.0/tests/test_ssl.py 2026-05-05 01:05:30.000000000
+0200
+++ new/pyopenssl-26.3.0/tests/test_ssl.py 2026-06-12 22:27:26.000000000
+0200
@@ -3108,12 +3108,22 @@
server.set_accept_state()
return server
- originalServer, originalClient = loopback(server_factory=makeServer)
+ clientCtx = Context(SSLv23_METHOD)
+
+ def makeOriginalClient(socket: socket) -> Connection:
+ client = Connection(clientCtx, socket)
+ client.set_connect_state()
+ return client
+
+ originalServer, originalClient = loopback(
+ server_factory=makeServer, client_factory=makeOriginalClient
+ )
originalSession = originalClient.get_session()
assert originalSession is not None
def makeClient(socket: socket) -> Connection:
- client = loopback_client_factory(socket)
+ client = Connection(clientCtx, socket)
+ client.set_connect_state()
client.set_session(originalSession)
return client
@@ -3129,18 +3139,15 @@
# connections is the same, the session was re-used!
assert originalServer.master_key() == resumedServer.master_key()
- def test_set_session_wrong_method(self) -> None:
+ def test_set_session_wrong_context(self) -> None:
"""
- If `Connection.set_session` is passed a `Session` instance associated
- with a context using a different SSL method than the `Connection`
- is using, a `OpenSSL.SSL.Error` is raised.
+ If `Connection.set_session` is passed a `Session` instance that was
+ created by a `Connection` using a different `Context` than the
+ `Connection` is using, a `ValueError` is raised.
"""
- v1 = TLSv1_2_METHOD
- v2 = TLSv1_METHOD
-
key = load_privatekey(FILETYPE_PEM, server_key_pem)
cert = load_certificate(FILETYPE_PEM, server_cert_pem)
- ctx = Context(v1)
+ ctx = Context(TLSv1_2_METHOD)
ctx.use_privatekey(key)
ctx.use_certificate(cert)
ctx.set_session_id(b"unity-test")
@@ -3150,26 +3157,15 @@
server.set_accept_state()
return server
- def makeOriginalClient(socket: socket) -> Connection:
- client = Connection(Context(v1), socket)
- client.set_connect_state()
- return client
-
- _, originalClient = loopback(
- server_factory=makeServer, client_factory=makeOriginalClient
- )
+ _, originalClient = loopback(server_factory=makeServer)
originalSession = originalClient.get_session()
assert originalSession is not None
- def makeClient(socket: socket) -> Connection:
- # Intentionally use a different, incompatible method here.
- client = Connection(Context(v2), socket)
- client.set_connect_state()
+ # Intentionally use a different Context here.
+ client = Connection(Context(SSLv23_METHOD), None)
+ client.set_connect_state()
+ with pytest.raises(ValueError):
client.set_session(originalSession)
- return client
-
- with pytest.raises(Error):
- loopback(client_factory=makeClient, server_factory=makeServer)
def test_wantWriteError(self) -> None:
"""
@@ -4478,6 +4474,26 @@
self._check_client_ca_list(single_ca)
+ def test_get_client_ca_list_as_cryptography(self) -> None:
+ """
+ `Connection.get_client_ca_list` returns a list of
+ `cryptography.x509.Name` when called with ``as_cryptography=True``.
+ """
+ cacert = load_certificate(FILETYPE_PEM, root_cert_pem)
+ expected = [cacert.to_cryptography().subject]
+
+ server_ctx = self._create_server_context()
+ server_ctx.set_client_ca_list([cacert.get_subject()])
+
+ server = self._server(None, server_ctx)
+ client = self._client(None)
+
+ assert client.get_client_ca_list(as_cryptography=True) == []
+ assert server.get_client_ca_list(as_cryptography=True) == expected
+ interact_in_memory(client, server)
+ assert client.get_client_ca_list(as_cryptography=True) == expected
+ assert server.get_client_ca_list(as_cryptography=True) == expected
+
def test_set_multiple_ca_list(self) -> None:
"""
If passed a list containing multiple X509Name objects,