Skip to content

Commit 92bd01a

Browse files
committed
Hand-write the CHANGELOG entries this PR needs
The two change types need different descriptions, so the label automation cannot supply them.
1 parent 7c384b1 commit 92bd01a

3 files changed

Lines changed: 23 additions & 19 deletions

File tree

.release-notes/handshake-failures-are-not-authentication-failures.md

Lines changed: 0 additions & 19 deletions
This file was deleted.

.release-notes/next-release.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,24 @@ A failed OpenSSL operation left error state on the scheduler thread that ran it.
66

77
`SSL.read` and `SSL.send` could return uninitialized memory. They no longer do.
88

9+
## Fix handshake failures being reported as authentication failures
10+
11+
`SSLAuthFail` was documented as the peer's certificate failing to verify, but a session reported it after failures that had nothing to do with authenticating the peer: a peer that sent something other than TLS to a TLS port, or two peers with no protocol version in common.
12+
13+
A session now reports `SSLAuthFail` when it required a certificate from its peer and did not get an acceptable one:
14+
15+
- the peer's certificate chain did not verify
16+
- the peer's certificate was not valid for the hostname the session was created with
17+
- the peer presented no certificate at all
18+
19+
Every other failure reports `SSLError`, including a peer that does not speak TLS, a peer that shares no protocol version with the session, and a peer that rejects the certificate the session presented.
20+
21+
## Report SSLAuthFail only for a peer certificate the session would not accept
22+
23+
Three things that reported `SSLAuthFail` before this release report `SSLError` now, and no compile error will point you at them.
24+
25+
A peer that presents a certificate it cannot prove it holds — which is what an impersonator using a copy of a public certificate produces — and a peer whose certificate will not parse are the first two. There is no way to tell either of them from any other `SSLError` through the session state.
26+
27+
A session created with verification off is the third. That includes a server built without `set_server_verify(true)`, which is the default: it sends no certificate request, so it has no peer identity to reject.
28+
29+
If you wrap a protocol in `SSLConnection`, what changes is whether `auth_failed` runs before `closed`. `SSLConnection` calls `auth_failed` for `SSLAuthFail` and nothing for `SSLError`, and closes the connection on both, so a protocol that used to get `auth_failed` for one of these now gets `closed` on its own. A `closed` with no `connected` or `accepted` before it means the handshake failed. The reverse does not hold: under TLS 1.3 a session can finish its own side of the handshake before its peer's rejection reaches it, so a peer that rejected the connection can still produce `connected` and then `closed`.

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,14 @@ All notable changes to this project will be documented in this file. This projec
88

99
- Fix connections being closed after an unrelated SSL failure ([PR #116](https://github.com/ponylang/ssl/pull/116))
1010
- Fix SSL sessions returning uninitialized memory ([PR #124](https://github.com/ponylang/ssl/pull/124))
11+
- Fix handshake failures being reported as authentication failures ([PR #126](https://github.com/ponylang/ssl/pull/126))
1112

1213
### Added
1314

1415

1516
### Changed
1617

18+
- Report SSLAuthFail only for a peer certificate the session would not accept ([PR #126](https://github.com/ponylang/ssl/pull/126))
1719

1820
## [3.0.0] - 2026-07-10
1921

0 commit comments

Comments
 (0)