diff --git a/Cargo.lock b/Cargo.lock index f005138..cffcc97 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -76,6 +76,12 @@ version = "0.21.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + [[package]] name = "bitflags" version = "1.3.2" @@ -145,6 +151,12 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + [[package]] name = "core-foundation" version = "0.9.4" @@ -180,6 +192,34 @@ dependencies = [ "typenum", ] +[[package]] +name = "curve25519-dalek" +version = "4.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89b8c6a2e4b1f45971ad09761aafb85514a84744b67a95e32c3cc1352d1f65c" +dependencies = [ + "cfg-if", + "cpufeatures", + "curve25519-dalek-derive", + "digest", + "fiat-crypto", + "platforms", + "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.41", +] + [[package]] name = "dashmap" version = "5.5.3" @@ -199,6 +239,16 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" +[[package]] +name = "der" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +dependencies = [ + "const-oid", + "zeroize", +] + [[package]] name = "deranged" version = "0.3.10" @@ -219,6 +269,30 @@ dependencies = [ "subtle", ] +[[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.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f628eaec48bfd21b865dc2950cfa014450c01d2fa2b69a86c2fd5844ec523c0" +dependencies = [ + "curve25519-dalek", + "ed25519", + "serde", + "sha2", + "subtle", + "zeroize", +] + [[package]] name = "enum-as-inner" version = "0.5.1" @@ -252,6 +326,12 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" +[[package]] +name = "fiat-crypto" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27573eac26f4dd11e2b1916c3fe1baa56407c83c71a773a8ba17ec0bca03b6b7" + [[package]] name = "finl_unicode" version = "1.2.0" @@ -832,6 +912,22 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "platforms" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14e6ab3f592e6fb464fc9712d8d6e6912de6473954635fd76a589d832cffcbb0" + [[package]] name = "postgres-protocol" version = "0.6.6" @@ -902,12 +998,12 @@ name = "quizzo-api" version = "0.7.0" dependencies = [ "dashmap", + "ed25519-dalek", "hex", "http-body-util", "hyper 1.1.0", "log", "quizzo-db", - "ring 0.17.7", "serde_json", "tokio", "twilight-http", @@ -1015,6 +1111,15 @@ version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] + [[package]] name = "rustls" version = "0.20.9" @@ -1101,6 +1206,12 @@ dependencies = [ "libc", ] +[[package]] +name = "semver" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" + [[package]] name = "serde" version = "1.0.193" @@ -1173,6 +1284,15 @@ dependencies = [ "libc", ] +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "rand_core", +] + [[package]] name = "siphasher" version = "0.3.11" @@ -1216,6 +1336,16 @@ version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] + [[package]] name = "stringprep" version = "0.1.4" @@ -1804,3 +1934,9 @@ name = "windows_x86_64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "zeroize" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" diff --git a/crates/api/Cargo.toml b/crates/api/Cargo.toml index 148d6aa..194556b 100644 --- a/crates/api/Cargo.toml +++ b/crates/api/Cargo.toml @@ -6,11 +6,11 @@ edition = "2021" [dependencies] dashmap = { version = "5.5", default-features = false } db = { path = "../db", package = "quizzo-db" } +ed25519-dalek = "2.1" hex = { version = "0.4", default-features = false } http-body-util = "0.1.0" hyper = { version = "1", default-features = false } log = "0.4" -ring = { version = "0.17", default-features = false } serde_json = "1" twilight-model = "0.15" diff --git a/crates/api/src/lib.rs b/crates/api/src/lib.rs index df343c4..194416c 100644 --- a/crates/api/src/lib.rs +++ b/crates/api/src/lib.rs @@ -7,20 +7,20 @@ use hyper::{ body::{Bytes, Incoming}, Request, Response, StatusCode, }; -use ring::signature::UnparsedPublicKey; pub use db::{Client, Config, Database, NoTls}; +pub use ed25519_dalek::VerifyingKey; pub struct App { /// Command handler. bot: Bot, /// Ed25519 public key. - public: UnparsedPublicKey>, + public: VerifyingKey, } impl App { - pub fn new(db: Database, id: NonZeroU64, token: String, public: Box<[u8]>) -> Self { - Self { bot: Bot::new(db, id, token), public: UnparsedPublicKey::new(&ring::signature::ED25519, public) } + pub fn new(db: Database, id: NonZeroU64, token: String, public: VerifyingKey) -> Self { + Self { bot: Bot::new(db, id, token), public } } pub async fn try_respond(&self, req: Request) -> Result>, StatusCode> { @@ -59,6 +59,7 @@ impl App { let (sig, timestamp) = signature.zip(timestamp).ok_or(StatusCode::UNAUTHORIZED)?; let mut signature = [0; 64]; hex::decode_to_slice(sig, &mut signature).map_err(|_| StatusCode::BAD_REQUEST)?; + let signature = ed25519_dalek::Signature::from_bytes(&signature); // Append body after the timestamp use http_body_util::BodyExt; @@ -79,7 +80,7 @@ impl App { log::debug!("Fully received payload body."); // Validate the challenge - self.public.verify(&message, &signature).map_err(|_| StatusCode::UNAUTHORIZED)?; + self.public.verify_strict(&message, &signature).map_err(|_| StatusCode::UNAUTHORIZED)?; // Parse incoming interaction let payload = message.get(start..).ok_or(StatusCode::BAD_REQUEST)?; diff --git a/src/main.rs b/src/main.rs index d5133af..bb92ead 100644 --- a/src/main.rs +++ b/src/main.rs @@ -13,8 +13,10 @@ fn main() -> anyhow::Result<()> { // Retrieve the public key use std::env::{var, VarError}; - let key = var("PUB_KEY")?; - let pub_key = hex::decode(key)?.into_boxed_slice(); + let pub_key = var("PUB_KEY")?.into_bytes(); + let mut pub_bytes = [0; 32]; + hex::decode_to_slice(pub_key, &mut pub_bytes)?; + let pub_key = api::VerifyingKey::from_bytes(&pub_bytes)?; // Set up Postgres driver configuration let app_port = var("PORT")?.parse()?;