diff options
author | Hynek Schlawack <hs@ox.cx> | 2015-10-20 18:34:13 +0200 |
---|---|---|
committer | Hynek Schlawack <hs@ox.cx> | 2015-10-20 21:14:48 +0200 |
commit | 80d005f68754f268da419540a593db83286f3d0c (patch) | |
tree | a2be0539075cfe3a3dfd580d78cfe756a196da68 /src/OpenSSL/rand.py | |
parent | d283a6454a9d3929edd1b17e4e02663a6947b5d1 (diff) | |
download | pyopenssl-80d005f68754f268da419540a593db83286f3d0c.tar.gz |
Replace the only EGD call by urandom
Also harmonize documentation. #boyScout
Diffstat (limited to 'src/OpenSSL/rand.py')
-rw-r--r-- | src/OpenSSL/rand.py | 97 |
1 files changed, 67 insertions, 30 deletions
diff --git a/src/OpenSSL/rand.py b/src/OpenSSL/rand.py index 65cd597..c12638f 100644 --- a/src/OpenSSL/rand.py +++ b/src/OpenSSL/rand.py @@ -1,9 +1,10 @@ """ PRNG management routines, thin wrappers. - -See the file RATIONALE for a short explanation of why this module was written. """ +import os +import warnings + from functools import partial from six import integer_types as _integer_types @@ -17,7 +18,17 @@ from OpenSSL._util import ( class Error(Exception): """ - An error occurred in an `OpenSSL.rand` API. + An error occurred in an :mod:`OpenSSL.rand` API. + + If the current RAND method supports any errors, this is raised when needed. + The default method does not raise this when the entropy pool is depleted. + + Whenever this exception is raised directly, it has a list of error messages + from the OpenSSL error queue, where each item is a tuple *(lib, function, + reason)*. Here *lib*, *function* and *reason* are all strings, describing + where and what the problem is. + + See :manpage:`err(3)` for more information. """ _raise_current_error = partial(_exception_from_error_queue, Error) @@ -29,10 +40,13 @@ _builtin_bytes = bytes def bytes(num_bytes): """ - Get some random bytes as a string. + Get some random bytes from the PRNG as a string. + + This is a wrapper for the C function ``RAND_bytes``. - :param num_bytes: The number of bytes to fetch - :return: A string of random bytes + :param num_bytes: The number of bytes to fetch. + + :return: A string of random bytes. """ if not isinstance(num_bytes, _integer_types): raise TypeError("num_bytes must be an integer") @@ -52,11 +66,17 @@ def bytes(num_bytes): def add(buffer, entropy): """ - Add data with a given entropy to the PRNG + Mix bytes from *string* into the PRNG state. - :param buffer: Buffer with random data - :param entropy: The entropy (in bytes) measurement of the buffer - :return: None + The *entropy* argument is (the lower bound of) an estimate of how much + randomness is contained in *string*, measured in bytes. + + For more information, see e.g. :rfc:`1750`. + + :param buffer: Buffer with random data. + :param entropy: The entropy (in bytes) measurement of the buffer. + + :return: :obj:`None` """ if not isinstance(buffer, _builtin_bytes): raise TypeError("buffer must be a byte string") @@ -70,10 +90,11 @@ def add(buffer, entropy): def seed(buffer): """ - Alias for rand_add, with entropy equal to length + Equivalent to calling :func:`add` with *entropy* as the length of *buffer*. :param buffer: Buffer with random data - :return: None + + :return: :obj:`None` """ if not isinstance(buffer, _builtin_bytes): raise TypeError("buffer must be a byte string") @@ -84,24 +105,33 @@ def seed(buffer): def status(): """ - Retrieve the status of the PRNG + Check whether the PRNG has been seeded with enough data. - :return: True if the PRNG is seeded enough, false otherwise + :return: :obj:`True` if the PRNG is seeded enough, :obj:`False` otherwise. """ return _lib.RAND_status() def egd(path, bytes=_unspecified): """ - Query an entropy gathering daemon (EGD) for random data and add it to the - PRNG. I haven't found any problems when the socket is missing, the function - just returns 0. + Query the system random source and seed the PRNG. + + Does *not* actually query the EGD. + + .. deprecated:: 15.2.0 + EGD was only necessary for some commercial UNIX systems that all + reached their ends of life more than a decade ago. See + `pyca/cryptography#1636 + <https://github.com/pyca/cryptography/pull/1636>`_. + + :param path: Ignored. + :param bytes: (optional) The number of bytes to read, default is 255. - :param path: The path to the EGD socket - :param bytes: (optional) The number of bytes to read, default is 255 - :returns: The number of bytes read (NB: a value of 0 isn't necessarily an - error, check rand.status()) + :returns: ``len(bytes)`` or 255 if not specified. """ + warnings.warn("OpenSSL.rand.egd() is deprecated as of 15.2.0.", + DeprecationWarning) + if not isinstance(path, _builtin_bytes): raise TypeError("path must be a byte string") @@ -110,14 +140,17 @@ def egd(path, bytes=_unspecified): elif not isinstance(bytes, int): raise TypeError("bytes must be an integer") - return _lib.RAND_egd_bytes(path, bytes) + seed(os.urandom(bytes)) + return bytes def cleanup(): """ Erase the memory used by the PRNG. - :return: None + This is a wrapper for the C function ``RAND_cleanup``. + + :return: :obj:`None` """ # TODO Nothing tests this call actually being made, or made properly. _lib.RAND_cleanup() @@ -125,11 +158,13 @@ def cleanup(): def load_file(filename, maxbytes=_unspecified): """ - Seed the PRNG with data from a file + Read *maxbytes* of data from *filename* and seed the PRNG with it. + + Read the whole file if *maxbytes* is not specified or negative. :param filename: The file to read data from (``bytes`` or ``unicode``). - :param maxbytes: (optional) The number of bytes to read, default is to read - the entire file + :param maxbytes: (optional) The number of bytes to read. Default is to + read the entire file. :return: The number of bytes read """ @@ -145,11 +180,12 @@ def load_file(filename, maxbytes=_unspecified): def write_file(filename): """ - Save PRNG state to a file + Write a number of random bytes (currently 1024) to the file *path*. This + file can then be used with :func:`load_file` to seed the PRNG again. :param filename: The file to write data to (``bytes`` or ``unicode``). - :return: The number of bytes written + :return: The number of bytes written. """ filename = _path_string(filename) return _lib.RAND_write_file(filename) @@ -158,8 +194,9 @@ def write_file(filename): # TODO There are no tests for screen at all def screen(): """ - Add the current contents of the screen to the PRNG state. Availability: - Windows. + Add the current contents of the screen to the PRNG state. + + Availability: Windows. :return: None """ |