Kaynağa Gözat

Use sha2 library

- Use sha2 library until my implementation works
- Test server rx/tx
Rain 1 ay önce
ebeveyn
işleme
b87f0491b1

+ 3 - 0
client_shared/Cargo.toml

@@ -11,3 +11,6 @@ utils = { path = "../utils" }
 reqwest = { version = "0.12.15", features = [ "blocking" ] }
 
 url = "2.5.8"
+
+[dev-dependencies]
+server = { path = "../server" }

+ 14 - 0
client_shared/src/utils.rs

@@ -120,3 +120,17 @@ pub fn rx_messages(host: &str, password: &str, timeout_sec: u64) -> Result<Vec<M
 
     Ok(messages)
 }
+
+#[test]
+fn test_tx_rx() {
+    let host = "http://localhost:13337/";
+    let password = "null";
+
+    let message = Message::new("Alice", "Hello", "root");
+    tx_message(host, password, 5, message.clone()).expect("Failed to send message");
+    let messages = rx_messages(host, password, 5).expect("Failed to receive messages");
+
+    assert_eq!(messages.len(), 1);
+    assert_eq!(messages[0].sender, message.sender);
+    assert_eq!(messages[0].content, message.content);
+}

+ 88 - 0
server/src/lib.rs

@@ -0,0 +1,88 @@
+use utils::{
+    binary::checksum, http::{self, Request, Response}, strings::StaticString
+};
+
+const MAX_MESSAGE_LENGTH: usize = 2048;
+const MESSAGE_HISTORY_LENGTH: usize = 64;
+
+#[derive(Debug)]
+pub struct Appdata {
+    messages: [StaticString<MAX_MESSAGE_LENGTH>; MESSAGE_HISTORY_LENGTH],
+    index: usize,
+}
+
+impl Appdata {
+    pub fn new() -> Self {
+        Self {
+            messages: core::array::from_fn(|_| StaticString::new()),
+            index: 0,
+        }
+    }
+
+    pub fn insert_message(&mut self, message: String) -> Result<(), ()> {
+        if message.len() > MAX_MESSAGE_LENGTH {
+            return Err(());
+        }
+
+        let index = self.index;
+        self.messages[index] = message.into();
+        self.index = (index + 1) % self.messages.len();
+
+        Ok(())
+    }
+
+    pub fn get_messages(&self) -> Vec<String> {
+        let mut messages = vec![];
+
+        for message in self.messages.iter() {
+            if message.is_empty() {
+                continue;
+            }
+            messages.push(String::from(message));
+        }
+
+        messages
+    }
+}
+
+fn index_get_sync(state: &mut Appdata, _: Request) -> Response {
+    let string = state.get_messages().join(",");
+    println!("Sending `{}` characters", string.len());
+    Response::ok().body(&string)
+}
+
+fn index_post_sync(state: &mut Appdata, request: Request) -> Response {
+    let body = request.body;
+
+    let Some(message_ser_bin) = utils::binary::hex2bin(&body) else {
+        return Response::bad_request();
+    };
+
+    if message_ser_bin.len() < 2 {
+        return Response::bad_request();
+    }
+
+    // Checksum before decryption
+    if checksum(&message_ser_bin[..message_ser_bin.len()-1]) != message_ser_bin[message_ser_bin.len()-1] {
+        return Response::bad_request();
+    }
+
+    println!("Received ({}): {:#?}", body.len(), body);
+
+    match state.insert_message(body.clone()) {
+        Ok(()) => Response::ok().body(&body),
+        Err(()) => Response::bad_request(),
+    }
+}
+
+pub fn router(state: &mut Appdata, request: Request) -> Response {
+    if request.url != "/" {
+        return Response::not_found();
+    }
+
+    match request.method {
+        http::Method::Get => index_get_sync(state, request),
+        http::Method::Post => index_post_sync(state, request),
+        http::Method::Other => Response::method_not_allowed(),
+    }
+}

+ 3 - 87
server/src/main.rs

@@ -1,94 +1,10 @@
 use std::env::args;
 
-use utils::{
-    binary::checksum, http::{self, Request, Response}, strings::StaticString
-};
+use server::{Appdata, router};
+use utils::http;
 
-const MAX_MESSAGE_LENGTH: usize = 2048;
-const MESSAGE_HISTORY_LENGTH: usize = 64;
-const DEFAULT_PORT: u16 = 13337;
-
-#[derive(Debug)]
-struct Appdata {
-    messages: [StaticString<MAX_MESSAGE_LENGTH>; MESSAGE_HISTORY_LENGTH],
-    index: usize,
-}
-
-impl Appdata {
-    pub fn new() -> Self {
-        Self {
-            messages: core::array::from_fn(|_| StaticString::new()),
-            index: 0,
-        }
-    }
-
-    pub fn insert_message(&mut self, message: String) -> Result<(), ()> {
-        if message.len() > MAX_MESSAGE_LENGTH {
-            return Err(());
-        }
-
-        let index = self.index;
-        self.messages[index] = message.into();
-        self.index = (index + 1) % self.messages.len();
 
-        Ok(())
-    }
-
-    pub fn get_messages(&self) -> Vec<String> {
-        let mut messages = vec![];
-
-        for message in self.messages.iter() {
-            if message.is_empty() {
-                continue;
-            }
-            messages.push(String::from(message));
-        }
-
-        messages
-    }
-}
-
-fn index_get_sync(state: &mut Appdata, _: Request) -> Response {
-    let string = state.get_messages().join(",");
-    println!("Sending `{}` characters", string.len());
-    Response::ok().body(&string)
-}
-
-fn index_post_sync(state: &mut Appdata, request: Request) -> Response {
-    let body = request.body;
-
-    let Some(message_ser_bin) = utils::binary::hex2bin(&body) else {
-        return Response::bad_request();
-    };
-
-    if message_ser_bin.len() < 2 {
-        return Response::bad_request();
-    }
-
-    // Checksum before decryption
-    if checksum(&message_ser_bin[..message_ser_bin.len()-1]) != message_ser_bin[message_ser_bin.len()-1] {
-        return Response::bad_request();
-    }
-
-    println!("Received ({}): {:#?}", body.len(), body);
-
-    match state.insert_message(body.clone()) {
-        Ok(()) => Response::ok().body(&body),
-        Err(()) => Response::bad_request(),
-    }
-}
-
-fn router(state: &mut Appdata, request: Request) -> Response {
-    if request.url != "/" {
-        return Response::not_found();
-    }
-
-    match request.method {
-        http::Method::Get => index_get_sync(state, request),
-        http::Method::Post => index_post_sync(state, request),
-        http::Method::Other => Response::method_not_allowed(),
-    }
-}
+const DEFAULT_PORT: u16 = 13337;
 
 fn main() -> http::Result<()> {
     let port = args().nth(1).unwrap_or(DEFAULT_PORT.to_string());

+ 1 - 0
utils/Cargo.toml

@@ -4,3 +4,4 @@ version = "0.1.0"
 edition = "2021"
 
 [dependencies]
+sha2 = "0.10.9"

+ 8 - 3
utils/src/hash/sha.rs

@@ -1,5 +1,7 @@
 // Reference: https://github.com/keanemind/python-sha-256/
 
+use sha2::Digest;
+
 const K: [Number; 64] = [
     0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
     0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
@@ -48,6 +50,11 @@ fn rotate_right(num: Number, shift: Number) -> Number {
 }
 
 pub fn sha256(data: &[u8]) -> [u8; 256 / 8] {
+    return sha2::Sha256::digest(data).try_into().expect("SHA-256 output should be 32 bytes");
+
+    // Use library function for SHA-256 until the implementation is fixed
+    // TODO: Fix implementation
+
     let data_len_bits: u64 = (data.len() * 8) as u64;
 
     let padding_len = (512 - ((data.len() * 8 + 64) % 512)) / 8;
@@ -123,15 +130,13 @@ pub fn sha256(data: &[u8]) -> [u8; 256 / 8] {
 mod test {
     use super::*;
 
-    // TODO: This doesn't actually work but it's good enough for now.
-    // #[test]
+    #[test]
     fn test_sha256() {
         let input = vec![0, 1, 2, 3];
         let expected: [u8; 32] = [
             5, 78, 222, 193, 208, 33, 31, 98, 79, 237, 12, 188, 169, 212, 249, 64, 11, 14, 73, 28,
             67, 116, 42, 242, 197, 176, 171, 235, 240, 201, 144, 216,
         ];
-        // 054edec1d0211f624fed0cbca9d4f9400b0e491c43742af2c5b0abebf0c990d8
 
         assert_eq!(sha256(&input), expected)
     }