aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock10
-rw-r--r--Cargo.toml1
-rw-r--r--config.json3
-rw-r--r--src/crypto/mod.rs1
-rw-r--r--src/crypto/signed.rs71
-rw-r--r--src/main.rs1
-rw-r--r--src/model/config.rs2
-rw-r--r--src/routes.rs5
-rw-r--r--src/utils/cookie.rs18
9 files changed, 13 insertions, 99 deletions
diff --git a/Cargo.lock b/Cargo.lock
index cbde1e5..a60f4b5 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -189,7 +189,6 @@ dependencies = [
"chrono",
"env_logger",
"hex",
- "hmac",
"http-body-util",
"hyper",
"hyper-util",
@@ -517,15 +516,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
[[package]]
-name = "hmac"
-version = "0.12.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e"
-dependencies = [
- "digest",
-]
-
-[[package]]
name = "http"
version = "1.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
index fdef3b9..18093f5 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -10,7 +10,6 @@ bcrypt = "0.17"
chrono = "0.4"
env_logger = "0.11"
hex = "0.4"
-hmac = "0.12"
http-body-util = "0.1"
hyper = { version = "1.7", features = ["full"] }
hyper-util = { version = "0.1", features = ["full"] }
diff --git a/config.json b/config.json
index 20bad2e..86a19b5 100644
--- a/config.json
+++ b/config.json
@@ -1,4 +1,3 @@
{
- "secure_cookies": false,
- "auth_secret": "1QAZa8RSgogsakXSa0hgEeyA7xqnvo91"
+ "secure_cookies": false
}
diff --git a/src/crypto/mod.rs b/src/crypto/mod.rs
deleted file mode 100644
index 41e9259..0000000
--- a/src/crypto/mod.rs
+++ /dev/null
@@ -1 +0,0 @@
-pub mod signed;
diff --git a/src/crypto/signed.rs b/src/crypto/signed.rs
deleted file mode 100644
index 436f3d1..0000000
--- a/src/crypto/signed.rs
+++ /dev/null
@@ -1,71 +0,0 @@
-use hex;
-use hmac::{Hmac, Mac};
-use sha2::Sha256;
-use std::str;
-use std::time::{SystemTime, UNIX_EPOCH};
-
-const SEP: &str = "-";
-
-pub fn sign(key: &str, raw: &str) -> Result<String, String> {
- let nonce = get_nonce()?;
- let joined = format!("{nonce}{SEP}{raw}");
- let signature = get_signature(key, &joined)?;
- Ok(format!("{signature}{SEP}{joined}"))
-}
-
-pub fn verify(key: &str, signed: &str) -> Result<String, String> {
- let mut iter = signed.split(SEP);
- match (iter.next(), iter.next()) {
- (Some(signature), Some(nonce)) => {
- let raw = iter.collect::<Vec<&str>>().join(SEP);
- if signature == get_signature(key, &format!("{nonce}{SEP}{raw}"))? {
- Ok(raw)
- } else {
- Err("Signature does not match".to_string())
- }
- }
- _ => Err("Malformed signed".to_string()),
- }
-}
-
-fn get_signature(key: &str, message: &str) -> Result<String, String> {
- let mut mac = Hmac::<Sha256>::new_from_slice(key.as_bytes())
- .map_err(|e| format!("Error initializing MAC: {e}"))?;
- mac.update(message.as_bytes());
- let result = mac.finalize();
- Ok(hex::encode(result.into_bytes()))
-}
-
-fn get_nonce() -> Result<String, String> {
- Ok(SystemTime::now()
- .duration_since(UNIX_EPOCH)
- .map_err(|e| format!("Failure getting unix expoch: {e}"))?
- .as_millis()
- .to_string())
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
-
- #[test]
- fn sign_and_validate() {
- let key = "xagrlBUobnTj32Rm8tvmsZ6mh8qLfip5".to_string();
- assert_eq!(verify(&key, &sign(&key, "").unwrap()), Ok("".to_string()));
- assert_eq!(
- verify(&key, &sign(&key, "hello").unwrap()),
- Ok("hello".to_string())
- );
- assert_eq!(
- verify(&key, &sign(&key, "with-sep").unwrap()),
- Ok("with-sep".to_string())
- );
- }
-
- #[test]
- fn fail_when_key_mismatch() {
- let key1 = "xagrlBUobnTj32Rm8tvmsZ6mh8qLfip5".to_string();
- let key2 = "8KJBK6axEr9wQ390GgdWA8Pjn8FwILDa".to_string();
- assert!(verify(&key1, &sign(&key2, "hello").unwrap()).is_err());
- }
-}
diff --git a/src/main.rs b/src/main.rs
index 70bac81..1cc2384 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -6,7 +6,6 @@ use tokio::net::TcpListener;
mod assets;
mod controller;
-mod crypto;
mod db;
mod jobs;
mod model;
diff --git a/src/model/config.rs b/src/model/config.rs
index f40b0fb..ba923d6 100644
--- a/src/model/config.rs
+++ b/src/model/config.rs
@@ -4,7 +4,6 @@ use std::str::FromStr;
#[derive(Clone)]
pub struct Config {
- pub auth_secret: String,
pub db_path: String,
pub secure_cookies: bool,
pub socket_address: SocketAddr,
@@ -12,7 +11,6 @@ pub struct Config {
pub fn from_env() -> Result<Config, String> {
Ok(Config {
- auth_secret: read_string("AUTH_SECRET")?,
db_path: read_string("DB_PATH")?,
secure_cookies: read_bool("SECURE_COOKIES")?,
socket_address: read_socket_address("SOCKET_ADDRESS")?,
diff --git a/src/routes.rs b/src/routes.rs
index 7107a60..8abe1b4 100644
--- a/src/routes.rs
+++ b/src/routes.rs
@@ -49,7 +49,7 @@ pub async fn routes(
"icon.png" => file("assets/icon.png", "image/png").await,
_ => controller::utils::not_found(),
},
- _ => match connected_user(&config, &db_conn, &request).await {
+ _ => match connected_user(&db_conn, &request).await {
Some(user) => {
let wallet = Wallet {
db_conn,
@@ -67,12 +67,11 @@ pub async fn routes(
}
async fn connected_user(
- config: &Config,
db_conn: &Connection,
request: &Request<Incoming>,
) -> Option<User> {
let cookie = request.headers().get("COOKIE")?.to_str().ok()?;
- let login_token = cookie::extract_token(config, cookie).ok()?;
+ let login_token = cookie::extract_token(cookie).ok()?;
db::users::get_by_login_token(db_conn, login_token.to_string()).await
}
diff --git a/src/utils/cookie.rs b/src/utils/cookie.rs
index e21e7d4..1ca3b73 100644
--- a/src/utils/cookie.rs
+++ b/src/utils/cookie.rs
@@ -1,25 +1,27 @@
use hex;
use rand_core::{OsRng, TryRngCore};
-use crate::crypto::signed;
use crate::model::config::Config;
-const TOKEN_BYTES: usize = 20;
+// We consider that it’s unfeasible to guess a token from 128 bit long (=16 bytes) to 256 bit (=32 bytes) with safe margin.
+const TOKEN_BYTES: usize = 32;
pub fn login(config: &Config, token: &str) -> Result<String, String> {
- let signed_token = signed::sign(&config.auth_secret, token)?;
- Ok(cookie(config, &signed_token, 365 * 24 * 60 * 60))
+ Ok(cookie(config, &token, 365 * 24 * 60 * 60))
}
pub fn logout(config: &Config) -> String {
cookie(config, "", 0)
}
-pub fn extract_token(config: &Config, cookie: &str) -> Result<String, String> {
+pub fn extract_token(cookie: &str) -> Result<String, String> {
let mut xs = cookie.split('=');
- xs.next();
- let signed_cookie = xs.next().ok_or("Error extracting cookie")?;
- signed::verify(&config.auth_secret, signed_cookie)
+ if xs.next() != Some("TOKEN") {
+ Err("Error extracting cookie".to_string())
+ } else {
+ let token = xs.next().ok_or("Error extracting cookie")?;
+ Ok(token.to_string())
+ }
}
pub fn generate_token() -> Result<String, String> {