From 8c8154f733b3d1a79cbc7232353839f49db07811 Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Tue, 11 Aug 2026 17:54:16 -0400 Subject: [PATCH 01/15] Cargo init --- .gitignore | 5 +++++ Cargo.toml | 6 ++++++ src/main.rs | 3 +++ 3 files changed, 14 insertions(+) create mode 100644 Cargo.toml create mode 100644 src/main.rs diff --git a/.gitignore b/.gitignore index ad67955..0728338 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,8 @@ target # and can be added to the global gitignore or merged into this file. For a more nuclear # option (not recommended) you can uncomment the following to ignore the entire idea folder. #.idea/ + + +# Added by cargo + +/target diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..d50c3f0 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "enclave-server" +version = "0.1.0" +edition = "2024" + +[dependencies] diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..e7a11a9 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} From 531881aafedf41fdc9dbd7597e97c3b04ba2226b Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Tue, 11 Aug 2026 18:27:12 -0400 Subject: [PATCH 02/15] Cargo lock --- Cargo.lock | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 Cargo.lock diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..73e52bc --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "enclave-server" +version = "0.1.0" From 0e8dbdd549368453cafa6abdb2ac7dd81bf05c8b Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Tue, 11 Aug 2026 18:38:33 -0400 Subject: [PATCH 03/15] Axum hello world --- Cargo.lock | 489 ++++++++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 2 + src/main.rs | 12 +- 3 files changed, 501 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 73e52bc..721aca8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,495 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + +[[package]] +name = "axum" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31b698c5f9a010f6573133b09e0de5408834d0c82f8d7475a89fc1867a71cd90" +dependencies = [ + "axum-core", + "bytes", + "form_urlencoded", + "futures-util", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-util", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "serde_core", + "serde_json", + "serde_path_to_error", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tower", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "axum-core" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08c78f31d7b1291f7ee735c1c6780ccde7785daae9a9206026862dab7d8792d1" +dependencies = [ + "bytes", + "futures-core", + "http", + "http-body", + "http-body-util", + "mime", + "pin-project-lite", + "sync_wrapper", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "bytes" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04" + [[package]] name = "enclave-server" version = "0.1.0" +dependencies = [ + "axum", + "tokio", +] + +[[package]] +name = "form_urlencoded" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "futures-channel" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f9e3d69d39e4862ffed03ed071a76f9a13ba1d9109d355b0f0aa6b15e393c4" +dependencies = [ + "futures-core", +] + +[[package]] +name = "futures-core" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92d699e522242e69e3003b94ecc1f960f3a5e015aa7c5d7486e65ad01dd94f5e" + +[[package]] +name = "futures-task" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd417de3d1d015fc3bfd2b1ea46dfc7bab72ef86f1cc7cc9c78e728b34a6d1fd" + +[[package]] +name = "futures-util" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d50a92467f8ba5dd6e3ee5d4bd04d73ab2e4e1c44474a0674821dfce14b79bc" +dependencies = [ + "futures-core", + "futures-task", + "pin-project-lite", + "slab", +] + +[[package]] +name = "http" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "918d3568bebf352712bc2ef3d46a8bcf1a75b373be6539de198e9105cbbf9ce0" +dependencies = [ + "bytes", + "itoa", +] + +[[package]] +name = "http-body" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2a8f2913ee65f60facd6a5905613afaa448497a0230cc41ce022d93290bc2c" +dependencies = [ + "bytes", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9f41fd6a08e4d4ec69df65976da761afd5ad5e58a9d4acb46bd1c953a9e3ff2" +dependencies = [ + "bytes", + "futures-core", + "http", + "http-body", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "hyper" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d22053281f852e11534f5198498373cbb59295120a20771d90f7ed1897490a72" +dependencies = [ + "atomic-waker", + "bytes", + "futures-channel", + "futures-core", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", +] + +[[package]] +name = "hyper-util" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" +dependencies = [ + "bytes", + "http", + "http-body", + "hyper", + "pin-project-lite", + "tokio", + "tower-service", +] + +[[package]] +name = "itoa" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" + +[[package]] +name = "libc" +version = "0.2.189" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2" + +[[package]] +name = "log" +version = "0.4.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad" + +[[package]] +name = "matchit" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3" + +[[package]] +name = "memchr" +version = "2.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "mio" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30d65c71f1ce40ab09135ce117d742b9f8a19ff91a41a8b57ed50bc2de59c427" +dependencies = [ + "libc", + "wasi", + "windows-sys", +] + +[[package]] +name = "once_cell" +version = "1.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" + +[[package]] +name = "percent-encoding" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" + +[[package]] +name = "pin-project-lite" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" + +[[package]] +name = "proc-macro2" +version = "1.0.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "ryu" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" + +[[package]] +name = "serde" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba" +dependencies = [ + "serde_core", +] + +[[package]] +name = "serde_core" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.151" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14" +dependencies = [ + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "serde_path_to_error" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10a9ff822e371bb5403e391ecd83e182e0e77ba7f6fe0160b795797109d1b457" +dependencies = [ + "itoa", + "serde", + "serde_core", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "slab" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" + +[[package]] +name = "smallvec" +version = "1.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" + +[[package]] +name = "socket2" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d1e2c7f27f8d4cb10542a02c49005dbd6e93095799d6f3be745fae9f8fedd4" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "syn" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53e9bae58849f64dfa4f5d5ae372c8341f7305f82a3868709269343628b659a3" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sync_wrapper" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" + +[[package]] +name = "tokio" +version = "1.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "202caea871b69668250d242070849eb495be178ed697a3e98aebce5bc81a0bed" +dependencies = [ + "libc", + "mio", + "pin-project-lite", + "socket2", + "tokio-macros", + "windows-sys", +] + +[[package]] +name = "tokio-macros" +version = "2.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78773a2a397f451582ce068015985c33193cf6dea8b74d2a639fe457b2f07b0e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tower" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" +dependencies = [ + "futures-core", + "futures-util", + "pin-project-lite", + "sync_wrapper", + "tokio", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + +[[package]] +name = "tracing" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" +dependencies = [ + "log", + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" +dependencies = [ + "once_cell", +] + +[[package]] +name = "unicode-ident" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" + +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + +[[package]] +name = "zmij" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" diff --git a/Cargo.toml b/Cargo.toml index d50c3f0..24a468e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,3 +4,5 @@ version = "0.1.0" edition = "2024" [dependencies] +axum = "0.8.9" +tokio = { version = "1.53.1", features = ["rt", "rt-multi-thread", "macros", "sync"] } diff --git a/src/main.rs b/src/main.rs index e7a11a9..cc74903 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,11 @@ -fn main() { - println!("Hello, world!"); +use axum::{Router, routing::get}; + +#[tokio::main] +async fn main() { + // build our application with a single route + let app = Router::new().route("/", get(|| async { "Hello, World!" })); + + // run our app with hyper, listening globally on port 3000 + let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap(); + axum::serve(listener, app).await.unwrap(); } From cf45fdd2b3cb2c079e7d75c33432049e7751da41 Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Tue, 11 Aug 2026 18:44:54 -0400 Subject: [PATCH 04/15] Axum ws --- Cargo.lock | 254 ++++++++++++++++++++++++++++++++++++++++++++++++++++- Cargo.toml | 2 +- 2 files changed, 253 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 721aca8..eb538d5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -15,6 +15,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "31b698c5f9a010f6573133b09e0de5408834d0c82f8d7475a89fc1867a71cd90" dependencies = [ "axum-core", + "base64", "bytes", "form_urlencoded", "futures-util", @@ -33,8 +34,10 @@ dependencies = [ "serde_json", "serde_path_to_error", "serde_urlencoded", + "sha1", "sync_wrapper", "tokio", + "tokio-tungstenite", "tower", "tower-layer", "tower-service", @@ -60,12 +63,68 @@ dependencies = [ "tracing", ] +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + [[package]] name = "bytes" version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04" +[[package]] +name = "cfg-if" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + +[[package]] +name = "crypto-common" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "data-encoding" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4583a4551df46e2792f82ceeac45e850d2e2d5debba0b91f102385cda5b11f06" + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", +] + [[package]] name = "enclave-server" version = "0.1.0" @@ -98,6 +157,12 @@ version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92d699e522242e69e3003b94ecc1f960f3a5e015aa7c5d7486e65ad01dd94f5e" +[[package]] +name = "futures-sink" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1944426bf7d03f1d14f708785e4b33efd750b36d48a157b836b3efc15ede8e1d" + [[package]] name = "futures-task" version = "0.3.34" @@ -111,11 +176,34 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d50a92467f8ba5dd6e3ee5d4bd04d73ab2e4e1c44474a0674821dfce14b79bc" dependencies = [ "futures-core", + "futures-sink", "futures-task", "pin-project-lite", "slab", ] +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasip2", +] + [[package]] name = "http" version = "1.5.0" @@ -261,6 +349,15 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + [[package]] name = "proc-macro2" version = "1.0.107" @@ -279,6 +376,41 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + +[[package]] +name = "rand" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9ef1d0d795eb7d84685bca4f72f3649f064e6641543d3a8c415898726a57b41" +dependencies = [ + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" +dependencies = [ + "getrandom", +] + [[package]] name = "ryu" version = "1.0.23" @@ -311,7 +443,7 @@ checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.3", ] [[package]] @@ -350,6 +482,17 @@ dependencies = [ "serde", ] +[[package]] +name = "sha1" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a978451301f4db1d02937a4ab3ccce137717b81826e79b7d49ffe3244a13c3b8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + [[package]] name = "slab" version = "0.4.12" @@ -372,6 +515,17 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "syn" +version = "2.0.119" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "syn" version = "3.0.3" @@ -389,12 +543,33 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" +[[package]] +name = "thiserror" +version = "2.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec86235f5fcc2a73650310756d2ac5b138a5780bbbdfae3eeccec992c435ba4f" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc04cd3e1236dd4a98afca4569f2deb3f120e5422a4023be2cb683f8486292af" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.3", +] + [[package]] name = "tokio" version = "1.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "202caea871b69668250d242070849eb495be178ed697a3e98aebce5bc81a0bed" dependencies = [ + "bytes", "libc", "mio", "pin-project-lite", @@ -411,7 +586,19 @@ checksum = "78773a2a397f451582ce068015985c33193cf6dea8b74d2a639fe457b2f07b0e" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.3", +] + +[[package]] +name = "tokio-tungstenite" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f72a05e828585856dacd553fba484c242c46e391fb0e58917c942ee9202915c" +dependencies = [ + "futures-util", + "log", + "tokio", + "tungstenite", ] [[package]] @@ -462,18 +649,55 @@ dependencies = [ "once_cell", ] +[[package]] +name = "tungstenite" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c01152af293afb9c7c2a57e4b559c5620b421f6d133261c60dd2d0cdb38e6b8" +dependencies = [ + "bytes", + "data-encoding", + "http", + "httparse", + "log", + "rand", + "sha1", + "thiserror", +] + +[[package]] +name = "typenum" +version = "1.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" + [[package]] name = "unicode-ident" version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + [[package]] name = "wasi" version = "0.11.1+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" +[[package]] +name = "wasip2" +version = "1.0.4+wasi-0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b67efb37e106e55ce722a510d6b5f9c17f083e5fc79afc2badeb12cc313d9487" +dependencies = [ + "wit-bindgen", +] + [[package]] name = "windows-link" version = "0.2.1" @@ -489,6 +713,32 @@ dependencies = [ "windows-link", ] +[[package]] +name = "wit-bindgen" +version = "0.57.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" + +[[package]] +name = "zerocopy" +version = "0.8.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "556764e583adb45a9f8d413c2a147fa7e8d821e48e12b14fd560b607998b75eb" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2ab42fc20575779bd240faa45f94a74256f755c0fa9e89f0ede20d91d0cdfc1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + [[package]] name = "zmij" version = "1.0.23" diff --git a/Cargo.toml b/Cargo.toml index 24a468e..7a1cdad 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,5 +4,5 @@ version = "0.1.0" edition = "2024" [dependencies] -axum = "0.8.9" +axum = { version = "0.8.9", features = ["ws"] } tokio = { version = "1.53.1", features = ["rt", "rt-multi-thread", "macros", "sync"] } From 4fd4f96521ccdacd04dd2f93b1dd330f07768fee Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Tue, 11 Aug 2026 19:09:37 -0400 Subject: [PATCH 05/15] Protocol --- Cargo.lock | 7 +++++++ Cargo.toml | 1 + src/main.rs | 28 ++++++++++++++++++++++++---- src/protocol/initialize.rs | 11 +++++++++++ src/protocol/mod.rs | 22 ++++++++++++++++++++++ 5 files changed, 65 insertions(+), 4 deletions(-) create mode 100644 src/protocol/initialize.rs create mode 100644 src/protocol/mod.rs diff --git a/Cargo.lock b/Cargo.lock index eb538d5..de0cd96 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,12 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "anyhow" +version = "1.0.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470" + [[package]] name = "atomic-waker" version = "1.1.2" @@ -129,6 +135,7 @@ dependencies = [ name = "enclave-server" version = "0.1.0" dependencies = [ + "anyhow", "axum", "tokio", ] diff --git a/Cargo.toml b/Cargo.toml index 7a1cdad..1ca7234 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,5 +4,6 @@ version = "0.1.0" edition = "2024" [dependencies] +anyhow = "1.0.104" axum = { version = "0.8.9", features = ["ws"] } tokio = { version = "1.53.1", features = ["rt", "rt-multi-thread", "macros", "sync"] } diff --git a/src/main.rs b/src/main.rs index cc74903..0b6f08c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,11 +1,31 @@ -use axum::{Router, routing::get}; +pub mod protocol; + +use axum::{ + Router, + extract::{WebSocketUpgrade, ws::WebSocket}, + response::Response, + routing::{any, get}, +}; + +use crate::protocol::Client; #[tokio::main] async fn main() { - // build our application with a single route - let app = Router::new().route("/", get(|| async { "Hello, World!" })); + let app = Router::new() + .route("/meta", get(|| async { "Hello, World!" })) + .route("/", any(ws_handler)); - // run our app with hyper, listening globally on port 3000 let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap(); axum::serve(listener, app).await.unwrap(); } + +async fn ws_handler(ws: WebSocketUpgrade) -> Response { + ws.on_upgrade(|socket: WebSocket| async { + match Client::initialize(socket).await { + Ok(client) => {} + Err(e) => { + eprintln!("Failed to initialize client {e}") + } + } + }) +} diff --git a/src/protocol/initialize.rs b/src/protocol/initialize.rs new file mode 100644 index 0000000..225e8ff --- /dev/null +++ b/src/protocol/initialize.rs @@ -0,0 +1,11 @@ +use axum::extract::ws::WebSocket; + +impl super::Client { + pub async fn initialize(mut socket: WebSocket) -> anyhow::Result { + Ok(Self { + socket, + meta: super::ClientMeta {}, + pub_key: String::new(), + }) + } +} diff --git a/src/protocol/mod.rs b/src/protocol/mod.rs new file mode 100644 index 0000000..8497cab --- /dev/null +++ b/src/protocol/mod.rs @@ -0,0 +1,22 @@ +use axum::extract::ws::WebSocket; + +pub mod initialize; + +pub struct Client { + pub socket: WebSocket, + pub meta: ClientMeta, + pub pub_key: String, +} + +pub struct ClientMeta {} + +pub enum ClientMessage {} + +pub enum ServerMessage {} + +impl Client { + pub async fn read_socket(mut socket: WebSocket) -> anyhow::Result { + unimplemented!() + // Ok(socket.recv().await?) + } +} From a902f7522d4b67dd92c4c5dd9b0911be1e71200b Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Tue, 11 Aug 2026 19:37:32 -0400 Subject: [PATCH 06/15] Protocol --- Cargo.lock | 3 ++ Cargo.toml | 2 ++ src/protocol/initialize.rs | 4 +++ src/protocol/mod.rs | 64 ++++++++++++++++++++++++++++++++++---- 4 files changed, 67 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index de0cd96..960b0f7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -137,6 +137,8 @@ version = "0.1.0" dependencies = [ "anyhow", "axum", + "serde", + "serde_json", "tokio", ] @@ -431,6 +433,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba" dependencies = [ "serde_core", + "serde_derive", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 1ca7234..8efba9b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,4 +6,6 @@ edition = "2024" [dependencies] anyhow = "1.0.104" axum = { version = "0.8.9", features = ["ws"] } +serde = { version = "1.0.229", features = ["serde_derive"] } +serde_json = "1.0.151" tokio = { version = "1.53.1", features = ["rt", "rt-multi-thread", "macros", "sync"] } diff --git a/src/protocol/initialize.rs b/src/protocol/initialize.rs index 225e8ff..4ee6b2b 100644 --- a/src/protocol/initialize.rs +++ b/src/protocol/initialize.rs @@ -1,7 +1,11 @@ use axum::extract::ws::WebSocket; +use super::*; + impl super::Client { pub async fn initialize(mut socket: WebSocket) -> anyhow::Result { + if let Some(ServerMessage::Initialize()) = Client::read_socket(&mut socket).await? {} + Ok(Self { socket, meta: super::ClientMeta {}, diff --git a/src/protocol/mod.rs b/src/protocol/mod.rs index 8497cab..43b30f3 100644 --- a/src/protocol/mod.rs +++ b/src/protocol/mod.rs @@ -1,4 +1,5 @@ -use axum::extract::ws::WebSocket; +use axum::extract::ws::{Message, Utf8Bytes, WebSocket}; +use serde::{Deserialize, Serialize}; pub mod initialize; @@ -8,15 +9,66 @@ pub struct Client { pub pub_key: String, } +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct ClientMeta {} -pub enum ClientMessage {} +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum ClientMessage<'a> { + Error(&'a str), +} -pub enum ServerMessage {} +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum ServerMessage { + Initialize(), +} impl Client { - pub async fn read_socket(mut socket: WebSocket) -> anyhow::Result { - unimplemented!() - // Ok(socket.recv().await?) + pub async fn read_socket(socket: &mut WebSocket) -> anyhow::Result> { + match socket.recv().await.transpose()? { + Some(Message::Text(text)) => { + if let Ok(msg) = serde_json::from_str(&text.to_string()) { + Ok(Some(msg)) + } else { + Client::send_socket( + socket, + ClientMessage::Error("Unable to parse message: {text}"), + ) + .await?; + + Ok(None) + } + } + + Some(Message::Ping(v)) => { + socket.send(Message::Pong(v)).await?; + + Ok(None) + } + + Some(_) => Ok(None), + + None => Ok(None), + } + } + + pub async fn send_socket<'a>( + socket: &mut WebSocket, + message: ClientMessage<'a>, + ) -> anyhow::Result<()> { + socket + .send(Message::Text(Utf8Bytes::from(serde_json::to_string( + &message, + )?))) + .await?; + + Ok(()) + } + + pub async fn read(&mut self) -> anyhow::Result> { + Self::read_socket(&mut self.socket).await + } + + pub async fn send<'a>(&mut self, message: ClientMessage<'a>) -> anyhow::Result<()> { + Self::send_socket(&mut self.socket, message).await } } From 0438bade23b6c2e7b5d7af72387ced8864728b18 Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Tue, 11 Aug 2026 20:25:26 -0400 Subject: [PATCH 07/15] Protocol --- src/protocol/initialize.rs | 33 ++++++++++++++++++++++++++-- src/protocol/mod.rs | 44 +++++++++++++++++++++++++++----------- 2 files changed, 62 insertions(+), 15 deletions(-) diff --git a/src/protocol/initialize.rs b/src/protocol/initialize.rs index 4ee6b2b..5053570 100644 --- a/src/protocol/initialize.rs +++ b/src/protocol/initialize.rs @@ -4,12 +4,41 @@ use super::*; impl super::Client { pub async fn initialize(mut socket: WebSocket) -> anyhow::Result { - if let Some(ServerMessage::Initialize()) = Client::read_socket(&mut socket).await? {} + let Some(ServerMethod::Initialize { + public_key, + timestamp, + signature, + }) = Client::read_socket(&mut socket).await? + else { + Client::send_socket( + &mut socket, + ClientMethod::Error { + error: Cow::Borrowed( + "Failed to initialize, unexpected method, expected: initialize", + ), + }, + ) + .await?; + + return Err(anyhow::anyhow!( + "Failed to initialize: Client sent the wrong method" + )); + }; + + Client::send_socket( + &mut socket, + ClientMethod::Initialized { + public_key, + timestamp, + signature, + }, + ) + .await?; Ok(Self { socket, meta: super::ClientMeta {}, - pub_key: String::new(), + public_key: String::new(), }) } } diff --git a/src/protocol/mod.rs b/src/protocol/mod.rs index 43b30f3..47e4e90 100644 --- a/src/protocol/mod.rs +++ b/src/protocol/mod.rs @@ -1,3 +1,5 @@ +use std::borrow::Cow; + use axum::extract::ws::{Message, Utf8Bytes, WebSocket}; use serde::{Deserialize, Serialize}; @@ -6,24 +8,41 @@ pub mod initialize; pub struct Client { pub socket: WebSocket, pub meta: ClientMeta, - pub pub_key: String, + pub public_key: String, } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ClientMeta {} #[derive(Debug, Clone, Serialize, Deserialize)] -pub enum ClientMessage<'a> { - Error(&'a str), +#[serde(tag = "method")] +pub enum ClientMethod { + Initialized { + public_key: String, + timestamp: u64, + signature: String, + }, + + #[serde(rename = "error")] + Error { error: Cow<'static, str> }, } #[derive(Debug, Clone, Serialize, Deserialize)] -pub enum ServerMessage { - Initialize(), +#[serde(tag = "method")] +pub enum ServerMethod { + Initialize { + public_key: String, + timestamp: u64, + signature: String, + }, + + Error { + error: String, + }, } impl Client { - pub async fn read_socket(socket: &mut WebSocket) -> anyhow::Result> { + pub async fn read_socket(socket: &mut WebSocket) -> anyhow::Result> { match socket.recv().await.transpose()? { Some(Message::Text(text)) => { if let Ok(msg) = serde_json::from_str(&text.to_string()) { @@ -31,7 +50,9 @@ impl Client { } else { Client::send_socket( socket, - ClientMessage::Error("Unable to parse message: {text}"), + ClientMethod::Error { + error: Cow::Borrowed("Unable to parse message: {text}"), + }, ) .await?; @@ -51,10 +72,7 @@ impl Client { } } - pub async fn send_socket<'a>( - socket: &mut WebSocket, - message: ClientMessage<'a>, - ) -> anyhow::Result<()> { + pub async fn send_socket(socket: &mut WebSocket, message: ClientMethod) -> anyhow::Result<()> { socket .send(Message::Text(Utf8Bytes::from(serde_json::to_string( &message, @@ -64,11 +82,11 @@ impl Client { Ok(()) } - pub async fn read(&mut self) -> anyhow::Result> { + pub async fn read(&mut self) -> anyhow::Result> { Self::read_socket(&mut self.socket).await } - pub async fn send<'a>(&mut self, message: ClientMessage<'a>) -> anyhow::Result<()> { + pub async fn send(&mut self, message: ClientMethod) -> anyhow::Result<()> { Self::send_socket(&mut self.socket, message).await } } From 180e7ec4ce0e6fb33ec7da4515e2a14b32294460 Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Tue, 11 Aug 2026 21:02:26 -0400 Subject: [PATCH 08/15] read loop --- src/main.rs | 11 +++++++++-- src/protocol/mod.rs | 24 ++++++++++++++++++++++-- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/src/main.rs b/src/main.rs index 0b6f08c..df8bf2c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -22,9 +22,16 @@ async fn main() { async fn ws_handler(ws: WebSocketUpgrade) -> Response { ws.on_upgrade(|socket: WebSocket| async { match Client::initialize(socket).await { - Ok(client) => {} + Ok(mut client) => { + if let Err(e) = client.read_loop().await { + eprintln!("Failed to handle client: {e}"); + } else { + println!("Client connection closed") + } + } + Err(e) => { - eprintln!("Failed to initialize client {e}") + eprintln!("Failed to initialize client: {e}") } } }) diff --git a/src/protocol/mod.rs b/src/protocol/mod.rs index 47e4e90..1bd8dfa 100644 --- a/src/protocol/mod.rs +++ b/src/protocol/mod.rs @@ -23,8 +23,9 @@ pub enum ClientMethod { signature: String, }, - #[serde(rename = "error")] - Error { error: Cow<'static, str> }, + Error { + error: Cow<'static, str>, + }, } #[derive(Debug, Clone, Serialize, Deserialize)] @@ -42,6 +43,25 @@ pub enum ServerMethod { } impl Client { + pub async fn read_loop(&mut self) -> anyhow::Result<()> { + while let Some(message) = self.read().await? { + match message { + ServerMethod::Initialize { .. } => { + self.send(ClientMethod::Error { + error: Cow::Borrowed("Already initialized"), + }) + .await?; + } + + ServerMethod::Error { error } => { + eprintln!("Client error: {error}"); + } + } + } + + Ok(()) + } + pub async fn read_socket(socket: &mut WebSocket) -> anyhow::Result> { match socket.recv().await.transpose()? { Some(Message::Text(text)) => { From 79366a28d091533529630d1852c1b36e57f5865d Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Tue, 11 Aug 2026 21:30:27 -0400 Subject: [PATCH 09/15] updated init message --- src/protocol/initialize.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/protocol/initialize.rs b/src/protocol/initialize.rs index 5053570..f03b58f 100644 --- a/src/protocol/initialize.rs +++ b/src/protocol/initialize.rs @@ -13,9 +13,7 @@ impl super::Client { Client::send_socket( &mut socket, ClientMethod::Error { - error: Cow::Borrowed( - "Failed to initialize, unexpected method, expected: initialize", - ), + error: Cow::Borrowed("Initialization required"), }, ) .await?; From c910769eb3f4a8e9286e2f80d4c2515bc4000765 Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Tue, 11 Aug 2026 22:07:02 -0400 Subject: [PATCH 10/15] Server structure --- Cargo.lock | 200 +++++++++++++++++++++++++++++++++++++++++++++-- Cargo.toml | 4 +- src/main.rs | 40 +++++----- src/server.rs | 41 ++++++++++ src/signature.rs | 21 +++++ 5 files changed, 278 insertions(+), 28 deletions(-) create mode 100644 src/server.rs create mode 100644 src/signature.rs diff --git a/Cargo.lock b/Cargo.lock index 960b0f7..1f732b0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -75,6 +75,12 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +[[package]] +name = "base64ct" +version = "1.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06" + [[package]] name = "block-buffer" version = "0.10.4" @@ -96,6 +102,12 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + [[package]] name = "cpufeatures" version = "0.2.17" @@ -115,12 +127,49 @@ dependencies = [ "typenum", ] +[[package]] +name = "curve25519-dalek" +version = "4.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" +dependencies = [ + "cfg-if", + "cpufeatures", + "curve25519-dalek-derive", + "digest", + "fiat-crypto", + "rustc_version", + "subtle", + "zeroize", +] + +[[package]] +name = "curve25519-dalek-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + [[package]] name = "data-encoding" version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4583a4551df46e2792f82ceeac45e850d2e2d5debba0b91f102385cda5b11f06" +[[package]] +name = "der" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" +dependencies = [ + "const-oid", + "zeroize", +] + [[package]] name = "digest" version = "0.10.7" @@ -131,17 +180,50 @@ dependencies = [ "crypto-common", ] +[[package]] +name = "ed25519" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" +dependencies = [ + "pkcs8", + "signature", +] + +[[package]] +name = "ed25519-dalek" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70e796c081cee67dc755e1a36a0a172b897fab85fc3f6bc48307991f64e4eca9" +dependencies = [ + "curve25519-dalek", + "ed25519", + "rand_core 0.6.4", + "serde", + "sha2", + "subtle", + "zeroize", +] + [[package]] name = "enclave-server" version = "0.1.0" dependencies = [ "anyhow", "axum", + "ed25519-dalek", + "rand 0.8.7", "serde", "serde_json", "tokio", ] +[[package]] +name = "fiat-crypto" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" + [[package]] name = "form_urlencoded" version = "1.2.2" @@ -201,6 +283,17 @@ dependencies = [ "version_check", ] +[[package]] +name = "getrandom" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + [[package]] name = "getrandom" version = "0.3.4" @@ -358,6 +451,16 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + [[package]] name = "ppv-lite86" version = "0.2.21" @@ -391,14 +494,35 @@ version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" +[[package]] +name = "rand" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22f6172bdec972074665ed81ed53b71da00bfc44b65a753cfde883ec4c702a1a" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + [[package]] name = "rand" version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9ef1d0d795eb7d84685bca4f72f3649f064e6641543d3a8c415898726a57b41" dependencies = [ - "rand_chacha", - "rand_core", + "rand_chacha 0.9.0", + "rand_core 0.9.5", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", ] [[package]] @@ -408,7 +532,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.9.5", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.17", ] [[package]] @@ -417,7 +550,16 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" dependencies = [ - "getrandom", + "getrandom 0.3.4", +] + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", ] [[package]] @@ -426,6 +568,12 @@ version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" +[[package]] +name = "semver" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" + [[package]] name = "serde" version = "1.0.229" @@ -503,6 +651,26 @@ dependencies = [ "digest", ] +[[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "rand_core 0.6.4", +] + [[package]] name = "slab" version = "0.4.12" @@ -525,6 +693,22 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + [[package]] name = "syn" version = "2.0.119" @@ -670,7 +854,7 @@ dependencies = [ "http", "httparse", "log", - "rand", + "rand 0.9.5", "sha1", "thiserror", ] @@ -749,6 +933,12 @@ dependencies = [ "syn 2.0.119", ] +[[package]] +name = "zeroize" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e" + [[package]] name = "zmij" version = "1.0.23" diff --git a/Cargo.toml b/Cargo.toml index 8efba9b..0a5a099 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,4 +8,6 @@ anyhow = "1.0.104" axum = { version = "0.8.9", features = ["ws"] } serde = { version = "1.0.229", features = ["serde_derive"] } serde_json = "1.0.151" -tokio = { version = "1.53.1", features = ["rt", "rt-multi-thread", "macros", "sync"] } +tokio = { version = "1.53.1", features = ["rt", "rt-multi-thread", "macros", "sync", "fs"] } +ed25519-dalek = { version = "2", features = ["rand_core"] } +rand = "0.8" diff --git a/src/main.rs b/src/main.rs index df8bf2c..5acf2b6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,38 +1,34 @@ pub mod protocol; +pub mod server; +pub mod signature; + +use std::sync::Arc; use axum::{ Router, - extract::{WebSocketUpgrade, ws::WebSocket}, + extract::{State, WebSocketUpgrade}, response::Response, routing::{any, get}, }; -use crate::protocol::Client; +use crate::server::Server; #[tokio::main] -async fn main() { +async fn main() -> anyhow::Result<()> { + let server = Server::new().await?; + let app = Router::new() .route("/meta", get(|| async { "Hello, World!" })) - .route("/", any(ws_handler)); + .route("/", any(ws_handler)) + .with_state(server); - let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap(); - axum::serve(listener, app).await.unwrap(); + let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await?; + + axum::serve(listener, app).await?; + + Ok(()) } -async fn ws_handler(ws: WebSocketUpgrade) -> Response { - ws.on_upgrade(|socket: WebSocket| async { - match Client::initialize(socket).await { - Ok(mut client) => { - if let Err(e) = client.read_loop().await { - eprintln!("Failed to handle client: {e}"); - } else { - println!("Client connection closed") - } - } - - Err(e) => { - eprintln!("Failed to initialize client: {e}") - } - } - }) +async fn ws_handler(State(server): State>, ws: WebSocketUpgrade) -> Response { + server.ws_handler(ws).await } diff --git a/src/server.rs b/src/server.rs new file mode 100644 index 0000000..eff425d --- /dev/null +++ b/src/server.rs @@ -0,0 +1,41 @@ +use std::sync::Arc; + +use axum::{ + extract::{WebSocketUpgrade, ws::WebSocket}, + response::Response, +}; +use ed25519_dalek::SigningKey; + +use crate::protocol::Client; + +pub struct Server { + pub key: SigningKey, +} + +impl Server { + pub async fn new() -> anyhow::Result> { + Ok(Arc::new(Self { + key: crate::signature::get().await?, + })) + } +} + +impl Server { + pub async fn ws_handler(self: &Arc, ws: WebSocketUpgrade) -> Response { + ws.on_upgrade(|socket: WebSocket| async { + match Client::initialize(socket).await { + Ok(mut client) => { + if let Err(e) = client.read_loop().await { + eprintln!("Failed to handle client: {e}"); + } else { + println!("Client connection closed") + } + } + + Err(e) => { + eprintln!("Failed to initialize client: {e}") + } + } + }) + } +} diff --git a/src/signature.rs b/src/signature.rs new file mode 100644 index 0000000..2c95e85 --- /dev/null +++ b/src/signature.rs @@ -0,0 +1,21 @@ +use std::path::PathBuf; + +use ed25519_dalek::SigningKey; +use rand::rngs::OsRng; + +pub async fn get() -> anyhow::Result { + let private_key_path = PathBuf::from("private.key"); + + if !private_key_path.exists() { + let key = SigningKey::generate(&mut OsRng); + tokio::fs::write(private_key_path, &key.to_bytes()).await?; + Ok(key) + } else { + Ok(SigningKey::from_bytes( + &tokio::fs::read(private_key_path) + .await? + .try_into() + .map_err(|_| anyhow::anyhow!("Invalid private key"))?, + )) + } +} From d5d79a73a2c832cced481d62ed24e6a74277969a Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Tue, 11 Aug 2026 22:27:37 -0400 Subject: [PATCH 11/15] Server config --- .gitignore | 3 +++ src/config.rs | 35 +++++++++++++++++++++++++++++++++++ src/main.rs | 1 + src/protocol/mod.rs | 6 ++++++ src/server.rs | 4 +++- 5 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 src/config.rs diff --git a/.gitignore b/.gitignore index 0728338..57c39e9 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,6 @@ target # Added by cargo /target + +private.key +config.json diff --git a/src/config.rs b/src/config.rs new file mode 100644 index 0000000..656a55d --- /dev/null +++ b/src/config.rs @@ -0,0 +1,35 @@ +use std::path::PathBuf; + +use serde::{Deserialize, Serialize}; + +use crate::protocol::ServerMeta; + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct Config { + pub meta: ServerMeta, +} + +impl Config { + pub fn new() -> Self { + Self { + meta: ServerMeta { + name: "New Server".to_string(), + description: String::new(), + }, + } + } + + pub async fn get() -> anyhow::Result { + let config_path = PathBuf::from("config.json"); + + if !config_path.exists() { + let config = Config::new(); + tokio::fs::write(config_path, &serde_json::to_string_pretty(&config)?).await?; + Ok(config) + } else { + Ok(serde_json::from_str( + &tokio::fs::read_to_string(config_path).await?, + )?) + } + } +} diff --git a/src/main.rs b/src/main.rs index 5acf2b6..26aaa8c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,4 @@ +pub mod config; pub mod protocol; pub mod server; pub mod signature; diff --git a/src/protocol/mod.rs b/src/protocol/mod.rs index 1bd8dfa..e7ead39 100644 --- a/src/protocol/mod.rs +++ b/src/protocol/mod.rs @@ -14,6 +14,12 @@ pub struct Client { #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ClientMeta {} +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct ServerMeta { + pub name: String, + pub description: String, +} + #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(tag = "method")] pub enum ClientMethod { diff --git a/src/server.rs b/src/server.rs index eff425d..c57c2b3 100644 --- a/src/server.rs +++ b/src/server.rs @@ -6,16 +6,18 @@ use axum::{ }; use ed25519_dalek::SigningKey; -use crate::protocol::Client; +use crate::{config::Config, protocol::Client}; pub struct Server { pub key: SigningKey, + pub config: Config, } impl Server { pub async fn new() -> anyhow::Result> { Ok(Arc::new(Self { key: crate::signature::get().await?, + config: Config::get().await?, })) } } From aacb11bc013a87f980e768507696cec87306f7f5 Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Tue, 11 Aug 2026 22:45:17 -0400 Subject: [PATCH 12/15] meta --- src/main.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main.rs b/src/main.rs index 26aaa8c..a4db3c4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -19,7 +19,7 @@ async fn main() -> anyhow::Result<()> { let server = Server::new().await?; let app = Router::new() - .route("/meta", get(|| async { "Hello, World!" })) + .route("/meta", get(meta)) .route("/", any(ws_handler)) .with_state(server); @@ -30,6 +30,10 @@ async fn main() -> anyhow::Result<()> { Ok(()) } +async fn meta(State(server): State>) -> String { + serde_json::to_string(&server.config.meta.clone()).unwrap() +} + async fn ws_handler(State(server): State>, ws: WebSocketUpgrade) -> Response { server.ws_handler(ws).await } From 019c2888cbf49527486675029ecafda166aad4dd Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Tue, 11 Aug 2026 23:43:56 -0400 Subject: [PATCH 13/15] Proper signature management --- Cargo.lock | 25 +++++++++++++++++++++++++ Cargo.toml | 1 + src/protocol/initialize.rs | 31 +++++++++++++++++++++++++------ src/protocol/mod.rs | 4 ++-- src/server.rs | 6 ++++-- src/signature.rs | 24 +++++++++++++++++++++++- 6 files changed, 80 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1f732b0..b649c17 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -90,6 +90,15 @@ dependencies = [ "generic-array", ] +[[package]] +name = "bs58" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" +dependencies = [ + "tinyvec", +] + [[package]] name = "bytes" version = "1.12.1" @@ -211,6 +220,7 @@ version = "0.1.0" dependencies = [ "anyhow", "axum", + "bs58", "ed25519-dalek", "rand 0.8.7", "serde", @@ -757,6 +767,21 @@ dependencies = [ "syn 3.0.3", ] +[[package]] +name = "tinyvec" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb4ebadaa0af04fab11ae01eb5f9fdb5f9c5b875506e210e71c07873528baa7f" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + [[package]] name = "tokio" version = "1.53.1" diff --git a/Cargo.toml b/Cargo.toml index 0a5a099..3072733 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,3 +11,4 @@ serde_json = "1.0.151" tokio = { version = "1.53.1", features = ["rt", "rt-multi-thread", "macros", "sync", "fs"] } ed25519-dalek = { version = "2", features = ["rand_core"] } rand = "0.8" +bs58 = "0.5.1" diff --git a/src/protocol/initialize.rs b/src/protocol/initialize.rs index f03b58f..2bea02a 100644 --- a/src/protocol/initialize.rs +++ b/src/protocol/initialize.rs @@ -1,11 +1,16 @@ +use std::sync::Arc; + use axum::extract::ws::WebSocket; +use ed25519_dalek::Signer; + +use crate::server::Server; use super::*; impl super::Client { - pub async fn initialize(mut socket: WebSocket) -> anyhow::Result { + pub async fn initialize(server: &Arc, mut socket: WebSocket) -> anyhow::Result { let Some(ServerMethod::Initialize { - public_key, + public_key: public_key_string, timestamp, signature, }) = Client::read_socket(&mut socket).await? @@ -23,12 +28,26 @@ impl super::Client { )); }; + let public_key = crate::signature::from_string(&public_key_string)?; + + if public_key + .verify_strict( + format!("{public_key_string}@{timestamp}@").as_bytes(), + &crate::signature::from_string_sig(&signature)?, + ) + .is_ok() + { + return Err(anyhow::anyhow!("Invalid signature")); + } + Client::send_socket( &mut socket, ClientMethod::Initialized { - public_key, - timestamp, - signature, + public_key: crate::signature::to_string(&server.key.verifying_key()), + signature: server + .key + .sign(format!("{public_key_string}@{timestamp}").as_bytes()) + .to_string(), }, ) .await?; @@ -36,7 +55,7 @@ impl super::Client { Ok(Self { socket, meta: super::ClientMeta {}, - public_key: String::new(), + public_key, }) } } diff --git a/src/protocol/mod.rs b/src/protocol/mod.rs index e7ead39..4c517c9 100644 --- a/src/protocol/mod.rs +++ b/src/protocol/mod.rs @@ -1,6 +1,7 @@ use std::borrow::Cow; use axum::extract::ws::{Message, Utf8Bytes, WebSocket}; +use ed25519_dalek::VerifyingKey; use serde::{Deserialize, Serialize}; pub mod initialize; @@ -8,7 +9,7 @@ pub mod initialize; pub struct Client { pub socket: WebSocket, pub meta: ClientMeta, - pub public_key: String, + pub public_key: VerifyingKey, } #[derive(Debug, Clone, Serialize, Deserialize)] @@ -25,7 +26,6 @@ pub struct ServerMeta { pub enum ClientMethod { Initialized { public_key: String, - timestamp: u64, signature: String, }, diff --git a/src/server.rs b/src/server.rs index c57c2b3..0eb6d92 100644 --- a/src/server.rs +++ b/src/server.rs @@ -24,8 +24,10 @@ impl Server { impl Server { pub async fn ws_handler(self: &Arc, ws: WebSocketUpgrade) -> Response { - ws.on_upgrade(|socket: WebSocket| async { - match Client::initialize(socket).await { + let s = self.clone(); + + ws.on_upgrade(move |socket: WebSocket| async move { + match Client::initialize(&s, socket).await { Ok(mut client) => { if let Err(e) = client.read_loop().await { eprintln!("Failed to handle client: {e}"); diff --git a/src/signature.rs b/src/signature.rs index 2c95e85..851b9eb 100644 --- a/src/signature.rs +++ b/src/signature.rs @@ -1,6 +1,6 @@ use std::path::PathBuf; -use ed25519_dalek::SigningKey; +use ed25519_dalek::{Signature, SigningKey, VerifyingKey}; use rand::rngs::OsRng; pub async fn get() -> anyhow::Result { @@ -19,3 +19,25 @@ pub async fn get() -> anyhow::Result { )) } } + +pub fn to_string(key: &VerifyingKey) -> String { + bs58::encode(key.to_bytes()).into_string() +} + +pub fn from_string(key: &str) -> anyhow::Result { + Ok(VerifyingKey::from_bytes( + &bs58::decode(key) + .into_vec()? + .try_into() + .map_err(|_| anyhow::anyhow!("Invalid public key"))?, + )?) +} + +pub fn from_string_sig(signature: &str) -> anyhow::Result { + Ok(Signature::from_bytes( + &bs58::decode(signature) + .into_vec()? + .try_into() + .map_err(|_| anyhow::anyhow!("Invalid public key"))?, + )) +} From 9cc2014e551c72ba60ff57c8dba950b3718f9c1d Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Wed, 12 Aug 2026 09:04:30 -0400 Subject: [PATCH 14/15] Signature layout --- src/protocol/initialize.rs | 40 +++++++++++++++++++++++++------------- src/protocol/mod.rs | 7 ++++++- 2 files changed, 32 insertions(+), 15 deletions(-) diff --git a/src/protocol/initialize.rs b/src/protocol/initialize.rs index 2bea02a..97bfd4d 100644 --- a/src/protocol/initialize.rs +++ b/src/protocol/initialize.rs @@ -1,4 +1,7 @@ -use std::sync::Arc; +use std::{ + sync::Arc, + time::{SystemTime, UNIX_EPOCH}, +}; use axum::extract::ws::WebSocket; use ed25519_dalek::Signer; @@ -11,8 +14,10 @@ impl super::Client { pub async fn initialize(server: &Arc, mut socket: WebSocket) -> anyhow::Result { let Some(ServerMethod::Initialize { public_key: public_key_string, - timestamp, signature, + + timestamp, + hostname, }) = Client::read_socket(&mut socket).await? else { Client::send_socket( @@ -32,7 +37,7 @@ impl super::Client { if public_key .verify_strict( - format!("{public_key_string}@{timestamp}@").as_bytes(), + format!("{timestamp}@{hostname}").as_bytes(), &crate::signature::from_string_sig(&signature)?, ) .is_ok() @@ -40,17 +45,24 @@ impl super::Client { return Err(anyhow::anyhow!("Invalid signature")); } - Client::send_socket( - &mut socket, - ClientMethod::Initialized { - public_key: crate::signature::to_string(&server.key.verifying_key()), - signature: server - .key - .sign(format!("{public_key_string}@{timestamp}").as_bytes()) - .to_string(), - }, - ) - .await?; + { + let timestamp = SystemTime::now().duration_since(UNIX_EPOCH)?.as_secs(); + + Client::send_socket( + &mut socket, + ClientMethod::Initialized { + public_key: crate::signature::to_string(&server.key.verifying_key()), + signature: server + .key + .sign(format!("{timestamp}@{hostname}@{public_key_string}").as_bytes()) + .to_string(), + + timestamp, + hostname, + }, + ) + .await?; + } Ok(Self { socket, diff --git a/src/protocol/mod.rs b/src/protocol/mod.rs index 4c517c9..efbb987 100644 --- a/src/protocol/mod.rs +++ b/src/protocol/mod.rs @@ -27,6 +27,9 @@ pub enum ClientMethod { Initialized { public_key: String, signature: String, + + timestamp: u64, + hostname: String, }, Error { @@ -39,8 +42,10 @@ pub enum ClientMethod { pub enum ServerMethod { Initialize { public_key: String, - timestamp: u64, signature: String, + + timestamp: u64, + hostname: String, }, Error { From fbf8dfc6592f869a6aef64453e3248b438b9e93a Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Wed, 12 Aug 2026 09:08:01 -0400 Subject: [PATCH 15/15] Meta --- src/protocol/initialize.rs | 16 +++++++++++++++- src/protocol/mod.rs | 4 ++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/protocol/initialize.rs b/src/protocol/initialize.rs index 97bfd4d..40b4d79 100644 --- a/src/protocol/initialize.rs +++ b/src/protocol/initialize.rs @@ -64,9 +64,23 @@ impl super::Client { .await?; } + let Some(ServerMethod::Meta(meta)) = Client::read_socket(&mut socket).await? else { + Client::send_socket( + &mut socket, + ClientMethod::Error { + error: Cow::Borrowed("Expected meta"), + }, + ) + .await?; + + return Err(anyhow::anyhow!( + "Expected meta, client called another method" + )); + }; + Ok(Self { socket, - meta: super::ClientMeta {}, + meta, public_key, }) } diff --git a/src/protocol/mod.rs b/src/protocol/mod.rs index efbb987..460530f 100644 --- a/src/protocol/mod.rs +++ b/src/protocol/mod.rs @@ -48,6 +48,8 @@ pub enum ServerMethod { hostname: String, }, + Meta(ClientMeta), + Error { error: String, }, @@ -64,6 +66,8 @@ impl Client { .await?; } + ServerMethod::Meta(meta) => {} + ServerMethod::Error { error } => { eprintln!("Client error: {error}"); }