blob: 9802a926164db99f94a8ca476b51ecae65bf6d51 [file] [log] [blame]
Jean-Paul Calderone897bc252008-02-18 20:50:23 -05001/*
2 * rand.c
3 *
4 * Copyright (C) AB Strakt 2001, All rights reserved
5 *
6 * PRNG management routines, thin wrappers.
7 * See the file RATIONALE for a short explanation of why this module was written.
8 *
9 * Reviewed 2001-07-23
10 */
11#include <Python.h>
12
13/*
14 * In order to get the RAND_screen definition from the rand.h
15 * WIN32 or WINDOWS needs to be defined, otherwise we get a
16 * warning.
17 */
18#ifdef MS_WINDOWS
19#define WIN32
20#endif
21#include <openssl/rand.h>
22
23static char rand_doc[] = "\n\
24PRNG management routines, thin wrappers.\n\
25See the file RATIONALE for a short explanation of why this module was written.\n\
26";
27
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050028static char rand_add_doc[] = "\n\
29Add data with a given entropy to the PRNG\n\
30\n\
31Arguments: spam - Always NULL\n\
32 args - The Python argument tuple, should be:\n\
33 buffer - Buffer with random data\n\
34 entropy - The entropy (in bytes) measurement of the buffer\n\
35Returns: None\n\
36";
37
38static PyObject *
39rand_add(PyObject *spam, PyObject *args)
40{
41 char *buf;
42 int size;
43 double entropy;
44
45 if (!PyArg_ParseTuple(args, "s#d:add", &buf, &size, &entropy))
46 return NULL;
47
48 RAND_add(buf, size, entropy);
49
50 Py_INCREF(Py_None);
51 return Py_None;
52}
53
54static char rand_seed_doc[] = "\n\
55Alias for rand_add, with entropy equal to length\n\
56\n\
57Arguments: spam - Always NULL\n\
58 args - The Python argument tuple, should be:\n\
59 buffer - Buffer with random data\n\
60Returns: None\n\
61";
62
63static PyObject *
64rand_seed(PyObject *spam, PyObject *args)
65{
66 char *buf;
67 int size;
68
69 if (!PyArg_ParseTuple(args, "s#:seed", &buf, &size))
70 return NULL;
71
72 RAND_seed(buf, size);
73
74 Py_INCREF(Py_None);
75 return Py_None;
76}
77
78static char rand_status_doc[] = "\n\
79Retrieve the status of the PRNG\n\
80\n\
81Arguments: spam - Always NULL\n\
82 args - The Python argument tuple, should be empty\n\
83Returns: True if the PRNG is seeded enough, false otherwise\n\
84";
85
86static PyObject *
87rand_status(PyObject *spam, PyObject *args)
88{
89 if (!PyArg_ParseTuple(args, ":status"))
90 return NULL;
91
92 return PyInt_FromLong((long)RAND_status());
93}
94
95#ifdef MS_WINDOWS
96static char rand_screen_doc[] = "\n\
97Add the current contents of the screen to the PRNG state. Availability:\n\
98Windows.\n\
99\n\
100Arguments: spam - Always NULL\n\
101 args - The Python argument tuple, should be empty\n\
102Returns: None\n\
103";
104
105static PyObject *
106rand_screen(PyObject *spam, PyObject *args)
107{
108 if (!PyArg_ParseTuple(args, ":screen"))
109 return NULL;
110
111 RAND_screen();
112 Py_INCREF(Py_None);
113 return Py_None;
114}
115#endif
116
117static char rand_egd_doc[] = "\n\
118Query an entropy gathering daemon (EGD) for random data and add it to the\n\
119PRNG. I haven't found any problems when the socket is missing, the function\n\
120just returns 0.\n\
121\n\
122Arguments: spam - Always NULL\n\
123 args - The Python argument tuple, should be:\n\
124 path - The path to the EGD socket\n\
125 bytes - (optional) The number of bytes to read, default is 255\n\
126Returns: The number of bytes read (NB: a value of 0 isn't necessarily an\n\
127 error, check rand.status())\n\
128";
129
130static PyObject *
131rand_egd(PyObject *spam, PyObject *args)
132{
133 char *path;
134 int bytes = 255;
135
136 if (!PyArg_ParseTuple(args, "s|i:egd", &path, &bytes))
137 return NULL;
138
139 return PyInt_FromLong((long)RAND_egd_bytes(path, bytes));
140}
141
142static char rand_cleanup_doc[] = "\n\
143Erase the memory used by the PRNG.\n\
144\n\
145Arguments: spam - Always NULL\n\
146 args - The Python argument tuple, should be empty\n\
147Returns: None\n\
148";
149
150static PyObject *
151rand_cleanup(PyObject *spam, PyObject *args)
152{
153 if (!PyArg_ParseTuple(args, ":cleanup"))
154 return NULL;
155
156 RAND_cleanup();
157
158 Py_INCREF(Py_None);
159 return Py_None;
160}
161
162static char rand_load_file_doc[] = "\n\
163Seed the PRNG with data from a file\n\
164\n\
165Arguments: spam - Always NULL\n\
166 args - The Python argument tuple, should be:\n\
167 filename - The file to read data from\n\
168 maxbytes - (optional) The number of bytes to read, default is\n\
169 to read the entire file\n\
170Returns: The number of bytes read\n\
171";
172
173static PyObject *
174rand_load_file(PyObject *spam, PyObject *args)
175{
176 char *filename;
177 int maxbytes = -1;
178
179 if (!PyArg_ParseTuple(args, "s|i:load_file", &filename, &maxbytes))
180 return NULL;
181
182 return PyInt_FromLong((long)RAND_load_file(filename, maxbytes));
183}
184
185static char rand_write_file_doc[] = "\n\
186Save PRNG state to a file\n\
187\n\
188Arguments: spam - Always NULL\n\
189 args - The Python argument tuple, should be:\n\
190 filename - The file to write data to\n\
191Returns: The number of bytes written\n\
192";
193
194static PyObject *
195rand_write_file(PyObject *spam, PyObject *args)
196{
197 char *filename;
198
199 if (!PyArg_ParseTuple(args, "s:write_file", &filename))
200 return NULL;
201
202 return PyInt_FromLong((long)RAND_write_file(filename));
203}
204
205
206/* Methods in the OpenSSL.rand module */
207static PyMethodDef rand_methods[] = {
208 { "add", (PyCFunction)rand_add, METH_VARARGS, rand_add_doc },
209 { "seed", (PyCFunction)rand_seed, METH_VARARGS, rand_seed_doc },
210 { "status", (PyCFunction)rand_status, METH_VARARGS, rand_status_doc },
211#ifdef MS_WINDOWS
212 { "screen", (PyCFunction)rand_screen, METH_VARARGS, rand_screen_doc },
213#endif
214 { "egd", (PyCFunction)rand_egd, METH_VARARGS, rand_egd_doc },
215 { "cleanup", (PyCFunction)rand_cleanup, METH_VARARGS, rand_cleanup_doc },
216 { "load_file", (PyCFunction)rand_load_file, METH_VARARGS, rand_load_file_doc },
217 { "write_file",(PyCFunction)rand_write_file, METH_VARARGS, rand_write_file_doc },
218 { NULL, NULL }
219};
220
221
222/*
223 * Initialize the rand sub module
224 *
225 * Arguments: None
226 * Returns: None
227 */
228void
229initrand(void)
230{
231 PyObject *module;
232
233 ERR_load_RAND_strings();
234
235 if ((module = Py_InitModule3("rand", rand_methods, rand_doc)) == NULL)
236 return;
237}
238