From fde2b723257ee7b15eb702223950397854b65f14 Mon Sep 17 00:00:00 2001 From: subcrip Date: Sat, 30 Mar 2024 22:28:18 +0800 Subject: [PATCH] feat(db): store the hash of client secret --- Cargo.lock | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 1 + src/db.rs | 28 +++++++++++++-- src/misc.rs | 4 +++ 4 files changed, 133 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4d2b2f0..508c0b2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -549,6 +549,24 @@ dependencies = [ "generic-array", ] +[[package]] +name = "commoncrypto" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d056a8586ba25a1e4d61cb090900e495952c7886786fc55f909ab2f819b69007" +dependencies = [ + "commoncrypto-sys", +] + +[[package]] +name = "commoncrypto-sys" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fed34f46747aa73dfaa578069fd8279d2818ade2b55f38f22a9401c7f4083e2" +dependencies = [ + "libc", +] + [[package]] name = "concurrent-queue" version = "2.4.0" @@ -624,6 +642,18 @@ dependencies = [ "typenum", ] +[[package]] +name = "crypto-hash" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a77162240fd97248d19a564a565eb563a3f592b386e4136fb300909e67dddca" +dependencies = [ + "commoncrypto", + "hex", + "openssl", + "winapi", +] + [[package]] name = "crypto-mac" version = "0.8.0" @@ -800,6 +830,21 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8fcfdc7a0362c9f4444381a9e697c79d435fe65b52a37466fc2c1184cee9edc6" +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + [[package]] name = "form_urlencoded" version = "1.2.1" @@ -992,6 +1037,12 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" +[[package]] +name = "hex" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77" + [[package]] name = "hkdf" version = "0.10.0" @@ -1252,6 +1303,7 @@ name = "oauth" version = "0.1.0" dependencies = [ "async-std", + "crypto-hash", "futures", "rand 0.8.5", "serde", @@ -1283,6 +1335,44 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" +[[package]] +name = "openssl" +version = "0.10.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f" +dependencies = [ + "bitflags 2.5.0", + "cfg-if 1.0.0", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "openssl-sys" +version = "0.9.102" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c597637d56fbc83893a35eb0dd04b2b8e7a50c91e64e9493e398b5df4fb45fa2" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "parking" version = "2.2.0" @@ -1385,6 +1475,12 @@ dependencies = [ "futures-io", ] +[[package]] +name = "pkg-config" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" + [[package]] name = "polling" version = "2.8.0" @@ -2261,6 +2357,12 @@ dependencies = [ "sval_serde", ] +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + [[package]] name = "version_check" version = "0.9.4" diff --git a/Cargo.toml b/Cargo.toml index bc7a68b..9de0fae 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,3 +15,4 @@ tokio-postgres = { version = "0.7.10", features = ["with-uuid-1"] } futures = "0.3.30" uuid = { verion = "1.0.0", features = ["v4", "fast-rng", "macro-diagnostics"] } rand = "0.8.5" +crypto-hash = "0.3.4" diff --git a/src/db.rs b/src/db.rs index b250802..9003553 100644 --- a/src/db.rs +++ b/src/db.rs @@ -1,5 +1,7 @@ use uuid::Uuid; +/// An abstract of OAuth application. The secret should be shown only once. After registration, we +/// should operate on `OAuthHashedApplication`. pub struct OAuthApplication { pub client_id: Uuid, pub client_secret: crate::misc::U256, @@ -16,6 +18,20 @@ impl OAuthApplication { } } +/// An abstract of OAuth application. The secret is hashed so it's safe to store it in the +/// database. +pub struct OAuthHashedApplication { + pub client_id: Uuid, + pub client_secret: Vec, +} + +impl OAuthHashedApplication { + // TEST: functionality + pub fn from(app: &OAuthApplication) -> Self { + Self { client_id: app.client_id, client_secret: crate::misc::digest(&app.client_secret) } + } +} + pub struct OAuthScope { pub scope_id: Uuid, pub scope_desc: String, @@ -85,18 +101,26 @@ impl OAuthDatabase { pub async fn trusted_register_application(&mut self) -> Result { // TEST: functionality let app = OAuthApplication::new(); - self.psql_execute("insert into Applications (client_id, client_secret) values ($1, $2)", &[&app.client_id, &&app.client_secret[..]]).await?; + let app_hash = OAuthHashedApplication::from(&app); + self.psql_execute("insert into Applications (client_id, client_secret) values ($1, $2)", &[&app_hash.client_id, &app_hash.client_secret]).await?; Ok(app) } /// Register a scope. - /// Applicant: Resource + /// Applicant: resource pub async fn trusted_register_scope(&mut self, description: String) -> Result { // TEST: functionality let scope = OAuthScope::new(description); self.psql_execute("insert into Scopes (scope_id, scope_desc) values ($1, $2)", &[&scope.scope_id, &scope.scope_desc]).await?; Ok(scope) } + + /// Register an access relation. + /// Applicant: client + pub async fn trusted_register_access(&mut self, app: OAuthHashedApplication, scope: OAuthScope) -> Result<(), tokio_postgres::Error> { + // TODO: implementation + Ok(()) + } } #[cfg(test)] diff --git a/src/misc.rs b/src/misc.rs index 31c474b..1e3f1d8 100644 --- a/src/misc.rs +++ b/src/misc.rs @@ -7,3 +7,7 @@ pub fn random_256() -> U256 { } res } + +pub fn digest(data: &[u8]) -> Vec { + crypto_hash::digest(crypto_hash::Algorithm::SHA256, data) +}