def ssh_KEX_DH_GEX_GROUP(self, packet): if self.kexAlg == 'diffie-hellman-group1-sha1': pubKey, packet = getNS(packet) f, packet = getMP(packet) signature, packet = getNS(packet) fingerprint = ':'.join(map(lambda c: '%02x'%ord(c), md5.new(pubKey).digest())) d = self.verifyHostKey(pubKey, fingerprint) d.addCallback(self._continueGEX_GROUP, pubKey, f, signature) d.addErrback(lambda unused,self=self:self.sendDisconnect(DISCONNECT_HOST_KEY_NOT_VERIFIABLE, 'bad host key')) else: self.p, rest = getMP(packet) self.g, rest = getMP(rest) self.x = getMP('\x00\x00\x00\x40'+entropy.get_bytes(64))[0] self.DHpubKey = pow(self.g, self.x, self.p) self.sendPacket(MSG_KEX_DH_GEX_INIT, MP(self.DHpubKey))
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)
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)
def ssh_KEX_DH_GEX_REPLY(self, packet): pubKey, packet = getNS(packet) f, packet = getMP(packet) signature, packet = getNS(packet) fingerprint = ':'.join(map(lambda c: '%02x'%ord(c), md5.new(pubKey).digest())) d = self.verifyHostKey(pubKey, fingerprint) d.addCallback(self._continueGEX_REPLY, pubKey, f, signature) d.addErrback(lambda unused, self=self: self.sendDisconnect(DISCONNECT_HOST_KEY_NOT_VERIFIABLE, 'bad host key'))
def getPrivateKeyObject_lsh(data, passphrase): #assert passphrase == '' data = ''.join(data) sexp = sexpy.parse(data) assert sexp[0] == 'private-key' kd = {} for name, data in sexp[1][1:]: kd[name] = common.getMP(common.NS(data))[0] if sexp[1][0] == 'dsa': assert len(kd) == 5, len(kd) return DSA.construct((kd['y'], kd['g'], kd['p'], kd['q'], kd['x'])) elif sexp[1][0] == 'rsa-pkcs1': assert len(kd) == 8, len(kd) return RSA.construct((kd['n'], kd['e'], kd['d'], kd['p'], kd['q'])) else: raise BadKeyError('unknown lsh key type %s' % sexp[1][0])
def __init__(self, initialVector, blockSize): """ @type initialVector: C{str} @param initialVector: A byte string representing the initial counter value. @type blockSize: C{int} @param blockSize: The length of the output buffer, as well as the number of bytes at the beginning of L{initialVector} to consider. """ initialVector = initialVector[:blockSize] self.count = getMP('\xff\xff\xff\xff' + initialVector)[0] self.blockSize = blockSize self.count = Util.number.long_to_bytes(self.count - 1) self.count = '\x00' * (self.blockSize - len(self.count)) + self.count self.count = array.array('c', self.count) self.len = len(self.count) - 1
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)
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)
def getPublicKeyObject(data): """ Return a C{Crypto.PublicKey.pubkey.pubkey} corresponding to the SSHv2 public key data. data is in the over-the-wire public key format. @type data: C{str} @rtype: C{Crypto.PublicKey.pubkey.pubkey} """ keyKind, rest = common.getNS(data) if keyKind == 'ssh-rsa': e, rest = common.getMP(rest) n, rest = common.getMP(rest) return RSA.construct((n, e)) elif keyKind == 'ssh-dss': p, rest = common.getMP(rest) q, rest = common.getMP(rest) g, rest = common.getMP(rest) y, rest = common.getMP(rest) return DSA.construct((y, g, p, q)) else: raise BadKeyError('unknown key type %s' % keyKind)
def verifySignature_rsa(obj, sig, data): sigTuple = [common.getMP(sig)[0]] return obj.verify(pkcs1Digest(data, lenSig(obj)), sigTuple)
def getPrivateKeyObject_agentv3(data, passphrase): if passphrase: raise BadKeyError("agent v3 key should not be encrypted") keyType, data = common.getNS(data) if keyType == 'ssh-dss': p, data = common.getMP(data) q, data = common.getMP(data) g, data = common.getMP(data) y, data = common.getMP(data) x, data = common.getMP(data) return DSA.construct((y,g,p,q,x)) elif keyType == 'ssh-rsa': e, data = common.getMP(data) d, data = common.getMP(data) n, data = common.getMP(data) u, data = common.getMP(data) p, data = common.getMP(data) q, data = common.getMP(data) return RSA.construct((n,e,d,p,q,u)) else: raise BadKeyError("unknown key type %s" % keyType)
def getPrivateKeyObject_agentv3(data, passphrase): if passphrase: raise BadKeyError("agent v3 key should not be encrypted") keyType, data = common.getNS(data) if keyType == 'ssh-dss': p, data = common.getMP(data) q, data = common.getMP(data) g, data = common.getMP(data) y, data = common.getMP(data) x, data = common.getMP(data) return DSA.construct((y, g, p, q, x)) elif keyType == 'ssh-rsa': e, data = common.getMP(data) d, data = common.getMP(data) n, data = common.getMP(data) u, data = common.getMP(data) p, data = common.getMP(data) q, data = common.getMP(data) return RSA.construct((n, e, d, p, q, u)) else: raise BadKeyError("unknown key type %s" % keyType)