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