feat(db): store the hash of client secret

This commit is contained in:
subcrip 2024-03-30 22:28:18 +08:00
parent b0fe35f69e
commit fde2b72325
Signed by: subcrip
SSH Key Fingerprint: SHA256:dFPFi68d8C87YkFkEBU4TkcrYRySWpekRR1hbnDWUCw
4 changed files with 133 additions and 2 deletions

102
Cargo.lock generated
View File

@ -549,6 +549,24 @@ dependencies = [
"generic-array", "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]] [[package]]
name = "concurrent-queue" name = "concurrent-queue"
version = "2.4.0" version = "2.4.0"
@ -624,6 +642,18 @@ dependencies = [
"typenum", "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]] [[package]]
name = "crypto-mac" name = "crypto-mac"
version = "0.8.0" version = "0.8.0"
@ -800,6 +830,21 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8fcfdc7a0362c9f4444381a9e697c79d435fe65b52a37466fc2c1184cee9edc6" 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]] [[package]]
name = "form_urlencoded" name = "form_urlencoded"
version = "1.2.1" version = "1.2.1"
@ -992,6 +1037,12 @@ version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024"
[[package]]
name = "hex"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77"
[[package]] [[package]]
name = "hkdf" name = "hkdf"
version = "0.10.0" version = "0.10.0"
@ -1252,6 +1303,7 @@ name = "oauth"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"async-std", "async-std",
"crypto-hash",
"futures", "futures",
"rand 0.8.5", "rand 0.8.5",
"serde", "serde",
@ -1283,6 +1335,44 @@ version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" 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]] [[package]]
name = "parking" name = "parking"
version = "2.2.0" version = "2.2.0"
@ -1385,6 +1475,12 @@ dependencies = [
"futures-io", "futures-io",
] ]
[[package]]
name = "pkg-config"
version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec"
[[package]] [[package]]
name = "polling" name = "polling"
version = "2.8.0" version = "2.8.0"
@ -2261,6 +2357,12 @@ dependencies = [
"sval_serde", "sval_serde",
] ]
[[package]]
name = "vcpkg"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
[[package]] [[package]]
name = "version_check" name = "version_check"
version = "0.9.4" version = "0.9.4"

View File

@ -15,3 +15,4 @@ tokio-postgres = { version = "0.7.10", features = ["with-uuid-1"] }
futures = "0.3.30" futures = "0.3.30"
uuid = { verion = "1.0.0", features = ["v4", "fast-rng", "macro-diagnostics"] } uuid = { verion = "1.0.0", features = ["v4", "fast-rng", "macro-diagnostics"] }
rand = "0.8.5" rand = "0.8.5"
crypto-hash = "0.3.4"

View File

@ -1,5 +1,7 @@
use uuid::Uuid; 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 struct OAuthApplication {
pub client_id: Uuid, pub client_id: Uuid,
pub client_secret: crate::misc::U256, 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<u8>,
}
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 struct OAuthScope {
pub scope_id: Uuid, pub scope_id: Uuid,
pub scope_desc: String, pub scope_desc: String,
@ -85,18 +101,26 @@ impl OAuthDatabase {
pub async fn trusted_register_application(&mut self) -> Result<OAuthApplication, tokio_postgres::Error> { pub async fn trusted_register_application(&mut self) -> Result<OAuthApplication, tokio_postgres::Error> {
// TEST: functionality // TEST: functionality
let app = OAuthApplication::new(); 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) Ok(app)
} }
/// Register a scope. /// Register a scope.
/// Applicant: Resource /// Applicant: resource
pub async fn trusted_register_scope(&mut self, description: String) -> Result<OAuthScope, tokio_postgres::Error> { pub async fn trusted_register_scope(&mut self, description: String) -> Result<OAuthScope, tokio_postgres::Error> {
// TEST: functionality // TEST: functionality
let scope = OAuthScope::new(description); 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?; self.psql_execute("insert into Scopes (scope_id, scope_desc) values ($1, $2)", &[&scope.scope_id, &scope.scope_desc]).await?;
Ok(scope) 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)] #[cfg(test)]

View File

@ -7,3 +7,7 @@ pub fn random_256() -> U256 {
} }
res res
} }
pub fn digest(data: &[u8]) -> Vec<u8> {
crypto_hash::digest(crypto_hash::Algorithm::SHA256, data)
}