Add expiration to webauthn challenges

This commit is contained in:
Pierre HUBERT 2022-04-23 20:22:32 +02:00
parent 9e345895ff
commit 933c8ff024
2 changed files with 21 additions and 4 deletions

View File

@ -57,3 +57,7 @@ pub const OPEN_ID_ACCESS_TOKEN_LEN: usize = 50;
pub const OPEN_ID_ACCESS_TOKEN_TIMEOUT: u64 = 3600; pub const OPEN_ID_ACCESS_TOKEN_TIMEOUT: u64 = 3600;
pub const OPEN_ID_REFRESH_TOKEN_LEN: usize = 120; pub const OPEN_ID_REFRESH_TOKEN_LEN: usize = 120;
pub const OPEN_ID_REFRESH_TOKEN_TIMEOUT: u64 = 360000; pub const OPEN_ID_REFRESH_TOKEN_TIMEOUT: u64 = 360000;
/// Webauthn constants
pub const WEBAUTHN_REGISTER_CHALLENGE_EXPIRE: u64 = 3600;
pub const WEBAUTHN_LOGIN_CHALLENGE_EXPIRE: u64 = 3600;

View File

@ -5,11 +5,12 @@ use actix_web::web;
use webauthn_rs::{AuthenticationState, RegistrationState, Webauthn, WebauthnConfig}; use webauthn_rs::{AuthenticationState, RegistrationState, Webauthn, WebauthnConfig};
use webauthn_rs::proto::{CreationChallengeResponse, Credential, PublicKeyCredential, RegisterPublicKeyCredential, RequestChallengeResponse}; use webauthn_rs::proto::{CreationChallengeResponse, Credential, PublicKeyCredential, RegisterPublicKeyCredential, RequestChallengeResponse};
use crate::constants::APP_NAME; use crate::constants::{APP_NAME, WEBAUTHN_LOGIN_CHALLENGE_EXPIRE, WEBAUTHN_REGISTER_CHALLENGE_EXPIRE};
use crate::data::app_config::AppConfig; use crate::data::app_config::AppConfig;
use crate::data::crypto_wrapper::CryptoWrapper; use crate::data::crypto_wrapper::CryptoWrapper;
use crate::data::user::{User, UserID}; use crate::data::user::{User, UserID};
use crate::utils::err::Res; use crate::utils::err::Res;
use crate::utils::time::time;
#[derive(Debug)] #[derive(Debug)]
struct WebAuthnAppConfig { struct WebAuthnAppConfig {
@ -45,7 +46,7 @@ pub struct RegisterKeyRequest {
struct RegisterKeyOpaqueData { struct RegisterKeyOpaqueData {
registration_state: RegistrationState, registration_state: RegistrationState,
user_id: UserID, user_id: UserID,
// TODO : add time expire: u64,
} }
pub struct AuthRequest { pub struct AuthRequest {
@ -57,7 +58,7 @@ pub struct AuthRequest {
struct AuthStateOpaqueData { struct AuthStateOpaqueData {
authentication_state: AuthenticationState, authentication_state: AuthenticationState,
user_id: UserID, user_id: UserID,
// TODO : add time expire: u64,
} }
@ -93,6 +94,7 @@ impl WebAuthManager {
opaque_state: self.crypto_wrapper.encrypt(&RegisterKeyOpaqueData { opaque_state: self.crypto_wrapper.encrypt(&RegisterKeyOpaqueData {
registration_state, registration_state,
user_id: user.uid.clone(), user_id: user.uid.clone(),
expire: time() + WEBAUTHN_REGISTER_CHALLENGE_EXPIRE,
})?, })?,
creation_challenge, creation_challenge,
}) })
@ -106,6 +108,11 @@ impl WebAuthManager {
std::io::Error::new(ErrorKind::Other, "Invalid user for pubkey!"))); std::io::Error::new(ErrorKind::Other, "Invalid user for pubkey!")));
} }
if state.expire < time() {
return Err(Box::new(
std::io::Error::new(ErrorKind::Other, "Challenge has expired!")));
}
let res = self.core let res = self.core
.register_credential(&pub_cred, &state.registration_state, |_| Ok(false))?; .register_credential(&pub_cred, &state.registration_state, |_| Ok(false))?;
@ -121,6 +128,7 @@ impl WebAuthManager {
opaque_state: self.crypto_wrapper.encrypt(&AuthStateOpaqueData { opaque_state: self.crypto_wrapper.encrypt(&AuthStateOpaqueData {
authentication_state, authentication_state,
user_id: user_id.clone(), user_id: user_id.clone(),
expire: time() + WEBAUTHN_LOGIN_CHALLENGE_EXPIRE,
})?, })?,
login_challenge, login_challenge,
}) })
@ -134,6 +142,11 @@ impl WebAuthManager {
std::io::Error::new(ErrorKind::Other, "Invalid user for pubkey!"))); std::io::Error::new(ErrorKind::Other, "Invalid user for pubkey!")));
} }
if state.expire < time() {
return Err(Box::new(
std::io::Error::new(ErrorKind::Other, "Challenge has expired!")));
}
self.core.authenticate_credential(pub_cred, &state.authentication_state)?; self.core.authenticate_credential(pub_cred, &state.authentication_state)?;
Ok(()) Ok(())