Table of Contents
Overview
The communication between the Quasar server and clients uses Transport Layer Security (TLS) with client & server certificates. TLS provides confidentiality and data integrity between the communicating components. TLS application data packets contain the exchanged messages between a client and server. The application data consists of a 4 bytes unsigned message length and a serialized message. Although a message length of 4 bytes results in a maximum message length of 2³² bytes, a lower limit of 5 MB is enforced on the client and server side to prevent huge buffer allocation attacks from exhausting the resources of a client or server.
---------------------------------------------------------------------
| |
| TLS application data |
| ----------------------------------------------------------- |
| | 4 bytes | x bytes | |
| | message length | serialized message | |
| ----------------------------------------------------------- |
--------------------------------------------------------------------
Initial handshake
During the TLS handshake the client verifies the server certificate and only continues the handshake when it is valid. Once the TLS connection is established the application-specific handshake of Quasar begins. For this the client will send a ClientIdentification
message while no other messages are allowed to be sent and will result in an immediate disconnection by the server. The ClientIdentification
message contains identifying properties, such as the client version, operating system, hardware ID, and most importantly the encryption key and signature. The encryption key is set during the build process by the server and signed with its private key. Both, the encryption key and signature of the server, are stored in the client. By verifying the received encryption key together with the signature the client is authenticated by the server.
[ProtoContract]
public class ClientIdentification : IMessage
{
[ProtoMember(1)]
public string Version { get; set; }
[ProtoMember(2)]
public string OperatingSystem { get; set; }
[ProtoMember(3)]
public string AccountType { get; set; }
[ProtoMember(4)]
public string Country { get; set; }
[ProtoMember(5)]
public string CountryCode { get; set; }
[ProtoMember(6)]
public int ImageIndex { get; set; }
[ProtoMember(7)]
public string Id { get; set; }
[ProtoMember(8)]
public string Username { get; set; }
[ProtoMember(9)]
public string PcName { get; set; }
[ProtoMember(10)]
public string Tag { get; set; }
[ProtoMember(11)]
public string EncryptionKey { get; set; }
[ProtoMember(12)]
public byte[] Signature { get; set; }
}
Once the authentication is completed the server will send a ClientIdentificationResult
message with the property Result
set to true if the authentication was successful or false if it failed resulting in a disconnection of the client initiated by the server. If the authentication was successful the client is allowed to send further messages.
[ProtoContract]
public class ClientIdentificationResult : IMessage
{
[ProtoMember(1)]
public bool Result { get; set; }
}
Note: Mutual authentication of client and server with client and server certificates during the TLS handshake is not implemented due a .NET framework bug on Windows 7 systems.
Message exchange
A list of all available messages to send and receive is available here.
Message serialization
The messages are serialized using Protocol Buffers version 3 by Google (specification). Quasar uses the library protobuf-net which provides Protocol Buffers-compatible serialization/deserialization for .NET applications.