Skip to content

Commit

Permalink
Allow Connection.get_verified_chain to return cryptography certificat…
Browse files Browse the repository at this point in the history
…es (#1354)
  • Loading branch information
alex authored Aug 11, 2024
1 parent b6e8c3c commit 1c62aab
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 2 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ Deprecations:
Changes:
^^^^^^^^

* ``OpenSSL.SSL.Connection.get_certificate``, ``OpenSSL.SSL.Connection.get_peer_certificate``, and ``OpenSSL.SSL.Connection.get_peer_cert_chain`` now take an ``as_cryptography`` keyword-argument. When ``True`` is passed then ``cryptography.x509.Certificate`` are returned, instead of ``OpenSSL.crypto.X509``. In the future, passing ``False`` (the default) will be deprecated.
* ``OpenSSL.SSL.Connection.get_certificate``, ``OpenSSL.SSL.Connection.get_peer_certificate``, ``OpenSSL.SSL.Connection.get_peer_cert_chain``, and ``OpenSSL.SSL.Connection.get_verified_chain`` now take an ``as_cryptography`` keyword-argument. When ``True`` is passed then ``cryptography.x509.Certificate`` are returned, instead of ``OpenSSL.crypto.X509``. In the future, passing ``False`` (the default) will be deprecated.


24.2.1 (2024-07-20)
Expand Down
24 changes: 23 additions & 1 deletion src/OpenSSL/SSL.py
Original file line number Diff line number Diff line change
Expand Up @@ -2834,13 +2834,33 @@ def get_peer_cert_chain(
return self._cert_stack_to_cryptography_list(cert_stack)
return self._cert_stack_to_list(cert_stack)

def get_verified_chain(self) -> list[X509] | None:
@typing.overload
def get_verified_chain(
self, *, as_cryptography: typing.Literal[True]
) -> list[x509.Certificate] | None:
pass

@typing.overload
def get_verified_chain(
self, *, as_cryptography: typing.Literal[False] = False
) -> list[X509] | None:
pass

def get_verified_chain(
self,
*,
as_cryptography: typing.Literal[True] | typing.Literal[False] = False,
) -> list[X509] | list[x509.Certificate] | None:
"""
Retrieve the verified certificate chain of the peer including the
peer's end entity certificate. It must be called after a session has
been successfully established. If peer verification was not successful
the chain may be incomplete, invalid, or None.
:param bool as_cryptography: Controls whether a list of
``cryptography.x509.Certificate`` or ``OpenSSL.crypto.X509``
object should be returned.
:return: A list of X509 instances giving the peer's verified
certificate chain, or None if it does not have one.
Expand All @@ -2851,6 +2871,8 @@ def get_verified_chain(self) -> list[X509] | None:
if cert_stack == _ffi.NULL:
return None

if as_cryptography:
return self._cert_stack_to_cryptography_list(cert_stack)
return self._cert_stack_to_list(cert_stack)

def want_read(self) -> bool:
Expand Down
15 changes: 15 additions & 0 deletions tests/test_ssl.py
Original file line number Diff line number Diff line change
Expand Up @@ -2671,6 +2671,21 @@ def test_get_verified_chain(self):
assert "Intermediate Certificate" == chain[1].get_subject().CN
assert "Authority Certificate" == chain[2].get_subject().CN

cryptography_chain = client.get_verified_chain(as_cryptography=True)
assert len(cryptography_chain) == 3
assert (
cryptography_chain[0].subject.rfc4514_string()
== "CN=Server Certificate"
)
assert (
cryptography_chain[1].subject.rfc4514_string()
== "CN=Intermediate Certificate"
)
assert (
cryptography_chain[2].subject.rfc4514_string()
== "CN=Authority Certificate"
)

def test_get_verified_chain_none(self):
"""
`Connection.get_verified_chain` returns `None` if the peer sends
Expand Down

0 comments on commit 1c62aab

Please sign in to comment.