Update webauthn-rs dependency

This commit is contained in:
2022-08-24 13:33:40 +02:00
parent 35b9bfc8bb
commit 4450a21225
5 changed files with 212 additions and 48 deletions

View File

@ -1,6 +1,6 @@
use actix_identity::Identity;
use actix_web::{HttpRequest, HttpResponse, Responder, web};
use webauthn_rs::proto::PublicKeyCredential;
use webauthn_rs::prelude::PublicKeyCredential;
use crate::data::session_identity::{SessionIdentity, SessionStatus};
use crate::data::webauthn_manager::WebAuthManagerReq;

View File

@ -1,7 +1,7 @@
use actix::Addr;
use actix_web::{HttpResponse, Responder, web};
use uuid::Uuid;
use webauthn_rs::proto::RegisterPublicKeyCredential;
use webauthn_rs::prelude::RegisterPublicKeyCredential;
use crate::actors::users_actor;
use crate::actors::users_actor::UsersActor;

View File

@ -2,39 +2,20 @@ use std::io::ErrorKind;
use std::sync::Arc;
use actix_web::web;
use webauthn_rs::{AuthenticationState, RegistrationState, Webauthn, WebauthnConfig};
use webauthn_rs::proto::{CreationChallengeResponse, Credential, PublicKeyCredential, RegisterPublicKeyCredential, RequestChallengeResponse};
use uuid::Uuid;
use webauthn_rs::{Webauthn, WebauthnBuilder};
use webauthn_rs::prelude::{CreationChallengeResponse, Passkey, PublicKeyCredential, RegisterPublicKeyCredential, RequestChallengeResponse};
use crate::constants::{APP_NAME, WEBAUTHN_LOGIN_CHALLENGE_EXPIRE, WEBAUTHN_REGISTER_CHALLENGE_EXPIRE};
use crate::constants::{WEBAUTHN_LOGIN_CHALLENGE_EXPIRE, WEBAUTHN_REGISTER_CHALLENGE_EXPIRE};
use crate::data::app_config::AppConfig;
use crate::data::crypto_wrapper::CryptoWrapper;
use crate::data::user::{User, UserID};
use crate::utils::err::Res;
use crate::utils::time::time;
#[derive(Debug)]
struct WebAuthnAppConfig {
origin: url::Url,
relying_party_id: String,
}
impl WebauthnConfig for WebAuthnAppConfig {
fn get_relying_party_name(&self) -> &str {
APP_NAME
}
fn get_origin(&self) -> &url::Url {
&self.origin
}
fn get_relying_party_id(&self) -> &str {
&self.relying_party_id
}
}
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
pub struct WebauthnPubKey {
creds: Credential,
creds: Passkey,
}
pub struct RegisterKeyRequest {
@ -44,7 +25,7 @@ pub struct RegisterKeyRequest {
#[derive(Debug, serde::Serialize, serde::Deserialize)]
struct RegisterKeyOpaqueData {
registration_state: RegistrationState,
registration_state: String,
user_id: UserID,
expire: u64,
}
@ -56,7 +37,7 @@ pub struct AuthRequest {
#[derive(Debug, serde::Serialize, serde::Deserialize)]
struct AuthStateOpaqueData {
authentication_state: AuthenticationState,
authentication_state: String,
user_id: UserID,
expire: u64,
}
@ -65,34 +46,40 @@ struct AuthStateOpaqueData {
pub type WebAuthManagerReq = web::Data<Arc<WebAuthManager>>;
pub struct WebAuthManager {
core: Webauthn<WebAuthnAppConfig>,
core: Webauthn,
crypto_wrapper: CryptoWrapper,
}
impl WebAuthManager {
pub fn init(conf: &AppConfig) -> Self {
Self {
core: Webauthn::new(WebAuthnAppConfig {
origin: url::Url::parse(&conf.website_origin)
.expect("Failed to parse configuration origin!"),
relying_party_id: conf.domain_name().split_once(':')
core: WebauthnBuilder::new(
conf.domain_name().split_once(':')
.map(|s| s.0)
.unwrap_or_else(|| conf.domain_name())
.to_string(),
}),
.unwrap_or_else(|| conf.domain_name()),
&url::Url::parse(&conf.website_origin)
.expect("Failed to parse configuration origin!"))
.expect("Invalid Webauthn configuration")
.build()
.expect("Failed to build webauthn")
,
crypto_wrapper: CryptoWrapper::new_random(),
}
}
pub fn start_register(&self, user: &User) -> Res<RegisterKeyRequest> {
let (creation_challenge, registration_state) = self.core.generate_challenge_register(
let (creation_challenge, registration_state)
= self.core.start_passkey_registration(
Uuid::parse_str(&user.uid.0).expect("Failed to parse user id"),
&user.username,
false,
&user.full_name(),
None,
)?;
Ok(RegisterKeyRequest {
opaque_state: self.crypto_wrapper.encrypt(&RegisterKeyOpaqueData {
registration_state,
registration_state: serde_json::to_string(&registration_state)?,
user_id: user.uid.clone(),
expire: time() + WEBAUTHN_REGISTER_CHALLENGE_EXPIRE,
})?,
@ -114,19 +101,19 @@ impl WebAuthManager {
}
let res = self.core
.register_credential(&pub_cred, &state.registration_state, |_| Ok(false))?;
.finish_passkey_registration(&pub_cred, &serde_json::from_str(&state.registration_state)?)?;
Ok(WebauthnPubKey { creds: res.0 })
Ok(WebauthnPubKey { creds: res })
}
pub fn start_authentication(&self, user_id: &UserID, key: &WebauthnPubKey) -> Res<AuthRequest> {
let (login_challenge, authentication_state) = self.core.generate_challenge_authenticate(vec![
let (login_challenge, authentication_state) = self.core.start_passkey_authentication(&vec![
key.creds.clone()
])?;
Ok(AuthRequest {
opaque_state: self.crypto_wrapper.encrypt(&AuthStateOpaqueData {
authentication_state,
authentication_state: serde_json::to_string(&authentication_state)?,
user_id: user_id.clone(),
expire: time() + WEBAUTHN_LOGIN_CHALLENGE_EXPIRE,
})?,
@ -147,7 +134,8 @@ impl WebAuthManager {
std::io::Error::new(ErrorKind::Other, "Challenge has expired!")));
}
self.core.authenticate_credential(pub_cred, &state.authentication_state)?;
self.core.finish_passkey_authentication(pub_cred,
&serde_json::from_str(&state.authentication_state)?)?;
Ok(())
}