diff options
Diffstat (limited to 'paramiko/kex_gex.py')
-rw-r--r-- | paramiko/kex_gex.py | 45 |
1 files changed, 23 insertions, 22 deletions
diff --git a/paramiko/kex_gex.py b/paramiko/kex_gex.py index c0455a1..5ff8a28 100644 --- a/paramiko/kex_gex.py +++ b/paramiko/kex_gex.py @@ -17,22 +17,25 @@ # 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. """ -Variant on L{KexGroup1 <paramiko.kex_group1.KexGroup1>} where the prime "p" and +Variant on `KexGroup1 <paramiko.kex_group1.KexGroup1>` where the prime "p" and generator "g" are provided by the server. A bit more work is required on the client side, and a B{lot} more on the server side. """ -from Crypto.Hash import SHA -from Crypto.Util import number +import os +from hashlib import sha1 -from paramiko.common import * from paramiko import util +from paramiko.common import DEBUG from paramiko.message import Message +from paramiko.py3compat import byte_chr, byte_ord, byte_mask from paramiko.ssh_exception import SSHException _MSG_KEXDH_GEX_REQUEST_OLD, _MSG_KEXDH_GEX_GROUP, _MSG_KEXDH_GEX_INIT, \ _MSG_KEXDH_GEX_REPLY, _MSG_KEXDH_GEX_REQUEST = range(30, 35) +c_MSG_KEXDH_GEX_REQUEST_OLD, c_MSG_KEXDH_GEX_GROUP, c_MSG_KEXDH_GEX_INIT, \ + c_MSG_KEXDH_GEX_REPLY, c_MSG_KEXDH_GEX_REQUEST = [byte_chr(c) for c in range(30, 35)] class KexGex (object): @@ -62,11 +65,11 @@ class KexGex (object): m = Message() if _test_old_style: # only used for unit tests: we shouldn't ever send this - m.add_byte(chr(_MSG_KEXDH_GEX_REQUEST_OLD)) + m.add_byte(c_MSG_KEXDH_GEX_REQUEST_OLD) m.add_int(self.preferred_bits) self.old_style = True else: - m.add_byte(chr(_MSG_KEXDH_GEX_REQUEST)) + m.add_byte(c_MSG_KEXDH_GEX_REQUEST) m.add_int(self.min_bits) m.add_int(self.preferred_bits) m.add_int(self.max_bits) @@ -86,23 +89,21 @@ class KexGex (object): return self._parse_kexdh_gex_request_old(m) raise SSHException('KexGex asked to handle packet type %d' % ptype) - ### internals... - def _generate_x(self): # generate an "x" (1 < x < (p-1)/2). q = (self.p - 1) // 2 qnorm = util.deflate_long(q, 0) - qhbyte = ord(qnorm[0]) - bytes = len(qnorm) + qhbyte = byte_ord(qnorm[0]) + byte_count = len(qnorm) qmask = 0xff while not (qhbyte & 0x80): qhbyte <<= 1 qmask >>= 1 while True: - x_bytes = self.transport.rng.read(bytes) - x_bytes = chr(ord(x_bytes[0]) & qmask) + x_bytes[1:] + x_bytes = os.urandom(byte_count) + x_bytes = byte_mask(x_bytes[0], qmask) + x_bytes[1:] x = util.inflate_long(x_bytes, 1) if (x > 1) and (x < q): break @@ -135,7 +136,7 @@ class KexGex (object): self.transport._log(DEBUG, 'Picking p (%d <= %d <= %d bits)' % (minbits, preferredbits, maxbits)) self.g, self.p = pack.get_modulus(minbits, preferredbits, maxbits) m = Message() - m.add_byte(chr(_MSG_KEXDH_GEX_GROUP)) + m.add_byte(c_MSG_KEXDH_GEX_GROUP) m.add_mpint(self.p) m.add_mpint(self.g) self.transport._send_message(m) @@ -156,7 +157,7 @@ class KexGex (object): self.transport._log(DEBUG, 'Picking p (~ %d bits)' % (self.preferred_bits,)) self.g, self.p = pack.get_modulus(self.min_bits, self.preferred_bits, self.max_bits) m = Message() - m.add_byte(chr(_MSG_KEXDH_GEX_GROUP)) + m.add_byte(c_MSG_KEXDH_GEX_GROUP) m.add_mpint(self.p) m.add_mpint(self.g) self.transport._send_message(m) @@ -175,7 +176,7 @@ class KexGex (object): # 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_byte(c_MSG_KEXDH_GEX_INIT) m.add_mpint(self.e) self.transport._send_message(m) self.transport._expect_packet(_MSG_KEXDH_GEX_REPLY) @@ -187,7 +188,7 @@ class KexGex (object): 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()) + key = self.transport.get_server_key().asbytes() # 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() hm.add(self.transport.remote_version, self.transport.local_version, @@ -203,19 +204,19 @@ class KexGex (object): hm.add_mpint(self.e) hm.add_mpint(self.f) hm.add_mpint(K) - H = SHA.new(str(hm)).digest() + H = sha1(hm.asbytes()).digest() self.transport._set_K_H(K, H) # sign it - sig = self.transport.get_server_key().sign_ssh_data(self.transport.rng, H) + sig = self.transport.get_server_key().sign_ssh_data(H) # send reply m = Message() - m.add_byte(chr(_MSG_KEXDH_GEX_REPLY)) + m.add_byte(c_MSG_KEXDH_GEX_REPLY) m.add_string(key) m.add_mpint(self.f) - m.add_string(str(sig)) + m.add_string(sig) self.transport._send_message(m) self.transport._activate_outbound() - + def _parse_kexdh_gex_reply(self, m): host_key = m.get_string() self.f = m.get_mpint() @@ -238,6 +239,6 @@ class KexGex (object): hm.add_mpint(self.e) hm.add_mpint(self.f) hm.add_mpint(K) - self.transport._set_K_H(K, SHA.new(str(hm)).digest()) + self.transport._set_K_H(K, sha1(hm.asbytes()).digest()) self.transport._verify_key(host_key, sig) self.transport._activate_outbound() |