Skip to content

Commit 888ebc1

Browse files
chore: improve hash utils, update deps
Signed-off-by: Henry <mail@henrygressmann.de>
1 parent 52330b4 commit 888ebc1

5 files changed

Lines changed: 34 additions & 54 deletions

File tree

‎Cargo.lock‎

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

‎bun.lock‎

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

‎crates/liwan/Cargo.toml‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,11 @@ tokio = { version = "1.53", default-features = false, features = ["macros", "net
3030
tokio-util = { version = "0.7", features = ["io", "time"] }
3131

3232
# encoding
33+
base64 = "0.23"
3334
md-5 = { version = "0.11.0" }
3435
serde = { version = "1.0", features = ["derive"] }
3536
serde_json = { version = "1.0" }
37+
subtle = { version = "2.6", default-features = false }
3638
tokio-tar = { package = "astral-tokio-tar", version = "0.7" }
3739
zstd = { version = "0.14", default-features = false }
3840

‎crates/liwan/src/utils/hash.rs‎

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use anyhow::Result;
77
use rand::distr::Alphanumeric;
88
use rand::distr::SampleString;
99
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
10+
use subtle::ConstantTimeEq;
1011

1112
pub fn hash_password(password: &str) -> Result<String> {
1213
let hash = Argon2::default().hash_password(password.as_bytes()).context("Failed to hash password")?;
@@ -38,18 +39,14 @@ pub fn visitor_group_id_cidr(
3839
}
3940

4041
fn hash_visitor_group(parts: &[&[u8]]) -> String {
41-
const CHARS: &[u8; 62] = b"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
42+
use base64::{Engine, engine::general_purpose::URL_SAFE_NO_PAD};
4243
let mut hasher = blake3::Hasher::new();
4344
for part in parts {
45+
hasher.update(&(part.len() as u64).to_le_bytes());
4446
hasher.update(part);
4547
}
4648
let hash = hasher.finalize();
47-
48-
let mut result = String::with_capacity(16);
49-
for byte in hash.as_bytes().iter().take(16) {
50-
result.push(CHARS[(byte % 62) as usize] as char);
51-
}
52-
result
49+
URL_SAFE_NO_PAD.encode(&hash.as_bytes()[..12])
5350
}
5451

5552
fn mask_ipv4(ip: Ipv4Addr, prefix: u8) -> Ipv4Addr {
@@ -74,15 +71,7 @@ pub fn session_token() -> String {
7471

7572
/// Compare onboarding tokens without short-circuiting on their contents.
7673
pub(crate) fn onboarding_token_matches(expected: &str, candidate: &str) -> bool {
77-
if expected.len() != candidate.len() {
78-
return false;
79-
}
80-
81-
let mut difference = 0u8;
82-
for (expected, candidate) in expected.bytes().zip(candidate.bytes()) {
83-
difference = std::hint::black_box(difference | (expected ^ candidate));
84-
}
85-
std::hint::black_box(difference) == 0
74+
bool::from(expected.as_bytes().ct_eq(candidate.as_bytes()))
8675
}
8776

8877
pub fn onboarding_token() -> String {

‎packages/web/package.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
"d3-transition": "^3.0.1",
2525
"d3-zoom": "^3.0.0",
2626
"date-fns": "^4.4.0",
27-
"lucide-react": "1.57.0",
27+
"lucide-react": "1.58.0",
2828
"react": "19.3.1",
2929
"react-dom": "19.3.1",
3030
"topojson-client": "^3.1.0"

0 commit comments

Comments
 (0)