示例#1
0
 def ssh_KEX_DH_GEX_REQUEST_OLD(self, packet):
     if self.ignoreNextPacket:
         self.ignoreNextPacket = 0
         return
     if self.kexAlg == 'diffie-hellman-group1-sha1': # this is really KEXDH_INIT
         clientDHPubKey, foo = getMP(packet)
         y = Util.number.getRandomNumber(16, entropy.get_bytes)
         f = pow(DH_GENERATOR, y, DH_PRIME)
         sharedSecret = _MPpow(clientDHPubKey, y, DH_PRIME)
         h = sha.new()
         h.update(NS(self.otherVersionString))
         h.update(NS(self.ourVersionString))
         h.update(NS(self.clientKexInitPayload))
         h.update(NS(self.ourKexInitPayload))
         h.update(NS(self.factory.publicKeys[self.keyAlg]))
         h.update(MP(clientDHPubKey))
         h.update(MP(f))
         h.update(sharedSecret)
         exchangeHash = h.digest()
         self.sendPacket(MSG_KEXDH_REPLY, NS(self.factory.publicKeys[self.keyAlg])+ \
                        MP(f)+NS(keys.signData(self.factory.privateKeys[self.keyAlg], exchangeHash)))
         self._keySetup(sharedSecret, exchangeHash)
     elif self.kexAlg == 'diffie-hellman-group-exchange-sha1':
         self.kexAlg = 'diffie-hellman-group-exchange-sha1-old'
         self.ideal = struct.unpack('>L', packet)[0]
         self.g, self.p = self.factory.getDHPrime(self.ideal)
         self.sendPacket(MSG_KEX_DH_GEX_GROUP, MP(self.p)+MP(self.g))
     else:
         raise error.ConchError('bad kexalg: %s'%self.kexAlg)
示例#2
0
 def ssh_KEX_DH_GEX_REQUEST_OLD(self, packet):
     if self.ignoreNextPacket:
         self.ignoreNextPacket = 0
         return
     if self.kexAlg == 'diffie-hellman-group1-sha1':  # this is really KEXDH_INIT
         clientDHPubKey, foo = getMP(packet)
         y = Util.number.getRandomNumber(16, entropy.get_bytes)
         f = pow(DH_GENERATOR, y, DH_PRIME)
         sharedSecret = _MPpow(clientDHPubKey, y, DH_PRIME)
         h = sha.new()
         h.update(NS(self.otherVersionString))
         h.update(NS(self.ourVersionString))
         h.update(NS(self.clientKexInitPayload))
         h.update(NS(self.ourKexInitPayload))
         h.update(NS(self.factory.publicKeys[self.keyAlg]))
         h.update(MP(clientDHPubKey))
         h.update(MP(f))
         h.update(sharedSecret)
         exchangeHash = h.digest()
         self.sendPacket(MSG_KEXDH_REPLY, NS(self.factory.publicKeys[self.keyAlg])+ \
                        MP(f)+NS(keys.signData(self.factory.privateKeys[self.keyAlg], exchangeHash)))
         self._keySetup(sharedSecret, exchangeHash)
     elif self.kexAlg == 'diffie-hellman-group-exchange-sha1':
         self.kexAlg = 'diffie-hellman-group-exchange-sha1-old'
         self.ideal = struct.unpack('>L', packet)[0]
         self.g, self.p = self.factory.getDHPrime(self.ideal)
         self.sendPacket(MSG_KEX_DH_GEX_GROUP, MP(self.p) + MP(self.g))
     else:
         raise error.ConchError('bad kexalg: %s' % self.kexAlg)
示例#3
0
    def ssh_KEX_DH_GEX_INIT(self, packet):
        clientDHPubKey, foo = getMP(packet)

        # if y < 1024, openssh will reject us: "bad server public DH value".
        # y<1024 means f will be short, and of the form 2^y, so an observer
        # could trivially derive our secret y from f. Openssh detects this
        # and complains, so avoid creating such values by requiring y to be
        # larger than ln2(self.p)

        # TODO: we should also look at the value they send to us and reject
        # insecure values of f (if g==2 and f has a single '1' bit while the
        # rest are '0's, then they must have used a small y also).

        # TODO: This could be computed when self.p is set up
        #  or do as openssh does and scan f for a single '1' bit instead

        minimum = long(math.floor(math.log(self.p) / math.log(2)) + 1)
        tries = 0
        pSize = Util.number.size(self.p)
        y = Util.number.getRandomNumber(pSize, entropy.get_bytes)
        while tries < 10 and y < minimum:
            tries += 1
            y = Util.number.getRandomNumber(pSize, entropy.get_bytes)
        assert(y >= minimum) # TODO: test_conch just hangs if this is hit
        # the chance of it being hit are really really low

        f = pow(self.g, y, self.p)
        sharedSecret = _MPpow(clientDHPubKey, y, self.p)
        h = sha.new()
        h.update(NS(self.otherVersionString))
        h.update(NS(self.ourVersionString))
        h.update(NS(self.clientKexInitPayload))
        h.update(NS(self.ourKexInitPayload))
        h.update(NS(self.factory.publicKeys[self.keyAlg]))
        if self.kexAlg == 'diffie-hellman-group-exchange-sha1':
            h.update(struct.pack('>3L', self.min, self.ideal, self.max))
        else:
            h.update(struct.pack('>L', self.ideal))
        h.update(MP(self.p))
        h.update(MP(self.g))
        h.update(MP(clientDHPubKey))
        h.update(MP(f))
        h.update(sharedSecret)
        exchangeHash = h.digest()
        self.sendPacket(MSG_KEX_DH_GEX_REPLY, NS(self.factory.publicKeys[self.keyAlg])+ \
                       MP(f)+NS(keys.signData(self.factory.privateKeys[self.keyAlg], exchangeHash)))
        self._keySetup(sharedSecret, exchangeHash)
示例#4
0
    def ssh_KEX_DH_GEX_INIT(self, packet):
        clientDHPubKey, foo = getMP(packet)

        # if y < 1024, openssh will reject us: "bad server public DH value".
        # y<1024 means f will be short, and of the form 2^y, so an observer
        # could trivially derive our secret y from f. Openssh detects this
        # and complains, so avoid creating such values by requiring y to be
        # larger than ln2(self.p)

        # TODO: we should also look at the value they send to us and reject
        # insecure values of f (if g==2 and f has a single '1' bit while the
        # rest are '0's, then they must have used a small y also).

        # TODO: This could be computed when self.p is set up
        #  or do as openssh does and scan f for a single '1' bit instead

        minimum = long(math.floor(math.log(self.p) / math.log(2)) + 1)
        tries = 0
        pSize = Util.number.size(self.p)
        y = Util.number.getRandomNumber(pSize, entropy.get_bytes)
        while tries < 10 and y < minimum:
            tries += 1
            y = Util.number.getRandomNumber(pSize, entropy.get_bytes)
        assert (y >= minimum)  # TODO: test_conch just hangs if this is hit
        # the chance of it being hit are really really low

        f = pow(self.g, y, self.p)
        sharedSecret = _MPpow(clientDHPubKey, y, self.p)
        h = sha.new()
        h.update(NS(self.otherVersionString))
        h.update(NS(self.ourVersionString))
        h.update(NS(self.clientKexInitPayload))
        h.update(NS(self.ourKexInitPayload))
        h.update(NS(self.factory.publicKeys[self.keyAlg]))
        if self.kexAlg == 'diffie-hellman-group-exchange-sha1':
            h.update(struct.pack('>3L', self.min, self.ideal, self.max))
        else:
            h.update(struct.pack('>L', self.ideal))
        h.update(MP(self.p))
        h.update(MP(self.g))
        h.update(MP(clientDHPubKey))
        h.update(MP(f))
        h.update(sharedSecret)
        exchangeHash = h.digest()
        self.sendPacket(MSG_KEX_DH_GEX_REPLY, NS(self.factory.publicKeys[self.keyAlg])+ \
                       MP(f)+NS(keys.signData(self.factory.privateKeys[self.keyAlg], exchangeHash)))
        self._keySetup(sharedSecret, exchangeHash)
示例#5
0
 def _continueGEX_GROUP(self, ignored, pubKey, f, signature):
     serverKey = keys.getPublicKeyObject(pubKey)
     sharedSecret = _MPpow(f, self.x, DH_PRIME)
     h = sha.new()
     h.update(NS(self.ourVersionString))
     h.update(NS(self.otherVersionString))
     h.update(NS(self.ourKexInitPayload))
     h.update(NS(self.serverKexInitPayload))
     h.update(NS(pubKey))
     h.update(MP(self.DHpubKey))
     h.update(MP(f))
     h.update(sharedSecret)
     exchangeHash = h.digest()
     if not keys.verifySignature(serverKey, signature, exchangeHash):
         self.sendDisconnect(DISCONNECT_KEY_EXCHANGE_FAILED, 'bad signature')
         return
     self._keySetup(sharedSecret, exchangeHash)
示例#6
0
 def _continueGEX_GROUP(self, ignored, pubKey, f, signature):
     serverKey = keys.getPublicKeyObject(pubKey)
     sharedSecret = _MPpow(f, self.x, DH_PRIME)
     h = sha.new()
     h.update(NS(self.ourVersionString))
     h.update(NS(self.otherVersionString))
     h.update(NS(self.ourKexInitPayload))
     h.update(NS(self.serverKexInitPayload))
     h.update(NS(pubKey))
     h.update(MP(self.DHpubKey))
     h.update(MP(f))
     h.update(sharedSecret)
     exchangeHash = h.digest()
     if not keys.verifySignature(serverKey, signature, exchangeHash):
         self.sendDisconnect(DISCONNECT_KEY_EXCHANGE_FAILED, 'bad signature')
         return
     self._keySetup(sharedSecret, exchangeHash)