Skip to content

bpo-43794: OpenSSL 3.0.0: set OP_IGNORE_UNEXPECTED_EOF by default (GH-25309) - #25309

Merged
tiran merged 1 commit into
python:masterfrom
tiran:bpo-43794-ssl-eof
Apr 9, 2021
Merged

tiran merged 1 commit into
python:masterfrom
tiran:bpo-43794-ssl-eof

Conversation

@tiran

@tiran tiran commented Apr 9, 2021 •

Copy link
Copy Markdown
Member

Signed-off-by: Christian Heimes <christian@python.org>
@tiran tiran changed the title bpo-43794: OpenSSL 3.0.0: set OP_IGNORE_UNEXPECTED_EOF by default bpo-43794: OpenSSL 3.0.0: set OP_IGNORE_UNEXPECTED_EOF by default (GH-25309) Apr 9, 2021
@tiran
tiran merged commit 6f37ebc into python:master Apr 9, 2021
@miss-islington

Copy link
Copy Markdown
Contributor

Thanks @tiran for the PR 🌮🎉.. I'm working now to backport this PR to: 3.8, 3.9.
🐍🍒⛏🤖

@tiran
tiran deleted the bpo-43794-ssl-eof branch April 9, 2021 15:59
@bedevere-bot

Copy link
Copy Markdown

GH-25313 is a backport of this pull request to the 3.9 branch.

miss-islington pushed a commit to miss-islington/cpython that referenced this pull request Apr 9, 2021
…thonGH-25309)

Signed-off-by: Christian Heimes <christian@python.org>
(cherry picked from commit 6f37ebc)

Co-authored-by: Christian Heimes <christian@python.org>
miss-islington pushed a commit to miss-islington/cpython that referenced this pull request Apr 9, 2021
…thonGH-25309)

Signed-off-by: Christian Heimes <christian@python.org>
(cherry picked from commit 6f37ebc)

Co-authored-by: Christian Heimes <christian@python.org>
@bedevere-bot

Copy link
Copy Markdown

GH-25314 is a backport of this pull request to the 3.8 branch.

miss-islington added a commit that referenced this pull request Apr 9, 2021
…-25309)

Signed-off-by: Christian Heimes <christian@python.org>
(cherry picked from commit 6f37ebc)

Co-authored-by: Christian Heimes <christian@python.org>
miss-islington added a commit that referenced this pull request Apr 9, 2021
…-25309)

Signed-off-by: Christian Heimes <christian@python.org>
(cherry picked from commit 6f37ebc)

Co-authored-by: Christian Heimes <christian@python.org>
davidben added a commit to davidben/cpython that referenced this pull request Jul 31, 2022
pythonGH-25309 enabled SSL_OP_IGNORE_UNEXPECTED_EOF by default, with a comment
that it restores OpenSSL 1.1.1 behavior, but this wasn't quite right.
That option causes OpenSSL to treat transport EOF as the same as
close_notify (i.e. SSL_ERROR_ZERO_RETURN), whereas Python actually has
distinct SSLEOFError and SSLZeroReturnError exceptions. (The latter is
usually mapped to a zero return from read.) In OpenSSL 1.1.1, the ssl
module would raise them for transport EOF and close_notify,
respectively. In OpenSSL 3.0, both act like close_notify.

Fix this by, instead, just detecting SSL_R_UNEXPECTED_EOF_WHILE_READING
and mapping that to the other exception type.

There doesn't seem to have been any unit test of this error, so fill in
the missing one. This had to be done with the BIO path because it's
actually slightly tricky to simulate a transport EOF with Python's fd
based APIs. (If you instruct the server to close the socket, it gets
confused, probably because the server's SSL object is still referencing
the now dead fd?)
Yhg1s pushed a commit that referenced this pull request Mar 22, 2023
GH-25309 enabled SSL_OP_IGNORE_UNEXPECTED_EOF by default, with a comment
that it restores OpenSSL 1.1.1 behavior, but this wasn't quite right.
That option causes OpenSSL to treat transport EOF as the same as
close_notify (i.e. SSL_ERROR_ZERO_RETURN), whereas Python actually has
distinct SSLEOFError and SSLZeroReturnError exceptions. (The latter is
usually mapped to a zero return from read.) In OpenSSL 1.1.1, the ssl
module would raise them for transport EOF and close_notify,
respectively. In OpenSSL 3.0, both act like close_notify.

Fix this by, instead, just detecting SSL_R_UNEXPECTED_EOF_WHILE_READING
and mapping that to the other exception type.

There doesn't seem to have been any unit test of this error, so fill in
the missing one. This had to be done with the BIO path because it's
actually slightly tricky to simulate a transport EOF with Python's fd
based APIs. (If you instruct the server to close the socket, it gets
confused, probably because the server's SSL object is still referencing
the now dead fd?)
miss-islington pushed a commit to miss-islington/cpython that referenced this pull request Mar 24, 2023
…5495)

pythonGH-25309 enabled SSL_OP_IGNORE_UNEXPECTED_EOF by default, with a comment
that it restores OpenSSL 1.1.1 behavior, but this wasn't quite right.
That option causes OpenSSL to treat transport EOF as the same as
close_notify (i.e. SSL_ERROR_ZERO_RETURN), whereas Python actually has
distinct SSLEOFError and SSLZeroReturnError exceptions. (The latter is
usually mapped to a zero return from read.) In OpenSSL 1.1.1, the ssl
module would raise them for transport EOF and close_notify,
respectively. In OpenSSL 3.0, both act like close_notify.

Fix this by, instead, just detecting SSL_R_UNEXPECTED_EOF_WHILE_READING
and mapping that to the other exception type.

There doesn't seem to have been any unit test of this error, so fill in
the missing one. This had to be done with the BIO path because it's
actually slightly tricky to simulate a transport EOF with Python's fd
based APIs. (If you instruct the server to close the socket, it gets
confused, probably because the server's SSL object is still referencing
the now dead fd?)
(cherry picked from commit 420bbb7)

Co-authored-by: David Benjamin <davidben@google.com>
miss-islington pushed a commit to miss-islington/cpython that referenced this pull request Mar 24, 2023
…5495)

pythonGH-25309 enabled SSL_OP_IGNORE_UNEXPECTED_EOF by default, with a comment
that it restores OpenSSL 1.1.1 behavior, but this wasn't quite right.
That option causes OpenSSL to treat transport EOF as the same as
close_notify (i.e. SSL_ERROR_ZERO_RETURN), whereas Python actually has
distinct SSLEOFError and SSLZeroReturnError exceptions. (The latter is
usually mapped to a zero return from read.) In OpenSSL 1.1.1, the ssl
module would raise them for transport EOF and close_notify,
respectively. In OpenSSL 3.0, both act like close_notify.

Fix this by, instead, just detecting SSL_R_UNEXPECTED_EOF_WHILE_READING
and mapping that to the other exception type.

There doesn't seem to have been any unit test of this error, so fill in
the missing one. This had to be done with the BIO path because it's
actually slightly tricky to simulate a transport EOF with Python's fd
based APIs. (If you instruct the server to close the socket, it gets
confused, probably because the server's SSL object is still referencing
the now dead fd?)
(cherry picked from commit 420bbb7)

Co-authored-by: David Benjamin <davidben@google.com>
Fidget-Spinner pushed a commit to Fidget-Spinner/cpython that referenced this pull request Mar 27, 2023
…5495)

pythonGH-25309 enabled SSL_OP_IGNORE_UNEXPECTED_EOF by default, with a comment
that it restores OpenSSL 1.1.1 behavior, but this wasn't quite right.
That option causes OpenSSL to treat transport EOF as the same as
close_notify (i.e. SSL_ERROR_ZERO_RETURN), whereas Python actually has
distinct SSLEOFError and SSLZeroReturnError exceptions. (The latter is
usually mapped to a zero return from read.) In OpenSSL 1.1.1, the ssl
module would raise them for transport EOF and close_notify,
respectively. In OpenSSL 3.0, both act like close_notify.

Fix this by, instead, just detecting SSL_R_UNEXPECTED_EOF_WHILE_READING
and mapping that to the other exception type.

There doesn't seem to have been any unit test of this error, so fill in
the missing one. This had to be done with the BIO path because it's
actually slightly tricky to simulate a transport EOF with Python's fd
based APIs. (If you instruct the server to close the socket, it gets
confused, probably because the server's SSL object is still referencing
the now dead fd?)
ambv pushed a commit that referenced this pull request Mar 27, 2023
…#103006)

GH-25309 enabled SSL_OP_IGNORE_UNEXPECTED_EOF by default, with a comment
that it restores OpenSSL 1.1.1 behavior, but this wasn't quite right.
That option causes OpenSSL to treat transport EOF as the same as
close_notify (i.e. SSL_ERROR_ZERO_RETURN), whereas Python actually has
distinct SSLEOFError and SSLZeroReturnError exceptions. (The latter is
usually mapped to a zero return from read.) In OpenSSL 1.1.1, the ssl
module would raise them for transport EOF and close_notify,
respectively. In OpenSSL 3.0, both act like close_notify.

Fix this by, instead, just detecting SSL_R_UNEXPECTED_EOF_WHILE_READING
and mapping that to the other exception type.

There doesn't seem to have been any unit test of this error, so fill in
the missing one. This had to be done with the BIO path because it's
actually slightly tricky to simulate a transport EOF with Python's fd
based APIs. (If you instruct the server to close the socket, it gets
confused, probably because the server's SSL object is still referencing
the now dead fd?)
(cherry picked from commit 420bbb7)

Co-authored-by: David Benjamin <davidben@google.com>
ambv pushed a commit that referenced this pull request Mar 27, 2023
…#103007)

GH-25309 enabled SSL_OP_IGNORE_UNEXPECTED_EOF by default, with a comment
that it restores OpenSSL 1.1.1 behavior, but this wasn't quite right.
That option causes OpenSSL to treat transport EOF as the same as
close_notify (i.e. SSL_ERROR_ZERO_RETURN), whereas Python actually has
distinct SSLEOFError and SSLZeroReturnError exceptions. (The latter is
usually mapped to a zero return from read.) In OpenSSL 1.1.1, the ssl
module would raise them for transport EOF and close_notify,
respectively. In OpenSSL 3.0, both act like close_notify.

Fix this by, instead, just detecting SSL_R_UNEXPECTED_EOF_WHILE_READING
and mapping that to the other exception type.

There doesn't seem to have been any unit test of this error, so fill in
the missing one. This had to be done with the BIO path because it's
actually slightly tricky to simulate a transport EOF with Python's fd
based APIs. (If you instruct the server to close the socket, it gets
confused, probably because the server's SSL object is still referencing
the now dead fd?)
(cherry picked from commit 420bbb7)

Co-authored-by: David Benjamin <davidben@google.com>
warsaw pushed a commit to warsaw/cpython that referenced this pull request Apr 11, 2023
…5495)

pythonGH-25309 enabled SSL_OP_IGNORE_UNEXPECTED_EOF by default, with a comment
that it restores OpenSSL 1.1.1 behavior, but this wasn't quite right.
That option causes OpenSSL to treat transport EOF as the same as
close_notify (i.e. SSL_ERROR_ZERO_RETURN), whereas Python actually has
distinct SSLEOFError and SSLZeroReturnError exceptions. (The latter is
usually mapped to a zero return from read.) In OpenSSL 1.1.1, the ssl
module would raise them for transport EOF and close_notify,
respectively. In OpenSSL 3.0, both act like close_notify.

Fix this by, instead, just detecting SSL_R_UNEXPECTED_EOF_WHILE_READING
and mapping that to the other exception type.

There doesn't seem to have been any unit test of this error, so fill in
the missing one. This had to be done with the BIO path because it's
actually slightly tricky to simulate a transport EOF with Python's fd
based APIs. (If you instruct the server to close the socket, it gets
confused, probably because the server's SSL object is still referencing
the now dead fd?)
stratakis pushed a commit to stratakis/cpython that referenced this pull request Mar 11, 2024
…thonGH-25309)

Signed-off-by: Christian Heimes <christian@python.org>
(cherry picked from commit 6f37ebc)

Co-authored-by: Christian Heimes <christian@python.org>
stratakis pushed a commit to stratakis/cpython that referenced this pull request Mar 25, 2024
…thonGH-25309)

Signed-off-by: Christian Heimes <christian@python.org>
(cherry picked from commit 6f37ebc)

Co-authored-by: Christian Heimes <christian@python.org>
mcepl pushed a commit to openSUSE-Python/cpython that referenced this pull request Apr 2, 2024
…thonGH-25309)

Signed-off-by: Christian Heimes <christian@python.org>
(cherry picked from commit 6f37ebc)

Co-authored-by: Christian Heimes <christian@python.org>
icanhasmath added a commit to ActiveState/cpython that referenced this pull request Oct 30, 2026
* closes bpo-39953: Update OpenSSL error codes table. (pythonGH-19082)

I updated the error codes using the OpenSSL 1.1.1f source tree.

(cherry picked from commit 3e0dd37)

* closes bpo-39953: Generate ifdefs around library code definitions. (pythonGH-19490)

(cherry picked from commit 909b87d)

* closes bpo-40266, closes bpo-39953: Use numeric lib code if compiling against old OpenSSL. (pythonGH-19506)

(cherry picked from commit 584a3cf)

* bpo-43789: OpenSSL 3.0.0 Don't call passwd callback again in error case (pythonGH-25303)

(cherry picked from commit d3b73f3)

Co-authored-by: Christian Heimes <christian@python.org>
(cherry picked from commit a188bd4)

* bpo-4379: Skip TLS 1.0/1.1 tests under OpenSSL 3.0.0 (pythonGH-25304)

Signed-off-by: Christian Heimes <christian@python.org>
(cherry picked from commit 5151d64)

Co-authored-by: Christian Heimes <christian@python.org>
(cherry picked from commit 4a5c101)

* bpo-43794: OpenSSL 3.0.0: set OP_IGNORE_UNEXPECTED_EOF by default (pythonGH-25309)

Signed-off-by: Christian Heimes <christian@python.org>
(cherry picked from commit 6f37ebc)

Co-authored-by: Christian Heimes <christian@python.org>
(cherry picked from commit 54d89a3)

* [3.9] bpo-43788: Generate version specific _ssl_data.h (pythonGH-25300) (pythonGH-25310)

(cherry picked from commit 150af75)

Co-authored-by: Christian Heimes <christian@python.org>
(cherry picked from commit 299ae9c)

* [3.9] bpo-46114: Fix OpenSSL version check for 3.0.1 (pythonGH-30170) (pythonGH-30173)

Co-authored-by: Christian Heimes <christian@python.org>
(cherry picked from commit a9b3edb)

* [3.9] bpo-41561: skip test_min_max_version_mismatch (pythonGH-22308) (pythonGH-23363)

skip test_min_max_version_mismatch when TLS 1.0 is not available

Signed-off-by: Christian Heimes <christian@python.org>
(cherry picked from commit ce04e71)

Co-authored-by: Christian Heimes <christian@python.org>

Automerge-Triggered-By: GH:tiran
(cherry picked from commit 802ff7c)

* 3.7.17.x: copy the OpenSSL DLLs by pattern on Windows

openssl.props copied libcrypto-1_1.dll and libssl-1_1.dll from the import
library directory, so building against OpenSSL 3 failed at the copy step.
OpenSSL 3 installs its DLLs in bin\ and names them libssl-3.dll or
libssl-3-x64.dll depending on how it was built; both forms occur among the
Platform's shared/openssl 3.5 builds.  python.props now sets opensslBinDir
(bin\ when OPENSSL_DIR has one, else the import library directory, which is
where 1.1 builds and the externals keep them), and openssl.props copies
whatever libcrypto-*/libssl-* DLLs and PDBs it finds there.

The ActiveState 3.9 builds get the same result from the Platform's core
patch, which computes the suffix instead.

* Doc: drop pasted citation markers from the 3.7.17.7 notes

The 3.7.17.7 section of Doc/whatsnew/3.7.rst carried source markers copied
along with its CVE descriptions ("NVD+5SUSE+5linux.oracle.com+5",
"starwindsoftware.com+2" and the like), which render as text.  The
descriptions themselves are unchanged.  The headings of the 3.7.17.4 to
3.7.17.7 sections also get underlines as long as their titles.

* Update version to 3.7.17.9 and add release notes

3.7.17.9 moves the 3.7 line to OpenSSL 3: the upstream ssl changes the
3.9 line got for OpenSSL 3 (unexpected-EOF handling, per-version error
tables, the password-callback fix and the matching test updates) and a
Windows build that copies OpenSSL 3's DLLs.  The notes list the behavior
changes that come with OpenSSL 3 itself.  OP_IGNORE_UNEXPECTED_EOF's
versionadded says 3.7.17.9, where this line gained it.

* 3.7.17.x: pick the OpenSSL DLL names from the OpenSSL version on Windows

Copying libssl-*.dll by wildcard broke the Platform's python-builder,
which edits openssl.props and stops when its x64 suffix line is missing.
Name the DLLs from SSL_MAJOR_VERSION/SSL_MINOR_VERSION (set by the
Platform build), detect a 3.x OpenSSL from bin\ when they are unset, and
add the x64 suffix only when that DLL exists.  python-builder removes
the x64 line, as it does for 3.9 and 3.10.

Co-Authored-By: Claude <noreply@anthropic.com>

* 3.7.17.x: state the RSA key floor for each OpenSSL 3 default security level

OpenSSL 3.2 raised the default security level from 1 to 2, so the floor
is 2048 bits on the 3.5 release the Platform builds with and 1024 bits on
3.0 and 3.1.

---------

Co-authored-by: Benjamin Peterson <benjamin@python.org>
Co-authored-by: Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Co-authored-by: Christian Heimes <christian@python.org>
Co-authored-by: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants