[fedor] use openssl random number generator if available, and improve entropy. Fixes #7550
This commit is contained in:
parent
1e68c92bc8
commit
0789b47646
3 changed files with 67 additions and 4 deletions
|
@ -139,9 +139,10 @@ class ConfigPaths:
|
||||||
self.config_root = self.cache_root = self.data_root = root
|
self.config_root = self.cache_root = self.data_root = root
|
||||||
|
|
||||||
d = {'MY_DATA': '', 'LOG_DB': 'logs.db', 'MY_CACERTS': 'cacerts.pem',
|
d = {'MY_DATA': '', 'LOG_DB': 'logs.db', 'MY_CACERTS': 'cacerts.pem',
|
||||||
'MY_EMOTS': 'emoticons', 'MY_ICONSETS': 'iconsets',
|
'MY_EMOTS': 'emoticons', 'MY_ICONSETS': 'iconsets',
|
||||||
'MY_MOOD_ICONSETS': 'moods', 'MY_ACTIVITY_ICONSETS': 'activities',
|
'MY_MOOD_ICONSETS': 'moods', 'MY_ACTIVITY_ICONSETS': 'activities',
|
||||||
'PLUGINS_USER': 'plugins', 'MY_PEER_CERTS': 'certs'}
|
'PLUGINS_USER': 'plugins', 'MY_PEER_CERTS': 'certs',
|
||||||
|
'RNG_SEED': u'rng_seed'}
|
||||||
for name in d:
|
for name in d:
|
||||||
self.add(name, TYPE_DATA, windowsify(d[name]))
|
self.add(name, TYPE_DATA, windowsify(d[name]))
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
## along with Gajim. If not, see <http://www.gnu.org/licenses/>.
|
## along with Gajim. If not, see <http://www.gnu.org/licenses/>.
|
||||||
##
|
##
|
||||||
|
|
||||||
|
import sys
|
||||||
import os
|
import os
|
||||||
import math
|
import math
|
||||||
|
|
||||||
|
@ -75,8 +76,53 @@ def base28(n):
|
||||||
else:
|
else:
|
||||||
return base28_chr[n]
|
return base28_chr[n]
|
||||||
|
|
||||||
|
def add_entropy_sources_OpenSSL():
|
||||||
|
# Other possibly variable data. This are very low quality sources of
|
||||||
|
# entropy, but some of them are installation dependent and can be hard
|
||||||
|
# to guess for the attacker.
|
||||||
|
# Data available on all platforms Unix, Windows
|
||||||
|
sources = [sys.argv, sys.builtin_module_names,
|
||||||
|
sys.copyright, sys.getfilesystemencoding(), sys.hexversion,
|
||||||
|
sys.modules, sys.path, sys.version, sys.api_version,
|
||||||
|
os.environ, os.getcwd(), os.getpid()]
|
||||||
|
|
||||||
|
for s in sources:
|
||||||
|
OpenSSL.rand.add(str(s), 0.01)
|
||||||
|
|
||||||
|
# On Windows add the current contents of the screen to the PRNG state.
|
||||||
|
if os.name == 'nt':
|
||||||
|
OpenSSL.rand.screen()
|
||||||
|
# The /proc filesystem on POSIX systems contains many random variables:
|
||||||
|
# memory statistics, interrupt counts, network packet counts
|
||||||
|
if os.name == 'posix':
|
||||||
|
dirs = ['/proc', '/proc/net', '/proc/self']
|
||||||
|
for d in dirs:
|
||||||
|
if os.access(d, os.R_OK):
|
||||||
|
for filename in os.listdir(d):
|
||||||
|
OpenSSL.rand.add(filename, 0)
|
||||||
|
try:
|
||||||
|
with open(d + os.sep + filename, "r") as fp:
|
||||||
|
# Limit the ammount of read bytes, in case a memory
|
||||||
|
# file was opened
|
||||||
|
OpenSSL.rand.add(str(fp.read(5000)), 0.01)
|
||||||
|
except:
|
||||||
|
# Ignore all read and access errors
|
||||||
|
pass
|
||||||
|
|
||||||
|
PYOPENSSL_PRNG_PRESENT = False
|
||||||
|
try:
|
||||||
|
import OpenSSL.rand
|
||||||
|
PYOPENSSL_PRNG_PRESENT = True
|
||||||
|
except ImportError:
|
||||||
|
# PyOpenSSL PRNG not available
|
||||||
|
pass
|
||||||
|
|
||||||
def random_bytes(bytes_):
|
def random_bytes(bytes_):
|
||||||
return os.urandom(bytes_)
|
if PYOPENSSL_PRNG_PRESENT:
|
||||||
|
OpenSSL.rand.add(os.urandom(bytes_), bytes_)
|
||||||
|
return OpenSSL.rand.bytes(bytes_)
|
||||||
|
else:
|
||||||
|
return os.urandom(bytes_)
|
||||||
|
|
||||||
def generate_nonce():
|
def generate_nonce():
|
||||||
return random_bytes(8)
|
return random_bytes(8)
|
||||||
|
|
16
src/gajim.py
16
src/gajim.py
|
@ -302,6 +302,19 @@ gajimpaths = common.configpaths.gajimpaths
|
||||||
pid_filename = gajimpaths['PID_FILE']
|
pid_filename = gajimpaths['PID_FILE']
|
||||||
config_filename = gajimpaths['CONFIG_FILE']
|
config_filename = gajimpaths['CONFIG_FILE']
|
||||||
|
|
||||||
|
# Seed the OpenSSL pseudo random number generator from file and initialize
|
||||||
|
RNG_SEED = gajimpaths['RNG_SEED']
|
||||||
|
PYOPENSSL_PRNG_PRESENT = False
|
||||||
|
try:
|
||||||
|
import OpenSSL.rand
|
||||||
|
from common import crypto
|
||||||
|
PYOPENSSL_PRNG_PRESENT = True
|
||||||
|
# Seed from file
|
||||||
|
OpenSSL.rand.load_file(RNG_SEED)
|
||||||
|
crypto.add_entropy_sources_OpenSSL()
|
||||||
|
except ImportError:
|
||||||
|
log.info("PyOpenSSL PRNG not available")
|
||||||
|
|
||||||
import traceback
|
import traceback
|
||||||
import errno
|
import errno
|
||||||
import dialogs
|
import dialogs
|
||||||
|
@ -448,6 +461,9 @@ except IOError as e2:
|
||||||
del pid_dir
|
del pid_dir
|
||||||
|
|
||||||
def on_exit():
|
def on_exit():
|
||||||
|
# Save the entropy from OpenSSL PRNG
|
||||||
|
if PYOPENSSL_PRNG_PRESENT:
|
||||||
|
OpenSSL.rand.write_file(RNG_SEED)
|
||||||
# delete pid file on normal exit
|
# delete pid file on normal exit
|
||||||
if os.path.exists(pid_filename):
|
if os.path.exists(pid_filename):
|
||||||
os.remove(pid_filename)
|
os.remove(pid_filename)
|
||||||
|
|
Loading…
Add table
Reference in a new issue