Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 5a740cd

Browse files
matiuszkagpshead
andauthored
gh-109109: Expose retrieving certificate chains in SSL module (#109113)
Adds APIs to get the TLS certificate chains, verified or full unverified, from SSLSocket and SSLObject. Co-authored-by: Gregory P. Smith [Google LLC] <[email protected]>
1 parent ddf2e95 commit 5a740cd

File tree

3 files changed

+63
-4
lines changed

3 files changed

+63
-4
lines changed

Doc/library/ssl.rst

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,10 @@ This module provides a class, :class:`ssl.SSLSocket`, which is derived from the
4343
:class:`socket.socket` type, and provides a socket-like wrapper that also
4444
encrypts and decrypts the data going over the socket with SSL. It supports
4545
additional methods such as :meth:`getpeercert`, which retrieves the
46-
certificate of the other side of the connection, and :meth:`cipher`, which
47-
retrieves the cipher being used for the secure connection.
46+
certificate of the other side of the connection, :meth:`cipher`, which
47+
retrieves the cipher being used for the secure connection or
48+
:meth:`get_verified_chain`, :meth:`get_unverified_chain` which retrieves
49+
certificate chain.
4850

4951
For more sophisticated applications, the :class:`ssl.SSLContext` class
5052
helps manage settings and certificates, which can then be inherited
@@ -1210,6 +1212,22 @@ SSL sockets also have the following additional methods and attributes:
12101212
.. versionchanged:: 3.9
12111213
IPv6 address strings no longer have a trailing new line.
12121214

1215+
.. method:: SSLSocket.get_verified_chain()
1216+
1217+
Returns verified certificate chain provided by the other
1218+
end of the SSL channel as a list of DER-encoded bytes.
1219+
If certificate verification was disabled method acts the same as
1220+
:meth:`~SSLSocket.get_unverified_chain`.
1221+
1222+
.. versionadded:: 3.13
1223+
1224+
.. method:: SSLSocket.get_unverified_chain()
1225+
1226+
Returns raw certificate chain provided by the other
1227+
end of the SSL channel as a list of DER-encoded bytes.
1228+
1229+
.. versionadded:: 3.13
1230+
12131231
.. method:: SSLSocket.cipher()
12141232

12151233
Returns a three-value tuple containing the name of the cipher being used, the
@@ -1656,8 +1674,9 @@ to speed up repeated connections from the same clients.
16561674
Due to the early negotiation phase of the TLS connection, only limited
16571675
methods and attributes are usable like
16581676
:meth:`SSLSocket.selected_alpn_protocol` and :attr:`SSLSocket.context`.
1659-
The :meth:`SSLSocket.getpeercert`,
1660-
:meth:`SSLSocket.cipher` and :meth:`SSLSocket.compression` methods require that
1677+
The :meth:`SSLSocket.getpeercert`, :meth:`SSLSocket.get_verified_chain`,
1678+
:meth:`SSLSocket.get_unverified_chain` :meth:`SSLSocket.cipher`
1679+
and :meth:`SSLSocket.compression` methods require that
16611680
the TLS connection has progressed beyond the TLS Client Hello and therefore
16621681
will not return meaningful values nor can they be called safely.
16631682

@@ -2414,6 +2433,8 @@ provided.
24142433
- :meth:`~SSLSocket.read`
24152434
- :meth:`~SSLSocket.write`
24162435
- :meth:`~SSLSocket.getpeercert`
2436+
- :meth:`~SSLSocket.get_verified_chain`
2437+
- :meth:`~SSLSocket.get_unverified_chain`
24172438
- :meth:`~SSLSocket.selected_alpn_protocol`
24182439
- :meth:`~SSLSocket.selected_npn_protocol`
24192440
- :meth:`~SSLSocket.cipher`

Lib/ssl.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -876,6 +876,31 @@ def getpeercert(self, binary_form=False):
876876
"""
877877
return self._sslobj.getpeercert(binary_form)
878878

879+
def get_verified_chain(self):
880+
"""Returns verified certificate chain provided by the other
881+
end of the SSL channel as a list of DER-encoded bytes.
882+
883+
If certificate verification was disabled method acts the same as
884+
``SSLSocket.get_unverified_chain``.
885+
"""
886+
chain = self._sslobj.get_verified_chain()
887+
888+
if chain is None:
889+
return []
890+
891+
return [cert.public_bytes(_ssl.ENCODING_DER) for cert in chain]
892+
893+
def get_unverified_chain(self):
894+
"""Returns raw certificate chain provided by the other
895+
end of the SSL channel as a list of DER-encoded bytes.
896+
"""
897+
chain = self._sslobj.get_unverified_chain()
898+
899+
if chain is None:
900+
return []
901+
902+
return [cert.public_bytes(_ssl.ENCODING_DER) for cert in chain]
903+
879904
def selected_npn_protocol(self):
880905
"""Return the currently selected NPN protocol as a string, or ``None``
881906
if a next protocol was not negotiated or if NPN is not supported by one
@@ -1129,6 +1154,14 @@ def getpeercert(self, binary_form=False):
11291154
self._check_connected()
11301155
return self._sslobj.getpeercert(binary_form)
11311156

1157+
@_sslcopydoc
1158+
def get_verified_chain(self):
1159+
return self._sslobj.get_verified_chain()
1160+
1161+
@_sslcopydoc
1162+
def get_unverified_chain(self):
1163+
return self._sslobj.get_unverified_chain()
1164+
11321165
@_sslcopydoc
11331166
def selected_npn_protocol(self):
11341167
self._checkClosed()
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
You can now get the raw TLS certificate chains from TLS connections via
2+
:meth:`ssl.SSLSocket.get_verified_chain` and
3+
:meth:`ssl.SSLSocket.get_unverified_chain` methods.
4+
5+
Contributed by Mateusz Nowak.

0 commit comments

Comments
 (0)