Update webauthn-rs dependency
				
					
				
			This commit is contained in:
		| @@ -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(®istration_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(()) | ||||
|     } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user