diff --git a/.vscode/launch.json b/.vscode/launch.json
deleted file mode 100644
index 67dd9f8..0000000
--- a/.vscode/launch.json
+++ /dev/null
@@ -1,26 +0,0 @@
-{
- "version": "0.2.0",
- "configurations": [
- {
- // Use IntelliSense to find out which attributes exist for C# debugging
- // Use hover for the description of the existing attributes
- // For further information visit https://github.com/dotnet/vscode-csharp/blob/main/debugger-launchjson.md
- "name": ".NET Core Launch (console)",
- "type": "coreclr",
- "request": "launch",
- "preLaunchTask": "build",
- // If you have changed target frameworks, make sure to update the program path.
- "program": "${workspaceFolder}/client/bin/Debug/net8.0/client.dll",
- "args": [],
- "cwd": "${workspaceFolder}/client",
- // For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console
- "console": "internalConsole",
- "stopAtEntry": false
- },
- {
- "name": ".NET Core Attach",
- "type": "coreclr",
- "request": "attach"
- }
- ]
-}
\ No newline at end of file
diff --git a/.vscode/tasks.json b/.vscode/tasks.json
deleted file mode 100644
index c2e2b15..0000000
--- a/.vscode/tasks.json
+++ /dev/null
@@ -1,41 +0,0 @@
-{
- "version": "2.0.0",
- "tasks": [
- {
- "label": "build",
- "command": "dotnet",
- "type": "process",
- "args": [
- "build",
- "${workspaceFolder}/online_security_project.sln",
- "/property:GenerateFullPaths=true",
- "/consoleloggerparameters:NoSummary;ForceNoAlign"
- ],
- "problemMatcher": "$msCompile"
- },
- {
- "label": "publish",
- "command": "dotnet",
- "type": "process",
- "args": [
- "publish",
- "${workspaceFolder}/online_security_project.sln",
- "/property:GenerateFullPaths=true",
- "/consoleloggerparameters:NoSummary;ForceNoAlign"
- ],
- "problemMatcher": "$msCompile"
- },
- {
- "label": "watch",
- "command": "dotnet",
- "type": "process",
- "args": [
- "watch",
- "run",
- "--project",
- "${workspaceFolder}/online_security_project.sln"
- ],
- "problemMatcher": "$msCompile"
- }
- ]
-}
\ No newline at end of file
diff --git a/client/Program.cs b/client/Program.cs
index 8381c75..3751555 100644
--- a/client/Program.cs
+++ b/client/Program.cs
@@ -1,50 +1,2 @@
-using System;
-using System.Net.Sockets;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Client;
-
-public class Program
-{
- static void Main(string[] args)
- {
- using TcpClient client = new("127.0.0.1", 12345);
-
- byte[] toSend = Encoding.ASCII.GetBytes("hello server");
-
- var stream = client.GetStream();
-
- var inputTask = Task.Run(async () => await HandleUserInput(client, stream));
- var serverInput = Task.Run(async () => await HandleServerInput(client, stream));
-
- _ = Task.WaitAny(inputTask, serverInput);
-
- }
-
- static async Task HandleUserInput(TcpClient client, NetworkStream stream) {
- while(client.Connected) {
- string? input = Console.ReadLine();
- if(input == null) {
- await Task.Delay(100);
- continue;
- }
- else {
- stream.Write(Encoding.ASCII.GetBytes(input));
- Console.WriteLine($"[{DateTime.Now}]Sent to server: {input}");
- }
- }
- }
-
- static async Task HandleServerInput(TcpClient client, NetworkStream stream) {
- byte[] buffer = new byte[1024];
- while(client.Connected) {
- int readLen = await stream.ReadAsync(buffer);
- if(readLen != 0) {
- string fromServer = Encoding.ASCII.GetString(buffer[..readLen]);
- Console.WriteLine($"[{DateTime.Now}]\t\tFrom server: {fromServer}");
-
- }
- }
- }
-}
\ No newline at end of file
+// See https://aka.ms/new-console-template for more information
+Console.WriteLine("Hello, World!");
diff --git a/client/client.csproj b/client/client.csproj
index 84912b2..47ba6e4 100644
--- a/client/client.csproj
+++ b/client/client.csproj
@@ -7,7 +7,7 @@
Exe
net8.0
- disable
+ enable
enable
diff --git a/lib/Class1.cs b/lib/Class1.cs
new file mode 100644
index 0000000..34def2d
--- /dev/null
+++ b/lib/Class1.cs
@@ -0,0 +1,6 @@
+namespace lib;
+
+public class Class1
+{
+
+}
diff --git a/lib/Request.cs b/lib/Request.cs
deleted file mode 100644
index e954151..0000000
--- a/lib/Request.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-namespace lib;
-
-public enum RequestType {
- Register = 1,
- ConfirmRegister = 2,
- GetMessages = 3,
- GetUserKey = 4,
- SendMessage = 5,
- SendAck = 6
-}
\ No newline at end of file
diff --git a/lib/Utils.cs b/lib/Utils.cs
deleted file mode 100644
index 8139470..0000000
--- a/lib/Utils.cs
+++ /dev/null
@@ -1,53 +0,0 @@
-using System.Text;
-using System.Linq;
-
-namespace lib;
-
-public static class Utils {
- public static byte[] NumberToBytes(string Number) {
- if(Number.Any(c => !char.IsDigit(c)) || Number.Length > 16) {
- throw new Exception("Invalid arguments!");
- }
- byte[] res = Enumerable.Repeat((byte)0b1111_1111, 8).ToArray();
- // Pad Number if needed to be of even length (because each 2 digits are turned into 1 byte)
- Number = Number.Length % 2 == 0 ? Number : Number + '-';
-
- for(int i = 0; i < Number.Length - 1; i += 2) {
- char c1 = Number[i];
- char c2 = Number[i + 1];
- res[i / 2] = (byte)((DigitToByte(c1) << 4) | DigitToByte(c2));
- }
- return res;
- }
-
- public static string BytesToNumber(byte[] Bytes) {
- string s = "";
- foreach(byte b in Bytes) {
- byte b1 = (byte)((b >> 4) & 0b1111);
- byte b2 = (byte)(b & 0b1111);
- s = s + ByteToDigit(b1) + ByteToDigit(b2);
- }
- return new string(s.Where(c => char.IsDigit(c)).ToArray());
- }
-
-
- public static byte DigitToByte(char c) {
- if (int.TryParse(c.ToString(), out int d)) {
- return (byte)d;
- }
- else {
- return 0b1111; // empty, turned into '-' later to be discarded
- }
- }
-
- public static char ByteToDigit(byte b) {
- byte offset = Encoding.ASCII.GetBytes("0")[0];
-
- if(b == 0b1111) {
- return '-';
- }
- else {
- return Encoding.ASCII.GetChars([(byte)(b + offset)])[0];
- }
- }
-}
\ No newline at end of file
diff --git a/online_security_project.sln b/online_security_project.sln
index 6e29e6d..704057d 100644
--- a/online_security_project.sln
+++ b/online_security_project.sln
@@ -5,10 +5,6 @@ VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "client", "client\client.csproj", "{F38E98E8-4FE8-4F34-B5A7-004444ED1F50}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "server", "server\server.csproj", "{36C3F9FE-FA02-4AC0-89A2-65B377767C8F}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "lib", "lib\lib.csproj", "{8E625330-2219-4E74-8524-A947D783B3BB}"
-EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -22,13 +18,5 @@ Global
{F38E98E8-4FE8-4F34-B5A7-004444ED1F50}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F38E98E8-4FE8-4F34-B5A7-004444ED1F50}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F38E98E8-4FE8-4F34-B5A7-004444ED1F50}.Release|Any CPU.Build.0 = Release|Any CPU
- {36C3F9FE-FA02-4AC0-89A2-65B377767C8F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {36C3F9FE-FA02-4AC0-89A2-65B377767C8F}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {36C3F9FE-FA02-4AC0-89A2-65B377767C8F}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {36C3F9FE-FA02-4AC0-89A2-65B377767C8F}.Release|Any CPU.Build.0 = Release|Any CPU
- {8E625330-2219-4E74-8524-A947D783B3BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {8E625330-2219-4E74-8524-A947D783B3BB}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {8E625330-2219-4E74-8524-A947D783B3BB}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {8E625330-2219-4E74-8524-A947D783B3BB}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
diff --git a/protocol.md b/protocol.md
index 26b32d8..4bee316 100644
--- a/protocol.md
+++ b/protocol.md
@@ -3,29 +3,34 @@
All encryptions are made using RSA (key size to be determined), no symmetric encryptions
are used due to messages being short.
-a. Encryption will be a-symmetric because we can assume messages are short
-b. See "Registration" below
-c. Server keeps public keys for everyone, and gives them to a user when they want to
-send a message to someone (only the relevant key)
-d. Every e2e message is both signed and encrypted aka, message M from A to B
-`EM = E_Bpub(E_Apriv(N))`
-e. message is sent to the server in a `E_server(E_Apriv(metadata + EM from d))`,
-message ack is sent to the server as a `MessageAck(msg_id)`, which will be retrieved
-by the user when it pulls for messages.
-f. TODO: properly explain the different api structs
-g. TODO: properly explain how the server handles data
+
+## Some problems
-### Key Derivation Function
+Do i need hasing? dont think it will help too much, can just sign-encrypt i think.
-as there is no use of symmetric keys (at least for this scope), I dont believe there
-is a need to use KDF, it will reduce the keyspace and we already have the public key
-of the server in the clients
+When asking for messages, maybe do a little back and forth with the server to make sure
+the request comes from the correct person?
+Maybe keep track of the last message ID every time? then add it to the request,
+ not good, as if there were no new messages an attacker can now use said req.
+Maybe the current timestamp? then the server keeps track of the last request with
+timestamp for a given user? kinda acts like a better counter i think.
+ I dont think someone can abuse this system.
+ I think adding this to every request is neccessary to make sure no duplicates are
+ being sent, ie. if an attacker listens on the channel and sees a package sent to
+ the server, it can repeat it and cause mischief (maybe send duplicate messages,
+ or flush the user's messages or something).
+
+ an attacker can also abuse duplicates to see who a user is talking to,
+ simply send the request and encrypt all public keys (gotten in a legitimate way)
+ using the user's public key (as the server would encrypt) and compare the result
+ from the server
+
## Registration:
- User sends a register request to server `(phone number, RSA public key)`,
giving them a public key and encrypting using the server's public key
-- Server sends the user a `VerificationRequired` message & a 6-digit code (Secure channel)
+- Server sends the user a `Confirm` message & a 6-digit code
- User sends the server the 6-digit code, signed using the key provided at stage 1
(this message is very short and funny, because its a 6-digit code, signed using the
user's private key, and encrypted using the server's public key)
@@ -46,40 +51,19 @@ request and ultimately signed by A and encrypted using the server's key.
The server will hold on to the message until B will send a `GetMessages` request
to the server.
-## "Control" requests
+## Requests:
-- Register `(phone, pub RSA key)`
- extra data: RSA key size (payload length)
-- ConfirmRegister (signed & encrypted 6 digit code)
- extra data: 6 bytes for the 6 digit code (can use less but it will be padding otherwise)
-- GetMessages (signed & encrypted to not allow someone to "flush" someone else's msgs)
- extra data: EMPTY
-- GetUserKey (dont think it needs any signing or encryption technically, as it is very
- simple registering and "stealing" a key outside the system, keys are assumed to be
- unbreakable)
- extra data: 8 bytes (4 bits per digit) of whoever we want to get the key of
-- SendMessage `(to_user, msg_id, EM from d above)`
- extra data: 8 bytes (4 bits per digit) of who to send the data, 4 bytes (32bit) for length
-- SendAck `(to_user, msg_id - signed and encrypted)`
- - server doesnt know if the msg itself is indeed valid and not tempered with
- extra data: 8 bytes (4 bits per digit) of who to send the data, 4 bytes (32bit) for length
+legend:
+ - `E(t)` encrypt t
+ - `S(t)` sign t
+ - `ES(t)` signed and encrypted (in that order!)
+ - `HS(t)`/`HS t` hash and sign t
+All requests are to be encrypted using the server's public key, have the sender phone
+and have a timestamp on them, except when otherwise noted
-I think it all can go into a:
-```
-{
- Version byte (0) - 1 byte
- RequestType - 1 byte,
- Phone number - 8 bytes (every 4 bits is a number, so we have 16 numbers),
- UTC timestamp - 8 bytes (long),
- extra data (based on the request given) - up to 18 bytes
-} = 32 bytes = 256 bits
-```
-and we can just append encrypted payloads to it (in SendMessage and SendAck)
-
-To each message we also append a sha3-256 signed hash
-
-enc_server( request - 256 bits, signed sha3-256 )
-
-which means:
- Keys: RSA-512
- Hashes: SHA3-256
\ No newline at end of file
+1. `Register(public key)`, no timestamp
+2. `HS RegisterConfirm(6-digit code)`
+3. `GetMessages`
+4. `GetUserKey(phone - user to get key for)`
+5. `SendMessage(phone - receiver, ES({ message_id, message }))`
+6. `SendMessageACK(phone - ack receiver, ES({ message_id[], ACK/NACK }))`
diff --git a/server/Program.cs b/server/Program.cs
index e361765..3751555 100644
--- a/server/Program.cs
+++ b/server/Program.cs
@@ -1,44 +1,2 @@
-using System;
-using System.Net;
-using System.Net.Sockets;
-
-namespace Server;
-
-public class Program
-{
- static void Main(string[] args)
- {
- int port = 12345;
- TcpListener server = new(IPAddress.Parse("0.0.0.0"), port);
- try {
- server.Start();
- byte[] buffer = new byte[256];
-
- while(true) {
- // Currently, every time it gets a block, it will simply send it back but ToUpper
- using TcpClient client = server.AcceptTcpClient();
- Console.WriteLine("Got a client!");
-
- var stream = client.GetStream();
- int readLen;
- while((readLen = stream.Read(buffer, 0, buffer.Length)) != 0) {
- // for now, lets just read it as an ascii string
- string input = System.Text.Encoding.ASCII.GetString(buffer, 0, readLen);
- Console.WriteLine($"Got block: {input}");
-
- byte[] ret = System.Text.Encoding.ASCII.GetBytes(input.ToUpper());
- stream.Write(ret, 0, ret.Length);
- }
-
-
- }
- }
- catch(Exception ex) {
- Console.WriteLine($"Server error: {ex.Message}");
- Console.WriteLine("Trace: " + ex.StackTrace);
- }
- finally {
- server.Stop();
- }
- }
-}
\ No newline at end of file
+// See https://aka.ms/new-console-template for more information
+Console.WriteLine("Hello, World!");
diff --git a/server/server.csproj b/server/server.csproj
index 84912b2..47ba6e4 100644
--- a/server/server.csproj
+++ b/server/server.csproj
@@ -7,7 +7,7 @@
Exe
net8.0
- disable
+ enable
enable