Skip to content

Commit 3afd59f

Browse files
chore: update crypto crates
Signed-off-by: Henry <mail@henrygressmann.de>
1 parent e5493e1 commit 3afd59f

8 files changed

Lines changed: 336 additions & 106 deletions

File tree

Cargo.lock

Lines changed: 306 additions & 72 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,21 @@ hex={version="0.4"}
2727
bs58="0.5"
2828
serde={version="1.0", features=["derive"]}
2929
serde_json={version="1.0"}
30-
md5={package="md-5", version="0.10.6"}
30+
md-5={version="0.10"}
3131
async-compression={version="0.4", default-features=false, features=["gzip", "tokio"]}
3232
tokio-tar={package="astral-tokio-tar", version="0.5"}
33-
sha3={version="0.10"}
34-
argon2={version="0.5", features=["rand"]}
35-
password-hash={version="0.5", features=["rand_core", "getrandom"]} # required for getrandom feature
33+
blake3={version="1.8"}
34+
argon2={version="0.6.0-rc.7", features=[]}
35+
password-hash={version="0.6.0-rc.12", features=[
36+
"rand_core",
37+
"getrandom",
38+
]} # required for getrandom feature
3639
zstd={version="0.13", default-features=false}
3740

3841
# general
3942
argh={version="0.1", default-features=false, features=["help"]}
4043
anyhow={version="1.0"}
44+
rand_core={version="0.10"}
4145
rand={version="0.9", default-features=false, features=["std", "thread_rng"]}
4246
chrono={version="0.4", default-features=false, features=["std", "now", "serde"]}
4347
figment={version="0.10", features=["toml", "env"]}

data/licenses-cargo.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

src/app/core/events.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,22 @@ use std::sync::Arc;
33
use anyhow::{Result, bail};
44
use arc_swap::ArcSwap;
55
use chrono::{DateTime, Utc};
6+
use password_hash::try_generate_salt;
67
use std::sync::mpsc::Receiver;
78

89
use crate::app::models::{Event, event_params};
910
use crate::app::{DuckDBPool, EVENT_BATCH_INTERVAL, SqlitePool};
10-
use crate::utils::hash::generate_salt;
1111

1212
#[derive(Clone)]
1313
pub struct LiwanEvents {
1414
duckdb: DuckDBPool,
1515
sqlite: SqlitePool,
16-
daily_salt: Arc<ArcSwap<(String, DateTime<Utc>)>>,
16+
daily_salt: Arc<ArcSwap<([u8; 16], DateTime<Utc>)>>,
1717
}
1818

1919
impl LiwanEvents {
2020
pub fn try_new(duckdb: DuckDBPool, sqlite: SqlitePool) -> Result<Self> {
21-
let daily_salt: (String, DateTime<Utc>) = {
21+
let daily_salt: ([u8; 16], DateTime<Utc>) = {
2222
tracing::debug!("Loading daily salt");
2323
sqlite.get()?.query_row("select salt, updated_at from salts where id = 1", [], |row| {
2424
Ok((row.get(0)?, row.get(1)?))
@@ -28,13 +28,13 @@ impl LiwanEvents {
2828
}
2929

3030
/// Get the daily salt, generating a new one if the current one is older than 24 hours
31-
pub fn get_salt(&self) -> Result<String> {
31+
pub fn get_salt(&self) -> Result<[u8; 16]> {
3232
let (salt, updated_at) = &**self.daily_salt.load();
3333

3434
// if the salt is older than 24 hours, replace it with a new one (utils::generate_salt)
3535
if (Utc::now() - updated_at) > chrono::Duration::hours(24) {
3636
tracing::debug!("Daily salt expired, generating a new one");
37-
let new_salt = generate_salt();
37+
let new_salt = try_generate_salt()?;
3838
let now = Utc::now();
3939
let conn = self.sqlite.get()?;
4040
conn.execute("update salts set salt = ?, updated_at = ? where id = 1", rusqlite::params![&new_salt, now])?;

src/app/core/geoip.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use crate::app::SqlitePool;
1111
use anyhow::{Context, Result, anyhow};
1212
use arc_swap::ArcSwapOption;
1313
use futures_lite::StreamExt;
14-
use md5::{Digest, Md5};
14+
use md5::Digest;
1515
use tokio_tar::Archive;
1616
use tokio_util::io::StreamReader;
1717

@@ -232,7 +232,7 @@ async fn get_latest_md5(edition: &str, account_id: &str, license_key: &str) -> R
232232
fn file_md5(path: &Path) -> Result<String> {
233233
let file = std::fs::File::open(path)?;
234234
let mut reader = std::io::BufReader::new(file);
235-
let mut hasher = Md5::new();
235+
let mut hasher = md5::Md5::new();
236236
std::io::copy(&mut reader, &mut hasher)?;
237237
Ok(format!("{:x}", hasher.finalize()))
238238
}

src/utils/hash.rs

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,31 @@
1+
use anyhow::Context;
12
use argon2::Argon2;
23
use argon2::PasswordVerifier;
3-
use argon2::password_hash::{PasswordHasher, SaltString, rand_core};
4+
use argon2::password_hash::PasswordHasher;
45

56
use anyhow::Result;
67
use rand::RngCore;
7-
use sha3::Digest;
88
use std::net::IpAddr;
99

1010
pub fn hash_password(password: &str) -> Result<String> {
11-
let salt = SaltString::generate(&mut rand_core::OsRng);
12-
let hash = Argon2::default()
13-
.hash_password(password.as_bytes(), &salt)
14-
.map_err(|_| anyhow::anyhow!("Failed to hash password"))?;
11+
let hash = Argon2::default().hash_password(password.as_bytes()).context("Failed to hash password")?;
1512
Ok(hash.to_string())
1613
}
1714

1815
pub fn verify_password(password: &str, hash: &str) -> Result<()> {
19-
let hash = argon2::PasswordHash::new(hash).map_err(|_| anyhow::anyhow!("Invalid hash"))?;
16+
let hash = argon2::PasswordHash::new(hash).context("Invalid hash")?;
2017
let argon2 = Argon2::default();
21-
argon2.verify_password(password.as_bytes(), &hash).map_err(|_| anyhow::anyhow!("Failed to verify password"))
18+
argon2.verify_password(password.as_bytes(), &hash).context("Failed to verify password")
2219
}
2320

24-
pub fn generate_salt() -> String {
25-
SaltString::generate(&mut rand_core::OsRng).to_string()
26-
}
27-
28-
pub fn hash_ip(ip: &IpAddr, user_agent: &str, daily_salt: &str, entity_id: &str) -> String {
29-
let mut hasher = sha3::Sha3_256::new();
30-
hasher.update(ip.to_string());
31-
hasher.update(user_agent);
32-
hasher.update(daily_salt);
33-
hasher.update(entity_id);
21+
pub fn hash_ip(ip: &IpAddr, user_agent: &str, daily_salt: [u8; 16], entity_id: &str) -> String {
22+
let mut hasher = blake3::Hasher::new();
23+
hasher.update(ip.to_string().as_bytes());
24+
hasher.update(user_agent.as_bytes());
25+
hasher.update(&daily_salt);
26+
hasher.update(entity_id.as_bytes());
3427
let hash = hasher.finalize();
35-
hex::encode(hash)[..32].to_string()
28+
hex::encode(hash.as_bytes())[..32].to_string()
3629
}
3730

3831
pub fn visitor_id() -> String {

src/utils/seed.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1+
use crate::app::models::Event;
12
use chrono::{DateTime, Duration, Utc};
23
use rand::Rng;
34

4-
use crate::app::models::Event;
5-
65
const PATHS: &[&str] = &["/", "/about", "/contact", "/pricing", "/blog", "/login", "/signup"];
76
const REFERRERS: &[&str] = &["", "google.com", "twitter.com", "liwan.dev", "example.com", "henrygressmann.de"];
87
const PLATFORMS: &[&str] = &["", "Windows", "macOS", "Linux", "Android", "iOS"];

src/web/routes/event.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ fn process_event(
9494
}
9595

9696
let visitor_id = match ip {
97-
Some(ip) => hash_ip(&ip, user_agent.as_str(), &app.events.get_salt()?, &event.entity_id),
97+
Some(ip) => hash_ip(&ip, user_agent.as_str(), app.events.get_salt()?, &event.entity_id),
9898
None => visitor_id(),
9999
};
100100

0 commit comments

Comments
 (0)