summaryrefslogtreecommitdiffstats
path: root/src/lib/tlslite/utils/entropy.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/tlslite/utils/entropy.c')
-rwxr-xr-xsrc/lib/tlslite/utils/entropy.c173
1 files changed, 173 insertions, 0 deletions
diff --git a/src/lib/tlslite/utils/entropy.c b/src/lib/tlslite/utils/entropy.c
new file mode 100755
index 000000000..c627794d2
--- /dev/null
+++ b/src/lib/tlslite/utils/entropy.c
@@ -0,0 +1,173 @@
+
+#include "Python.h"
+
+
+#ifdef MS_WINDOWS
+
+/* The following #define is not needed on VC6 with the Platform SDK, and it
+may not be needed on VC7, I'm not sure. I don't think it hurts anything.*/
+#define _WIN32_WINNT 0x0400
+
+#include <windows.h>
+
+
+typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
+ LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
+ DWORD dwFlags );
+typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
+ BYTE *pbBuffer );
+typedef BOOL (WINAPI *CRYPTRELEASECONTEXT)(HCRYPTPROV hProv,\
+ DWORD dwFlags);
+
+
+static PyObject* entropy(PyObject *self, PyObject *args)
+{
+ int howMany = 0;
+ HINSTANCE hAdvAPI32 = NULL;
+ CRYPTACQUIRECONTEXTA pCryptAcquireContextA = NULL;
+ CRYPTGENRANDOM pCryptGenRandom = NULL;
+ CRYPTRELEASECONTEXT pCryptReleaseContext = NULL;
+ HCRYPTPROV hCryptProv = 0;
+ unsigned char* bytes = NULL;
+ PyObject* returnVal = NULL;
+
+
+ /* Read arguments */
+ if (!PyArg_ParseTuple(args, "i", &howMany))
+ return(NULL);
+
+ /* Obtain handle to the DLL containing CryptoAPI
+ This should not fail */
+ if( (hAdvAPI32 = GetModuleHandle("advapi32.dll")) == NULL) {
+ PyErr_Format(PyExc_SystemError,
+ "Advapi32.dll not found");
+ return NULL;
+ }
+
+ /* Obtain pointers to the CryptoAPI functions
+ This will fail on some early version of Win95 */
+ pCryptAcquireContextA = (CRYPTACQUIRECONTEXTA)GetProcAddress(hAdvAPI32,\
+ "CryptAcquireContextA");
+ pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(hAdvAPI32,\
+ "CryptGenRandom");
+ pCryptReleaseContext = (CRYPTRELEASECONTEXT) GetProcAddress(hAdvAPI32,\
+ "CryptReleaseContext");
+ if (pCryptAcquireContextA == NULL || pCryptGenRandom == NULL ||
+ pCryptReleaseContext == NULL) {
+ PyErr_Format(PyExc_NotImplementedError,
+ "CryptoAPI not available on this version of Windows");
+ return NULL;
+ }
+
+ /* Allocate bytes */
+ if ((bytes = (unsigned char*)PyMem_Malloc(howMany)) == NULL)
+ return PyErr_NoMemory();
+
+
+ /* Acquire context */
+ if(!pCryptAcquireContextA(&hCryptProv, NULL, NULL, PROV_RSA_FULL,
+ CRYPT_VERIFYCONTEXT)) {
+ PyErr_Format(PyExc_SystemError,
+ "CryptAcquireContext failed, error %d", GetLastError());
+ PyMem_Free(bytes);
+ return NULL;
+ }
+
+ /* Get random data */
+ if(!pCryptGenRandom(hCryptProv, howMany, bytes)) {
+ PyErr_Format(PyExc_SystemError,
+ "CryptGenRandom failed, error %d", GetLastError());
+ PyMem_Free(bytes);
+ CryptReleaseContext(hCryptProv, 0);
+ return NULL;
+ }
+
+ /* Build return value */
+ returnVal = Py_BuildValue("s#", bytes, howMany);
+ PyMem_Free(bytes);
+
+ /* Release context */
+ if (!pCryptReleaseContext(hCryptProv, 0)) {
+ PyErr_Format(PyExc_SystemError,
+ "CryptReleaseContext failed, error %d", GetLastError());
+ return NULL;
+ }
+
+ return returnVal;
+}
+
+#elif defined(HAVE_UNISTD_H) && defined(HAVE_FCNTL_H)
+
+#include <unistd.h>
+#include <fcntl.h>
+
+static PyObject* entropy(PyObject *self, PyObject *args)
+{
+ int howMany;
+ int fd;
+ unsigned char* bytes = NULL;
+ PyObject* returnVal = NULL;
+
+
+ /* Read arguments */
+ if (!PyArg_ParseTuple(args, "i", &howMany))
+ return(NULL);
+
+ /* Allocate bytes */
+ if ((bytes = (unsigned char*)PyMem_Malloc(howMany)) == NULL)
+ return PyErr_NoMemory();
+
+ /* Open device */
+ if ((fd = open("/dev/urandom", O_RDONLY, 0)) == -1) {
+ PyErr_Format(PyExc_NotImplementedError,
+ "No entropy source found");
+ PyMem_Free(bytes);
+ return NULL;
+ }
+
+ /* Get random data */
+ if (read(fd, bytes, howMany) < howMany) {
+ PyErr_Format(PyExc_SystemError,
+ "Reading from /dev/urandom failed");
+ PyMem_Free(bytes);
+ close(fd);
+ return NULL;
+ }
+
+ /* Build return value */
+ returnVal = Py_BuildValue("s#", bytes, howMany);
+ PyMem_Free(bytes);
+
+ /* Close device */
+ close(fd);
+
+ return returnVal;
+}
+
+#else
+
+static PyObject* entropy(PyObject *self, PyObject *args)
+{
+ PyErr_Format(PyExc_NotImplementedError,
+ "Function not supported");
+ return NULL;
+}
+
+#endif
+
+
+
+/* List of functions exported by this module */
+
+static struct PyMethodDef entropy_functions[] = {
+ {"entropy", (PyCFunction)entropy, METH_VARARGS, "Return a string of random bytes produced by a platform-specific\nentropy source."},
+ {NULL, NULL} /* Sentinel */
+};
+
+
+/* Initialize this module. */
+
+PyMODINIT_FUNC initentropy(void)
+{
+ Py_InitModule("entropy", entropy_functions);
+} \ No newline at end of file