Skip to content

Commit d8eca31

Browse files
committed
gh-155327: Guard SSLSocket chain methods after TLS teardown
get_verified_chain() and get_unverified_chain() accessed self._sslobj without the guard used by the other query methods, raising AttributeError after unwrap(). Return an empty list instead.
1 parent 8b048eb commit d8eca31

3 files changed

Lines changed: 28 additions & 0 deletions

File tree

Lib/ssl.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1183,6 +1183,9 @@ def getpeercert(self, binary_form=False):
11831183

11841184
@_sslcopydoc
11851185
def get_verified_chain(self):
1186+
self._checkClosed()
1187+
if self._sslobj is None:
1188+
return []
11861189
chain = self._sslobj.get_verified_chain()
11871190

11881191
if chain is None:
@@ -1192,6 +1195,9 @@ def get_verified_chain(self):
11921195

11931196
@_sslcopydoc
11941197
def get_unverified_chain(self):
1198+
self._checkClosed()
1199+
if self._sslobj is None:
1200+
return []
11951201
chain = self._sslobj.get_unverified_chain()
11961202

11971203
if chain is None:

Lib/test/test_ssl.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5435,6 +5435,24 @@ def test_certificate_chain(self):
54355435
self.assertEqual(ee, uvc[0])
54365436
self.assertNotEqual(ee, ca)
54375437

5438+
def test_chain_methods_after_unwrap(self):
5439+
# The chain methods must not crash once the TLS layer is torn down;
5440+
# like the other query methods they return an empty list when
5441+
# _sslobj is gone.
5442+
client_context, server_context, hostname = testing_context()
5443+
server = ThreadedEchoServer(context=server_context, chatty=False)
5444+
with server:
5445+
with client_context.wrap_socket(
5446+
socket.socket(),
5447+
server_hostname=hostname
5448+
) as s:
5449+
s.connect((HOST, server.port))
5450+
self.assertGreater(len(s.get_verified_chain()), 0)
5451+
s.unwrap()
5452+
self.assertIsNone(s._sslobj)
5453+
self.assertEqual(s.get_verified_chain(), [])
5454+
self.assertEqual(s.get_unverified_chain(), [])
5455+
54385456
def test_internal_chain_server(self):
54395457
client_context, server_context, hostname = testing_context()
54405458
client_context.load_cert_chain(SIGNED_CERTFILE)
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Fix ``ssl.SSLSocket.get_verified_chain()`` and
2+
``ssl.SSLSocket.get_unverified_chain()`` to return an empty list instead of
3+
raising :exc:`AttributeError` when called after the socket's TLS layer has been
4+
shut down. Patch by tonghuaroot.

0 commit comments

Comments
 (0)