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"))?, + )) + } +}