示例#1
0
 def getKey(self):
     with newkey_lock[self.serverid]:
         if self.serverid not in keys:
             for _ in range(2):
                 logger.debug('hxsocks getKey')
                 host, port, usn, psw = (self.hxsServer.hostname, self.hxsServer.port, self.hxsServer.username, self.hxsServer.password)
                 if self._sock is None:
                     logger.debug('hxsocks connect')
                     from connection import create_connection
                     self._sock = create_connection((host, port), self.timeout, parentproxy=self.parentproxy, tunnel=True)
                     self.pskcipher = encrypt.Encryptor(self.PSK, self.method)
                 acipher = ECC(self.pskcipher.key_len)
                 pubk = acipher.get_pub_key()
                 logger.debug('hxsocks send key exchange request')
                 ts = struct.pack('>I', int(time.time()))
                 padding_len = random.randint(64, 255)
                 data = chr(10) + ts + chr(len(pubk)) + pubk + hmac.new(psw.encode(), ts + pubk + usn.encode(), hashlib.sha256).digest()\
                     + chr(padding_len) + b'\x00' * padding_len
                 self._sock.sendall(self.pskcipher.encrypt(data))
                 fp = self._sock.makefile('rb', 0)
                 resp_len = 1 if self.pskcipher.decipher else self.pskcipher.iv_len + 1
                 resp = ord(self.pskcipher.decrypt(fp.read(resp_len)))
                 if resp == 0:
                     logger.debug('hxsocks read key exchange respond')
                     pklen = ord(self.pskcipher.decrypt(fp.read(1)))
                     server_key = self.pskcipher.decrypt(fp.read(pklen))
                     auth = self.pskcipher.decrypt(fp.read(32))
                     pklen = ord(self.pskcipher.decrypt(fp.read(1)))
                     server_cert = self.pskcipher.decrypt(fp.read(pklen))
                     sig_len = ord(self.pskcipher.decrypt(fp.read(1)))
                     signature = self.pskcipher.decrypt(fp.read(sig_len))
                     pad_len = ord(self.pskcipher.decrypt(fp.read(1)))
                     self.pskcipher.decrypt(fp.read(pad_len))
                     # TODO: ask user if a certificate should be accepted or not.
                     if host not in known_hosts:
                         logger.info('hxs: server %s new cert %s saved.' % (host, hashlib.sha256(server_cert).hexdigest()[:8]))
                         with open('./.hxs_known_hosts/' + host + '.cert', 'wb') as f:
                             f.write(server_cert)
                             known_hosts[host] = server_cert
                     elif known_hosts[host] != server_cert:
                         logger.error('hxs: server %s certificate mismatch! PLEASE CHECK!' % host)
                         raise OSError(0, 'hxs: bad certificate')
                     if auth == hmac.new(psw.encode(), pubk + server_key + usn.encode(), hashlib.sha256).digest():
                         if ECC.verify_with_pub_key(server_cert, auth, signature, self.hash_algo):
                             shared_secret = acipher.get_dh_key(server_key)
                             keys[self.serverid] = (hashlib.md5(pubk).digest(), shared_secret)
                             self.cipher = encrypt.AEncryptor(keys[self.serverid][1], self.method, SALT, CTX, 0)
                             logger.debug('hxs key exchange success')
                             return
                         else:
                             logger.error('hxs getKey Error: server auth failed, bad signature')
                     else:
                         logger.error('hxs getKey Error: server auth failed, bad username or password')
                 else:
                     fp.read(ord(self.pskcipher.decrypt(fp.read(1))))
                     logger.error('hxs getKey Error. bad password or timestamp.')
             else:
                 raise IOError(0, 'hxs getKey Error')
         else:
             self.cipher = encrypt.AEncryptor(keys[self.serverid][1], self.method, SALT, CTX, 0)
示例#2
0
    def getKey(self):
        with newkey_lock[self.serverid]:
            if self.serverid not in keys:
                for _ in range(2):
                    logger.debug('hxsocks getKey')
                    host, port, usn, psw = (self.hxsServer.hostname,
                                            self.hxsServer.port,
                                            self.hxsServer.username,
                                            self.hxsServer.password)
                    if self._sock is None:
                        logger.debug('hxsocks connect')
                        from connection import create_connection
                        self._sock = create_connection(
                            (host, port),
                            self.timeout,
                            parentproxy=self.parentproxy,
                            tunnel=True)
                        self.pskcipher = encrypt.Encryptor(
                            self.PSK, self.method)
                        self._rfile = self._sock.makefile('rb')
                        self._header_sent = False
                        self._header_received = False
                    acipher = ECC(self.pskcipher.key_len)
                    pubk = acipher.get_pub_key()
                    logger.debug('hxsocks send key exchange request')
                    ts = struct.pack('>I', int(time.time()))
                    padding_len = random.randint(64, 255)
                    data = b''.join([
                        ts,
                        chr(len(pubk)).encode('latin1'), pubk,
                        hmac.new(psw.encode(), ts + pubk + usn.encode(),
                                 hashlib.sha256).digest(),
                        b'\x00' * padding_len
                    ])
                    data = chr(10).encode() + struct.pack('>H',
                                                          len(data)) + data
                    self._sock_sendall(self.pskcipher.encrypt(data))
                    resp_len = 2 if self.pskcipher.decipher else self.pskcipher.iv_len + 2
                    resp_len = self.pskcipher.decrypt(
                        self._rfile_read(resp_len))
                    resp_len = struct.unpack('>H', resp_len)[0]
                    data = self.pskcipher.decrypt(self._rfile_read(resp_len))

                    data = io.BytesIO(data)

                    resp_code = byte2int(data.read(1))
                    if resp_code == 0:
                        logger.debug('hxsocks read key exchange respond')
                        pklen = byte2int(data.read(1))
                        scertlen = byte2int(data.read(1))
                        siglen = byte2int(data.read(1))

                        server_key = data.read(pklen)
                        auth = data.read(32)
                        server_cert = data.read(scertlen)
                        signature = data.read(siglen)

                        # TODO: ask user if a certificate should be accepted or not.
                        if host not in known_hosts:
                            logger.info(
                                'hxs: server %s new cert %s saved.' %
                                (host,
                                 hashlib.sha256(server_cert).hexdigest()[:8]))
                            with open('./.hxs_known_hosts/' + host + '.cert',
                                      'wb') as f:
                                f.write(server_cert)
                                known_hosts[host] = server_cert
                        elif known_hosts[host] != server_cert:
                            logger.error(
                                'hxs: server %s certificate mismatch! PLEASE CHECK!'
                                % host)
                            raise OSError(0, 'hxs: bad certificate')
                        if auth == hmac.new(psw.encode(),
                                            pubk + server_key + usn.encode(),
                                            hashlib.sha256).digest():
                            if ECC.verify_with_pub_key(server_cert, auth,
                                                       signature,
                                                       self.hash_algo):
                                shared_secret = acipher.get_dh_key(server_key)
                                keys[self.serverid] = (
                                    hashlib.md5(pubk).digest(), shared_secret)
                                self.cipher = encrypt.AEncryptor(
                                    keys[self.serverid][1], self.method, SALT,
                                    CTX, 0, MAC_LEN)
                                logger.debug('hxs key exchange success')
                                return
                            else:
                                logger.error(
                                    'hxs getKey Error: server auth failed, bad signature'
                                )
                        else:
                            logger.error(
                                'hxs getKey Error: server auth failed, bad username or password'
                            )
                    else:
                        logger.error(
                            'hxs getKey Error. bad password or timestamp.')
                else:
                    raise IOError(0, 'hxs getKey Error')
            else:
                self.cipher = encrypt.AEncryptor(keys[self.serverid][1],
                                                 self.method, SALT, CTX, 0,
                                                 MAC_LEN)
示例#3
0
    def getKey(self):
        logger.debug('hxsocks2 getKey')
        host, port, usn, psw = (self.hxsServer.hostname, self.hxsServer.port, self.hxsServer.username, self.hxsServer.password)
        logger.debug('hxsocks2 connect to server')
        from connection import create_connection
        self._sock = create_connection((host, port), self.timeout, parentproxy=self.parentproxy, tunnel=True)

        self._rfile = self._sock.makefile('rb')

        acipher = ECC(self.__pskcipher._key_len)
        pubk = acipher.get_pub_key()
        logger.debug('hxsocks2 send key exchange request')
        ts = int(time.time()) // 30
        ts = struct.pack('>I', ts)
        padding_len = random.randint(64, 255)
        data = b''.join([chr(len(pubk)).encode('latin1'),
                         pubk,
                         hmac.new(psw.encode(), ts + pubk + usn.encode(), hashlib.sha256).digest(),
                         b'\x00' * padding_len])
        data = chr(20).encode() + struct.pack('>H', len(data)) + data

        ct = self.__pskcipher.encrypt(data)
        self._sock.sendall(ct)

        self.__pskcipher.decrypt(self._rfile.read(self.__pskcipher._iv_len))

        if encrypt.is_aead(self.method):
            ct_len = self.__pskcipher.decrypt(self._rfile.read(18))
            ct_len, = struct.unpack('!H', ct_len)
            ct = self.__pskcipher.decrypt(self._rfile.read(ct_len + 16))
            data = ct[2:]
        else:
            resp_len = self.__pskcipher.decrypt(self._rfile.read(2))
            resp_len, = struct.unpack('>H', resp_len)
            data = self.__pskcipher.decrypt(self._rfile.read(resp_len))

        data = io.BytesIO(data)

        resp_code = byte2int(data.read(1))
        if resp_code == 0:
            logger.debug('hxsocks read key exchange respond')
            pklen = byte2int(data.read(1))
            scertlen = byte2int(data.read(1))
            siglen = byte2int(data.read(1))

            server_key = data.read(pklen)
            auth = data.read(32)
            server_cert = data.read(scertlen)
            signature = data.read(siglen)

            # TODO: ask user if a certificate should be accepted or not.
            server_id = '%s_%d' % (host, port)
            if server_id not in known_hosts:
                logger.info('hxs: server %s new cert %s saved.' % (server_id, hashlib.sha256(server_cert).hexdigest()[:8]))
                with open('./.hxs_known_hosts/' + server_id + '.cert', 'wb') as f:
                    f.write(server_cert)
                    known_hosts[server_id] = server_cert
            elif known_hosts[server_id] != server_cert:
                logger.error('hxs: server %s certificate mismatch! PLEASE CHECK!' % server_id)
                raise OSError(0, 'hxs: bad certificate')

            if auth == hmac.new(psw.encode(), pubk + server_key + usn.encode(), hashlib.sha256).digest():
                if ECC.verify_with_pub_key(server_cert, auth, signature, self.hash_algo):
                    shared_secret = acipher.get_dh_key(server_key)
                    logger.debug('hxs key exchange success')
                    self.__cipher = AEncryptor(shared_secret, self.method, CTX)
                    return
                else:
                    logger.error('hxs getKey Error: server auth failed, bad signature')
            else:
                logger.error('hxs getKey Error: server auth failed, bad username or password')
        else:
            logger.error('hxs getKey Error. bad password or timestamp.')
        raise OSError(0, 'hxs getKey Error')