commit 9636f33fdbc070afcc80321359621c3bfe75535d
parent bbe2a1b264b5ef4d8eba6643857a03e905ff9dec
Author: Daniel GarcĂa <dani-garcia@users.noreply.github.com>
Date: Mon, 11 Feb 2019 23:45:55 +0100
Implement constant time equal check for admin, 2fa recover and 2fa remember tokens
Diffstat:
4 files changed, 13 insertions(+), 3 deletions(-)
diff --git a/src/api/admin.rs b/src/api/admin.rs
@@ -89,7 +89,7 @@ fn post_admin_login(data: Form<LoginForm>, mut cookies: Cookies, ip: ClientIp) -
fn _validate_token(token: &str) -> bool {
match CONFIG.admin_token().as_ref() {
None => false,
- Some(t) => t == token,
+ Some(t) => crate::crypto::ct_eq(t, token),
}
}
diff --git a/src/api/identity.rs b/src/api/identity.rs
@@ -170,8 +170,9 @@ fn twofactor_auth(
match TwoFactorType::from_i32(provider) {
Some(TwoFactorType::Remember) => {
+ use crate::crypto::ct_eq;
match device.twofactor_remember {
- Some(ref remember) if remember == twofactor_code => return Ok(None), // No twofactor token needed here
+ Some(ref remember) if ct_eq(remember, twofactor_code) => return Ok(None), // No twofactor token needed here
_ => err_json!(_json_err_twofactor(&providers, user_uuid, conn)?),
}
}
diff --git a/src/crypto.rs b/src/crypto.rs
@@ -36,3 +36,12 @@ pub fn get_random(mut array: Vec<u8>) -> Vec<u8> {
array
}
+
+//
+// Constant time compare
+//
+pub fn ct_eq<T: AsRef<[u8]>, U: AsRef<[u8]>>(a: T, b: U) -> bool {
+ use ring::constant_time::verify_slices_are_equal;
+
+ verify_slices_are_equal(a.as_ref(), b.as_ref()).is_ok()
+}
diff --git a/src/db/models/user.rs b/src/db/models/user.rs
@@ -86,7 +86,7 @@ impl User {
pub fn check_valid_recovery_code(&self, recovery_code: &str) -> bool {
if let Some(ref totp_recover) = self.totp_recover {
- recovery_code == totp_recover.to_lowercase()
+ crate::crypto::ct_eq(recovery_code, totp_recover.to_lowercase())
} else {
false
}