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 sending 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 January 26th, 2008

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.

Screenshot

screenshot

RS Chat v2 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](http://msdn.microsoft.com/en-us/library/system.net.security.sslstream.aspx) 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.

Screenshots

screenshot screenshot

RS Chat v3 October 20th, 2010

Exactly a year and a day later, 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:

Screenshots

screenshot screenshot

Encrypted file transfers

This transfer has been proxied through a public anonymous proxy so I could capture the file transfer. It's safe to do this, because the connection is encrypted and every packet is signed to prevent tampering.

screenshot

screenshot

New connection window

The settings aren't sent in the handshake packet, which means if your settings don't match, the connection will fail instantly.

screenshot
screenshot
screenshot
screenshot

 

RS Chat v4 August 18th, 2012

The development has been restarted, however this time it's only developed as a low-priority hobby project, and I mainly focus on writing clean code behind a thought-out and extensible architecture.

The project is currently under development. As of now, there isn't even an UI or a protocol, just a bunch of classes.

Things implemented so far

Things to be implemented

Communication protocols

Plain-text protocol

This protocol was supposed to be similar syntactically to the IRC protocol. It isn't the default protocol, since it is only implemented for fun, debugging and educational purposes. A typical chat session looks like this:

HELLO RoliSoft rolisoft@gmail.com         | ->  HelloEvent, String name, String email
PING 1234567890                           | ->  PingEvent, Long timestamp
TYPNG 1                                   | ->  TypingEvent, Boolean isOccurring
MSG This is a message.                    | ->  MessageEvent, LeftoverString message
BYE                                       | ->  ByeEvent

Binary protocol

This is the smallest, fastest and default protocol. A packet looks like this:

+--------------+[+--------------+]
|  EVENT UID   |[|  ARGUMENTS   |]
|    2 bytes   |[|              |]
|     uint16   |[|              |]
+--------------+[+--------------+]

Arguments are optional, but since most of the events contain some kind of data (TypingEvent has bool IsOccurring, PingEvent has ulong Timestamp, etc) the following bytes are deserialized into an object[] instance, via a pre-mapped event-arguments-datatype list. The datatypes can be one of the following:

Once the communication protocol deserialized the arguments into an object[] instance, the LoadArguments(object[]) method will be called on the previously initialized Event object. Once the event has been successfully reconstructed, whoever is listening on the PacketReceived event of the communication protocol will receive this object.

Supported algorithms and benchmarks

Compression

Toggle benchmark table of supported compression algorithms.

Encryption

Toggle benchmark table of supported encryption algorithms.

Hashing

Toggle benchmark table of supported hashing algorithms.

RS Chat v5 April 4th, 2014

Being in the second year of my B.Sc. studies, the Networking class had an assignment to create a simple chat application. While I could've easily turned in any of the earlier versions, I decided to implement a new one in Qt and C++.

The application has an architecture similar to the previous version. Since this application was never published outside of the class assignment, I never ended up creating a page for it and fully documenting it.