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() self.f = pow(self.g, self.x, self.p) K = pow(self.e, self.x, self.p) key = bytes(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() hm.add(self.transport.remote_version, self.transport.local_version, self.transport.remote_kex_init, self.transport.local_kex_init, key) if not self.old_style: hm.add_int(self.min_bits) hm.add_int(self.preferred_bits) if not self.old_style: hm.add_int(self.max_bits) hm.add_mpint(self.p) hm.add_mpint(self.g) hm.add_mpint(self.e) hm.add_mpint(self.f) hm.add_mpint(K) H = SHA.new(bytes(hm)).digest() self.transport._set_K_H(K, H) # sign it sig = self.transport.get_server_key().sign_ssh_data(self.transport.rng, H) # send reply m = Message() m.add_byte(pack_byte(_MSG_KEXDH_GEX_REPLY)) m.add_string(key) m.add_mpint(self.f) m.add_string(bytes(sig)) self.transport._send_message(m) self.transport._activate_outbound()
def _parse_kexdh_gex_request(self, m): minbits = m.get_int() preferredbits = m.get_int() maxbits = m.get_int() # smoosh the user's preferred size into our own limits if preferredbits > self.max_bits: preferredbits = self.max_bits if preferredbits < self.min_bits: preferredbits = 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 minbits > preferredbits: minbits = preferredbits if maxbits < preferredbits: maxbits = preferredbits # now save a copy self.min_bits = minbits self.preferred_bits = preferredbits self.max_bits = maxbits # generate prime pack = self.transport._get_modulus_pack() if pack is None: raise SSHException('Can\'t do server-side gex with no modulus pack') 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(pack_byte(_MSG_KEXDH_GEX_GROUP)) m.add_mpint(self.p) m.add_mpint(self.g) self.transport._send_message(m) self.transport._expect_packet(_MSG_KEXDH_GEX_INIT)