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

Add more test code

This commit is contained in:
Colton Hurst
2025-05-22 16:00:06 -04:00
parent 8c8b9625ae
commit 214bf02f34
3 changed files with 246 additions and 49 deletions

View File

@@ -2,6 +2,9 @@
#![allow(non_snake_case)]
#![allow(non_camel_case_types)]
use std::ffi::OsString;
use std::os::windows::ffi::OsStrExt;
use std::ffi::c_uchar;
use std::ffi::c_ulong;
use std::ptr;
@@ -38,14 +41,164 @@ pub fn register() -> std::result::Result<(), String> {
util::message(String::from("About to call add_authenticator()"));
let r = add_authenticator();
//let r = add_authenticator_using_wide_encoding();
util::message(format!("added the authenticator: {:?}", r));
util::message(String::from("sleeping for 20 seconds..."));
thread::sleep(Duration::from_millis(20000));
util::message(String::from("sleeping done"));
// // ---------------------------------------
// // ----- *** add test credential *** -----
// // ----- using encode_utf16 -----
// // ---------------------------------------
// // Style 1, currently used: mem::forget
// let mut credential_id_string = String::from("32");
// let credential_id_byte_count = credential_id_string.as_bytes().len() as c_ulong;
// let credential_id_pointer: *mut c_uchar = credential_id_string.as_mut_ptr();
// std::mem::forget(credential_id_string);
// // Style 2, experimental: Box::leak
// // Additionally, might need to Pin (same for style 1)
// //
// // let credential_id_string = String::from("32");
// // let credential_id_byte_count = credential_id_string.as_bytes().len() as c_ulong;
// // let credential_id_box = Box::new(credential_id_string);
// // let credential_id_pointer: *mut c_uchar = credential_id_box.leak().as_mut_ptr();
// let mut rpid_string = String::from("webauthn.io");
// let mut rpid_vec: Vec<u16> = rpid_string.encode_utf16().collect();
// rpid_vec.push(0);
// let rpid: *mut u16 = rpid_vec.as_mut_ptr();
// std::mem::forget(rpid_string);
// std::mem::forget(rpid_vec);
// let mut rp_friendly_name_string = String::from("WebAuthn Website");
// let mut rp_friendly_name_vec: Vec<u16> = rp_friendly_name_string.encode_utf16().collect();
// rp_friendly_name_vec.push(0);
// let rp_friendly_name: *mut u16 = rp_friendly_name_vec.as_mut_ptr();
// std::mem::forget(rp_friendly_name_string);
// std::mem::forget(rp_friendly_name_vec);
// let mut user_id_string = String::from("14");
// let user_id_byte_count = user_id_string.as_bytes().len() as c_ulong;
// let user_id_pointer: *mut c_uchar = user_id_string.as_mut_ptr();
// std::mem::forget(user_id_string);
// let mut user_name_string = String::from("webauthn.io username");
// let mut user_name_vec: Vec<u16> = user_name_string.encode_utf16().collect();
// user_name_vec.push(0);
// let user_name: *mut u16 = user_name_vec.as_mut_ptr();
// std::mem::forget(user_name_string);
// std::mem::forget(user_name_vec);
// let mut user_display_name_string = String::from("webauthn.io display name");
// let mut user_display_name_vec: Vec<u16> = user_display_name_string.encode_utf16().collect();
// user_display_name_vec.push(0);
// let user_display_name: *mut u16 = user_display_name_vec.as_mut_ptr();
// std::mem::forget(user_display_name_string);
// std::mem::forget(user_display_name_vec);
// let mut credential_details = ExperimentalWebAuthnPluginCredentialDetails {
// credential_id_byte_count,
// credential_id_pointer,
// rpid,
// rp_friendly_name,
// user_id_byte_count,
// user_id_pointer,
// user_name,
// user_display_name,
// };
// let credential_details_ptr: *mut ExperimentalWebAuthnPluginCredentialDetails =
// &mut credential_details;
// std::mem::forget(credential_details);
// let mut clsid_string = String::from(format!("{{{}}}", CLSID));
// let mut clsid_vec: Vec<u16> = clsid_string.encode_utf16().collect();
// clsid_vec.push(0);
// let plugin_clsid: *mut u16 = clsid_vec.as_mut_ptr();
// std::mem::forget(clsid_string);
// std::mem::forget(clsid_vec);
// let mut credentials: Vec<*mut ExperimentalWebAuthnPluginCredentialDetails> =
// vec![credential_details_ptr];
// let credential_count: c_ulong = credentials.len() as c_ulong;
// let credentials_ptr: *mut *mut ExperimentalWebAuthnPluginCredentialDetails =
// credentials.as_mut_ptr();
// std::mem::forget(credentials);
// let mut credentials_details_list = ExperimentalWebAuthnPluginCredentialDetailsList {
// plugin_clsid,
// credential_count,
// credentials: credentials_ptr,
// };
// let credentials_details_list_ptr: *mut ExperimentalWebAuthnPluginCredentialDetailsList =
// &mut credentials_details_list;
// std::mem::forget(credentials_details_list);
// util::message(format!("about to link the fn pointer for add credentials"));
// let result = unsafe {
// delay_load::<EXPERIMENTAL_WebAuthNPluginAuthenticatorAddCredentialsFnDeclaration>(
// s!("webauthn.dll"),
// s!("EXPERIMENTAL_WebAuthNPluginAuthenticatorAddCredentials"),
// )
// };
// util::message(format!("about to call add credentials"));
// let result = match result {
// Some(api) => {
// let result = unsafe { api(credentials_details_list_ptr) };
// if result.is_err() {
// return Err(format!(
// "Error: Error response from EXPERIMENTAL_WebAuthNPluginAuthenticatorAddCredentials()\n{}",
// result.message()
// ));
// }
// Ok(())
// },
// None => {
// Err(String::from("Error: Can't complete add_credentials(), as the function EXPERIMENTAL_WebAuthNPluginAuthenticatorAddCredentials can't be loaded."))
// }
// };
// util::message(format!("add credentials attempt: {:?}", result));
// --------------------------------------------------------------------------------------------
// std::mem::forget(credential_id);
// let mut test_credential = ExperimentalWebAuthnPluginCredentialDetails::create(
// String::from("32"),
// String::from("webauthn.io"),
// String::from("WebAuthn Website"),
// String::from("14"),
// String::from("web user name"),
// String::from("web user display name"),
// );
// let test_credential_ptr: *mut ExperimentalWebAuthnPluginCredentialDetails = &mut test_credential;
// //std::mem::forget(test_credential);
// let mut test_credential_list: Vec<*mut ExperimentalWebAuthnPluginCredentialDetails> = vec![test_credential_ptr];
// let test_credential_list_ptr: *mut *mut ExperimentalWebAuthnPluginCredentialDetails = test_credential_list.as_mut_ptr();
// let pluginclsid = String::from(CLSID).into_win_utf16().0;
// let credentials = ExperimentalWebAuthnPluginCredentialDetailsList {
// plugin_clsid: pluginclsid,
// credential_count: 1,
// credentials: test_credential_list_ptr,
// };
// let r = add_credentials(credentials);
// util::message(format!("added the credentials: {:?}", r));
// --------------------------------------------------------------------------------------------
// ---------------------------------------
// ----- *** add test credential *** -----
// ----- using encode_wide -----
// ---------------------------------------
// Style 1, currently used: mem::forget
@@ -54,26 +207,16 @@ pub fn register() -> std::result::Result<(), String> {
let credential_id_pointer: *mut c_uchar = credential_id_string.as_mut_ptr();
std::mem::forget(credential_id_string);
// Style 2, experimental: Box::leak
// Additionally, might need to Pin (same for style 1)
//
// let credential_id_string = String::from("32");
// let credential_id_byte_count = credential_id_string.as_bytes().len() as c_ulong;
// let credential_id_box = Box::new(credential_id_string);
// let credential_id_pointer: *mut c_uchar = credential_id_box.leak().as_mut_ptr();
let mut rpid_string = String::from("webauthn.io");
let mut rpid_vec: Vec<u16> = rpid_string.encode_utf16().collect();
let rpid_string = String::from("webauthn.io");
let mut rpid_vec: Vec<u16> = OsString::from(rpid_string).encode_wide().collect();
rpid_vec.push(0);
let rpid: *mut u16 = rpid_vec.as_mut_ptr();
std::mem::forget(rpid_string);
std::mem::forget(rpid_vec);
let mut rp_friendly_name_string = String::from("WebAuthn Website");
let mut rp_friendly_name_vec: Vec<u16> = rp_friendly_name_string.encode_utf16().collect();
let rp_friendly_name_string = String::from("WebAuthn Websitewide ");
let mut rp_friendly_name_vec: Vec<u16> = OsString::from(rp_friendly_name_string).encode_wide().collect();
rp_friendly_name_vec.push(0);
let rp_friendly_name: *mut u16 = rp_friendly_name_vec.as_mut_ptr();
std::mem::forget(rp_friendly_name_string);
std::mem::forget(rp_friendly_name_vec);
let mut user_id_string = String::from("14");
@@ -81,18 +224,16 @@ pub fn register() -> std::result::Result<(), String> {
let user_id_pointer: *mut c_uchar = user_id_string.as_mut_ptr();
std::mem::forget(user_id_string);
let mut user_name_string = String::from("webauthn.io username");
let mut user_name_vec: Vec<u16> = user_name_string.encode_utf16().collect();
let user_name_string = String::from("webauthn.io wide username");
let mut user_name_vec: Vec<u16> = OsString::from(user_name_string).encode_wide().collect();
user_name_vec.push(0);
let user_name: *mut u16 = user_name_vec.as_mut_ptr();
std::mem::forget(user_name_string);
std::mem::forget(user_name_vec);
let mut user_display_name_string = String::from("webauthn.io display name");
let mut user_display_name_vec: Vec<u16> = user_display_name_string.encode_utf16().collect();
let user_display_name_string = String::from("webauthn.io wide display name");
let mut user_display_name_vec: Vec<u16> = OsString::from(user_display_name_string).encode_wide().collect();
user_display_name_vec.push(0);
let user_display_name: *mut u16 = user_display_name_vec.as_mut_ptr();
std::mem::forget(user_display_name_string);
std::mem::forget(user_display_name_vec);
let mut credential_details = ExperimentalWebAuthnPluginCredentialDetails {
@@ -109,11 +250,10 @@ pub fn register() -> std::result::Result<(), String> {
&mut credential_details;
std::mem::forget(credential_details);
let mut clsid_string = String::from(format!("{{{}}}", CLSID));
let mut clsid_vec: Vec<u16> = clsid_string.encode_utf16().collect();
let clsid_string = String::from(format!("{{{}}}", CLSID));
let mut clsid_vec: Vec<u16> = OsString::from(clsid_string).encode_wide().collect();
clsid_vec.push(0);
let plugin_clsid: *mut u16 = clsid_vec.as_mut_ptr();
std::mem::forget(clsid_string);
std::mem::forget(clsid_vec);
let mut credentials: Vec<*mut ExperimentalWebAuthnPluginCredentialDetails> =
@@ -163,29 +303,7 @@ pub fn register() -> std::result::Result<(), String> {
util::message(format!("add credentials attempt: {:?}", result));
// std::mem::forget(credential_id);
// let mut test_credential = ExperimentalWebAuthnPluginCredentialDetails::create(
// String::from("32"),
// String::from("webauthn.io"),
// String::from("WebAuthn Website"),
// String::from("14"),
// String::from("web user name"),
// String::from("web user display name"),
// );
// let test_credential_ptr: *mut ExperimentalWebAuthnPluginCredentialDetails = &mut test_credential;
// //std::mem::forget(test_credential);
// let mut test_credential_list: Vec<*mut ExperimentalWebAuthnPluginCredentialDetails> = vec![test_credential_ptr];
// let test_credential_list_ptr: *mut *mut ExperimentalWebAuthnPluginCredentialDetails = test_credential_list.as_mut_ptr();
// let pluginclsid = String::from(CLSID).into_win_utf16().0;
// let credentials = ExperimentalWebAuthnPluginCredentialDetailsList {
// plugin_clsid: pluginclsid,
// credential_count: 1,
// credentials: test_credential_list_ptr,
// };
// let r = add_credentials(credentials);
// util::message(format!("added the credentials: {:?}", r));
// --------------------------------------------------------------------------------------------
Ok(())
}
@@ -271,6 +389,74 @@ fn register_com_library() -> std::result::Result<(), String> {
}
}
// testing wide encoding
fn add_authenticator_using_wide_encoding() -> std::result::Result<(), String> {
// let (authenticator_name_pointer, authenticator_name_bytes) = String::from(AUTHENTICATOR_NAME).into_win_utf16_wide();
let mut authenticator_name: Vec<u16> = OsString::from(AUTHENTICATOR_NAME).encode_wide().collect();
//authenticator_name.push(0);
let authenticator_name_pointer = authenticator_name.as_mut_ptr();
// let (clsid_pointer, clsid_bytes) = String::from(CLSID).into_win_utf16_wide();
let mut clsid: Vec<u16> = OsString::from(CLSID).encode_wide().collect();
//clsid.push(0);
let clsid_pointer = clsid.as_mut_ptr();
// let (rpid_pointer, rpid_bytes) = String::from(RPID).into_win_utf16_wide();
let mut rpid: Vec<u16> = OsString::from(RPID).encode_wide().collect();
//rpid.push(0);
let rpid_pointer = rpid.as_mut_ptr();
// Example authenticator info blob
let cbor_authenticator_info = "A60182684649444F5F325F30684649444F5F325F310282637072666B686D61632D7365637265740350D548826E79B4DB40A3D811116F7E834904A362726BF5627570F5627576F5098168696E7465726E616C0A81A263616C672664747970656A7075626C69632D6B6579";
let mut authenticator_info_bytes = hex::decode(cbor_authenticator_info).unwrap();
let add_authenticator_options = webauthn::ExperimentalWebAuthnPluginAddAuthenticatorOptions {
authenticator_name: authenticator_name_pointer,
plugin_clsid: clsid_pointer,
rpid: rpid_pointer,
light_theme_logo: ptr::null(),
dark_theme_logo: ptr::null(),
cbor_authenticator_info_byte_count: authenticator_info_bytes.len() as u32,
cbor_authenticator_info: authenticator_info_bytes.as_mut_ptr(),
};
let plugin_signing_public_key_byte_count: u32 = 0;
let mut plugin_signing_public_key: c_uchar = 0;
let plugin_signing_public_key_ptr = &mut plugin_signing_public_key;
let mut add_response = webauthn::ExperimentalWebAuthnPluginAddAuthenticatorResponse {
plugin_operation_signing_key_byte_count: plugin_signing_public_key_byte_count,
plugin_operation_signing_key: plugin_signing_public_key_ptr,
};
let mut add_response_ptr: *mut webauthn::ExperimentalWebAuthnPluginAddAuthenticatorResponse =
&mut add_response;
let result = unsafe {
delay_load::<EXPERIMENTAL_WebAuthNPluginAddAuthenticatorFnDeclaration>(
s!("webauthn.dll"),
s!("EXPERIMENTAL_WebAuthNPluginAddAuthenticator"),
)
};
match result {
Some(api) => {
let result = unsafe { api(&add_authenticator_options, &mut add_response_ptr) };
if result.is_err() {
return Err(format!(
"Error: Error response from EXPERIMENTAL_WebAuthNPluginAddAuthenticator()\n{}",
result.message()
));
}
Ok(())
},
None => {
Err(String::from("Error: Can't complete add_authenticator(), as the function EXPERIMENTAL_WebAuthNPluginAddAuthenticator can't be found."))
}
}
}
/// Adds Bitwarden as a plugin authenticator.
fn add_authenticator() -> std::result::Result<(), String> {
let authenticator_name: HSTRING = AUTHENTICATOR_NAME.into();
@@ -293,8 +479,8 @@ fn add_authenticator() -> std::result::Result<(), String> {
authenticator_name: authenticator_name_ptr,
plugin_clsid: clsid_ptr,
rpid: relying_party_id_ptr,
light_theme_logo: ptr::null(), // unused by Windows
dark_theme_logo: ptr::null(), // unused by Windows
light_theme_logo: ptr::null(),
dark_theme_logo: ptr::null(),
cbor_authenticator_info_byte_count: authenticator_info_bytes.len() as u32,
cbor_authenticator_info: authenticator_info_bytes.as_mut_ptr(),
};

View File

@@ -12,7 +12,7 @@
*/
use windows::Win32::System::Com::*;
use windows::{Foundation::*, Win32::System::Com::*};
//use windows::{Foundation::*, Win32::System::Com::*};
use windows_core::*;
use crate::util;

View File

@@ -1,3 +1,6 @@
use std::ffi::OsString;
use std::os::windows::ffi::OsStrExt;
use serde_json::json;
use windows::Win32::Foundation::*;
use windows::Win32::System::LibraryLoader::*;
@@ -24,6 +27,7 @@ pub unsafe fn delay_load<T>(library: PCSTR, function: PCSTR) -> Option<T> {
pub trait WindowsString {
fn into_win_utf8(self: Self) -> (*mut u8, u32);
fn into_win_utf16(self: Self) -> (*mut u16, u32);
fn into_win_utf16_wide(self: Self) -> (*mut u16, u32);
}
impl WindowsString for String {
@@ -40,6 +44,13 @@ impl WindowsString for String {
(v.as_mut_ptr(), v.len() as u32)
}
fn into_win_utf16_wide(self: Self) -> (*mut u16, u32) {
let mut v: Vec<u16> = OsString::from(self).encode_wide().collect();
v.push(0);
(v.as_mut_ptr(), v.len() as u32)
}
}
pub fn message(message: String) {