OLD | NEW |
| (Empty) |
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 | |
8 may 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 | |
14 typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\ | |
15 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\ | |
16 DWORD dwFlags ); | |
17 typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\ | |
18 BYTE *pbBuffer ); | |
19 typedef BOOL (WINAPI *CRYPTRELEASECONTEXT)(HCRYPTPROV hProv,\ | |
20 DWORD dwFlags); | |
21 | |
22 | |
23 static 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 | |
104 static 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 | |
149 static 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 | |
162 static struct PyMethodDef entropy_functions[] = { | |
163 {"entropy", (PyCFunction)entropy, METH_VARARGS, "Return a string of random b
ytes produced by a platform-specific\nentropy source."}, | |
164 {NULL, NULL} /* Sentinel */ | |
165 }; | |
166 | |
167 | |
168 /* Initialize this module. */ | |
169 | |
170 PyMODINIT_FUNC initentropy(void) | |
171 { | |
172 Py_InitModule("entropy", entropy_functions); | |
173 } | |
OLD | NEW |