Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

gh-109109: Expose retrieving certificate chains in SSL module #109113

Merged
merged 10 commits into from
Sep 20, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
23 changes: 19 additions & 4 deletions Doc/library/ssl.rst
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,10 @@ This module provides a class, :class:`ssl.SSLSocket`, which is derived from the
:class:`socket.socket` type, and provides a socket-like wrapper that also
encrypts and decrypts the data going over the socket with SSL. It supports
additional methods such as :meth:`getpeercert`, which retrieves the
certificate of the other side of the connection, and :meth:`cipher`, which
retrieves the cipher being used for the secure connection.
certificate of the other side of the connection, :meth:`cipher`, which
retrieves the cipher being used for the secure connection or
:meth:`get_verified_chain`, :meth:`get_unverified_chain` which retrieves
certificate chain.

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

.. method:: SSLSocket.get_verified_chain()
matiuszka marked this conversation as resolved.
Show resolved Hide resolved

Returns verified verified certificate chain provided by the other
matiuszka marked this conversation as resolved.
Show resolved Hide resolved
end of the SSL channel. Return ``None`` if no certificates were provided.

.. method:: SSLSocket.get_unverified_chain()

Returns unverified verified certificate chain provided by the other
end of the SSL channel. Return ``None`` if no certificates were provided.

.. method:: SSLSocket.cipher()

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

Expand Down Expand Up @@ -2414,6 +2427,8 @@ provided.
- :meth:`~SSLSocket.read`
- :meth:`~SSLSocket.write`
- :meth:`~SSLSocket.getpeercert`
- :meth:`~SSLSocket.get_verified_chain`
- :meth:`~SSLSocket.get_unverified_chain`
- :meth:`~SSLSocket.selected_alpn_protocol`
- :meth:`~SSLSocket.selected_npn_protocol`
- :meth:`~SSLSocket.cipher`
Expand Down
24 changes: 24 additions & 0 deletions Lib/ssl.py
Original file line number Diff line number Diff line change
Expand Up @@ -876,6 +876,22 @@ def getpeercert(self, binary_form=False):
"""
return self._sslobj.getpeercert(binary_form)

def get_verified_chain(self):
"""Returns verified verified certificate chain provided by the other
end of the SSL channel.

Return None if no certificates were provided.
"""
return self._sslobj.get_verified_chain()

def get_unverified_chain(self):
"""Returns unverified verified certificate chain provided by the other
end of the SSL channel.

Return None if no certificates were provided.
"""
return self._sslobj.get_unverified_chain()

def selected_npn_protocol(self):
"""Return the currently selected NPN protocol as a string, or ``None``
if a next protocol was not negotiated or if NPN is not supported by one
Expand Down Expand Up @@ -1129,6 +1145,14 @@ def getpeercert(self, binary_form=False):
self._check_connected()
return self._sslobj.getpeercert(binary_form)

@_sslcopydoc
def get_verified_chain(self):
return self._sslobj.get_verified_chain()

@_sslcopydoc
def get_unverified_chain(self):
return self._sslobj.get_unverified_chain()

@_sslcopydoc
def selected_npn_protocol(self):
self._checkClosed()
Expand Down