[project @ Arch-1:robey@lag.net--2003-public%secsh--dev--1.0--patch-4]

change kex-gex server code to generate primes by hand
added a util function "generate_prime" to compare to the incredibly slow C
version, but it's no faster of course.  i think kex-gex from the server is
just not going to be feasible without having a separate thread generate some
primes in the background to have handy when a request comes in.  so in short,
this still doesn't work.

also i put bit_length into util and a tb_strings function which gets stack
traceback info and splits it into a list of strings.
This commit is contained in:
Robey Pointer 2003-11-09 20:59:51 +00:00
parent 7d4d90a8c5
commit 79fecc4564
2 changed files with 33 additions and 3 deletions

View File

@ -4,7 +4,8 @@
# are provided by the server. a bit more work is required on our side (and a # are provided by the server. a bit more work is required on our side (and a
# LOT more on the server side). # LOT more on the server side).
from message import Message, inflate_long, deflate_long from message import Message
from util import inflate_long, deflate_long, generate_prime
from secsh import SSHException from secsh import SSHException
from transport import MSG_NEWKEYS from transport import MSG_NEWKEYS
from Crypto.Hash import SHA from Crypto.Hash import SHA
@ -95,10 +96,11 @@ class KexGex(object):
# generate prime # generate prime
while 1: while 1:
# does not work FIXME # does not work FIXME
# the problem is that it's too fscking SLOW
self.transport.log(DEBUG, 'stir...') self.transport.log(DEBUG, 'stir...')
self.transport.randpool.stir() self.transport.randpool.stir()
self.transport.log(DEBUG, 'get-prime %d...' % preferred) self.transport.log(DEBUG, 'get-prime %d...' % preferred)
self.p = number.getPrime(preferred, self.transport.randpool.get_bytes) self.p = generate_prime(preferred, self.transport.randpool)
self.transport.log(DEBUG, 'got ' + repr(self.p)) self.transport.log(DEBUG, 'got ' + repr(self.p))
if number.isPrime((self.p - 1) // 2): if number.isPrime((self.p - 1) // 2):
break break

30
util.py
View File

@ -1,6 +1,7 @@
#!/usr/bin/python #!/usr/bin/python
import struct import sys, struct, traceback
from Crypto.Util import number
def inflate_long(s, always_positive=0): def inflate_long(s, always_positive=0):
"turns a normalized byte string into a long-int (adapted from Crypto.Util.number)" "turns a normalized byte string into a long-int (adapted from Crypto.Util.number)"
@ -87,3 +88,30 @@ def safe_string(s):
return out return out
# ''.join([['%%%02X' % ord(c), c][(ord(c) >= 32) and (ord(c) <= 127)] for c in s]) # ''.join([['%%%02X' % ord(c), c][(ord(c) >= 32) and (ord(c) <= 127)] for c in s])
def bit_length(n):
norm = deflate_long(n, 0)
hbyte = ord(norm[0])
bitlen = len(norm) * 8
while not (hbyte & 0x80):
hbyte <<= 1
bitlen -= 1
return bitlen
def generate_prime(bits, randpool):
hbyte_mask = pow(2, bits % 8) - 1
x = randpool.get_bytes((bits+7) // 8)
if hbyte_mask > 0:
x = chr(ord(x[0]) & hbyte_mask) + x[1:]
n = inflate_long(x, 1)
n |= 1
n |= (1 << (bits - 1))
while 1:
# loop catches the case where we increment n into a higher bit-range
while not number.isPrime(n):
n += 2
if bit_length(n) == bits:
return n
def tb_strings():
return ''.join(traceback.format_exception(*sys.exc_info())).split('\n')