blob: ece09352165dd64e2b18a77919bdc370b60febc5 [file] [log] [blame]
Jean-Paul Calderone8671c852011-03-02 19:26:20 -05001# Copyright (c) Frederick Dean
2# See LICENSE for details.
Rick Dean433dc642009-07-07 13:11:55 -05003
4"""
Jonathan Ballet648875f2011-07-16 14:14:58 +09005Unit tests for :py:obj:`OpenSSL.rand`.
Rick Dean433dc642009-07-07 13:11:55 -05006"""
7
Jean-Paul Calderonee379d732010-07-30 17:06:48 -04008import os
Rick Dean433dc642009-07-07 13:11:55 -05009import stat
Jean-Paul Calderonec7cd3e62013-12-31 13:54:39 -050010import sys
Rick Dean433dc642009-07-07 13:11:55 -050011
Hynek Schlawack80d005f2015-10-20 18:34:13 +020012import pytest
13
Rick Dean433dc642009-07-07 13:11:55 -050014from OpenSSL import rand
15
Hynek Schlawackf0e66852015-10-16 20:18:38 +020016from .util import NON_ASCII, TestCase, b
17
Jean-Paul Calderonebc2bb812009-07-16 13:31:20 -040018
Rick Dean433dc642009-07-07 13:11:55 -050019class RandTests(TestCase):
Jean-Paul Calderonee379d732010-07-30 17:06:48 -040020 def test_bytes_wrong_args(self):
21 """
Hynek Schlawack4f960d32015-09-05 18:15:53 +020022 :py:obj:`OpenSSL.rand.bytes` raises :py:obj:`TypeError` if called with
23 the wrong number of arguments or with a non-:py:obj:`int` argument.
Jean-Paul Calderonee379d732010-07-30 17:06:48 -040024 """
25 self.assertRaises(TypeError, rand.bytes)
26 self.assertRaises(TypeError, rand.bytes, None)
27 self.assertRaises(TypeError, rand.bytes, 3, None)
28
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -050029 def test_insufficientMemory(self):
30 """
31 :py:obj:`OpenSSL.rand.bytes` raises :py:obj:`MemoryError` if more bytes
32 are requested than will fit in memory.
33 """
Jean-Paul Calderone5c3f0522014-01-11 09:08:37 -050034 self.assertRaises(MemoryError, rand.bytes, sys.maxsize)
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -050035
Rick Dean433dc642009-07-07 13:11:55 -050036 def test_bytes(self):
37 """
38 Verify that we can obtain bytes from rand_bytes() and
39 that they are different each time. Test the parameter
40 of rand_bytes() for bad values.
41 """
42 b1 = rand.bytes(50)
43 self.assertEqual(len(b1), 50)
44 b2 = rand.bytes(num_bytes=50) # parameter by name
Hynek Schlawack4f960d32015-09-05 18:15:53 +020045 self.assertNotEqual(b1, b2) # Hip, Hip, Horay! FIPS complaince
Jean-Paul Calderonee379d732010-07-30 17:06:48 -040046 b3 = rand.bytes(num_bytes=0)
Rick Dean433dc642009-07-07 13:11:55 -050047 self.assertEqual(len(b3), 0)
Jean-Paul Calderonebc2bb812009-07-16 13:31:20 -040048 exc = self.assertRaises(ValueError, rand.bytes, -1)
Jean-Paul Calderoned2ead822009-07-16 19:03:30 -040049 self.assertEqual(str(exc), "num_bytes must not be negative")
Rick Dean433dc642009-07-07 13:11:55 -050050
Jean-Paul Calderoneee0a1f02010-07-30 17:04:24 -040051 def test_add_wrong_args(self):
52 """
Hynek Schlawack4f960d32015-09-05 18:15:53 +020053 When called with the wrong number of arguments, or with arguments not
54 of type :py:obj:`str` and :py:obj:`int`, :py:obj:`OpenSSL.rand.add`
55 raises :py:obj:`TypeError`.
Jean-Paul Calderoneee0a1f02010-07-30 17:04:24 -040056 """
57 self.assertRaises(TypeError, rand.add)
Jean-Paul Calderone22cb3122010-10-02 15:55:22 -040058 self.assertRaises(TypeError, rand.add, b("foo"), None)
Jean-Paul Calderoneee0a1f02010-07-30 17:04:24 -040059 self.assertRaises(TypeError, rand.add, None, 3)
Jean-Paul Calderone22cb3122010-10-02 15:55:22 -040060 self.assertRaises(TypeError, rand.add, b("foo"), 3, None)
Jean-Paul Calderoneee0a1f02010-07-30 17:04:24 -040061
Rick Dean433dc642009-07-07 13:11:55 -050062 def test_add(self):
63 """
Jonathan Ballet648875f2011-07-16 14:14:58 +090064 :py:obj:`OpenSSL.rand.add` adds entropy to the PRNG.
Rick Dean433dc642009-07-07 13:11:55 -050065 """
Jean-Paul Calderone22cb3122010-10-02 15:55:22 -040066 rand.add(b('hamburger'), 3)
Jean-Paul Calderonebc2bb812009-07-16 13:31:20 -040067
Jean-Paul Calderoneee0a1f02010-07-30 17:04:24 -040068 def test_seed_wrong_args(self):
69 """
Hynek Schlawack4f960d32015-09-05 18:15:53 +020070 When called with the wrong number of arguments, or with
71 a non-:py:obj:`str` argument, :py:obj:`OpenSSL.rand.seed` raises
72 :py:obj:`TypeError`.
Jean-Paul Calderoneee0a1f02010-07-30 17:04:24 -040073 """
74 self.assertRaises(TypeError, rand.seed)
75 self.assertRaises(TypeError, rand.seed, None)
Jean-Paul Calderone22cb3122010-10-02 15:55:22 -040076 self.assertRaises(TypeError, rand.seed, b("foo"), None)
Jean-Paul Calderoneee0a1f02010-07-30 17:04:24 -040077
Jean-Paul Calderonebc2bb812009-07-16 13:31:20 -040078 def test_seed(self):
79 """
Jonathan Ballet648875f2011-07-16 14:14:58 +090080 :py:obj:`OpenSSL.rand.seed` adds entropy to the PRNG.
Jean-Paul Calderonebc2bb812009-07-16 13:31:20 -040081 """
Jean-Paul Calderone22cb3122010-10-02 15:55:22 -040082 rand.seed(b('milk shake'))
Jean-Paul Calderonebc2bb812009-07-16 13:31:20 -040083
Jean-Paul Calderoneee0a1f02010-07-30 17:04:24 -040084 def test_status_wrong_args(self):
85 """
Hynek Schlawack4f960d32015-09-05 18:15:53 +020086 :py:obj:`OpenSSL.rand.status` raises :py:obj:`TypeError` when called
87 with any arguments.
Jean-Paul Calderoneee0a1f02010-07-30 17:04:24 -040088 """
89 self.assertRaises(TypeError, rand.status, None)
90
Jean-Paul Calderonebc2bb812009-07-16 13:31:20 -040091 def test_status(self):
92 """
Hynek Schlawack4f960d32015-09-05 18:15:53 +020093 :py:obj:`OpenSSL.rand.status` returns :py:obj:`True` if the PRNG has
94 sufficient entropy, :py:obj:`False` otherwise.
Jean-Paul Calderonebc2bb812009-07-16 13:31:20 -040095 """
96 # It's hard to know what it is actually going to return. Different
97 # OpenSSL random engines decide differently whether they have enough
98 # entropy or not.
99 self.assertTrue(rand.status() in (1, 2))
Rick Dean433dc642009-07-07 13:11:55 -0500100
Hynek Schlawack80d005f2015-10-20 18:34:13 +0200101 def test_egd_warning(self):
102 """
103 Calling egd raises :exc:`DeprecationWarning`.
104 """
105 pytest.deprecated_call(rand.egd, b"foo", 255)
106 pytest.deprecated_call(rand.egd, b"foo")
107
Jean-Paul Calderoneee0a1f02010-07-30 17:04:24 -0400108 def test_egd_wrong_args(self):
109 """
Hynek Schlawack80d005f2015-10-20 18:34:13 +0200110 :meth:`OpenSSL.rand.egd` raises :exc:`TypeError` when called with the
111 wrong number of arguments or with arguments not of type :obj:`str` and
112 :obj:`int`.
Jean-Paul Calderoneee0a1f02010-07-30 17:04:24 -0400113 """
Hynek Schlawack80d005f2015-10-20 18:34:13 +0200114 for args in [(),
115 (None,),
116 ("foo", None),
117 (None, 3),
118 ("foo", 3, None)]:
119 with pytest.raises(TypeError):
120 rand.egd(*args)
Jean-Paul Calderone7cf3bf52013-12-29 10:29:48 -0500121
Jean-Paul Calderoneee0a1f02010-07-30 17:04:24 -0400122 def test_cleanup_wrong_args(self):
123 """
Hynek Schlawack4f960d32015-09-05 18:15:53 +0200124 :py:obj:`OpenSSL.rand.cleanup` raises :py:obj:`TypeError` when called
125 with any arguments.
Jean-Paul Calderoneee0a1f02010-07-30 17:04:24 -0400126 """
127 self.assertRaises(TypeError, rand.cleanup, None)
128
Jean-Paul Calderoneee0a1f02010-07-30 17:04:24 -0400129 def test_cleanup(self):
130 """
Hynek Schlawack4f960d32015-09-05 18:15:53 +0200131 :py:obj:`OpenSSL.rand.cleanup` releases the memory used by the PRNG and
132 returns :py:obj:`None`.
Jean-Paul Calderoneee0a1f02010-07-30 17:04:24 -0400133 """
134 self.assertIdentical(rand.cleanup(), None)
135
Jean-Paul Calderoneee0a1f02010-07-30 17:04:24 -0400136 def test_load_file_wrong_args(self):
137 """
Hynek Schlawack4f960d32015-09-05 18:15:53 +0200138 :py:obj:`OpenSSL.rand.load_file` raises :py:obj:`TypeError` when called
139 the wrong number of arguments or arguments not of type :py:obj:`str`
140 and :py:obj:`int`.
Jean-Paul Calderoneee0a1f02010-07-30 17:04:24 -0400141 """
142 self.assertRaises(TypeError, rand.load_file)
143 self.assertRaises(TypeError, rand.load_file, "foo", None)
144 self.assertRaises(TypeError, rand.load_file, None, 1)
145 self.assertRaises(TypeError, rand.load_file, "foo", 1, None)
146
Jean-Paul Calderoneee0a1f02010-07-30 17:04:24 -0400147 def test_write_file_wrong_args(self):
148 """
Hynek Schlawack4f960d32015-09-05 18:15:53 +0200149 :py:obj:`OpenSSL.rand.write_file` raises :py:obj:`TypeError` when
150 called with the wrong number of arguments or a non-:py:obj:`str`
151 argument.
Jean-Paul Calderoneee0a1f02010-07-30 17:04:24 -0400152 """
153 self.assertRaises(TypeError, rand.write_file)
154 self.assertRaises(TypeError, rand.write_file, None)
155 self.assertRaises(TypeError, rand.write_file, "foo", None)
156
Jean-Paul Calderonecbb68cc2015-04-11 12:41:30 -0400157 def _read_write_test(self, path):
Rick Dean433dc642009-07-07 13:11:55 -0500158 """
Jean-Paul Calderonecbb68cc2015-04-11 12:41:30 -0400159 Verify that ``rand.write_file`` and ``rand.load_file`` can be used.
Rick Dean433dc642009-07-07 13:11:55 -0500160 """
Jean-Paul Calderonecbb68cc2015-04-11 12:41:30 -0400161 # Create the file so cleanup is more straightforward
162 with open(path, "w"):
163 pass
164
Jean-Paul Calderoneb534ff42009-07-16 13:44:56 -0400165 try:
Jean-Paul Calderonecbb68cc2015-04-11 12:41:30 -0400166 # Write random bytes to a file
167 rand.write_file(path)
168
Jean-Paul Calderoneb534ff42009-07-16 13:44:56 -0400169 # Verify length of written file
Jean-Paul Calderonecbb68cc2015-04-11 12:41:30 -0400170 size = os.stat(path)[stat.ST_SIZE]
Jean-Paul Calderone20aae942014-01-11 09:46:47 -0500171 self.assertEqual(1024, size)
Jean-Paul Calderonecbb68cc2015-04-11 12:41:30 -0400172
Jean-Paul Calderoneee0a1f02010-07-30 17:04:24 -0400173 # Read random bytes from file
Jean-Paul Calderonecbb68cc2015-04-11 12:41:30 -0400174 rand.load_file(path)
175 rand.load_file(path, 4) # specify a length
Jean-Paul Calderoneb534ff42009-07-16 13:44:56 -0400176 finally:
177 # Cleanup
Jean-Paul Calderonecbb68cc2015-04-11 12:41:30 -0400178 os.unlink(path)
179
Jean-Paul Calderonecbb68cc2015-04-11 12:41:30 -0400180 def test_bytes_paths(self):
181 """
182 Random data can be saved and loaded to files with paths specified as
183 bytes.
184 """
185 path = self.mktemp()
Jean-Paul Calderone210c0f32015-04-12 09:20:31 -0400186 path += NON_ASCII.encode(sys.getfilesystemencoding())
Jean-Paul Calderonecbb68cc2015-04-11 12:41:30 -0400187 self._read_write_test(path)
188
Jean-Paul Calderonecbb68cc2015-04-11 12:41:30 -0400189 def test_unicode_paths(self):
190 """
191 Random data can be saved and loaded to files with paths specified as
192 unicode.
193 """
Jean-Paul Calderone210c0f32015-04-12 09:20:31 -0400194 path = self.mktemp().decode('utf-8') + NON_ASCII
Jean-Paul Calderonecbb68cc2015-04-11 12:41:30 -0400195 self._read_write_test(path)