summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Gaynor <alex.gaynor@gmail.com>2017-07-25 10:33:17 -0400
committerHynek Schlawack <hs@ox.cx>2017-07-25 16:33:17 +0200
commit23c965e7864bd9f37cf2c6076895c9bec395f00c (patch)
treec90c026df662bee4f21a46e29f72feb0895dc41a
parent209de940c3d36e700d73385b417cb94064c13919 (diff)
downloadpyopenssl-23c965e7864bd9f37cf2c6076895c9bec395f00c.tar.gz
Delete rand.py (#675)
-rw-r--r--CHANGELOG.rst4
-rw-r--r--src/OpenSSL/__init__.py4
-rw-r--r--src/OpenSSL/rand.py169
-rw-r--r--tests/test_rand.py172
4 files changed, 6 insertions, 343 deletions
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 7b2f4db..213c397 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -14,6 +14,10 @@ Backward-incompatible changes:
- Dropped support for Python 3.3.
`#677 <https://github.com/pyca/pyopenssl/pull/677>`_
+- Removed the deprecated ``OpenSSL.rand`` module.
+ This is being done ahead of our normal deprecation schedule due to its lack of use and the fact that it was becoming a maintenance burden.
+ ``os.urandom()`` should be used instead.
+ `#675 <https://github.com/pyca/pyopenssl/pull/675>`_
Deprecations:
diff --git a/src/OpenSSL/__init__.py b/src/OpenSSL/__init__.py
index b827e3c..810d00d 100644
--- a/src/OpenSSL/__init__.py
+++ b/src/OpenSSL/__init__.py
@@ -5,7 +5,7 @@
pyOpenSSL - A simple wrapper around the OpenSSL library
"""
-from OpenSSL import rand, crypto, SSL
+from OpenSSL import crypto, SSL
from OpenSSL.version import (
__author__, __copyright__, __email__, __license__, __summary__, __title__,
__uri__, __version__,
@@ -13,7 +13,7 @@ from OpenSSL.version import (
__all__ = [
- "SSL", "crypto", "rand",
+ "SSL", "crypto",
"__author__", "__copyright__", "__email__", "__license__", "__summary__",
"__title__", "__uri__", "__version__",
diff --git a/src/OpenSSL/rand.py b/src/OpenSSL/rand.py
deleted file mode 100644
index e2f6373..0000000
--- a/src/OpenSSL/rand.py
+++ /dev/null
@@ -1,169 +0,0 @@
-"""
-PRNG management routines, thin wrappers.
-"""
-
-import warnings
-from functools import partial
-
-from six import integer_types as _integer_types
-
-from OpenSSL._util import (
- ffi as _ffi,
- lib as _lib,
- exception_from_error_queue as _exception_from_error_queue,
- path_string as _path_string)
-
-
-warnings.warn(
- "OpenSSL.rand is deprecated - you should use os.urandom instead",
- DeprecationWarning, stacklevel=3
-)
-
-
-class Error(Exception):
- """
- 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)
-
-_unspecified = object()
-
-_builtin_bytes = bytes
-
-
-def bytes(num_bytes):
- """
- 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.
- """
- if not isinstance(num_bytes, _integer_types):
- raise TypeError("num_bytes must be an integer")
-
- if num_bytes < 0:
- raise ValueError("num_bytes must not be negative")
-
- result_buffer = _ffi.new("unsigned char[]", num_bytes)
- result_code = _lib.RAND_bytes(result_buffer, num_bytes)
- if result_code == -1:
- # TODO: No tests for this code path. Triggering a RAND_bytes failure
- # might involve supplying a custom ENGINE? That's hard.
- _raise_current_error()
-
- return _ffi.buffer(result_buffer)[:]
-
-
-def add(buffer, entropy):
- """
- Mix bytes from *string* into the PRNG state.
-
- 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")
-
- if not isinstance(entropy, int):
- raise TypeError("entropy must be an integer")
-
- # TODO Nothing tests this call actually being made, or made properly.
- _lib.RAND_add(buffer, len(buffer), entropy)
-
-
-def seed(buffer):
- """
- Equivalent to calling :func:`add` with *entropy* as the length of *buffer*.
-
- :param buffer: Buffer with random data
-
- :return: :obj:`None`
- """
- if not isinstance(buffer, _builtin_bytes):
- raise TypeError("buffer must be a byte string")
-
- # TODO Nothing tests this call actually being made, or made properly.
- _lib.RAND_seed(buffer, len(buffer))
-
-
-def status():
- """
- Check whether the PRNG has been seeded with enough data.
-
- :return: 1 if the PRNG is seeded enough, 0 otherwise.
- """
- return _lib.RAND_status()
-
-
-def cleanup():
- """
- Erase the memory used by the PRNG.
-
- 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()
-
-
-def load_file(filename, maxbytes=_unspecified):
- """
- 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.
-
- :return: The number of bytes read
- """
- filename = _path_string(filename)
-
- if maxbytes is _unspecified:
- maxbytes = -1
- elif not isinstance(maxbytes, int):
- raise TypeError("maxbytes must be an integer")
-
- return _lib.RAND_load_file(filename, maxbytes)
-
-
-def write_file(filename):
- """
- 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.
- """
- filename = _path_string(filename)
- return _lib.RAND_write_file(filename)
-
-
-# TODO There are no tests for the RAND strings being loaded, whatever that
-# means.
-_lib.ERR_load_RAND_strings()
diff --git a/tests/test_rand.py b/tests/test_rand.py
deleted file mode 100644
index 41a4f27..0000000
--- a/tests/test_rand.py
+++ /dev/null
@@ -1,172 +0,0 @@
-# Copyright (c) Frederick Dean
-# See LICENSE for details.
-
-"""
-Unit tests for `OpenSSL.rand`.
-"""
-
-import os
-import stat
-import sys
-
-import pytest
-
-from OpenSSL import rand
-
-from .util import NON_ASCII
-
-
-class TestRand(object):
-
- @pytest.mark.parametrize('args', [
- (None,),
- (b"foo",),
- ])
- def test_bytes_wrong_args(self, args):
- """
- `OpenSSL.rand.bytes` raises `TypeError` if called with a non-`int`
- argument.
- """
- with pytest.raises(TypeError):
- rand.bytes(*args)
-
- def test_insufficient_memory(self):
- """
- `OpenSSL.rand.bytes` raises `MemoryError` or `OverflowError` if more
- bytes are requested than will fit in memory.
- """
- with pytest.raises((MemoryError, OverflowError)):
- rand.bytes(sys.maxsize + 1)
-
- def test_bytes(self):
- """
- Verify that we can obtain bytes from rand_bytes() and that they are
- different each time. Test the parameter of rand_bytes() for
- bad values.
- """
- b1 = rand.bytes(50)
- assert len(b1) == 50
- b2 = rand.bytes(num_bytes=50) # parameter by name
- assert b1 != b2 # Hip, Hip, Horay! FIPS complaince
- b3 = rand.bytes(num_bytes=0)
- assert len(b3) == 0
- with pytest.raises(ValueError) as exc:
- rand.bytes(-1)
- assert str(exc.value) == "num_bytes must not be negative"
-
- @pytest.mark.parametrize('args', [
- (b"foo", None),
- (None, 3),
- ])
- def test_add_wrong_args(self, args):
- """
- `OpenSSL.rand.add` raises `TypeError` if called with arguments not of
- type `str` and `int`.
- """
- with pytest.raises(TypeError):
- rand.add(*args)
-
- def test_add(self):
- """
- `OpenSSL.rand.add` adds entropy to the PRNG.
- """
- rand.add(b'hamburger', 3)
-
- @pytest.mark.parametrize('args', [
- (None,),
- (42,),
- ])
- def test_seed_wrong_args(self, args):
- """
- `OpenSSL.rand.seed` raises `TypeError` if called with
- a non-`str` argument.
- """
- with pytest.raises(TypeError):
- rand.seed(*args)
-
- def test_seed(self):
- """
- `OpenSSL.rand.seed` adds entropy to the PRNG.
- """
- rand.seed(b'milk shake')
-
- def test_status(self):
- """
- `OpenSSL.rand.status` returns `1` if the PRNG has sufficient entropy,
- `0` otherwise.
- """
- # It's hard to know what it is actually going to return. Different
- # OpenSSL random engines decide differently whether they have enough
- # entropy or not.
- assert rand.status() in (0, 1)
-
- def test_cleanup(self):
- """
- `OpenSSL.rand.cleanup` releases the memory used by the PRNG and
- returns `None`.
- """
- assert rand.cleanup() is None
-
- @pytest.mark.parametrize('args', [
- ("foo", None),
- (None, 1),
- ])
- def test_load_file_wrong_args(self, args):
- """
- `OpenSSL.rand.load_file` raises `TypeError` when with arguments
- not of type `str` and `int`.
- """
- with pytest.raises(TypeError):
- rand.load_file(*args)
-
- @pytest.mark.parametrize('args', [
- None,
- 1,
- ])
- def test_write_file_wrong_args(self, args):
- """
- `OpenSSL.rand.write_file` raises `TypeError` when called with
- a non-`str` argument.
- """
- with pytest.raises(TypeError):
- rand.write_file(*args)
-
- def _read_write_test(self, path):
- """
- Verify that ``rand.write_file`` and ``rand.load_file`` can be used.
- """
- # Create the file so cleanup is more straightforward
- with open(path, "w"):
- pass
-
- try:
- # Write random bytes to a file
- rand.write_file(path)
-
- # Verify length of written file
- size = os.stat(path)[stat.ST_SIZE]
- assert size == 1024
-
- # Read random bytes from file
- rand.load_file(path)
- rand.load_file(path, 4) # specify a length
- finally:
- # Cleanup
- os.unlink(path)
-
- def test_bytes_paths(self, tmpfile):
- """
- Random data can be saved and loaded to files with paths specified as
- bytes.
- """
- path = tmpfile
- path += NON_ASCII.encode(sys.getfilesystemencoding())
- self._read_write_test(path)
-
- def test_unicode_paths(self, tmpfile):
- """
- Random data can be saved and loaded to files with paths specified as
- unicode.
- """
- path = tmpfile.decode('utf-8') + NON_ASCII
- self._read_write_test(path)