summaryrefslogtreecommitdiff
path: root/Lib/test
diff options
context:
space:
mode:
authorChristian Heimes <christian@cheimes.de>2013-08-21 13:26:05 +0200
committerChristian Heimes <christian@cheimes.de>2013-08-21 13:26:05 +0200
commit5ac4b5df2c236c92a1c9bf79d15f0b0bf88b9904 (patch)
tree108ed0eb8455c36f30cf152e65b3c9a97c435284 /Lib/test
parent569e928349f973c4629e8770f91d184270281a3d (diff)
downloadcpython-5ac4b5df2c236c92a1c9bf79d15f0b0bf88b9904.tar.gz
Issue #18747: Re-seed OpenSSL's pseudo-random number generator after fork.
A pthread_atfork() child handler is used to seeded the PRNG with pid, time and some stack data.
Diffstat (limited to 'Lib/test')
-rw-r--r--Lib/test/test_ssl.py32
1 files changed, 32 insertions, 0 deletions
diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py
index 0ecf4a1226..9bebd1aa0f 100644
--- a/Lib/test/test_ssl.py
+++ b/Lib/test/test_ssl.py
@@ -130,6 +130,38 @@ class BasicSocketTests(unittest.TestCase):
self.assertRaises(TypeError, ssl.RAND_egd, 'foo', 1)
ssl.RAND_add("this is a random string", 75.0)
+ @unittest.skipUnless(os.name == 'posix', 'requires posix')
+ def test_random_fork(self):
+ status = ssl.RAND_status()
+ if not status:
+ self.fail("OpenSSL's PRNG has insufficient randomness")
+
+ rfd, wfd = os.pipe()
+ pid = os.fork()
+ if pid == 0:
+ try:
+ os.close(rfd)
+ child_random = ssl.RAND_pseudo_bytes(16)[0]
+ self.assertEqual(len(child_random), 16)
+ os.write(wfd, child_random)
+ os.close(wfd)
+ except BaseException:
+ os._exit(1)
+ else:
+ os._exit(0)
+ else:
+ os.close(wfd)
+ self.addCleanup(os.close, rfd)
+ _, status = os.waitpid(pid, 0)
+ self.assertEqual(status, 0)
+
+ child_random = os.read(rfd, 16)
+ self.assertEqual(len(child_random), 16)
+ parent_random = ssl.RAND_pseudo_bytes(16)[0]
+ self.assertEqual(len(parent_random), 16)
+
+ self.assertNotEqual(child_random, parent_random)
+
def test_parse_cert(self):
# note that this uses an 'unofficial' function in _ssl.c,
# provided solely for this test, to exercise the certificate