1
0
mirror of https://github.com/bitwarden/browser synced 2026-02-02 17:53:41 +00:00

Implement EXPERIMENTAL2

This commit is contained in:
Anders Åberg
2025-08-14 21:34:54 +02:00
parent 65cb4bf4b2
commit 3032f4f523

View File

@@ -7,6 +7,13 @@ use crate::make_credential::experimental_plugin_make_credential;
use crate::util::debug_log;
use crate::webauthn::WEBAUTHN_CREDENTIAL_LIST;
/// Plugin request type enum as defined in the IDL
#[repr(u32)]
#[derive(Debug, Copy, Clone)]
pub enum WebAuthnPluginRequestType {
CTAP2_CBOR = 0x01,
}
/// Plugin lock status enum as defined in the IDL
#[repr(u32)]
#[derive(Debug, Copy, Clone)]
@@ -30,6 +37,22 @@ pub struct ExperimentalWebAuthnPluginOperationRequest {
pub encoded_request_pointer: *mut u8,
}
/// Used when creating and asserting credentials with EXPERIMENTAL2 interface.
/// Header File Name: _EXPERIMENTAL2_WEBAUTHN_PLUGIN_OPERATION_REQUEST
/// Header File Usage: EXPERIMENTAL_MakeCredential()
/// EXPERIMENTAL_GetAssertion()
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct Experimental2WebAuthnPluginOperationRequest {
pub window_handle: windows::Win32::Foundation::HWND,
pub transaction_id: windows_core::GUID,
pub request_signature_byte_count: u32,
pub request_signature_pointer: *mut u8,
pub request_type: WebAuthnPluginRequestType,
pub encoded_request_byte_count: u32,
pub encoded_request_pointer: *mut u8,
}
/// Used as a response when creating and asserting credentials.
/// Header File Name: _EXPERIMENTAL_WEBAUTHN_PLUGIN_OPERATION_RESPONSE
@@ -75,6 +98,28 @@ pub unsafe trait EXPERIMENTAL_IPluginAuthenticator: windows_core::IUnknown {
) -> HRESULT;
}
#[interface("d26bcf6f-b54c-43ff-9f06-d5bf148625f7")]
pub unsafe trait EXPERIMENTAL2_IPluginAuthenticator: windows_core::IUnknown {
fn EXPERIMENTAL_MakeCredential(
&self,
request: *const Experimental2WebAuthnPluginOperationRequest,
response: *mut *mut ExperimentalWebAuthnPluginOperationResponse,
) -> HRESULT;
fn EXPERIMENTAL_GetAssertion(
&self,
request: *const Experimental2WebAuthnPluginOperationRequest,
response: *mut *mut ExperimentalWebAuthnPluginOperationResponse,
) -> HRESULT;
fn EXPERIMENTAL_CancelOperation(
&self,
request: *const ExperimentalWebAuthnPluginCancelOperationRequest,
) -> HRESULT;
fn EXPERIMENTAL_GetLockStatus(
&self,
lock_status: *mut PluginLockStatus,
) -> HRESULT;
}
pub unsafe fn parse_credential_list(credential_list: &WEBAUTHN_CREDENTIAL_LIST) -> Vec<Vec<u8>> {
let mut allowed_credentials = Vec::new();
@@ -129,7 +174,7 @@ pub unsafe fn parse_credential_list(credential_list: &WEBAUTHN_CREDENTIAL_LIST)
allowed_credentials
}
#[implement(EXPERIMENTAL_IPluginAuthenticator)]
#[implement(EXPERIMENTAL_IPluginAuthenticator, EXPERIMENTAL2_IPluginAuthenticator)]
pub struct PluginAuthenticatorComObject;
#[implement(IClassFactory)]
@@ -168,7 +213,62 @@ impl EXPERIMENTAL_IPluginAuthenticator_Impl for PluginAuthenticatorComObject_Imp
if lock_status.is_null() {
return HRESULT(-2147024809); // E_INVALIDARG
}
// For now, always return unlocked
*lock_status = PluginLockStatus::PluginUnlocked;
HRESULT(0)
}
}
impl EXPERIMENTAL2_IPluginAuthenticator_Impl for PluginAuthenticatorComObject_Impl {
unsafe fn EXPERIMENTAL_MakeCredential(
&self,
request: *const Experimental2WebAuthnPluginOperationRequest,
response: *mut *mut ExperimentalWebAuthnPluginOperationResponse,
) -> HRESULT {
debug_log("EXPERIMENTAL2_MakeCredential() called");
let legacy_request = ExperimentalWebAuthnPluginOperationRequest {
window_handle: (*request).window_handle,
transaction_id: (*request).transaction_id,
request_signature_byte_count: (*request).request_signature_byte_count,
request_signature_pointer: (*request).request_signature_pointer,
encoded_request_byte_count: (*request).encoded_request_byte_count,
encoded_request_pointer: (*request).encoded_request_pointer,
};
experimental_plugin_make_credential(&legacy_request, response)
}
unsafe fn EXPERIMENTAL_GetAssertion(
&self,
request: *const Experimental2WebAuthnPluginOperationRequest,
response: *mut *mut ExperimentalWebAuthnPluginOperationResponse,
) -> HRESULT {
debug_log("EXPERIMENTAL2_GetAssertion() called");
let legacy_request = ExperimentalWebAuthnPluginOperationRequest {
window_handle: (*request).window_handle,
transaction_id: (*request).transaction_id,
request_signature_byte_count: (*request).request_signature_byte_count,
request_signature_pointer: (*request).request_signature_pointer,
encoded_request_byte_count: (*request).encoded_request_byte_count,
encoded_request_pointer: (*request).encoded_request_pointer,
};
experimental_plugin_get_assertion(&legacy_request, response)
}
unsafe fn EXPERIMENTAL_CancelOperation(
&self,
_request: *const ExperimentalWebAuthnPluginCancelOperationRequest,
) -> HRESULT {
debug_log("EXPERIMENTAL2_CancelOperation() called");
HRESULT(0)
}
unsafe fn EXPERIMENTAL_GetLockStatus(
&self,
lock_status: *mut PluginLockStatus,
) -> HRESULT {
debug_log("EXPERIMENTAL2_GetLockStatus() called");
if lock_status.is_null() {
return HRESULT(-2147024809); // E_INVALIDARG
}
*lock_status = PluginLockStatus::PluginUnlocked;
HRESULT(0)
}