mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
113 lines
3.9 KiB
Python
113 lines
3.9 KiB
Python
#!/usr/bin/python
|
|
# -*- coding: ascii -*-
|
|
# Copyright (C) 2008 Dwayne C. Litzenberger <dlitz@dlitz.net>
|
|
#
|
|
# This file is part of paramiko.
|
|
#
|
|
# Paramiko is free software; you can redistribute it and/or modify it under the
|
|
# terms of the GNU Lesser General Public License as published by the Free
|
|
# Software Foundation; either version 2.1 of the License, or (at your option)
|
|
# any later version.
|
|
#
|
|
# Paramiko is distrubuted in the hope that it will be useful, but WITHOUT ANY
|
|
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
|
# details.
|
|
#
|
|
# You should have received a copy of the GNU Lesser General Public License
|
|
# along with Paramiko; if not, write to the Free Software Foundation, Inc.,
|
|
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
|
|
import sys
|
|
import threading
|
|
from Crypto.Util.randpool import RandomPool as _RandomPool
|
|
|
|
try:
|
|
import platform
|
|
except ImportError:
|
|
platform = None # Not available using Python 2.2
|
|
|
|
def _strxor(a, b):
|
|
assert len(a) == len(b)
|
|
return "".join(map(lambda x, y: chr(ord(x) ^ ord(y)), a, b))
|
|
|
|
##
|
|
## Find a strong random entropy source, depending on the detected platform.
|
|
## WARNING TO DEVELOPERS: This will fail on some systems, but do NOT use
|
|
## Crypto.Util.randpool.RandomPool as a fall-back. RandomPool will happily run
|
|
## with very little entropy, thus _silently_ defeating any security that
|
|
## Paramiko attempts to provide. (This is current as of PyCrypto 2.0.1).
|
|
## See http://www.lag.net/pipermail/paramiko/2008-January/000599.html
|
|
## and http://www.lag.net/pipermail/paramiko/2008-April/000678.html
|
|
##
|
|
|
|
if ((platform is not None and platform.system().lower() == 'windows') or
|
|
sys.platform == 'win32'):
|
|
# MS Windows
|
|
from paramiko import rng_win32
|
|
rng_device = rng_win32.open_rng_device()
|
|
else:
|
|
# Assume POSIX (any system where /dev/urandom exists)
|
|
from paramiko import rng_posix
|
|
rng_device = rng_posix.open_rng_device()
|
|
|
|
|
|
class StrongLockingRandomPool(object):
|
|
"""Wrapper around RandomPool guaranteeing strong random numbers.
|
|
|
|
Crypto.Util.randpool.RandomPool will silently operate even if it is seeded
|
|
with little or no entropy, and it provides no prediction resistance if its
|
|
state is ever compromised throughout its runtime. It is also not thread-safe.
|
|
|
|
This wrapper augments RandomPool by XORing its output with random bits from
|
|
the operating system, and by controlling access to the underlying
|
|
RandomPool using an exclusive lock.
|
|
"""
|
|
|
|
def __init__(self, instance=None):
|
|
if instance is None:
|
|
instance = _RandomPool()
|
|
self.randpool = instance
|
|
self.randpool_lock = threading.Lock()
|
|
self.entropy = rng_device
|
|
|
|
# Stir 256 bits of entropy from the RNG device into the RandomPool.
|
|
self.randpool.stir(self.entropy.read(32))
|
|
self.entropy.randomize()
|
|
|
|
def stir(self, s=''):
|
|
self.randpool_lock.acquire()
|
|
try:
|
|
self.randpool.stir(s)
|
|
finally:
|
|
self.randpool_lock.release()
|
|
self.entropy.randomize()
|
|
|
|
def randomize(self, N=0):
|
|
self.randpool_lock.acquire()
|
|
try:
|
|
self.randpool.randomize(N)
|
|
finally:
|
|
self.randpool_lock.release()
|
|
self.entropy.randomize()
|
|
|
|
def add_event(self, s=''):
|
|
self.randpool_lock.acquire()
|
|
try:
|
|
self.randpool.add_event(s)
|
|
finally:
|
|
self.randpool_lock.release()
|
|
|
|
def get_bytes(self, N):
|
|
self.randpool_lock.acquire()
|
|
try:
|
|
randpool_data = self.randpool.get_bytes(N)
|
|
finally:
|
|
self.randpool_lock.release()
|
|
entropy_data = self.entropy.read(N)
|
|
result = _strxor(randpool_data, entropy_data)
|
|
assert len(randpool_data) == N and len(entropy_data) == N and len(result) == N
|
|
return result
|
|
|
|
# vim:set ts=4 sw=4 sts=4 expandtab:
|