Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/Crypto/Random/OSRNG/posix.py: 74%
38 statements
« prev ^ index » next coverage.py v7.2.7, created at 2023-06-07 07:03 +0000
« prev ^ index » next coverage.py v7.2.7, created at 2023-06-07 07:03 +0000
1#
2# Random/OSRNG/posix.py : OS entropy source for POSIX systems
3#
4# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
5#
6# ===================================================================
7# The contents of this file are dedicated to the public domain. To
8# the extent that dedication to the public domain is not available,
9# everyone is granted a worldwide, perpetual, royalty-free,
10# non-exclusive license to exercise all rights associated with the
11# contents of this file for any purpose whatsoever.
12# No rights are reserved.
13#
14# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
18# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
19# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21# SOFTWARE.
22# ===================================================================
25__revision__ = "$Id$"
26__all__ = ['DevURandomRNG']
28import errno
29import os
30import stat
32from .rng_base import BaseRNG
33from Crypto.Util.py3compat import b
35class DevURandomRNG(BaseRNG):
37 def __init__(self, devname=None):
38 if devname is None:
39 self.name = "/dev/urandom"
40 else:
41 self.name = devname
43 # Test that /dev/urandom is a character special device
44 f = open(self.name, "rb", 0)
45 fmode = os.fstat(f.fileno())[stat.ST_MODE]
46 if not stat.S_ISCHR(fmode):
47 f.close()
48 raise TypeError("%r is not a character special device" % (self.name,))
50 self.__file = f
52 BaseRNG.__init__(self)
54 def _close(self):
55 self.__file.close()
57 def _read(self, N):
58 # Starting with Python 3 open with buffering=0 returns a FileIO object.
59 # FileIO.read behaves like read(2) and not like fread(3) and thus we
60 # have to handle the case that read returns less data as requested here
61 # more carefully.
62 data = b("")
63 while len(data) < N:
64 try:
65 d = self.__file.read(N - len(data))
66 except IOError as e:
67 # read(2) has been interrupted by a signal; redo the read
68 if e.errno == errno.EINTR:
69 continue
70 raise
72 if d is None:
73 # __file is in non-blocking mode and no data is available
74 return data
75 if len(d) == 0:
76 # __file is in blocking mode and arrived at EOF
77 return data
79 data += d
80 return data
82def new(*args, **kwargs):
83 return DevURandomRNG(*args, **kwargs)
86# vim:set ts=4 sw=4 sts=4 expandtab: