Skip to content

Commit e738186

Browse files
reaperhulkalex
authored andcommitted
fix a memory leak and a potential UAF and also #722 (#723)
* fix a memory leak and a potential UAF and also #722 * sanity check * bump cryptography minimum version, add changelog
1 parent f724786 commit e738186

File tree

6 files changed

+36
-11
lines changed

6 files changed

+36
-11
lines changed

Diff for: CHANGELOG.rst

+3-3
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ The third digit is only for regressions.
1111
Backward-incompatible changes:
1212
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1313

14-
*none*
14+
* The minimum ``cryptography`` version is now 2.1.4.
1515

1616

1717
Deprecations:
@@ -23,8 +23,8 @@ Deprecations:
2323
Changes:
2424
^^^^^^^^
2525

26-
27-
*none*
26+
- Fixed a potential use-after-free in the verify callback and resolved a memory leak when loading PKCS12 files with ``cacerts``.
27+
`#723 <https://github.com/pyca/pyopenssl/pull/723>`_
2828

2929
----
3030

Diff for: setup.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ def find_meta(meta):
9595
package_dir={"": "src"},
9696
install_requires=[
9797
# Fix cryptographyMinimum in tox.ini when changing this!
98-
"cryptography>=1.9",
98+
"cryptography>=2.1.4",
9999
"six>=1.5.2"
100100
],
101101
extras_require={

Diff for: src/OpenSSL/SSL.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -309,8 +309,9 @@ def __init__(self, callback):
309309

310310
@wraps(callback)
311311
def wrapper(ok, store_ctx):
312-
cert = X509.__new__(X509)
313-
cert._x509 = _lib.X509_STORE_CTX_get_current_cert(store_ctx)
312+
x509 = _lib.X509_STORE_CTX_get_current_cert(store_ctx)
313+
_lib.X509_up_ref(x509)
314+
cert = X509._from_raw_x509_ptr(x509)
314315
error_number = _lib.X509_STORE_CTX_get_error(store_ctx)
315316
error_depth = _lib.X509_STORE_CTX_get_error_depth(store_ctx)
316317

Diff for: src/OpenSSL/crypto.py

+3-4
Original file line numberDiff line numberDiff line change
@@ -3058,8 +3058,7 @@ def load_pkcs12(buffer, passphrase=None):
30583058
pycert = None
30593059
friendlyname = None
30603060
else:
3061-
pycert = X509.__new__(X509)
3062-
pycert._x509 = _ffi.gc(cert[0], _lib.X509_free)
3061+
pycert = X509._from_raw_x509_ptr(cert[0])
30633062

30643063
friendlyname_length = _ffi.new("int*")
30653064
friendlyname_buffer = _lib.X509_alias_get0(
@@ -3073,8 +3072,8 @@ def load_pkcs12(buffer, passphrase=None):
30733072

30743073
pycacerts = []
30753074
for i in range(_lib.sk_X509_num(cacerts)):
3076-
pycacert = X509.__new__(X509)
3077-
pycacert._x509 = _lib.sk_X509_value(cacerts, i)
3075+
x509 = _lib.sk_X509_value(cacerts, i)
3076+
pycacert = X509._from_raw_x509_ptr(x509)
30783077
pycacerts.append(pycacert)
30793078
if not pycacerts:
30803079
pycacerts = None

Diff for: tests/test_ssl.py

+25
Original file line numberDiff line numberDiff line change
@@ -1279,6 +1279,31 @@ def callback(self, connection, *args):
12791279

12801280
assert verify.connection is clientConnection
12811281

1282+
def test_x509_in_verify_works(self):
1283+
"""
1284+
We had a bug where the X509 cert instantiated in the callback wrapper
1285+
didn't __init__ so it was missing objects needed when calling
1286+
get_subject. This test sets up a handshake where we call get_subject
1287+
on the cert provided to the verify callback.
1288+
"""
1289+
serverContext = Context(TLSv1_METHOD)
1290+
serverContext.use_privatekey(
1291+
load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM))
1292+
serverContext.use_certificate(
1293+
load_certificate(FILETYPE_PEM, cleartextCertificatePEM))
1294+
serverConnection = Connection(serverContext, None)
1295+
1296+
def verify_cb_get_subject(conn, cert, errnum, depth, ok):
1297+
assert cert.get_subject()
1298+
return 1
1299+
1300+
clientContext = Context(TLSv1_METHOD)
1301+
clientContext.set_verify(VERIFY_PEER, verify_cb_get_subject)
1302+
clientConnection = Connection(clientContext, None)
1303+
clientConnection.set_connect_state()
1304+
1305+
handshake_in_memory(clientConnection, serverConnection)
1306+
12821307
def test_set_verify_callback_exception(self):
12831308
"""
12841309
If the verify callback passed to `Context.set_verify` raises an

Diff for: tox.ini

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ extras =
1010
deps =
1111
coverage>=4.2
1212
cryptographyMaster: git+https://github.com/pyca/cryptography.git
13-
cryptographyMinimum: cryptography<=1.9
13+
cryptographyMinimum: cryptography==2.1.4
1414
setenv =
1515
# Do not allow the executing environment to pollute the test environment
1616
# with extra packages.

0 commit comments

Comments
 (0)