summaryrefslogtreecommitdiffhomepage
path: root/kex_gex.py
diff options
context:
space:
mode:
authorRobey Pointer <robey@lag.net>2003-12-27 01:49:19 +0000
committerRobey Pointer <robey@lag.net>2003-12-27 01:49:19 +0000
commit877cd974b8182d26fa76d566072917ea67b64e67 (patch)
tree577da518d93f7b4d1d6b6fa48dbbbe95ab36ceca /kex_gex.py
parentf6e1e84d60ae75cd28030b4c41856ec768566a46 (diff)
[project @ Arch-1:robey@lag.net--2003-public%secsh--dev--1.0--patch-14]
move the paramiko files into a paramiko/ folder. just moving the files into a folder. it won't build this way yet.
Diffstat (limited to 'kex_gex.py')
-rw-r--r--kex_gex.py173
1 files changed, 0 insertions, 173 deletions
diff --git a/kex_gex.py b/kex_gex.py
deleted file mode 100644
index 19bc699a..00000000
--- a/kex_gex.py
+++ /dev/null
@@ -1,173 +0,0 @@
-#!/usr/bin/python
-
-# variant on group1 (see kex_group1.py) where the prime "p" and generator "g"
-# are provided by the server. a bit more work is required on our side (and a
-# LOT more on the server side).
-
-from message import Message
-from util import inflate_long, deflate_long, generate_prime, bit_length
-from paramiko import SSHException
-from transport import MSG_NEWKEYS
-from Crypto.Hash import SHA
-from Crypto.Util import number
-from logging import DEBUG
-
-MSG_KEXDH_GEX_GROUP, MSG_KEXDH_GEX_INIT, MSG_KEXDH_GEX_REPLY, MSG_KEXDH_GEX_REQUEST = range(31, 35)
-
-
-class KexGex(object):
-
- name = 'diffie-hellman-group-exchange-sha1'
- min_bits = 1024
- max_bits = 8192
- preferred_bits = 2048
-
- def __init__(self, transport):
- self.transport = transport
-
- def start_kex(self):
- if self.transport.server_mode:
- self.transport.expected_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
- # minimum up above 1024.
- m = Message()
- m.add_byte(chr(MSG_KEXDH_GEX_REQUEST))
- 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
-
- def parse_next(self, ptype, m):
- if ptype == MSG_KEXDH_GEX_REQUEST:
- return self.parse_kexdh_gex_request(m)
- elif ptype == MSG_KEXDH_GEX_GROUP:
- return self.parse_kexdh_gex_group(m)
- elif ptype == MSG_KEXDH_GEX_INIT:
- return self.parse_kexdh_gex_init(m)
- elif ptype == MSG_KEXDH_GEX_REPLY:
- return self.parse_kexdh_gex_reply(m)
- raise SSHException('KexGex asked to handle packet type %d' % ptype)
-
- def generate_x(self):
- # generate an "x" (1 < x < (p-1)/2).
- q = (self.p - 1) // 2
- qnorm = deflate_long(q, 0)
- qhbyte = ord(qnorm[0])
- bytes = len(qnorm)
- qmask = 0xff
- while not (qhbyte & 0x80):
- qhbyte <<= 1
- qmask >>= 1
- while 1:
- self.transport.randpool.stir()
- x_bytes = self.transport.randpool.get_bytes(bytes)
- x_bytes = chr(ord(x_bytes[0]) & qmask) + x_bytes[1:]
- x = inflate_long(x_bytes, 1)
- if (x > 1) and (x < q):
- break
- self.x = x
-
- def parse_kexdh_gex_request(self, m):
- min = m.get_int()
- preferred = m.get_int()
- max = m.get_int()
- # smoosh the user's preferred size into our own limits
- if preferred > self.max_bits:
- preferred = self.max_bits
- if preferred < self.min_bits:
- preferred = self.min_bits
- # 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
- 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
-
- 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()
- # 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
-
- 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)
- 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)
- hm.add(self.transport.remote_kex_init).add(self.transport.local_kex_init).add(key)
- hm.add_int(self.min_bits)
- hm.add_int(self.preferred_bits)
- hm.add_int(self.max_bits)
- hm.add_mpint(self.p)
- 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)
- # sign it
- sig = self.transport.get_server_key().sign_ssh_data(self.transport.randpool, H)
- # send reply
- m = Message()
- m.add_byte(chr(MSG_KEXDH_GEX_REPLY))
- 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
-
- def parse_kexdh_gex_reply(self, m):
- host_key = m.get_string()
- self.f = m.get_mpint()
- sig = m.get_string()
- if (self.f < 1) or (self.f > self.p - 1):
- raise SSHException('Server kex "f" is out of range')
- K = pow(self.f, self.x, self.p)
- # 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.local_version).add(self.transport.remote_version)
- hm.add(self.transport.local_kex_init).add(self.transport.remote_kex_init).add(host_key)
- hm.add_int(self.min_bits)
- hm.add_int(self.preferred_bits)
- hm.add_int(self.max_bits)
- 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
-
-