« back to lab.rolisoft.net

RS Chat

Project history

Since I started programming, a chat application was kind of a milestone. A very primitive chat application can be developed by making a TCP connection and send a message through it when you press the send button on the form. Not hard at all, but since it involves networking, it's considered stepping to the next level, if you're a complete beginner.

I started tasting C# in the beginning of 2007. Writing a chat application was one of my goals, but due to the lack of knowledge at that time, that wasn't doable. In January 26th, 2008, I finally went for it for the first time.

RS Chat v1

The application made two TCP connections, a server and a client on both ends. I don't know why I did this, since TCP sockets are bidirectional. Probably I didn't know this then.

I really wanted to make it secure, so I made some encryption functions. It used AES and TripleDES, but because I was lacking *real* cryptographic knowledge, they were improperly padded and used ECB. The password was generated dynamically, where I relied on security through obscurity. Yeah, I know now, that's not a good idea, especially when the generated assembly can be really easily decompiled and analysed.

Overall, the application is functional, but has lots of issues.

RS Chat v2

On October 19th, 2009, after gaining some usable knowledge, I restarted the project from scratch. And this time, it only used one TCP socket to communicate. :)

This time I made an actual protocol and documented it. It didn't blindly send strings anymore. It had 7 commands: CONNREQ, CONNOK, PING, PONG, TYPING, NOTTYPING, MESSAGE. Every command ended with a null, so they could be separated on the stream.

For encryption it used Blowfish and AES with a key derived using PBKDF2 which was salted using a shared secret key using Diffie-Hellman key exchange on the CONNREQ command. Optionally it could pass the whole stream through SslStream providing an extra layer of security.

This version had some more advanced features: it could measure connection latency and show when the remote user is typing.

I attempted developing a file transfer feature, but since I was trying to push the file through the active connection, it was extremely slow and blocked the whole connection while the transfer was running.

RS Chat v3

Exactly a year and a day later, on October 20th, 2010, I restarted the development, again, from scratch. This time I'm focusing on performance, extensibility and to do cryptography right.

Now I fully understand the concept of object-oriented programming and I know a thing or two about cryptography.

Main components

When a message is sent or an event is fired, these are the interfaces it needs to goes through – but not in the listed order. Every single part in the application is extensible:

File transfers

For the first time ever, I've succeded at implementing high-speed secure file transfers. When a file transfer is initiated, the software creates an unidirectional TCP socket on the server side and starts sending the file. The reason why not necessarily the file sender is used as a server is really simple: it might not be reachable, it might be behind a firewall or NAT. If the client originally used a proxy to create a connection, then that proxy will be contacted again to initiate the file transfer through it.

The file transfer being on another form, thread and connection, has the ability to continue the transfer even if the main chat connection is closed or lost. The connection used for the transfer, as stated above, is unidirectional and will close automatically after the size of the file is received, therefore it's not a security concern.

The speed of the transfers average on 95 MB/s. If encryption is enabled, the speed is really determined by the algorithm in use, but if a high-speed stream cipher is chosen, then the speed is around 60 MB/s.

Identity verification

If you're very paranoid you might be concerned about your connection being rerouted to someone else, or the DNS resolving to the fake IP, or to man-in-the-middle attacks. Version 1 and 2 didn't address this issue. Version 3 however, supports using SSL certificates to authenticate the connection and to tamper-proof every single packet. Any certificate that can be used for email encryption, can be used for this purpose too. You can get fully free email certificates from CACert, StartCom or InstantSSL.

Some ideas

These didn't make it into the software yet, but they're on my TODO list: