class Bee: def __init__(self): DEBUG_POSITION = 'Symbiosis_Bee:Bee:Init:' self.alive = True # Flower Socket self.flower = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # Deflector Socket self.deflector = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # Diffie Hellman self.dh = DiffieHellman() self.exchange = False # Stream self.stream = Stream() def fly(self, flower_host, flower_port, deflector_host, deflector_port): DEBUG_POSITION = 'Symbiosis_Bee:Bee:Fly:' # Connect to Deflector # try: # self.deflector.connect((deflector_host, deflector_port)) # except socket.error as e: # if DEBUG: print(DEBUG_POSITION, 'Deflector와의 연결에 실패하였습니다:') # if DEBUG: print(e) # return # Connect to Flower try: self.flower.connect((flower_host, flower_port)) except socket.error as e: if DEBUG: print(DEBUG_POSITION, 'Flower와의 연결에 실패하였습니다:') if DEBUG: print(e) return if DEBUG: print('Key Exchange: Start') self.exchange = False # Key Exchange data = self.dh.publicKey.to_bytes((self.dh.publicKey.bit_length() + 7) // 8, 'big') self.flower.send(encodeCell(SYMBIOSIS_CELL_TYPE_KEY_REQUEST, len(data), 0, bytes(32), data)) # Catch : Select _thread.start_new_thread(self.catch, (self.flower, self.deflector)) # self.catch(self.flower, self.deflector) # Feel : Browsing self.feel() # Die self.die() def feel(self): DEBUG_POSITION = 'Symbiosis_Bee:Bee:Feel:' try: listener = socket.socket(socket.AF_INET, socket.SOCK_STREAM); listener.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) listener.bind(('', SYMBIOSIS_BEE_PORT)) listener.listen(5) while self.alive: if self.exchange == False: continue # Accept conn, _ = listener.accept() # Stream self.stream.add(conn) except socket.error as e: if listener: listener.close() if DEBUG: print(DEBUG_POSITION, 'Browser의 요청을 기다리던 도중 오류가 발생했습니다:') if DEBUG: print(e) def catch(self, flower, deflector): DEBUG_POSITION = 'Symbiosis_Bee:Bee:Catch:' data_flower = b'' data_deflector = b'' key_data = b'' keys = [] aes_recv = None timeout = TIMEOUT while self.alive: # (read, _, exception) = select.select([flower, deflector], [], [flower, deflector], timeout) (read, _, exception) = select.select([flower], [], [flower], timeout) if exception: if DEBUG: print(DEBUG_POSITION, 'select exception이 발생했습니다:') if DEBUG: print(exception) return elif read: for i in read: if i == flower: try: # Receive Data data_flower = data_flower + i.recv(1024) if len(data_flower) >= 1024: # Raw Cell raw_cell, data_flower = data_flower[0:1024], data_flower[1024:] # Decode Cell cell = decodeCell(raw_cell) #printCell(cell) if cell['type'] == SYMBIOSIS_CELL_TYPE_RESPONSE: # Decrypt data = cell['data'] decrypted = b'' while len(data) >= 16: decrypted = decrypted + aes_recv.decrypt(data[:16]) data = data[16:] decrypted = decrypted + data # Digest digest = SHA256.new(decrypted + keys[2]).digest() if digest != cell['digest']: continue # Send Data self.stream.send(cell['streamID'], decrypted) elif cell['type'] == SYMBIOSIS_CELL_TYPE_REQUEST: # Flower Request print('FLOWER REQ > BEE > DEFLECTOR:') #printCell(cell) deflector.send(raw_cell) pass elif cell['type'] == SYMBIOSIS_CELL_TYPE_KEY_REQUEST: # Flower Key Request #deflector.send(raw_cell) pass elif cell['type'] == SYMBIOSIS_CELL_TYPE_KEY_RESPONSE: # crt:1099, g_y:512, sig:256, h_k:32 key_data = key_data + cell['data'] if cell['streamID'] == 0: continue # split crt = key_data[:1099] g_y = key_data[1099:1099+512] sig = (int.from_bytes(key_data[1099+512:1099+512+256], byteorder='big'), ) h_k = key_data[1099+512+256:] key_data = b'' # get public key from crt pem = crt.decode('utf-8') lines = pem.replace(" ",'').split() der = a2b_base64(''.join(lines[1:-1]).encode('ascii')) cert = DerSequence() cert.decode(der) tbsCertificate = DerSequence() tbsCertificate.decode(cert[0]) subjectPublicKeyInfo = tbsCertificate[5] puk = RSA.importKey(subjectPublicKeyInfo) # verify hash = SHA256.new(g_y).digest() if puk.verify(hash, sig): print("Key Exchange: Verify") self.dh.genKey(int.from_bytes(g_y, byteorder='big')) # h.digest() = SHA256.new(K).digest() K = self.dh.getKey() h = hashlib.sha256() h.update(str(K).encode(encoding='utf_8', errors='strict')) if h_k == h.digest(): print("Key Exchange: Complete") K = self.dh.getKey() aes = AES.new(K, AES.MODE_ECB) # Keys for i in range(4): keys = keys + [ str(i).encode() + K[1:] ] aes_recv = AES.new(keys[3], AES.MODE_ECB) aes_send = AES.new(keys[1], AES.MODE_ECB) self.exchange = True else: print("Key Exchange: Retry") data = self.dh.publicKey.to_bytes((self.dh.publicKey.bit_length() + 7) // 8, 'big') self.flower.send(encodeCell(SYMBIOSIS_CELL_TYPE_KEY_REQUEST, len(data), 0, bytes(32), data)) else: print("Key Exchange: Retry") data = self.dh.publicKey.to_bytes((self.dh.publicKey.bit_length() + 7) // 8, 'big') self.flower.send(encodeCell(SYMBIOSIS_CELL_TYPE_KEY_REQUEST, len(data), 0, bytes(32), data)) except socket.error as e: if DEBUG: print(DEBUG_POSITION, '알 수 없는 오류가 발생했습니다:flower') if DEBUG: print(e) return elif i == deflector: try: # Receive Data data_deflector = data_deflector + i.recv(1024) if len(data_deflector) >= 1024: # Raw Cell raw_cell, data_deflector = data_deflector[0:1024], data_deflector[1024:] # Deflector Response print('DEFLECTOR RES > BEE > FLOWER') flower.send(raw_cell) except socket.error as e: if DEBUG: print(DEBUG_POSITION, '알 수 없는 오류가 발생했습니다:deflector') if DEBUG: print(e) return if self.exchange == True: self.stream.select(flower, SYMBIOSIS_CELL_TYPE_REQUEST, aes_send, keys[0]) def die(self): DEBUG_POSITION = 'Symbiosis_Bee:Bee:Die:' self.alive = False self.stream.clear() self.stream = None self.deflector.close() self.deflector = None self.flower.close() self.flower = None
class Server: def __init__(self): DEBUG_POSITION = 'Symbiosis_Server:Server:Init:' self.running = True # Flower Listener Socket self.listener = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.listener.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # Diffie Hellman self.exchange = False # Stream self.stream = Stream() def run(self): DEBUG_POSITION = 'Symbiosis_Server:Server:Run:' try: # Listen to Flower self.listener.bind(('', SYMBIOSIS_SERVER_PORT)) self.listener.listen(5) if DEBUG: print('Flower를 기다리는 중...') while self.running: # Accept Flower flower, _ = self.listener.accept() if DEBUG: print('Flower와 연결되었습니다.') # Handle Flower _thread.start_new_thread(self.handle, (flower,)) except socket.error as e: if self.listener: self.listener.close() self.listener = None if DEBUG: print('Flower를 기다리던 도중 오류가 발생했습니다:') if DEBUG: print(e) def handle(self, flower): DEBUG_POSITION = 'Symbiosis_Server:Server:Handle:' dh = DiffieHellman() data_proxy = b'' keys = [] aes_recv = None timeout = TIMEOUT while self.running: (read, _, exception) = select.select([flower], [], [flower], timeout) if exception: if DEBUG: print(DEBUG_POSITION, 'select exception이 발생했습니다:') if DEBUG: print(exception) return elif read: for i in read: try: # Receive Data data_proxy = data_proxy + i.recv(1024) if len(data_proxy) >= 1024: # Raw Cell raw_cell, data_proxy = data_proxy[0:1024], data_proxy[1024:] # Decode Cell cell = decodeCell(raw_cell) if cell['type'] == SYMBIOSIS_CELL_TYPE_REQUEST: # Decrypt data = cell['data'] decrypted = b'' while len(data) >= 16: decrypted = decrypted + aes_recv.decrypt(data[:16]) data = data[16:] decrypted = decrypted + data # Digest digest = SHA256.new(decrypted + keys[0]).digest() if digest != cell['digest']: continue # Connect to Squid with streamID if not cell['streamID'] in self.stream.streams.keys(): if self.stream.connect('localhost', 3128, cell['streamID']) == False: if DEBUG: print(DEBUG_POSITION, 'Squid에 연결할 수 없습니다.') continue # Send Data self.stream.send(cell['streamID'], decrypted) elif cell['type'] == SYMBIOSIS_CELL_TYPE_KEY_REQUEST: print("Key Exchange: Start") # g_x g_x = cell['data'] # g_y g_y = dh.publicKey.to_bytes((dh.publicKey.bit_length() + 7) // 8, 'big') # H(K) dh.genKey(int.from_bytes(g_x, byteorder='big')) K = dh.getKey() # h_k = SHA256.new(K.decode('utf-8')).digest() h = hashlib.sha256() h.update(str(K).encode(encoding='utf_8', errors='strict')) h_k = h.digest() # certificate crt = open("./ss.crt").read().encode() # sig = sign(SHA256(g_y)) prk = RSA.importKey(open('private.key','r').read()) hash = SHA256.new(g_y).digest() n = int(prk.sign(hash, '')[0]) sig = n.to_bytes((n.bit_length() + 7) // 8, 'big') # Keys for i in range(4): keys = keys + [ str(i).encode() + K[1:] ] aes_recv = AES.new(keys[1], AES.MODE_ECB) aes_send = AES.new(keys[3], AES.MODE_ECB) # crt:1099, g_y:512, sig:256, h_k:32 data = crt + g_y + sig + h_k while len(data) > 0: if len(data) <= 987: end = 1 else: end = 0 flower.send(encodeCell(SYMBIOSIS_CELL_TYPE_KEY_RESPONSE, len(data[:987]), end, bytes(32), data[:987])) data = data[987:] self.exchange = True print('Key Exchange: End') except socket.error as e: if DEBUG: print(DEBUG_POSITION, '알 수 없는 오류가 발생했습니다:') if DEBUG: print(e) return if self.exchange == True: self.stream.select(flower, SYMBIOSIS_CELL_TYPE_RESPONSE, aes_send, keys[2])