summaryrefslogtreecommitdiff
path: root/OpenSSL/crypto
diff options
context:
space:
mode:
authorZiga Seilnacht <ziga.seilnacht@gmail.com>2009-12-22 14:58:01 +0100
committerJean-Paul Calderone <exarkun@divmod.com>2009-12-22 14:58:01 +0100
commit781295ae151fb709e613d1d30f47f31426f8008e (patch)
tree5e049389c765d7960b55ad8ea9c5cc7a6822eedb /OpenSSL/crypto
parent6b90a40aaaae00de1ba4eef736255fc0eeb7f72a (diff)
downloadpyopenssl-781295ae151fb709e613d1d30f47f31426f8008e.tar.gz
Additional error checks and a refcount fix for global_passphrase_callback.
There were two really big problems in this function: the first one was the silent truncation of passphrases, the second was the refcounting bug, which kept the passphrase in memory until the process exited. See tests for details.
Diffstat (limited to 'OpenSSL/crypto')
-rw-r--r--OpenSSL/crypto/crypto.c13
1 files changed, 11 insertions, 2 deletions
diff --git a/OpenSSL/crypto/crypto.c b/OpenSSL/crypto/crypto.c
index d9ce52e..ec4d0b3 100644
--- a/OpenSSL/crypto/crypto.c
+++ b/OpenSSL/crypto/crypto.c
@@ -45,19 +45,28 @@ global_passphrase_callback(char *buf, int len, int rwflag, void *cb_arg)
func = (PyObject *)cb_arg;
argv = Py_BuildValue("(i)", rwflag);
+ if (argv == NULL) {
+ return 0;
+ }
ret = PyEval_CallObject(func, argv);
Py_DECREF(argv);
if (ret == NULL)
return 0;
if (!PyBytes_Check(ret))
{
+ Py_DECREF(ret);
PyErr_SetString(PyExc_ValueError, "String expected");
return 0;
}
nchars = PyBytes_Size(ret);
- if (nchars > len)
- nchars = len;
+ if (nchars > len) {
+ Py_DECREF(ret);
+ PyErr_SetString(PyExc_ValueError,
+ "passphrase returned by callback is too long");
+ return 0;
+ }
strncpy(buf, PyBytes_AsString(ret), nchars);
+ Py_DECREF(ret);
return nchars;
}