SentinelChat is an end-to-end encrypted chat application that supports secure file transfer between clients using the Boost and CryptoPP libraries.
While this application focuses on memory security, there are other potential attack vectors to consider:
- Man-in-the-Middle (MITM) / Interception attacks
- Message client_id spoofing / Client Impersonation / Authentication Bypass
- Denial of Service (DoS) attacks
- Replay vulnerabilities
- Protocol vulnerabilities
- Messaging Feature Denial of Service
- Possible Buffer Overflow vulnerabilities
For more information on secure software development, refer to the book "The Art of Software Security Assessment - Identifying and Preventing Software Vulnerabilities."
# Check out the library.
git clone https://github.com/Netanelshoshan/SentinelChat.git
# Build the project
make
# Go to the server directory and run it.
python3 server/server.py
# In a seperate terminal, run the two clients
cd client1/ && ./client
cd client2/ && ./client
Follow the steps below to establish a secure connection between two clients:
1. Register both clients.
2. Retrieve the list of clients on both clients.
3. Client A requests Client B's public key.
4. Client A requests Client B's symmetric key.
5. Client B requests pending messages.
6. Client B requests Client A's public key.
7. Client B sends their symmetric key.
8. Client A requests pending messages.
9. Client A sends their symmetric key.
10. Client B requests pending messages.
After completing these steps, you can start chatting and sending files securely between the clients.
-
The application is client-server based, meaning, the messages are relayed through the server.
-
The clients will send a "pull request" to the server to check for new messages and server will then send the messages to the clients.
-
This will allow the clients to send messages while both online and offline. In addition, the messages will be encrypted on the client side and are sent in an encrypted form to the server, so even the server will not be able to read the messages, only the recipient client will be able to decrypt the messages.
The server is written in Python and will act in a stateless manner, meaning each request will be handled independently and the server will not store any state information about the clients.
The db will hold two tables, one for the clients and one for the messages.
Name | Type | Details |
---|---|---|
ID | 16 bytes | uuid |
userName | string- 255 bytes | ascii representing user name - null terminated |
publicKey | 160 bytes | client's public key |
lastSeen | date and time | The time the server got it's last request from the client |
Name | Type | Details |
---|---|---|
ID | 4 bytes | index |
toClient | 15 bytes | recipient's uuid |
fromClient | 16 bytes | sender's uuid |
type | byte | type of message |
content | blob | message content |
Request | field name | size | details |
---|---|---|---|
Header | Client ID ----------------- Version ----------------- Code ----------------- Payload size |
16 bytes ----------------- byte ----------------- 2 bytes ----------------- 4 bytes |
Client's uuid ------------------------------------ Client's version ------------------------------------ Request code ------------------------------------ Request size |
Payload | Payload | Changes | Request content. Changes according to the type of request |
Response | field name | size | details |
---|---|---|---|
Header | Version ----------------- Code ----------------- Payload size |
byte ----------------- 2 bytes ----------------- 4 bytes |
server's version ------------------------------------ response code ------------------------------------ response size |
Payload | Payload | Changes | Response content. Changes according to the type of response |