diff options
author | Jeremy Hylton <jeremy@alum.mit.edu> | 2001-10-18 00:28:50 (GMT) |
---|---|---|
committer | Jeremy Hylton <jeremy@alum.mit.edu> | 2001-10-18 00:28:50 (GMT) |
commit | de80f2efb5c189a9e709651af99e495b2a578b5a (patch) | |
tree | dc0eb0291bbd137b96cbb58f589279b2988083f9 /Modules | |
parent | 5449e08412a5abd83c21d59764ef6240c58872b0 (diff) | |
download | cpython-de80f2efb5c189a9e709651af99e495b2a578b5a.zip cpython-de80f2efb5c189a9e709651af99e495b2a578b5a.tar.gz cpython-de80f2efb5c189a9e709651af99e495b2a578b5a.tar.bz2 |
Expose three OpenSSL API calls for dealing with the PRNG.
Quoth the OpenSSL RAND_add man page:
OpenSSL makes sure that the PRNG state is unique for each
thread. On systems that provide /dev/urandom, the
randomness device is used to seed the PRNG transparently.
However, on all other systems, the application is
responsible for seeding the PRNG by calling RAND_add(),
RAND_egd(3) or RAND_load_file(3).
I decided to expose RAND_add() because it's general and RAND_egd()
because it's a useful special case. RAND_load_file() didn't seem to
offer much over RAND_add(), so I skipped it. Also supplied
RAND_status() which returns true if the PRNG is seeded and false if
not.
Diffstat (limited to 'Modules')
-rw-r--r-- | Modules/socketmodule.c | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index b6e415e..8c8ebb7 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -211,6 +211,7 @@ Socket methods: #include "openssl/pem.h" #include "openssl/ssl.h" #include "openssl/err.h" +#include "openssl/rand.h" #endif /* USE_SSL */ #ifndef HAVE_INET_PTON @@ -2762,6 +2763,66 @@ staticforward PyTypeObject PySSL_Type = { 0, /*tp_hash*/ }; +/* helper routines for seeding the SSL PRNG */ +static PyObject * +PySSL_RAND_add(PyObject *self, PyObject *args) +{ + char *buf; + int len; + double entropy; + + if (!PyArg_ParseTuple(args, "s#d:RAND_add", &buf, &len, &entropy)) + return NULL; + RAND_add(buf, len, entropy); + Py_INCREF(Py_None); + return Py_None; +} + +static char PySSL_RAND_add_doc[] = +"RAND_add(string, entropy)\n\ +\n\ +Mix string into the OpenSSL PRNG state. entropy (a float) is a lower\n\ +bound on the entropy contained in string."; + +static PyObject * +PySSL_RAND_status(PyObject *self) +{ + return PyInt_FromLong(RAND_status()); +} + +static char PySSL_RAND_status_doc[] = +"RAND_status() -> 0 or 1\n\ +\n\ +Returns 1 if the OpenSSL PRNG has been seeded with enough data and 0 if not.\n\ +It is necessary to seed the PRNG with RAND_add() on some platforms before\n\ +using the ssl() function."; + +static PyObject * +PySSL_RAND_egd(PyObject *self, PyObject *arg) +{ + int bytes; + + if (!PyString_Check(arg)) + return PyErr_Format(PyExc_TypeError, + "RAND_egd() expected string, found %s", + arg->ob_type->tp_name); + bytes = RAND_egd(PyString_AS_STRING(arg)); + if (bytes == -1) { + PyErr_SetString(PySSLErrorObject, + "EGD connection failed or EGD did not return " + "enough data to seed the PRNG"); + return NULL; + } + return PyInt_FromLong(bytes); +} + +static char PySSL_RAND_egd_doc[] = +"RAND_egd(path) -> bytes +\n\ +Queries the entropy gather daemon (EGD) on socket path. Returns number\n\ +of bytes read. Raises socket.sslerror if connection to EGD fails or\n\ +if it does provide enough data to seed PRNG."; + #endif /* USE_SSL */ @@ -2805,6 +2866,12 @@ static PyMethodDef PySocket_methods[] = { #ifdef USE_SSL {"ssl", PySocket_ssl, METH_VARARGS, ssl_doc}, + {"RAND_add", PySSL_RAND_add, METH_VARARGS, + PySSL_RAND_add_doc}, + {"RAND_egd", PySSL_RAND_egd, METH_O, + PySSL_RAND_egd_doc}, + {"RAND_status", (PyCFunction)PySSL_RAND_status, METH_NOARGS, + PySSL_RAND_status_doc}, #endif /* USE_SSL */ {NULL, NULL} /* Sentinel */ }; |