diff options
author | Jeremy Cline <jeremy@jcline.org> | 2017-09-13 21:14:53 -0400 |
---|---|---|
committer | Paul Kehrer <paul.l.kehrer@gmail.com> | 2017-09-14 09:14:53 +0800 |
commit | 58193f195b4673bb3c34e0464f878b63fd52d929 (patch) | |
tree | dd499159ddc70a3ba1a7030bc1f6b432ec1874dd /src/OpenSSL/crypto.py | |
parent | 9e15eca29625f0aa87635a613b093ba1ecaa28fb (diff) | |
download | pyopenssl-git-58193f195b4673bb3c34e0464f878b63fd52d929.tar.gz |
Avoid a double call to X509_STORE_CTX_init as it leaks memory (#691)
This fixes an issue where each instance of ``X509StoreContext`` would
leak a small amount of memory, but only if ``verify_certificate`` was
called.
The reason for this is that ``X509_STORE_CTX_init`` is called in
``X509StoreContext.__init__`` and at the start of
``X509StoreContext.verify_certificate``. According to the man page for
``X509_STORE_CTX_init``:
"X509_STORE_CTX_init() sets up ctx for a subsequent verification
operation. It must be called before each call to X509_verify_cert(),
i.e. a ctx is only good for one call to X509_verify_cert(); if you want
to verify a second certificate with the same ctx then you must call
X509_STORE_CTX_cleanup() and then X509_STORE_CTX_init() again before
the second call to X509_verify_cert()."
Prior to this commit, the following script would cause a memory leak:
```
from OpenSSL.crypto import (
X509Store, X509StoreContext, load_certificate, FILETYPE_PEM)
certificate = """
-----BEGIN CERTIFICATE-----
MIIESTCCA7KgAwIBAgIBAzANBgkqhkiG9w0BAQUFADCBoDELMAkGA1UEBhMCVVMx
CzAJBgNVBAgTAk5DMRAwDgYDVQQHEwdSYWxlaWdoMRcwFQYDVQQKEw5GZWRvcmEg
UHJvamVjdDEPMA0GA1UECxMGZmVkbXNnMQ8wDQYDVQQDEwZmZWRtc2cxDzANBgNV
BCkTBmZlZG1zZzEmMCQGCSqGSIb3DQEJARYXYWRtaW5AZmVkb3JhcHJvamVjdC5v
cmcwHhcNMTIwNzE1MjExODUyWhcNMjIwNzEzMjExODUyWjCB2DELMAkGA1UEBhMC
VVMxCzAJBgNVBAgTAk5DMRAwDgYDVQQHEwdSYWxlaWdoMRcwFQYDVQQKEw5GZWRv
cmEgUHJvamVjdDEPMA0GA1UECxMGZmVkbXNnMSswKQYDVQQDEyJzaGVsbC1hcHAw
MS5waHgyLmZlZG9yYXByb2plY3Qub3JnMSswKQYDVQQpEyJzaGVsbC1hcHAwMS5w
aHgyLmZlZG9yYXByb2plY3Qub3JnMSYwJAYJKoZIhvcNAQkBFhdhZG1pbkBmZWRv
cmFwcm9qZWN0Lm9yZzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAyV0ydvno
pITmFs0kfploKj6nW0/COzp0rDwwvuWZF2KDdl1AeRWzfspOQOWIK5V+o2qxYA6t
aiK4bPfylYL1IGIwlVP9ma5zwkRvWketWjGORp5B7g7oECQOBo3gnQt0Uf5TWAQ1
6Wn0bCrIQSqOWVKScK9vUk/oomUlAZbksEcCAwEAAaOCAVcwggFTMAkGA1UdEwQC
MAAwLQYJYIZIAYb4QgENBCAWHkVhc3ktUlNBIEdlbmVyYXRlZCBDZXJ0aWZpY2F0
ZTAdBgNVHQ4EFgQUd3FXBbD2JW3qcmq+5VP7GcuxHF4wgdUGA1UdIwSBzTCByoAU
AJil1efEVQ6Eo2f+ZkoW4AQV3SGhgaakgaMwgaAxCzAJBgNVBAYTAlVTMQswCQYD
VQQIEwJOQzEQMA4GA1UEBxMHUmFsZWlnaDEXMBUGA1UEChMORmVkb3JhIFByb2pl
Y3QxDzANBgNVBAsTBmZlZG1zZzEPMA0GA1UEAxMGZmVkbXNnMQ8wDQYDVQQpEwZm
ZWRtc2cxJjAkBgkqhkiG9w0BCQEWF2FkbWluQGZlZG9yYXByb2plY3Qub3JnggkA
juso2KkTnXwwEwYDVR0lBAwwCgYIKwYBBQUHAwIwCwYDVR0PBAQDAgeAMA0GCSqG
SIb3DQEBBQUAA4GBABG1zG/lzYyz/phhROq6nzk3QUVeNGyxFdxxoB57j4xDi60y
zy2yAYe9swqlL1Gk94/Zf/lLPFxOM+NinTOh/o6z0bEBBCufwFKiS+ug/pjsI
o69vC03F21S0pquM8bQjcdoA5q5pdiY/Bq5HULmosyA+ENu69ovQGZZUiJb/
-----END CERTIFICATE-----
"""
ca_certificate = """
-----BEGIN CERTIFICATE-----
MIIDyzCCAzSgAwIBAgIJAI7rKNipE518MA0GCSqGSIb3DQEBBQUAMIGgMQswCQYD
VQQGEwJVUzELMAkGA1UECBMCTkMxEDAOBgNVBAcTB1JhbGVpZ2gxFzAVBgNVBAoT
DkZlZG9yYSBQcm9qZWN0MQ8wDQYDVQQLEwZmZWRtc2cxDzANBgNVBAMTBmZlZG1z
ZzEPMA0GA1UEKRMGZmVkbXNnMSYwJAYJKoZIhvcNAQkBFhdhZG1pbkBmZWRvcmFw
cm9qZWN0Lm9yZzAeFw0xMjA3MTUyMTE4NTFaFw0yMjA3MTMyMTE4NTFaMIGgMQsw
CQYDVQQGEwJVUzELMAkGA1UECBMCTkMxEDAOBgNVBAcTB1JhbGVpZ2gxFzAVBgNV
BAoTDkZlZG9yYSBQcm9qZWN0MQ8wDQYDVQQLEwZmZWRtc2cxDzANBgNVBAMTBmZl
ZG1zZzEPMA0GA1UEKRMGZmVkbXNnMSYwJAYJKoZIhvcNAQkBFhdhZG1pbkBmZWRv
cmFwcm9qZWN0Lm9yZzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA9J6RmGr1
LzSJ5Fau2wdkVUiS5WXBcd0bNPyUJ9/G7t9SrycnLnEK4GQh2B525p4SCqvsHZtM
8rqii/Y2PPF5PbpgVjJLYsJk4SSv84aH+VPYcaEtYlPClXgHb3J9jgAxgHBHkJMQ
7mvxiIau7frKFqmJGZkxO2M+Sv8eLCKLJP8CAwEAAaOCAQkwggEFMB0GA1UdDgQW
BBQAmKXV58RVDoSjZ/5mShbgBBXdITCB1QYDVR0jBIHNMIHKgBQAmKXV58RVDoSj
Z/5mShbgBBXdIaGBpqSBozCBoDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAk5DMRAw
DgYDVQQHEwdSYWxlaWdoMRcwFQYDVQQKEw5GZWRvcmEgUHJvamVjdDEPMA0GA1UE
CxMGZmVkbXNnMQ8wDQYDVQQDEwZmZWRtc2cxDzANBgNVBCkTBmZlZG1zZzEmMCQG
CSqGSIb3DQEJARYXYWRtaW5AZmVkb3JhcHJvamVjdC5vcmeCCQCO6yjYqROdfDAM
BgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GBAN5r+1rbeTyGDdlelbqWOXBu
uS0a9BfusO0uwf3tHK9zeB5CDKFgxdfSZ+Fxg1w2HFRHhCOYoZ2ASPfbyANTzxUF
fVAId1uhBD1SlhXpTb3Ndo4uXfalf3W8MrQzFiVHbevvfsyd+RwoVT/PDokE3i4A
fftCd0uwvSqVgyE28SFt
-----END CERTIFICATE-----
"""
ca_cert = load_certificate(FILETYPE_PEM, ca_certificate)
cert = load_certificate(FILETYPE_PEM, certificate)
cert_store = X509Store()
cert_store.add_cert(ca_cert)
while True:
cert_store_context = X509StoreContext(cert_store, cert)
cert_store_context.verify_certificate()
```
Moving the creation of ``X509StoreContext`` outside the loop stops the
memory leak.
Signed-off-by: Jeremy Cline <jeremy@jcline.org>
Diffstat (limited to 'src/OpenSSL/crypto.py')
-rw-r--r-- | src/OpenSSL/crypto.py | 7 |
1 files changed, 7 insertions, 0 deletions
diff --git a/src/OpenSSL/crypto.py b/src/OpenSSL/crypto.py index 4255358..72c04b0 100644 --- a/src/OpenSSL/crypto.py +++ b/src/OpenSSL/crypto.py @@ -1655,6 +1655,9 @@ class X509StoreContext(object): def _init(self): """ Set up the store context for a subsequent verification operation. + + Calling this method more than once without first calling + :meth:`_cleanup` will leak memory. """ ret = _lib.X509_STORE_CTX_init( self._store_ctx, self._store._store, self._cert._x509, _ffi.NULL @@ -1715,6 +1718,10 @@ class X509StoreContext(object): """ # Always re-initialize the store context in case # :meth:`verify_certificate` is called multiple times. + # + # :meth:`_init` is called in :meth:`__init__` so _cleanup is called + # before _init to ensure memory is not leaked. + self._cleanup() self._init() ret = _lib.X509_verify_cert(self._store_ctx) self._cleanup() |