Skip to content

Commit 38d8b04

Browse files
authored
Allow Connection.get_certificate to return a cryptography certificate (#1351)
1 parent 265adc5 commit 38d8b04

File tree

3 files changed

+38
-2
lines changed

3 files changed

+38
-2
lines changed

CHANGELOG.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ Deprecations:
2121
Changes:
2222
^^^^^^^^
2323

24+
* ``OpenSSL.SSL.Connection.get_certificate`` now takes an ``as_cryptography`` keyword-argument. When ``True`` is passed then a ``cryptography.x509.Certificate`` is returned, instead of an ``OpenSSL.crypto.X509``. In the future, passing ``False`` (the default) will be deprecated.
25+
2426

2527
24.2.1 (2024-07-20)
2628
-------------------

src/OpenSSL/SSL.py

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2696,16 +2696,43 @@ def sock_shutdown(self, *args: Any, **kwargs: Any) -> None:
26962696
"""
26972697
return self._socket.shutdown(*args, **kwargs) # type: ignore[return-value, union-attr]
26982698

2699-
def get_certificate(self) -> X509 | None:
2699+
@typing.overload
2700+
def get_certificate(
2701+
self, *, as_cryptography: typing.Literal[True]
2702+
) -> x509.Certificate | None:
2703+
pass
2704+
2705+
@typing.overload
2706+
def get_certificate(
2707+
self, *, as_cryptography: typing.Literal[False] = False
2708+
) -> X509 | None:
2709+
pass
2710+
2711+
@typing.overload
2712+
def get_certificate(
2713+
self, *, as_cryptography: bool = False
2714+
) -> X509 | x509.Certificate | None:
2715+
pass
2716+
2717+
def get_certificate(
2718+
self, *, as_cryptography: bool = False
2719+
) -> X509 | x509.Certificate | None:
27002720
"""
27012721
Retrieve the local certificate (if any)
27022722
2723+
:param bool as_cryptography: Controls whether a
2724+
``cryptography.x509.Certificate`` or an ``OpenSSL.crypto.X509``
2725+
object should be returned.
2726+
27032727
:return: The local certificate
27042728
"""
27052729
cert = _lib.SSL_get_certificate(self._ssl)
27062730
if cert != _ffi.NULL:
27072731
_lib.X509_up_ref(cert)
2708-
return X509._from_raw_x509_ptr(cert)
2732+
pycert = X509._from_raw_x509_ptr(cert)
2733+
if as_cryptography:
2734+
return pycert.to_cryptography()
2735+
return pycert
27092736
return None
27102737

27112738
def get_peer_certificate(self) -> X509 | None:

tests/test_ssl.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2556,6 +2556,13 @@ def test_get_certificate(self):
25562556
assert cert is not None
25572557
assert "Server Certificate" == cert.get_subject().CN
25582558

2559+
cryptography_cert = client.get_certificate(as_cryptography=True)
2560+
assert cryptography_cert is not None
2561+
assert (
2562+
cryptography_cert.subject.rfc4514_string()
2563+
== "CN=Server Certificate"
2564+
)
2565+
25592566
def test_get_certificate_none(self):
25602567
"""
25612568
`Connection.get_certificate` returns the local certificate.

0 commit comments

Comments
 (0)