Skip to content

Commit 1c62aab

Browse files
authored
Allow Connection.get_verified_chain to return cryptography certificates (#1354)
1 parent b6e8c3c commit 1c62aab

File tree

3 files changed

+39
-2
lines changed

3 files changed

+39
-2
lines changed

CHANGELOG.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ Deprecations:
2121
Changes:
2222
^^^^^^^^
2323

24-
* ``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.
24+
* ``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.
2525

2626

2727
24.2.1 (2024-07-20)

src/OpenSSL/SSL.py

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2834,13 +2834,33 @@ def get_peer_cert_chain(
28342834
return self._cert_stack_to_cryptography_list(cert_stack)
28352835
return self._cert_stack_to_list(cert_stack)
28362836

2837-
def get_verified_chain(self) -> list[X509] | None:
2837+
@typing.overload
2838+
def get_verified_chain(
2839+
self, *, as_cryptography: typing.Literal[True]
2840+
) -> list[x509.Certificate] | None:
2841+
pass
2842+
2843+
@typing.overload
2844+
def get_verified_chain(
2845+
self, *, as_cryptography: typing.Literal[False] = False
2846+
) -> list[X509] | None:
2847+
pass
2848+
2849+
def get_verified_chain(
2850+
self,
2851+
*,
2852+
as_cryptography: typing.Literal[True] | typing.Literal[False] = False,
2853+
) -> list[X509] | list[x509.Certificate] | None:
28382854
"""
28392855
Retrieve the verified certificate chain of the peer including the
28402856
peer's end entity certificate. It must be called after a session has
28412857
been successfully established. If peer verification was not successful
28422858
the chain may be incomplete, invalid, or None.
28432859
2860+
:param bool as_cryptography: Controls whether a list of
2861+
``cryptography.x509.Certificate`` or ``OpenSSL.crypto.X509``
2862+
object should be returned.
2863+
28442864
:return: A list of X509 instances giving the peer's verified
28452865
certificate chain, or None if it does not have one.
28462866
@@ -2851,6 +2871,8 @@ def get_verified_chain(self) -> list[X509] | None:
28512871
if cert_stack == _ffi.NULL:
28522872
return None
28532873

2874+
if as_cryptography:
2875+
return self._cert_stack_to_cryptography_list(cert_stack)
28542876
return self._cert_stack_to_list(cert_stack)
28552877

28562878
def want_read(self) -> bool:

tests/test_ssl.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2671,6 +2671,21 @@ def test_get_verified_chain(self):
26712671
assert "Intermediate Certificate" == chain[1].get_subject().CN
26722672
assert "Authority Certificate" == chain[2].get_subject().CN
26732673

2674+
cryptography_chain = client.get_verified_chain(as_cryptography=True)
2675+
assert len(cryptography_chain) == 3
2676+
assert (
2677+
cryptography_chain[0].subject.rfc4514_string()
2678+
== "CN=Server Certificate"
2679+
)
2680+
assert (
2681+
cryptography_chain[1].subject.rfc4514_string()
2682+
== "CN=Intermediate Certificate"
2683+
)
2684+
assert (
2685+
cryptography_chain[2].subject.rfc4514_string()
2686+
== "CN=Authority Certificate"
2687+
)
2688+
26742689
def test_get_verified_chain_none(self):
26752690
"""
26762691
`Connection.get_verified_chain` returns `None` if the peer sends

0 commit comments

Comments
 (0)