Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .audit/oberstet_fix_2016.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
- [ ] I did **not** use any AI-assistance tools to help create this pull request.
- [x] I **did** use AI-assistance tools to *help* create this pull request.
- [x] I have read, understood and followed the project's AI_POLICY.md when creating code, documentation etc. for this pull request.

Submitted by: @oberstet
Date: 2026-10-20
Related issue(s): #2016
Branch: oberstet:fix_2016
3 changes: 2 additions & 1 deletion docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,15 @@ Changelog
* Fix the TLS peer certificate never being available on Twisted WebSocket and RawSocket connections: it was read when the TCP connection was made, before the TLS handshake, and so was always ``None``. It is now read when the TLS handshake is complete, together with the TLS channel ID. With this, TLS client certificate authentication (Crossbar.io authmethod ``tls``, and dynamic authenticators reading ``transport.peer_cert``) works again (#2014)
* Fix asyncio: fill ``TransportDetails.peer_cert`` (it was always ``None``), and treat a TLS server connection without a client certificate as secure, with a TLS channel ID: ``is_secure`` was derived from the peer certificate, so WAMP-cryptosign with channel binding failed on asyncio servers (#2014)
* **⚠ behaviour change** — the TLS channel ID ``tls-unique`` on Twisted now follows RFC 5929 (the first TLS Finished message of the handshake, in a full handshake the client's), as Python's ``ssl`` module, and so autobahn on asyncio, already did. Twisted used the server's Finished message, so WAMP-cryptosign with channel binding failed between Twisted and asyncio peers over WebSocket, and between Twisted RawSocket peers (whose protocols did not set ``is_server``, so the client side used the wrong message). Twisted peers on autobahn 26.10.1 or older and on 26.10.2 no longer agree on the channel ID over WebSocket: upgrade both sides of connections that use channel binding (#2014)
* Work around a PyPy bug: PyPy's ``ssl`` module (up to at least PyPy 7.3.23) returns the server's TLS Finished message from ``get_channel_binding("tls-unique")`` instead of the first (the client's), so autobahn on asyncio on PyPy disagreed with all other peers on the channel ID. The new ``autobahn.util.tls_unique()`` uses PyPy's own ``tls_unique_cb()`` on PyPy, which returns the right message (#2014)
* Work around a PyPy bug: PyPy's ``ssl`` module (up to at least PyPy 7.3.23) returns the server's TLS Finished message from ``get_channel_binding("tls-unique")`` instead of the first (the client's), so autobahn on asyncio on PyPy disagreed with all other peers on the channel ID. The new ``autobahn.util.tls_unique()`` uses PyPy's own ``tls_unique_cb()`` on PyPy, which returns the right message (#2014; reported as `pypy/pypy#5676 <https://github.com/pypy/pypy/issues/5676>`__)
* ``TransportDetails.is_server`` is now set on Twisted RawSocket and asyncio WebSocket connections (it was ``None``) (#2014)

**Tests & CI/CD**

* Add tests for WAMP over TLS on Twisted and asyncio, over WebSocket and RawSocket, on TLS 1.2 and 1.3, with certificates created per test: the peer certificate, TLS client certificate authentication, WAMP-cryptosign with channel binding, and ``tls-unique`` against Python's ``ssl`` module (#2014)
* Fix ``test_tx_choosereactor`` replacing ``sys.modules`` with a copy, which broke later lazy imports in the same test process (``KeyError: '_strptime'``) (#2014)
* CI runs the asyncio unit tests also when the Twisted unit tests fail, so that both backends always report (#2014)
* Release 26.10.2: changelog, release notes and version (#2016)

26.10.1
-------
Expand Down
35 changes: 35 additions & 0 deletions docs/release-notes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,41 @@ Release Notes
This page provides a high-level overview of important changes in each release.
For detailed technical changes, see the :ref:`changelog <changelog>`.

26.10.2
-------

**Release Type:** Stable release (bug fix)

Highlights
^^^^^^^^^^

* **WAMP over TLS**: the TLS peer certificate (``TransportDetails.peer_cert``) is
read again with pyOpenSSL 26.2.0 and later, and on Twisted WebSocket and
RawSocket connections it is read after the TLS handshake (it was always
``None``), so TLS client certificate authentication works again. On asyncio,
``peer_cert`` is filled, and a TLS server connection without a client
certificate is secure and has a channel ID. The certificate is read with
``cryptography``, in the new ``autobahn.util.peer_certificate_details()``.

* **⚠ TLS channel binding**: ``tls-unique`` on Twisted now follows RFC 5929, as
Python's ``ssl`` module does, so WAMP-cryptosign with channel binding works
between Twisted and asyncio peers. Twisted peers on 26.10.1 or older and on
26.10.2 no longer agree on the channel ID over WebSocket: upgrade both sides of
connections that use channel binding. On PyPy, autobahn works around a PyPy
``ssl`` bug (`pypy/pypy#5676 <https://github.com/pypy/pypy/issues/5676>`__).

* **⚠ peer_cert format**: ``extensions[].value`` is OpenSSL's text only for
subject and issuer alternative names, other extensions are given as
``cryptography`` prints them; ``signature_algorithm`` is ``ed25519`` instead of
``ED25519`` for Ed25519 certificates.

Release Links
^^^^^^^^^^^^^

* `PyPI Package <https://pypi.org/project/autobahn/26.10.2/>`__

**Detailed Changes:** See :ref:`changelog` (26.10.2 section)

26.10.1
-------

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "hatchling.build"

[project]
name = "autobahn"
version = "26.10.2.dev1"
version = "26.10.2"
description = "WebSocket client & server library, WAMP real-time framework"
readme = "README.md"
requires-python = ">=3.11"
Expand Down
2 changes: 1 addition & 1 deletion src/autobahn/_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,6 @@
#
###############################################################################

__version__ = "26.10.2.dev1"
__version__ = "26.10.2"

__build__ = "00000000-0000000"
Loading