summaryrefslogtreecommitdiff
path: root/paramiko/kex_gex.py
diff options
context:
space:
mode:
authorRobey Pointer <robey@lag.net>2003-12-28 03:20:42 +0000
committerRobey Pointer <robey@lag.net>2003-12-28 03:20:42 +0000
commit36d6d95dc6db1f47d187b87ab1c1a10c1d30558f (patch)
tree3f7cee6177b8d4865370e902e96f9f0b7c340aa5 /paramiko/kex_gex.py
parenteb4c279ec4392d23c5dd7271458299fb3196f8d4 (diff)
downloadparamiko-36d6d95dc6db1f47d187b87ab1c1a10c1d30558f.tar.gz
[project @ Arch-1:robey@lag.net--2003-public%secsh--dev--1.0--patch-16]
hook up server-side kex-gex; add more documentation group-exchange kex should work now on the server side. it will only be advertised if a "moduli" file has been loaded (see the -gasp- docs) so we don't spend hours (literally. hours.) computing primes. some of the logic was previously wrong, too, since it had never been tested. fixed repr() string for Transport/BaseTransport. moved is_authenticated to Transport where it belongs. added lots of documentation (but still only about 10% documented). lots of methods were made private finally.
Diffstat (limited to 'paramiko/kex_gex.py')
-rw-r--r--paramiko/kex_gex.py80
1 files changed, 40 insertions, 40 deletions
diff --git a/paramiko/kex_gex.py b/paramiko/kex_gex.py
index f1b8058d..5e02bab7 100644
--- a/paramiko/kex_gex.py
+++ b/paramiko/kex_gex.py
@@ -5,7 +5,7 @@
# LOT more on the server side).
from message import Message
-from util import inflate_long, deflate_long, generate_prime, bit_length
+from util import inflate_long, deflate_long, bit_length
from ssh_exception import SSHException
from transport import MSG_NEWKEYS
from Crypto.Hash import SHA
@@ -27,7 +27,7 @@ class KexGex(object):
def start_kex(self):
if self.transport.server_mode:
- self.transport.expected_packet = MSG_KEXDH_GEX_REQUEST
+ self.transport._expect_packet(MSG_KEXDH_GEX_REQUEST)
return
# request a bit range: we accept (min_bits) to (max_bits), but prefer
# (preferred_bits). according to the spec, we shouldn't pull the
@@ -37,21 +37,21 @@ class KexGex(object):
m.add_int(self.min_bits)
m.add_int(self.preferred_bits)
m.add_int(self.max_bits)
- self.transport.send_message(m)
- self.transport.expected_packet = MSG_KEXDH_GEX_GROUP
+ self.transport._send_message(m)
+ self.transport._expect_packet(MSG_KEXDH_GEX_GROUP)
def parse_next(self, ptype, m):
if ptype == MSG_KEXDH_GEX_REQUEST:
- return self.parse_kexdh_gex_request(m)
+ return self._parse_kexdh_gex_request(m)
elif ptype == MSG_KEXDH_GEX_GROUP:
- return self.parse_kexdh_gex_group(m)
+ return self._parse_kexdh_gex_group(m)
elif ptype == MSG_KEXDH_GEX_INIT:
- return self.parse_kexdh_gex_init(m)
+ return self._parse_kexdh_gex_init(m)
elif ptype == MSG_KEXDH_GEX_REPLY:
- return self.parse_kexdh_gex_reply(m)
+ return self._parse_kexdh_gex_reply(m)
raise SSHException('KexGex asked to handle packet type %d' % ptype)
- def generate_x(self):
+ def _generate_x(self):
# generate an "x" (1 < x < (p-1)/2).
q = (self.p - 1) // 2
qnorm = deflate_long(q, 0)
@@ -70,7 +70,7 @@ class KexGex(object):
break
self.x = x
- def parse_kexdh_gex_request(self, m):
+ def _parse_kexdh_gex_request(self, m):
min = m.get_int()
preferred = m.get_int()
max = m.get_int()
@@ -79,52 +79,53 @@ class KexGex(object):
preferred = self.max_bits
if preferred < self.min_bits:
preferred = self.min_bits
+ # fix min/max if they're inconsistent. technically, we could just pout
+ # and hang up, but there's no harm in giving them the benefit of the
+ # doubt and just picking a bitsize for them.
+ if min > preferred:
+ min = preferred
+ if max < preferred:
+ max = preferred
# now save a copy
self.min_bits = min
self.preferred_bits = preferred
self.max_bits = max
# generate prime
- while 1:
- # does not work FIXME
- # the problem is that it's too fscking SLOW
- self.transport.log(DEBUG, 'stir...')
- self.transport.randpool.stir()
- self.transport.log(DEBUG, 'get-prime %d...' % preferred)
- self.p = generate_prime(preferred, self.transport.randpool)
- self.transport.log(DEBUG, 'got ' + repr(self.p))
- if number.isPrime((self.p - 1) // 2):
- break
- self.g = 2
+ pack = self.transport._get_modulus_pack()
+ if pack is None:
+ raise SSHException('Can\'t do server-side gex with no modulus pack')
+ self.g, self.p = pack.get_modulus(min, preferred, max)
m = Message()
m.add_byte(chr(MSG_KEXDH_GEX_GROUP))
m.add_mpint(self.p)
m.add_mpint(self.g)
- self.transport.send_message(m)
- self.transport.expected_packet = MSG_KEXDH_GEX_INIT
+ self.transport._send_message(m)
+ self.transport._expect_packet(MSG_KEXDH_GEX_INIT)
- def parse_kexdh_gex_group(self, m):
+ def _parse_kexdh_gex_group(self, m):
self.p = m.get_mpint()
self.g = m.get_mpint()
# reject if p's bit length < 1024 or > 8192
bitlen = bit_length(self.p)
if (bitlen < 1024) or (bitlen > 8192):
raise SSHException('Server-generated gex p (don\'t ask) is out of range (%d bits)' % bitlen)
- self.transport.log(DEBUG, 'Got server p (%d bits)' % bitlen)
- self.generate_x()
+ self.transport._log(DEBUG, 'Got server p (%d bits)' % bitlen)
+ self._generate_x()
# now compute e = g^x mod p
self.e = pow(self.g, self.x, self.p)
m = Message()
m.add_byte(chr(MSG_KEXDH_GEX_INIT))
m.add_mpint(self.e)
- self.transport.send_message(m)
- self.transport.expected_packet = MSG_KEXDH_GEX_REPLY
+ self.transport._send_message(m)
+ self.transport._expect_packet(MSG_KEXDH_GEX_REPLY)
- def parse_kexdh_gex_init(self, m):
+ def _parse_kexdh_gex_init(self, m):
self.e = m.get_mpint()
if (self.e < 1) or (self.e > self.p - 1):
raise SSHException('Client kex "e" is out of range')
- self.generate_x()
- K = pow(self.e, self.x, P)
+ self._generate_x()
+ self.f = pow(self.g, self.x, self.p)
+ K = pow(self.e, self.x, self.p)
key = str(self.transport.get_server_key())
# okay, build up the hash H of (V_C || V_S || I_C || I_S || K_S || min || n || max || p || g || e || f || K)
hm = Message().add(self.transport.remote_version).add(self.transport.local_version)
@@ -136,7 +137,7 @@ class KexGex(object):
hm.add_mpint(self.g)
hm.add(self.e).add(self.f).add(K)
H = SHA.new(str(hm)).digest()
- self.transport.set_K_H(K, H)
+ self.transport._set_K_H(K, H)
# sign it
sig = self.transport.get_server_key().sign_ssh_data(self.transport.randpool, H)
# send reply
@@ -145,11 +146,10 @@ class KexGex(object):
m.add_string(key)
m.add_mpint(self.f)
m.add_string(sig)
- self.transport.send_message(m)
- self.transport.activate_outbound()
- self.transport.expected_packet = MSG_NEWKEYS
+ self.transport._send_message(m)
+ self.transport._activate_outbound()
- def parse_kexdh_gex_reply(self, m):
+ def _parse_kexdh_gex_reply(self, m):
host_key = m.get_string()
self.f = m.get_mpint()
sig = m.get_string()
@@ -165,9 +165,9 @@ class KexGex(object):
hm.add_mpint(self.p)
hm.add_mpint(self.g)
hm.add(self.e).add(self.f).add(K)
- self.transport.set_K_H(K, SHA.new(str(hm)).digest())
- self.transport.verify_key(host_key, sig)
- self.transport.activate_outbound()
- self.transport.expected_packet = MSG_NEWKEYS
+ self.transport._set_K_H(K, SHA.new(str(hm)).digest())
+ self.transport._verify_key(host_key, sig)
+ self.transport._activate_outbound()
+