OLD | NEW |
(Empty) | |
| 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 # =================================================================== |
| 23 |
| 24 |
| 25 __revision__ = "$Id$" |
| 26 __all__ = ['DevURandomRNG'] |
| 27 |
| 28 import errno |
| 29 import os |
| 30 import stat |
| 31 |
| 32 from rng_base import BaseRNG |
| 33 from Crypto.Util.py3compat import b |
| 34 |
| 35 class DevURandomRNG(BaseRNG): |
| 36 |
| 37 def __init__(self, devname=None): |
| 38 if devname is None: |
| 39 self.name = "/dev/urandom" |
| 40 else: |
| 41 self.name = devname |
| 42 |
| 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,
)) |
| 49 |
| 50 self.__file = f |
| 51 |
| 52 BaseRNG.__init__(self) |
| 53 |
| 54 def _close(self): |
| 55 self.__file.close() |
| 56 |
| 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, e: |
| 67 # read(2) has been interrupted by a signal; redo the read |
| 68 if e.errno == errno.EINTR: |
| 69 continue |
| 70 raise |
| 71 |
| 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 |
| 78 |
| 79 data += d |
| 80 return data |
| 81 |
| 82 def new(*args, **kwargs): |
| 83 return DevURandomRNG(*args, **kwargs) |
| 84 |
| 85 |
| 86 # vim:set ts=4 sw=4 sts=4 expandtab: |
OLD | NEW |