def enc_prekey(self): crtObj = crypto.load_certificate(crypto.FILETYPE_PEM, self.C_Certs[0]) pubKeyObject = crtObj.get_pubkey() pubKeyString = crypto.dump_publickey(crypto.FILETYPE_PEM, pubKeyObject) key = RSA.importKey(pubKeyString) Encrypter = PKCS1OAEP_Cipher(key, None, None, None) return Encrypter.encrypt(self.PKs)
def listener(msgList: tkinter.Text, s: socket, clientEncryptor: PKCS1OAEP_Cipher): while True: if s.fileno() == -1: # socket closed break r, _, _ = select.select([s], [], []) for rs in r: if s == rs: try: data = rs.recv(4096) except OSError: # connection terminated (for some reason) break if not data: break msg = clientEncryptor.decrypt(data) msg = pickle.loads(msg) if msg[0]: message = "<SERVER>: " + msg[3] else: message = msg[2] + ": " + msg[3] msgList.tag_config(str(msg[1]), foreground=str(msg[1])) msgList.config(state=tkinter.NORMAL) msgList.insert(tkinter.END, message + '\n', str(msg[1])) msgList.config(state=tkinter.DISABLED)
def str_send_handler(s, serverEncryptor: PKCS1OAEP_Cipher, msg: string): if len(msg) == 0: return if msg.startswith("/"): if msg in ["/quit", "/exit"]: msgList = [True, "/quit"] msgDump = pickle.dumps(msgList) formattedMsg = serverEncryptor.encrypt(msgDump) s.send(formattedMsg) s.shutdown(socket.SHUT_RDWR) s.close() quit(0) else: # sends non-quit command message, continues execution msg = pickle.dumps([True, msg]) msg = serverEncryptor.encrypt(msg) s.send(msg) else: msg = pickle.dumps([False, msg]) msg = serverEncryptor.encrypt(msg) s.send(msg)
def client_mgr(cli, serverEncryptor: PKCS1OAEP_Cipher): while True: try: message = cli.conn.recv(4096) except (ConnectionResetError, ConnectionAbortedError): # Connection failed, possibly due to a non-expected termination on client side # i.e. client crashed or force close try: active_connections.remove(cli) cli.conn.shutdown(socket.SHUT_RDWR) cli.conn.close() msg_handler(User(None, None, "<SERVER>", None, "#FF0000"), cli.nick + serverAlertMessages["USERDISCONNECT"]) except ValueError: pass break if message: # handle client message here # decrypt message object message = serverEncryptor.decrypt(message) message = pickle.loads(message) print(cli.nick, ":", message[1]) if message[0]: # if message[0] is true for messages sent to the server, that message is a control message # think /quit, /nick, etc. if not control_msg_handler(cli, message[1]): # control_msg_handler returns False, so we are terminating connection break # if non-control message, broadcast message else: msg_handler(cli, message[1]) else: # message is empty. Do we kill the connection, or do we send an error message? # prevent empty message sent from client side? # remove client from the list of connected clients pass
def __generateRSADecrypter(self): with open(KEY_PEM_FILE_PATH) as key_pem_file: key_bytes = key_pem_file.read() key = RSA.importKey(key_bytes) rsa_decrypter = PKCS1OAEP_Cipher(key, None, None, None) self.__handshakeDecrypter = rsa_decrypter
def __generateRSAEncrypter(self, cert_string): peer_pk = self.__getPubKeyFromCert(cert_string) peer_rsa_encrypter = PKCS1OAEP_Cipher(peer_pk, None, None, None) self.__handshakeEncrypter = peer_rsa_encrypter
def data_received(self, data): self.deserializer.update(data) for pkt in self.deserializer.nextPackets(): if self.status == 0: if isinstance(pkt, PlsHello): self.ServerCert = pkt.Certs if self.ChainVerifyer(self.ServerCert): print("Client: PlsHello packet receive!") self.PacketsList.append(pkt) self.ServerNonce = pkt.Nonce self.ServerCertificate = self.ServerCert[0].decode() self.tmpPublickey = OpenSSL.crypto.load_certificate( OpenSSL.crypto.FILETYPE_PEM, self.ServerCertificate).get_pubkey() self.publickeystring = OpenSSL.crypto.dump_publickey( OpenSSL.crypto.FILETYPE_PEM, self.tmpPublickey).decode() self.serverPublicKey = RSA.importKey( self.publickeystring) KeyExchangePacket = PlsKeyExchange() self.ClientPrekey = os.urandom(16) Encrypter = PKCS1OAEP_Cipher(self.serverPublicKey, None, None, None) cipher = Encrypter.encrypt(self.ClientPrekey) KeyExchangePacket.PreKey = cipher KeyExchangePacket.NoncePlusOne = self.ServerNonce + 1 self.transport.write(KeyExchangePacket.__serialize__()) print("Client: KeyExchange sent!") self.PacketsList.append(KeyExchangePacket) else: print("Client: Authentication Error!") if isinstance(pkt, PlsKeyExchange): print("Client: PlskeyExchange receive!") self.PacketsList.append(pkt) self.ServerPrekey = PKCS1OAEP_Cipher( self.privateKey, None, None, None).decrypt(pkt.PreKey) self.validation = b'' for packet in self.PacketsList: pktdata = packet.__serialize__() self.validation = self.validation + pktdata self.hashvalidation = hashlib.sha1( self.validation).digest() HandshakeDonePacket = PlsHandshakeDone() HandshakeDonePacket.ValidationHash = self.hashvalidation self.transport.write(HandshakeDonePacket.__serialize__()) print("Client: HandshakeDone packet sent!") if isinstance(pkt, PlsHandshakeDone): print("Client: Handshake Done!") self.CalHash() self.encrt = Counter.new(128, initial_value=int( hexlify(self.IVc), 16)) self.aesEncrypter = AES.new(self.EKc, counter=self.encrt, mode=AES.MODE_CTR) self.decrt = Counter.new(128, initial_value=int( hexlify(self.IVs), 16)) self.aesDecrypter = AES.new(self.EKs, counter=self.decrt, mode=AES.MODE_CTR) self.higherProtocol().connection_made(self.higherTransport) self.status = 1 if isinstance(pkt, PlsClose): self.connection_lost("Error raised!") if self.status == 1: if isinstance(pkt, PlsData): if pkt.Mac == self.VerificationEngine(pkt.Ciphertext): higherData = self.decryptEngine(pkt.Ciphertext) self.higherProtocol().data_received(higherData)
def dec_prekey(self, ciphertext): CpriK = RSA.importKey(self.SPriK) Decrypter = PKCS1OAEP_Cipher(CpriK, None, None, None) return Decrypter.decrypt(ciphertext)