haste_server/auth_n/constant_time.rs
1//! Comparisons of secrets whose running time does not depend on where the
2//! values first differ.
3//!
4//! `==` on strings stops at the first mismatching byte, so how long a
5//! comparison takes tells a caller how many leading bytes they got right.
6//! Client secrets and CSRF tokens are compared here instead.
7
8use subtle::ConstantTimeEq;
9
10/// Whether `a` and `b` are the same string, in time that depends only on
11/// their lengths.
12pub fn str_eq(a: &str, b: &str) -> bool {
13 a.as_bytes().ct_eq(b.as_bytes()).into()
14}
15
16/// Whether an optional secret matches: both absent, or both present and
17/// equal under [`str_eq`].
18pub fn optional_str_eq(a: Option<&str>, b: Option<&str>) -> bool {
19 match (a, b) {
20 (None, None) => true,
21 (Some(a), Some(b)) => str_eq(a, b),
22 _ => false,
23 }
24}