[Python-checkins] CVS: python/dist/src/Modules socketmodule.c,1.181,1.182

Jeremy Hylton jhylton@users.sourceforge.net
Wed, 17 Oct 2001 17:28:52 -0700


Update of /cvsroot/python/python/dist/src/Modules
In directory usw-pr-cvs1:/tmp/cvs-serv12731/Modules

Modified Files:
	socketmodule.c 
Log Message:
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.


Index: socketmodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/socketmodule.c,v
retrieving revision 1.181
retrieving revision 1.182
diff -C2 -d -r1.181 -r1.182
*** socketmodule.c	2001/10/15 21:12:54	1.181
--- socketmodule.c	2001/10/18 00:28:50	1.182
***************
*** 212,215 ****
--- 212,216 ----
  #include "openssl/ssl.h"
  #include "openssl/err.h"
+ #include "openssl/rand.h"
  #endif /* USE_SSL */
  
***************
*** 2763,2766 ****
--- 2764,2827 ----
  };
  
+ /* 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 */
  
***************
*** 2806,2809 ****
--- 2867,2876 ----
  	{"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 */