blob: 8f51ad84ae911f764f881e3ad8fccf81cb824bc3 [file] [log] [blame]
Jean-Paul Calderone8210b922013-02-09 09:03:18 -08001"""
2PRNG management routines, thin wrappers.
Jean-Paul Calderone8210b922013-02-09 09:03:18 -08003"""
4
Hynek Schlawack80d005f2015-10-20 18:34:13 +02005import os
6import warnings
7
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05008from functools import partial
Jean-Paul Calderone8210b922013-02-09 09:03:18 -08009
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -050010from six import integer_types as _integer_types
11
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -050012from OpenSSL._util import (
13 ffi as _ffi,
14 lib as _lib,
Jean-Paul Calderonecbb68cc2015-04-11 12:41:30 -040015 exception_from_error_queue as _exception_from_error_queue,
16 path_string as _path_string)
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -050017
18
Jean-Paul Calderone8210b922013-02-09 09:03:18 -080019class Error(Exception):
Jean-Paul Calderone511cde02013-12-29 10:31:13 -050020 """
Hynek Schlawack80d005f2015-10-20 18:34:13 +020021 An error occurred in an :mod:`OpenSSL.rand` API.
22
23 If the current RAND method supports any errors, this is raised when needed.
24 The default method does not raise this when the entropy pool is depleted.
25
26 Whenever this exception is raised directly, it has a list of error messages
27 from the OpenSSL error queue, where each item is a tuple *(lib, function,
28 reason)*. Here *lib*, *function* and *reason* are all strings, describing
29 where and what the problem is.
30
31 See :manpage:`err(3)` for more information.
Jean-Paul Calderone511cde02013-12-29 10:31:13 -050032 """
Jean-Paul Calderone8210b922013-02-09 09:03:18 -080033
Alex Chanc6077062016-11-18 13:53:39 +000034
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -050035_raise_current_error = partial(_exception_from_error_queue, Error)
Jean-Paul Calderone8210b922013-02-09 09:03:18 -080036
37_unspecified = object()
38
Jean-Paul Calderonee80a25a2014-01-09 14:33:42 -050039_builtin_bytes = bytes
40
Alex Gaynorca87ff62015-09-04 23:31:03 -040041
Jean-Paul Calderone8210b922013-02-09 09:03:18 -080042def bytes(num_bytes):
43 """
Hynek Schlawack80d005f2015-10-20 18:34:13 +020044 Get some random bytes from the PRNG as a string.
Jean-Paul Calderone8210b922013-02-09 09:03:18 -080045
Hynek Schlawack80d005f2015-10-20 18:34:13 +020046 This is a wrapper for the C function ``RAND_bytes``.
47
48 :param num_bytes: The number of bytes to fetch.
49
50 :return: A string of random bytes.
Jean-Paul Calderone8210b922013-02-09 09:03:18 -080051 """
Jean-Paul Calderone53a5e132014-01-11 08:31:19 -050052 if not isinstance(num_bytes, _integer_types):
Jean-Paul Calderone8210b922013-02-09 09:03:18 -080053 raise TypeError("num_bytes must be an integer")
54
55 if num_bytes < 0:
56 raise ValueError("num_bytes must not be negative")
57
Paul Kehrer9f9113a2016-09-20 20:10:25 -050058 result_buffer = _ffi.new("unsigned char[]", num_bytes)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050059 result_code = _lib.RAND_bytes(result_buffer, num_bytes)
Jean-Paul Calderone8210b922013-02-09 09:03:18 -080060 if result_code == -1:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -050061 # TODO: No tests for this code path. Triggering a RAND_bytes failure
62 # might involve supplying a custom ENGINE? That's hard.
63 _raise_current_error()
64
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050065 return _ffi.buffer(result_buffer)[:]
Jean-Paul Calderone8210b922013-02-09 09:03:18 -080066
67
Jean-Paul Calderone8210b922013-02-09 09:03:18 -080068def add(buffer, entropy):
69 """
Hynek Schlawack80d005f2015-10-20 18:34:13 +020070 Mix bytes from *string* into the PRNG state.
Jean-Paul Calderone8210b922013-02-09 09:03:18 -080071
Hynek Schlawack80d005f2015-10-20 18:34:13 +020072 The *entropy* argument is (the lower bound of) an estimate of how much
73 randomness is contained in *string*, measured in bytes.
74
75 For more information, see e.g. :rfc:`1750`.
76
77 :param buffer: Buffer with random data.
78 :param entropy: The entropy (in bytes) measurement of the buffer.
79
80 :return: :obj:`None`
Jean-Paul Calderone8210b922013-02-09 09:03:18 -080081 """
Jean-Paul Calderonee80a25a2014-01-09 14:33:42 -050082 if not isinstance(buffer, _builtin_bytes):
Jean-Paul Calderone8210b922013-02-09 09:03:18 -080083 raise TypeError("buffer must be a byte string")
84
85 if not isinstance(entropy, int):
86 raise TypeError("entropy must be an integer")
87
88 # TODO Nothing tests this call actually being made, or made properly.
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050089 _lib.RAND_add(buffer, len(buffer), entropy)
Jean-Paul Calderone8210b922013-02-09 09:03:18 -080090
91
Jean-Paul Calderone8210b922013-02-09 09:03:18 -080092def seed(buffer):
93 """
Hynek Schlawack80d005f2015-10-20 18:34:13 +020094 Equivalent to calling :func:`add` with *entropy* as the length of *buffer*.
Jean-Paul Calderone8210b922013-02-09 09:03:18 -080095
96 :param buffer: Buffer with random data
Hynek Schlawack80d005f2015-10-20 18:34:13 +020097
98 :return: :obj:`None`
Jean-Paul Calderone8210b922013-02-09 09:03:18 -080099 """
Jean-Paul Calderonee80a25a2014-01-09 14:33:42 -0500100 if not isinstance(buffer, _builtin_bytes):
Jean-Paul Calderone8210b922013-02-09 09:03:18 -0800101 raise TypeError("buffer must be a byte string")
102
103 # TODO Nothing tests this call actually being made, or made properly.
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500104 _lib.RAND_seed(buffer, len(buffer))
Jean-Paul Calderone8210b922013-02-09 09:03:18 -0800105
106
Jean-Paul Calderone8210b922013-02-09 09:03:18 -0800107def status():
108 """
Hynek Schlawack80d005f2015-10-20 18:34:13 +0200109 Check whether the PRNG has been seeded with enough data.
Jean-Paul Calderone8210b922013-02-09 09:03:18 -0800110
Alex Chan6b69c552016-10-24 16:34:41 +0100111 :return: 1 if the PRNG is seeded enough, 0 otherwise.
Jean-Paul Calderone8210b922013-02-09 09:03:18 -0800112 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500113 return _lib.RAND_status()
Jean-Paul Calderone8210b922013-02-09 09:03:18 -0800114
115
Jean-Paul Calderone8210b922013-02-09 09:03:18 -0800116def egd(path, bytes=_unspecified):
117 """
Hynek Schlawack80d005f2015-10-20 18:34:13 +0200118 Query the system random source and seed the PRNG.
Jean-Paul Calderone8210b922013-02-09 09:03:18 -0800119
Hynek Schlawack80d005f2015-10-20 18:34:13 +0200120 Does *not* actually query the EGD.
121
Hynek Schlawack0cc61542016-01-19 14:09:32 +0100122 .. deprecated:: 16.0.0
Hynek Schlawack80d005f2015-10-20 18:34:13 +0200123 EGD was only necessary for some commercial UNIX systems that all
124 reached their ends of life more than a decade ago. See
125 `pyca/cryptography#1636
126 <https://github.com/pyca/cryptography/pull/1636>`_.
127
128 :param path: Ignored.
129 :param bytes: (optional) The number of bytes to read, default is 255.
130
131 :returns: ``len(bytes)`` or 255 if not specified.
Jean-Paul Calderone8210b922013-02-09 09:03:18 -0800132 """
Hynek Schlawack0cc61542016-01-19 14:09:32 +0100133 warnings.warn("OpenSSL.rand.egd() is deprecated as of 16.0.0.",
Hynek Schlawack80d005f2015-10-20 18:34:13 +0200134 DeprecationWarning)
135
Jean-Paul Calderonea8f7a942014-01-11 08:45:37 -0500136 if not isinstance(path, _builtin_bytes):
137 raise TypeError("path must be a byte string")
Jean-Paul Calderone8210b922013-02-09 09:03:18 -0800138
139 if bytes is _unspecified:
140 bytes = 255
141 elif not isinstance(bytes, int):
142 raise TypeError("bytes must be an integer")
143
Hynek Schlawack80d005f2015-10-20 18:34:13 +0200144 seed(os.urandom(bytes))
145 return bytes
Jean-Paul Calderone8210b922013-02-09 09:03:18 -0800146
147
Jean-Paul Calderone8210b922013-02-09 09:03:18 -0800148def cleanup():
149 """
150 Erase the memory used by the PRNG.
151
Hynek Schlawack80d005f2015-10-20 18:34:13 +0200152 This is a wrapper for the C function ``RAND_cleanup``.
153
154 :return: :obj:`None`
Jean-Paul Calderone8210b922013-02-09 09:03:18 -0800155 """
156 # TODO Nothing tests this call actually being made, or made properly.
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500157 _lib.RAND_cleanup()
Jean-Paul Calderone8210b922013-02-09 09:03:18 -0800158
159
Jean-Paul Calderone8210b922013-02-09 09:03:18 -0800160def load_file(filename, maxbytes=_unspecified):
161 """
Hynek Schlawack80d005f2015-10-20 18:34:13 +0200162 Read *maxbytes* of data from *filename* and seed the PRNG with it.
163
164 Read the whole file if *maxbytes* is not specified or negative.
Jean-Paul Calderone8210b922013-02-09 09:03:18 -0800165
Jean-Paul Calderone4e0c43f2015-04-13 10:15:17 -0400166 :param filename: The file to read data from (``bytes`` or ``unicode``).
Hynek Schlawack80d005f2015-10-20 18:34:13 +0200167 :param maxbytes: (optional) The number of bytes to read. Default is to
168 read the entire file.
Jean-Paul Calderone4e0c43f2015-04-13 10:15:17 -0400169
Jean-Paul Calderone8210b922013-02-09 09:03:18 -0800170 :return: The number of bytes read
171 """
Jean-Paul Calderonecbb68cc2015-04-11 12:41:30 -0400172 filename = _path_string(filename)
Jean-Paul Calderone8210b922013-02-09 09:03:18 -0800173
174 if maxbytes is _unspecified:
175 maxbytes = -1
176 elif not isinstance(maxbytes, int):
177 raise TypeError("maxbytes must be an integer")
178
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500179 return _lib.RAND_load_file(filename, maxbytes)
Jean-Paul Calderone8210b922013-02-09 09:03:18 -0800180
181
Jean-Paul Calderone8210b922013-02-09 09:03:18 -0800182def write_file(filename):
183 """
Hynek Schlawack80d005f2015-10-20 18:34:13 +0200184 Write a number of random bytes (currently 1024) to the file *path*. This
185 file can then be used with :func:`load_file` to seed the PRNG again.
Jean-Paul Calderone8210b922013-02-09 09:03:18 -0800186
Jean-Paul Calderone4e0c43f2015-04-13 10:15:17 -0400187 :param filename: The file to write data to (``bytes`` or ``unicode``).
188
Hynek Schlawack80d005f2015-10-20 18:34:13 +0200189 :return: The number of bytes written.
Jean-Paul Calderone8210b922013-02-09 09:03:18 -0800190 """
Jean-Paul Calderonecbb68cc2015-04-11 12:41:30 -0400191 filename = _path_string(filename)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500192 return _lib.RAND_write_file(filename)
Jean-Paul Calderone8210b922013-02-09 09:03:18 -0800193
194
195# TODO There are no tests for screen at all
196def screen():
197 """
Hynek Schlawack80d005f2015-10-20 18:34:13 +0200198 Add the current contents of the screen to the PRNG state.
199
200 Availability: Windows.
Jean-Paul Calderone8210b922013-02-09 09:03:18 -0800201
202 :return: None
203 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500204 _lib.RAND_screen()
Jean-Paul Calderone8210b922013-02-09 09:03:18 -0800205
Alex Chanc6077062016-11-18 13:53:39 +0000206
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500207if getattr(_lib, 'RAND_screen', None) is None:
Jean-Paul Calderone8210b922013-02-09 09:03:18 -0800208 del screen
209
210
211# TODO There are no tests for the RAND strings being loaded, whatever that
212# means.
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500213_lib.ERR_load_RAND_strings()