blob: 087b2436a65686567c7b267ea7a9d55a443bc806 [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
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -050034_raise_current_error = partial(_exception_from_error_queue, Error)
Jean-Paul Calderone8210b922013-02-09 09:03:18 -080035
36_unspecified = object()
37
Jean-Paul Calderonee80a25a2014-01-09 14:33:42 -050038_builtin_bytes = bytes
39
Alex Gaynorca87ff62015-09-04 23:31:03 -040040
Jean-Paul Calderone8210b922013-02-09 09:03:18 -080041def bytes(num_bytes):
42 """
Hynek Schlawack80d005f2015-10-20 18:34:13 +020043 Get some random bytes from the PRNG as a string.
Jean-Paul Calderone8210b922013-02-09 09:03:18 -080044
Hynek Schlawack80d005f2015-10-20 18:34:13 +020045 This is a wrapper for the C function ``RAND_bytes``.
46
47 :param num_bytes: The number of bytes to fetch.
48
49 :return: A string of random bytes.
Jean-Paul Calderone8210b922013-02-09 09:03:18 -080050 """
Jean-Paul Calderone53a5e132014-01-11 08:31:19 -050051 if not isinstance(num_bytes, _integer_types):
Jean-Paul Calderone8210b922013-02-09 09:03:18 -080052 raise TypeError("num_bytes must be an integer")
53
54 if num_bytes < 0:
55 raise ValueError("num_bytes must not be negative")
56
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050057 result_buffer = _ffi.new("char[]", num_bytes)
58 result_code = _lib.RAND_bytes(result_buffer, num_bytes)
Jean-Paul Calderone8210b922013-02-09 09:03:18 -080059 if result_code == -1:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -050060 # TODO: No tests for this code path. Triggering a RAND_bytes failure
61 # might involve supplying a custom ENGINE? That's hard.
62 _raise_current_error()
63
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050064 return _ffi.buffer(result_buffer)[:]
Jean-Paul Calderone8210b922013-02-09 09:03:18 -080065
66
Jean-Paul Calderone8210b922013-02-09 09:03:18 -080067def add(buffer, entropy):
68 """
Hynek Schlawack80d005f2015-10-20 18:34:13 +020069 Mix bytes from *string* into the PRNG state.
Jean-Paul Calderone8210b922013-02-09 09:03:18 -080070
Hynek Schlawack80d005f2015-10-20 18:34:13 +020071 The *entropy* argument is (the lower bound of) an estimate of how much
72 randomness is contained in *string*, measured in bytes.
73
74 For more information, see e.g. :rfc:`1750`.
75
76 :param buffer: Buffer with random data.
77 :param entropy: The entropy (in bytes) measurement of the buffer.
78
79 :return: :obj:`None`
Jean-Paul Calderone8210b922013-02-09 09:03:18 -080080 """
Jean-Paul Calderonee80a25a2014-01-09 14:33:42 -050081 if not isinstance(buffer, _builtin_bytes):
Jean-Paul Calderone8210b922013-02-09 09:03:18 -080082 raise TypeError("buffer must be a byte string")
83
84 if not isinstance(entropy, int):
85 raise TypeError("entropy must be an integer")
86
87 # TODO Nothing tests this call actually being made, or made properly.
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050088 _lib.RAND_add(buffer, len(buffer), entropy)
Jean-Paul Calderone8210b922013-02-09 09:03:18 -080089
90
Jean-Paul Calderone8210b922013-02-09 09:03:18 -080091def seed(buffer):
92 """
Hynek Schlawack80d005f2015-10-20 18:34:13 +020093 Equivalent to calling :func:`add` with *entropy* as the length of *buffer*.
Jean-Paul Calderone8210b922013-02-09 09:03:18 -080094
95 :param buffer: Buffer with random data
Hynek Schlawack80d005f2015-10-20 18:34:13 +020096
97 :return: :obj:`None`
Jean-Paul Calderone8210b922013-02-09 09:03:18 -080098 """
Jean-Paul Calderonee80a25a2014-01-09 14:33:42 -050099 if not isinstance(buffer, _builtin_bytes):
Jean-Paul Calderone8210b922013-02-09 09:03:18 -0800100 raise TypeError("buffer must be a byte string")
101
102 # TODO Nothing tests this call actually being made, or made properly.
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500103 _lib.RAND_seed(buffer, len(buffer))
Jean-Paul Calderone8210b922013-02-09 09:03:18 -0800104
105
Jean-Paul Calderone8210b922013-02-09 09:03:18 -0800106def status():
107 """
Hynek Schlawack80d005f2015-10-20 18:34:13 +0200108 Check whether the PRNG has been seeded with enough data.
Jean-Paul Calderone8210b922013-02-09 09:03:18 -0800109
Hynek Schlawack80d005f2015-10-20 18:34:13 +0200110 :return: :obj:`True` if the PRNG is seeded enough, :obj:`False` otherwise.
Jean-Paul Calderone8210b922013-02-09 09:03:18 -0800111 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500112 return _lib.RAND_status()
Jean-Paul Calderone8210b922013-02-09 09:03:18 -0800113
114
Jean-Paul Calderone8210b922013-02-09 09:03:18 -0800115def egd(path, bytes=_unspecified):
116 """
Hynek Schlawack80d005f2015-10-20 18:34:13 +0200117 Query the system random source and seed the PRNG.
Jean-Paul Calderone8210b922013-02-09 09:03:18 -0800118
Hynek Schlawack80d005f2015-10-20 18:34:13 +0200119 Does *not* actually query the EGD.
120
Hynek Schlawack0cc61542016-01-19 14:09:32 +0100121 .. deprecated:: 16.0.0
Hynek Schlawack80d005f2015-10-20 18:34:13 +0200122 EGD was only necessary for some commercial UNIX systems that all
123 reached their ends of life more than a decade ago. See
124 `pyca/cryptography#1636
125 <https://github.com/pyca/cryptography/pull/1636>`_.
126
127 :param path: Ignored.
128 :param bytes: (optional) The number of bytes to read, default is 255.
129
130 :returns: ``len(bytes)`` or 255 if not specified.
Jean-Paul Calderone8210b922013-02-09 09:03:18 -0800131 """
Hynek Schlawack0cc61542016-01-19 14:09:32 +0100132 warnings.warn("OpenSSL.rand.egd() is deprecated as of 16.0.0.",
Hynek Schlawack80d005f2015-10-20 18:34:13 +0200133 DeprecationWarning)
134
Jean-Paul Calderonea8f7a942014-01-11 08:45:37 -0500135 if not isinstance(path, _builtin_bytes):
136 raise TypeError("path must be a byte string")
Jean-Paul Calderone8210b922013-02-09 09:03:18 -0800137
138 if bytes is _unspecified:
139 bytes = 255
140 elif not isinstance(bytes, int):
141 raise TypeError("bytes must be an integer")
142
Hynek Schlawack80d005f2015-10-20 18:34:13 +0200143 seed(os.urandom(bytes))
144 return bytes
Jean-Paul Calderone8210b922013-02-09 09:03:18 -0800145
146
Jean-Paul Calderone8210b922013-02-09 09:03:18 -0800147def cleanup():
148 """
149 Erase the memory used by the PRNG.
150
Hynek Schlawack80d005f2015-10-20 18:34:13 +0200151 This is a wrapper for the C function ``RAND_cleanup``.
152
153 :return: :obj:`None`
Jean-Paul Calderone8210b922013-02-09 09:03:18 -0800154 """
155 # TODO Nothing tests this call actually being made, or made properly.
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500156 _lib.RAND_cleanup()
Jean-Paul Calderone8210b922013-02-09 09:03:18 -0800157
158
Jean-Paul Calderone8210b922013-02-09 09:03:18 -0800159def load_file(filename, maxbytes=_unspecified):
160 """
Hynek Schlawack80d005f2015-10-20 18:34:13 +0200161 Read *maxbytes* of data from *filename* and seed the PRNG with it.
162
163 Read the whole file if *maxbytes* is not specified or negative.
Jean-Paul Calderone8210b922013-02-09 09:03:18 -0800164
Jean-Paul Calderone4e0c43f2015-04-13 10:15:17 -0400165 :param filename: The file to read data from (``bytes`` or ``unicode``).
Hynek Schlawack80d005f2015-10-20 18:34:13 +0200166 :param maxbytes: (optional) The number of bytes to read. Default is to
167 read the entire file.
Jean-Paul Calderone4e0c43f2015-04-13 10:15:17 -0400168
Jean-Paul Calderone8210b922013-02-09 09:03:18 -0800169 :return: The number of bytes read
170 """
Jean-Paul Calderonecbb68cc2015-04-11 12:41:30 -0400171 filename = _path_string(filename)
Jean-Paul Calderone8210b922013-02-09 09:03:18 -0800172
173 if maxbytes is _unspecified:
174 maxbytes = -1
175 elif not isinstance(maxbytes, int):
176 raise TypeError("maxbytes must be an integer")
177
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500178 return _lib.RAND_load_file(filename, maxbytes)
Jean-Paul Calderone8210b922013-02-09 09:03:18 -0800179
180
Jean-Paul Calderone8210b922013-02-09 09:03:18 -0800181def write_file(filename):
182 """
Hynek Schlawack80d005f2015-10-20 18:34:13 +0200183 Write a number of random bytes (currently 1024) to the file *path*. This
184 file can then be used with :func:`load_file` to seed the PRNG again.
Jean-Paul Calderone8210b922013-02-09 09:03:18 -0800185
Jean-Paul Calderone4e0c43f2015-04-13 10:15:17 -0400186 :param filename: The file to write data to (``bytes`` or ``unicode``).
187
Hynek Schlawack80d005f2015-10-20 18:34:13 +0200188 :return: The number of bytes written.
Jean-Paul Calderone8210b922013-02-09 09:03:18 -0800189 """
Jean-Paul Calderonecbb68cc2015-04-11 12:41:30 -0400190 filename = _path_string(filename)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500191 return _lib.RAND_write_file(filename)
Jean-Paul Calderone8210b922013-02-09 09:03:18 -0800192
193
194# TODO There are no tests for screen at all
195def screen():
196 """
Hynek Schlawack80d005f2015-10-20 18:34:13 +0200197 Add the current contents of the screen to the PRNG state.
198
199 Availability: Windows.
Jean-Paul Calderone8210b922013-02-09 09:03:18 -0800200
201 :return: None
202 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500203 _lib.RAND_screen()
Jean-Paul Calderone8210b922013-02-09 09:03:18 -0800204
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500205if getattr(_lib, 'RAND_screen', None) is None:
Jean-Paul Calderone8210b922013-02-09 09:03:18 -0800206 del screen
207
208
209# TODO There are no tests for the RAND strings being loaded, whatever that
210# means.
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500211_lib.ERR_load_RAND_strings()