Package paramiko :: Module rng_win32 |
[frames] | no frames]

# Source Code for Module paramiko.rng_win32

      1  #!/usr/bin/python
      2  # -*- coding: ascii -*-
      3  # Copyright (C) 2008  Dwayne C. Litzenberger <dlitz@dlitz.net>
      4  # Copyright (C) 2008  Open Systems Canada Limited
      5  #
      6  # This file is part of paramiko.
      7  #
      8  # Paramiko is free software; you can redistribute it and/or modify it under the
      9  # terms of the GNU Lesser General Public License as published by the Free
     10  # Software Foundation; either version 2.1 of the License, or (at your option)
     11  # any later version.
     12  #
     13  # Paramiko is distrubuted in the hope that it will be useful, but WITHOUT ANY
     14  # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
     15  # A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
     16  # details.
     17  #
     18  # You should have received a copy of the GNU Lesser General Public License
     19  # along with Paramiko; if not, write to the Free Software Foundation, Inc.,
     20  # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
     21
     22 -class error(Exception):
     23      pass
     24
     25  # Try to import the "winrandom" module
     26  try:
     27      from Crypto.Util import winrandom as _winrandom
     28  except ImportError:
     29      _winrandom = None
     30
     31  # Try to import the "urandom" module
     32  try:
     33      from os import urandom as _urandom
     34  except ImportError:
     35      _urandom = None
     36
     37
     38 -class _RNG(object):
     39 -    def __init__(self, readfunc):
     40          self.read = readfunc
     41
     42 -    def randomize(self):
     43          # According to "Cryptanalysis of the Random Number Generator of the
     44          # Windows Operating System", by Leo Dorrendorf and Zvi Gutterman
     45          # and Benny Pinkas <http://eprint.iacr.org/2007/419>,
     46          # CryptGenRandom only updates its internal state using kernel-provided
     47          # random data every 128KiB of output.
     48          self.read(128*1024)    # discard 128 KiB of output
     49
     50 -def _open_winrandom():
     51      if _winrandom is None:
     52          raise error("Crypto.Util.winrandom module not found")
     53
     54      # Check that we can open the winrandom module
     55      try:
     56          r0 = _winrandom.new()
     57          r1 = _winrandom.new()
     58      except Exception, exc:
     59          raise error("winrandom.new() failed: %s" % str(exc), exc)
     60
     61      # Check that we can read from the winrandom module
     62      try:
     63          x = r0.get_bytes(20)
     64          y = r1.get_bytes(20)
     65      except Exception, exc:
     66          raise error("winrandom get_bytes failed: %s" % str(exc), exc)
     67
     68      # Check that the requested number of bytes are returned
     69      if len(x) != 20 or len(y) != 20:
     70          raise error("Error reading from winrandom: input truncated")
     71
     72      # Check that different reads return different data
     73      if x == y:
     74          raise error("winrandom broken: returning identical data")
     75
     76      return _RNG(r0.get_bytes)
     77
     78 -def _open_urandom():
     79      if _urandom is None:
     80          raise error("os.urandom function not found")
     81
     82      # Check that we can read from os.urandom()
     83      try:
     84          x = _urandom(20)
     85          y = _urandom(20)
     86      except Exception, exc:
     87          raise error("os.urandom failed: %s" % str(exc), exc)
     88
     89      # Check that the requested number of bytes are returned
     90      if len(x) != 20 or len(y) != 20:
     91          raise error("os.urandom failed: input truncated")
     92
     93      # Check that different reads return different data
     94      if x == y:
     95          raise error("os.urandom failed: returning identical data")
     96
     97      return _RNG(_urandom)
     98
     99 -def open_rng_device():
    100      # Try using the Crypto.Util.winrandom module
    101      try:
    102          return _open_winrandom()
    103      except error:
    104          pass
    105
    106      # Several versions of PyCrypto do not contain the winrandom module, but
    107      # Python >= 2.4 has os.urandom, so try to use that.
    108      try:
    109          return _open_urandom()
    110      except error:
    111          pass
    112
    113      # SECURITY NOTE: DO NOT USE Crypto.Util.randpool.RandomPool HERE!
    114      # If we got to this point, RandomPool will silently run with very little
    115      # entropy.  (This is current as of PyCrypto 2.0.1).
    116      # See http://www.lag.net/pipermail/paramiko/2008-January/000599.html
    117      # and http://www.lag.net/pipermail/paramiko/2008-April/000678.html
    118
    119      raise error("Unable to find a strong random entropy source.  You cannot run this software securely under the current configuration.")
    120
    121  # vim:set ts=4 sw=4 sts=4 expandtab:
    122