PageRenderTime 48ms CodeModel.GetById 32ms app.highlight 12ms RepoModel.GetById 1ms app.codeStats 1ms

/gdata/tlslite/utils/entropy.c

http://radioappz.googlecode.com/
C | 173 lines | 112 code | 41 blank | 20 comment | 20 complexity | d1809e936e59e78373d037c929b7e772 MD5 | raw file
  1
  2#include "Python.h"
  3
  4
  5#ifdef MS_WINDOWS
  6
  7/* The following #define is not needed on VC6 with the Platform SDK, and it
  8may not be needed on VC7, I'm not sure.  I don't think it hurts anything.*/
  9#define _WIN32_WINNT 0x0400
 10
 11#include <windows.h>
 12
 13
 14typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
 15              LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
 16              DWORD dwFlags );
 17typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
 18              BYTE *pbBuffer );
 19typedef BOOL (WINAPI *CRYPTRELEASECONTEXT)(HCRYPTPROV hProv,\
 20              DWORD dwFlags);
 21
 22
 23static PyObject* entropy(PyObject *self, PyObject *args)
 24{
 25    int howMany = 0;
 26    HINSTANCE hAdvAPI32 = NULL;
 27    CRYPTACQUIRECONTEXTA pCryptAcquireContextA = NULL;
 28    CRYPTGENRANDOM pCryptGenRandom = NULL;
 29    CRYPTRELEASECONTEXT pCryptReleaseContext = NULL;
 30    HCRYPTPROV hCryptProv = 0;
 31    unsigned char* bytes = NULL;
 32    PyObject* returnVal = NULL;
 33
 34
 35    /* Read arguments */
 36    if (!PyArg_ParseTuple(args, "i", &howMany))
 37        return(NULL);
 38
 39	/* Obtain handle to the DLL containing CryptoAPI
 40	   This should not fail	*/
 41	if( (hAdvAPI32 = GetModuleHandle("advapi32.dll")) == NULL) {
 42        PyErr_Format(PyExc_SystemError,
 43            "Advapi32.dll not found");
 44        return NULL;
 45	}
 46
 47	/* Obtain pointers to the CryptoAPI functions
 48	   This will fail on some early version of Win95 */
 49	pCryptAcquireContextA = (CRYPTACQUIRECONTEXTA)GetProcAddress(hAdvAPI32,\
 50	                        "CryptAcquireContextA");
 51	pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(hAdvAPI32,\
 52	                  "CryptGenRandom");
 53	pCryptReleaseContext = (CRYPTRELEASECONTEXT) GetProcAddress(hAdvAPI32,\
 54	                       "CryptReleaseContext");
 55	if (pCryptAcquireContextA == NULL || pCryptGenRandom == NULL ||
 56	                                     pCryptReleaseContext == NULL) {
 57        PyErr_Format(PyExc_NotImplementedError,
 58            "CryptoAPI not available on this version of Windows");
 59        return NULL;
 60	}
 61
 62    /* Allocate bytes */
 63    if ((bytes = (unsigned char*)PyMem_Malloc(howMany)) == NULL)
 64        return PyErr_NoMemory();
 65
 66
 67    /* Acquire context */
 68    if(!pCryptAcquireContextA(&hCryptProv, NULL, NULL, PROV_RSA_FULL,
 69                            CRYPT_VERIFYCONTEXT)) {
 70        PyErr_Format(PyExc_SystemError,
 71                     "CryptAcquireContext failed, error %d", GetLastError());
 72        PyMem_Free(bytes);
 73        return NULL;
 74    }
 75
 76    /* Get random data */
 77    if(!pCryptGenRandom(hCryptProv, howMany, bytes)) {
 78        PyErr_Format(PyExc_SystemError,
 79                     "CryptGenRandom failed, error %d", GetLastError());
 80        PyMem_Free(bytes);
 81        CryptReleaseContext(hCryptProv, 0);
 82        return NULL;
 83    }
 84
 85    /* Build return value */
 86    returnVal = Py_BuildValue("s#", bytes, howMany);
 87    PyMem_Free(bytes);
 88
 89    /* Release context */
 90    if (!pCryptReleaseContext(hCryptProv, 0)) {
 91        PyErr_Format(PyExc_SystemError,
 92                     "CryptReleaseContext failed, error %d", GetLastError());
 93        return NULL;
 94    }
 95
 96    return returnVal;
 97}
 98
 99#elif defined(HAVE_UNISTD_H) && defined(HAVE_FCNTL_H)
100
101#include <unistd.h>
102#include <fcntl.h>
103
104static PyObject* entropy(PyObject *self, PyObject *args)
105{
106    int howMany;
107    int fd;
108    unsigned char* bytes = NULL;
109    PyObject* returnVal = NULL;
110
111
112    /* Read arguments */
113    if (!PyArg_ParseTuple(args, "i", &howMany))
114        return(NULL);
115
116    /* Allocate bytes */
117    if ((bytes = (unsigned char*)PyMem_Malloc(howMany)) == NULL)
118        return PyErr_NoMemory();
119
120    /* Open device */
121    if ((fd = open("/dev/urandom", O_RDONLY, 0)) == -1) {
122        PyErr_Format(PyExc_NotImplementedError,
123            "No entropy source found");
124        PyMem_Free(bytes);
125        return NULL;
126    }
127
128    /* Get random data */
129    if (read(fd, bytes, howMany) < howMany) {
130        PyErr_Format(PyExc_SystemError,
131            "Reading from /dev/urandom failed");
132        PyMem_Free(bytes);
133        close(fd);
134        return NULL;
135    }
136
137    /* Build return value */
138    returnVal = Py_BuildValue("s#", bytes, howMany);
139    PyMem_Free(bytes);
140
141    /* Close device */
142    close(fd);
143
144    return returnVal;
145}
146
147#else
148
149static PyObject* entropy(PyObject *self, PyObject *args)
150{
151    PyErr_Format(PyExc_NotImplementedError,
152            "Function not supported");
153    return NULL;
154}
155
156#endif
157
158
159
160/* List of functions exported by this module */
161
162static struct PyMethodDef entropy_functions[] = {
163    {"entropy", (PyCFunction)entropy, METH_VARARGS, "Return a string of random bytes produced by a platform-specific\nentropy source."},
164    {NULL,  NULL}        /* Sentinel */
165};
166
167
168/* Initialize this module. */
169
170PyMODINIT_FUNC initentropy(void)
171{
172    Py_InitModule("entropy", entropy_functions);
173}