Commit 8b6f16de authored by Yann Leboulanger's avatar Yann Leboulanger

[Fedor Brunner] Use better random number generator when openssl is available. Fixes #12

parent 4e45ce5b
......@@ -27,7 +27,6 @@ from protocol import Node, NodeProcessed, isResultNode, Iq, Protocol, JID
from plugin import PlugIn
from smacks import Smacks
import base64
import random
import itertools
import dispatcher_nb
import hashlib
......@@ -37,6 +36,8 @@ import hashlib
import logging
log = logging.getLogger('nbxmpp.auth_nb')
import rndg
def HH(some): return hashlib.md5(some).hexdigest()
def H(some): return hashlib.md5(some).digest()
def C(some): return ':'.join(some)
......@@ -433,8 +434,7 @@ class SASL(PlugIn):
else:
self.resp['realm'] = self._owner.Server
self.resp['nonce'] = chal['nonce']
self.resp['cnonce'] = ''.join("%x" % randint(0, 2**28) for randint \
in itertools.repeat(random.randint, 7))
self.resp['cnonce'] = '%x' % rngd.getrandbits(196)
self.resp['nc'] = ('00000001')
self.resp['qop'] = 'auth'
self.resp['digest-uri'] = 'xmpp/' + self._owner.Server
......@@ -464,8 +464,7 @@ class SASL(PlugIn):
def set_password(self, password):
self.password = '' if password is None else password
if self.mechanism == 'SCRAM-SHA-1':
nonce = ''.join('%x' % randint(0, 2 ** 28) for randint in \
itertools.repeat(random.randint, 7))
nonce = '%x' % rndg.getrandbits(196)
self.scram_soup = 'n=' + self.username + ',r=' + nonce
self.scram_gs2 = 'n,,' # No CB yet.
sasl_data = (self.scram_gs2 + self.scram_soup).encode('base64').\
......
......@@ -18,7 +18,7 @@
## along with Gajim. If not, see <http://www.gnu.org/licenses/>.
import locale, random
import locale
from hashlib import sha1
from transports_nb import NonBlockingTransport, NonBlockingHTTPBOSH,\
CONNECTED, CONNECTING, DISCONNECTED, DISCONNECTING,\
......@@ -29,6 +29,8 @@ from simplexml import Node
import logging
log = logging.getLogger('nbxmpp.bosh')
import rndg
KEY_COUNT = 10
# Fake file descriptor - it's used for setting read_timeout in idlequeue for
......@@ -486,9 +488,7 @@ def get_rand_number():
# to 7881299347898368 messages to raise rid over 2**53
# (see http://www.xmpp.org/extensions/xep-0124.html#rids)
# it's also used for sequence key initialization
r = random.Random()
r.seed()
return r.getrandbits(50)
return rndg.getrandbits(50)
......
## rndg.py
##
## cryptographically secure pseudo-random number generator.
## When possible use OpenSSL PRNG combined with os.random,
## if OpenSSL PRNG is not available, use only os.random.
##
## Copyright (C) 2013 Fedor Brunner <fedor.brunner@azet.sk>
##
## This file is part of Gajim.
##
## Gajim is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published
## by the Free Software Foundation; version 3 only.
##
## Gajim is distributed 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 General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with Gajim. If not, see <http://www.gnu.org/licenses/>.
USE_PYOPENSSL = False
try:
import OpenSSL.rand
import binascii, os
USE_PYOPENSSL = True
except ImportError:
import random
if not USE_PYOPENSSL:
getrandbits = random.SystemRandom().getrandbits
else:
def getrandbits(k):
"""getrandbits(k) -> x. Generates a long int with k random bits."""
if k <= 0:
raise ValueError('number of bits must be greater than zero')
if k != int(k):
raise TypeError('number of bits should be an integer')
bytes = (k + 7) // 8 # bits / 8 and rounded up
# Add system entropy to OpenSSL PRNG
OpenSSL.rand.add(os.urandom(bytes), bytes)
# Extract random bytes from OpenSSL PRNG
random_str = OpenSSL.rand.bytes(bytes)
x = long(binascii.hexlify(random_str), 16)
return x >> (bytes * 8 - k) # trim excess bits
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment