summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Lainé <jeremy.laine@m4x.org>2018-05-16 19:44:19 +0200
committerPaul Kehrer <paul.l.kehrer@gmail.com>2018-05-16 13:44:19 -0400
commit460a19d45425218c34dcb7d6fde478f80a987fea (patch)
tree27a774b3666b094b1677aee76539342a6ca1f5e2
parente7f334583541e1de98614e76a65b7d04e7be4979 (diff)
downloadpyopenssl-git-460a19d45425218c34dcb7d6fde478f80a987fea.tar.gz
Add Connection.get_certificate method (#733)
This makes it possible to retrieve the local certificate (if any) for a Connection. An example where this is useful is when negotiating a DTLS-SRTP connection, the fingerprint of the local certificate needs to be communicated to the remote party out-of-band via SDP.
-rw-r--r--CHANGELOG.rst2
-rw-r--r--src/OpenSSL/SSL.py12
-rw-r--r--tests/test_ssl.py25
3 files changed, 39 insertions, 0 deletions
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 0d8765f..1a659a0 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -24,6 +24,8 @@ Deprecations:
Changes:
^^^^^^^^
+- Added ``Connection.get_certificate`` to retrieve the local certificate.
+ `#733 <https://github.com/pyca/pyopenssl/pull/733>`_
- ``OpenSSL.SSL.Connection`` now sets ``SSL_MODE_AUTO_RETRY`` by default.
`#753 <https://github.com/pyca/pyopenssl/pull/753>`_
- Added ``Context.set_tlsext_use_srtp`` to enable negotiation of SRTP keying material.
diff --git a/src/OpenSSL/SSL.py b/src/OpenSSL/SSL.py
index 4c708ba..e3eddae 100644
--- a/src/OpenSSL/SSL.py
+++ b/src/OpenSSL/SSL.py
@@ -2176,6 +2176,18 @@ class Connection(object):
"""
return self._socket.shutdown(*args, **kwargs)
+ def get_certificate(self):
+ """
+ Retrieve the local certificate (if any)
+
+ :return: The local certificate
+ """
+ cert = _lib.SSL_get_certificate(self._ssl)
+ if cert != _ffi.NULL:
+ _lib.X509_up_ref(cert)
+ return X509._from_raw_x509_ptr(cert)
+ return None
+
def get_peer_certificate(self):
"""
Retrieve the other side's certificate (if any)
diff --git a/tests/test_ssl.py b/tests/test_ssl.py
index b09fce7..0831904 100644
--- a/tests/test_ssl.py
+++ b/tests/test_ssl.py
@@ -2418,6 +2418,31 @@ class TestConnection(object):
with pytest.raises(NotImplementedError):
conn.makefile()
+ def test_get_certificate(self):
+ """
+ `Connection.get_certificate` returns the local certificate.
+ """
+ chain = _create_certificate_chain()
+ [(cakey, cacert), (ikey, icert), (skey, scert)] = chain
+
+ context = Context(TLSv1_METHOD)
+ context.use_certificate(scert)
+ client = Connection(context, None)
+ cert = client.get_certificate()
+ assert cert is not None
+ assert "Server Certificate" == cert.get_subject().CN
+
+ def test_get_certificate_none(self):
+ """
+ `Connection.get_certificate` returns the local certificate.
+
+ If there is no certificate, it returns None.
+ """
+ context = Context(TLSv1_METHOD)
+ client = Connection(context, None)
+ cert = client.get_certificate()
+ assert cert is None
+
def test_get_peer_cert_chain(self):
"""
`Connection.get_peer_cert_chain` returns a list of certificates