Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitb5bf6c1

Browse files
[3.10]GH-95494: Fix transport EOF handling in OpenSSL 3.0 (GH-95495) (#103007)
GH-25309 enabled SSL_OP_IGNORE_UNEXPECTED_EOF by default, with a commentthat it restores OpenSSL 1.1.1 behavior, but this wasn't quite right.That option causes OpenSSL to treat transport EOF as the same asclose_notify (i.e. SSL_ERROR_ZERO_RETURN), whereas Python actually hasdistinct SSLEOFError and SSLZeroReturnError exceptions. (The latter isusually mapped to a zero return from read.) In OpenSSL 1.1.1, the sslmodule 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_READINGand mapping that to the other exception type.There doesn't seem to have been any unit test of this error, so fill inthe missing one. This had to be done with the BIO path because it'sactually slightly tricky to simulate a transport EOF with Python's fdbased APIs. (If you instruct the server to close the socket, it getsconfused, probably because the server's SSL object is still referencingthe now dead fd?)(cherry picked from commit420bbb7)Co-authored-by: David Benjamin <davidben@google.com>
1 parentae8a721 commitb5bf6c1

File tree

3 files changed

+32
-7
lines changed

3 files changed

+32
-7
lines changed

‎Lib/test/test_ssl.py‎

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,6 @@ def data_file(*name):
155155
OP_SINGLE_ECDH_USE=getattr(ssl,"OP_SINGLE_ECDH_USE",0)
156156
OP_CIPHER_SERVER_PREFERENCE=getattr(ssl,"OP_CIPHER_SERVER_PREFERENCE",0)
157157
OP_ENABLE_MIDDLEBOX_COMPAT=getattr(ssl,"OP_ENABLE_MIDDLEBOX_COMPAT",0)
158-
OP_IGNORE_UNEXPECTED_EOF=getattr(ssl,"OP_IGNORE_UNEXPECTED_EOF",0)
159158

160159
# Ubuntu has patched OpenSSL and changed behavior of security level 2
161160
# see https://bugs.python.org/issue41561#msg389003
@@ -1199,8 +1198,7 @@ def test_options(self):
11991198
# SSLContext also enables these by default
12001199
default|= (OP_NO_COMPRESSION|OP_CIPHER_SERVER_PREFERENCE|
12011200
OP_SINGLE_DH_USE|OP_SINGLE_ECDH_USE|
1202-
OP_ENABLE_MIDDLEBOX_COMPAT|
1203-
OP_IGNORE_UNEXPECTED_EOF)
1201+
OP_ENABLE_MIDDLEBOX_COMPAT)
12041202
self.assertEqual(default,ctx.options)
12051203
withwarnings_helper.check_warnings():
12061204
ctx.options|=ssl.OP_NO_TLSv1
@@ -2362,6 +2360,20 @@ def test_bio_read_write_data(self):
23622360
self.assertEqual(buf,b'foo\n')
23632361
self.ssl_io_loop(sock,incoming,outgoing,sslobj.unwrap)
23642362

2363+
deftest_transport_eof(self):
2364+
client_context,server_context,hostname=testing_context()
2365+
withsocket.socket(socket.AF_INET)assock:
2366+
sock.connect(self.server_addr)
2367+
incoming=ssl.MemoryBIO()
2368+
outgoing=ssl.MemoryBIO()
2369+
sslobj=client_context.wrap_bio(incoming,outgoing,
2370+
server_hostname=hostname)
2371+
self.ssl_io_loop(sock,incoming,outgoing,sslobj.do_handshake)
2372+
2373+
# Simulate EOF from the transport.
2374+
incoming.write_eof()
2375+
self.assertRaises(ssl.SSLEOFError,sslobj.read)
2376+
23652377

23662378
@support.requires_resource('network')
23672379
classNetworkedTests(unittest.TestCase):
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
When built against OpenSSL 3.0, the:mod:`ssl` module had a bug where it
2+
reported unauthenticated EOFs (i.e. without close_notify) as a clean TLS-level
3+
EOF. It now raises:exc:`~ssl.SSLEOFError`, matching the behavior in previous
4+
versions of OpenSSL. The:attr:`~ssl.SSLContext.options` attribute on
5+
:class:`~ssl.SSLContext` also no longer includes
6+
:data:`~ssl.OP_IGNORE_UNEXPECTED_EOF` by default. This option may be set to
7+
specify the previous OpenSSL 3.0 behavior.

‎Modules/_ssl.c‎

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -671,6 +671,16 @@ PySSL_SetError(PySSLSocket *sslsock, int ret, const char *filename, int lineno)
671671
ERR_GET_REASON(e)==SSL_R_CERTIFICATE_VERIFY_FAILED) {
672672
type=state->PySSLCertVerificationErrorObject;
673673
}
674+
#if defined(SSL_R_UNEXPECTED_EOF_WHILE_READING)
675+
/* OpenSSL 3.0 changed transport EOF from SSL_ERROR_SYSCALL with
676+
* zero return value to SSL_ERROR_SSL with a special error code. */
677+
if (ERR_GET_LIB(e)==ERR_LIB_SSL&&
678+
ERR_GET_REASON(e)==SSL_R_UNEXPECTED_EOF_WHILE_READING) {
679+
p=PY_SSL_ERROR_EOF;
680+
type=state->PySSLEOFErrorObject;
681+
errstr="EOF occurred in violation of protocol";
682+
}
683+
#endif
674684
break;
675685
}
676686
default:
@@ -3133,10 +3143,6 @@ _ssl__SSLContext_impl(PyTypeObject *type, int proto_version)
31333143
#endif
31343144
#ifdefSSL_OP_SINGLE_ECDH_USE
31353145
options |=SSL_OP_SINGLE_ECDH_USE;
3136-
#endif
3137-
#ifdefSSL_OP_IGNORE_UNEXPECTED_EOF
3138-
/* Make OpenSSL 3.0.0 behave like 1.1.1 */
3139-
options |=SSL_OP_IGNORE_UNEXPECTED_EOF;
31403146
#endif
31413147
SSL_CTX_set_options(self->ctx,options);
31423148

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp