diff --git a/apps/desktop/desktop_native/core/src/autofill/windows.rs b/apps/desktop/desktop_native/core/src/autofill/windows.rs index f6f0c7eb7db..5dd804097a0 100644 --- a/apps/desktop/desktop_native/core/src/autofill/windows.rs +++ b/apps/desktop/desktop_native/core/src/autofill/windows.rs @@ -59,7 +59,9 @@ fn handle_user_verification_request( request: UserVerificationParameters, ) -> Result { tracing::debug!(?request, "Handling user verification request"); - let (buf, _) = request.transaction_context[..16].split_at(16); + // 0-15 GUID + // 16..47 SHA256 hash of Windows operation request + let (buf, operation_request_hash) = request.transaction_context[..16].split_at(16); let guid_u128 = buf .try_into() .map_err(|e| anyhow!("Failed to parse transaction ID as u128: {e}"))?; @@ -81,7 +83,10 @@ fn handle_user_verification_request( user_name: request.username, display_hint: Some(request.display_hint), }; - let _response = WebAuthnPlugin::perform_user_verification(uv_request) + let clsid = Clsid::try_from(PLUGIN_CLSID) + .map_err(|err| anyhow!("Failed to parse CLSID from string {PLUGIN_CLSID}: {err}"))?; + let plugin = WebAuthnPlugin::new(clsid); + let _response = plugin.perform_user_verification(uv_request, operation_request_hash) .map_err(|err| anyhow!("User Verification request failed: {err}"))?; return Ok(UserVerificationResponse {}); } diff --git a/apps/desktop/desktop_native/win_webauthn/src/plugin/mod.rs b/apps/desktop/desktop_native/win_webauthn/src/plugin/mod.rs index b1cb395b813..d912021b36c 100644 --- a/apps/desktop/desktop_native/win_webauthn/src/plugin/mod.rs +++ b/apps/desktop/desktop_native/win_webauthn/src/plugin/mod.rs @@ -149,10 +149,19 @@ impl WebAuthnPlugin { } } + /// Perform user verification related to an associated MakeCredential or GetAssertion request. + /// request pub fn perform_user_verification( + &self, request: PluginUserVerificationRequest, + operation_request: &[u8], ) -> Result { tracing::debug!(?request, "Handling user verification request"); + + // Get pub key + let pub_key = crypto::get_user_verification_public_key(&self.clsid.0)?; + + // Send UV request let user_name = request.user_name.to_utf16().to_com_buffer(); let hint = request.display_hint.map(|d| d.to_utf16().to_com_buffer()); let uv_request = WEBAUTHN_PLUGIN_USER_VERIFICATION_REQUEST { @@ -174,11 +183,13 @@ impl WebAuthnPlugin { Vec::new() } else { // SAFETY: Windows returned successful response code and length, so we assume that the data is initialized - unsafe { + let signature = unsafe { // SAFETY: Windows only runs on platforms where usize >= u32; let len = response_len as usize; std::slice::from_raw_parts(response_ptr, len).to_vec() - } + }; + pub_key.verify_signature(operation_request, &signature)?; + signature }; webauthn_plugin_free_user_verification_response(response_ptr)?; Ok(PluginUserVerificationResponse {