Skip to content

Commit

Permalink
add Connection.set_verify, fix pyca#255
Browse files Browse the repository at this point in the history
  • Loading branch information
mhils committed Jan 6, 2022
1 parent d184fbb commit f370413
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 2 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ Deprecations:
Changes:
^^^^^^^^

- Add ``OpenSSL.SSL.Connection.set_verify`` and ``OpenSSL.SSL.Connection.get_verify_mode``
to override the context object's verification flags.
`#1073 <https://github.com/pyca/pyopenssl/pull/1073>`_
- Expose wrappers for some `DTLS
<https://en.wikipedia.org/wiki/Datagram_Transport_Layer_Security>`_
primitives. `#1026 <https://github.com/pyca/pyopenssl/pull/1026>`_
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ def find_meta(meta):
package_dir={"": "src"},
install_requires=[
# Fix cryptographyMinimum in tox.ini when changing this!
"cryptography>=35.0",
"cryptography>=37.0",
],
extras_require={
"test": ["flaky", "pretend", "pytest>=3.0.1"],
Expand Down
29 changes: 29 additions & 0 deletions src/OpenSSL/SSL.py
Original file line number Diff line number Diff line change
Expand Up @@ -1736,6 +1736,35 @@ def get_servername(self):

return _ffi.string(name)

def set_verify(self, mode, callback=None):
"""
Override the Context object's verification flags for this specific
connection. See :py:meth:`Context.set_verify` for details.
"""
if not isinstance(mode, int):
raise TypeError("mode must be an integer")

if callback is None:
self._verify_helper = None
self._verify_callback = None
_lib.SSL_set_verify(self._ssl, mode, _ffi.NULL)
else:
if not callable(callback):
raise TypeError("callback must be callable")

self._verify_helper = _VerifyHelper(callback)
self._verify_callback = self._verify_helper.callback
_lib.SSL_set_verify(self._ssl, mode, self._verify_callback)

def get_verify_mode(self):
"""
Retrieve the Connection object's verify mode, as set by
:meth:`set_verify`.
:return: The verify mode
"""
return _lib.SSL_get_verify_mode(self._ssl)

def set_ciphertext_mtu(self, mtu):
"""
For DTLS, set the maximum UDP payload size (*not* including IP/UDP
Expand Down
45 changes: 45 additions & 0 deletions tests/test_ssl.py
Original file line number Diff line number Diff line change
Expand Up @@ -2629,6 +2629,51 @@ def test_get_verified_chain_unconnected(self):
server = Connection(ctx, None)
assert None is server.get_verified_chain()

def test_set_verify_overrides_context(self):
context = Context(SSLv23_METHOD)
context.set_verify(VERIFY_PEER)
conn = Connection(context, None)
conn.set_verify(VERIFY_NONE)

assert context.get_verify_mode() == VERIFY_PEER
assert conn.get_verify_mode() == VERIFY_NONE

with pytest.raises(TypeError):
conn.set_verify(None)

with pytest.raises(TypeError):
conn.set_verify(VERIFY_PEER, "not a callable")

def test_set_verify_callback_reference(self):
"""
The callback for certificate verification should only be forgotten if the context and all connections
created by it do not use it anymore.
"""
def callback(conn, cert, errnum, depth, ok): # pragma: no cover
return ok

tracker = ref(callback)

context = Context(SSLv23_METHOD)
context.set_verify(VERIFY_PEER, callback)
del callback

conn = Connection(context, None)
context.set_verify(VERIFY_NONE)

collect()
collect()
assert tracker()

conn.set_verify(VERIFY_PEER, lambda conn, cert, errnum, depth, ok: ok)
collect()
collect()
callback = tracker()
if callback is not None:
referrers = get_referrers(callback)
if len(referrers) > 1: # pragma: nocover
pytest.fail("Some references remain: %r" % (referrers,))

def test_get_session_unconnected(self):
"""
`Connection.get_session` returns `None` when used with an object
Expand Down
2 changes: 1 addition & 1 deletion tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ extras =
deps =
coverage>=4.2
cryptographyMain: git+https://github.com/pyca/cryptography.git
cryptographyMinimum: cryptography==35.0
cryptographyMinimum: cryptography==37.0
randomorder: pytest-randomly
setenv =
# Do not allow the executing environment to pollute the test environment
Expand Down

0 comments on commit f370413

Please sign in to comment.