diff --git a/apps/desktop/desktop_native/Cargo.lock b/apps/desktop/desktop_native/Cargo.lock
index 2fc15fceb7e..e45955de069 100644
--- a/apps/desktop/desktop_native/Cargo.lock
+++ b/apps/desktop/desktop_native/Cargo.lock
@@ -5161,6 +5161,7 @@ checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2"
name = "windows_plugin_authenticator"
version = "0.0.0"
dependencies = [
+ "base64",
"ciborium",
"desktop_core",
"futures",
diff --git a/apps/desktop/desktop_native/windows_plugin_authenticator/Cargo.toml b/apps/desktop/desktop_native/windows_plugin_authenticator/Cargo.toml
index 83bf70b9dbe..89ade1f6ea4 100644
--- a/apps/desktop/desktop_native/windows_plugin_authenticator/Cargo.toml
+++ b/apps/desktop/desktop_native/windows_plugin_authenticator/Cargo.toml
@@ -24,6 +24,7 @@ tracing-subscriber = { workspace = true }
ciborium = "0.2"
sha2 = "0.10"
tokio = { workspace = true }
+base64 = { workspace = true }
[lints]
workspace = true
diff --git a/apps/desktop/desktop_native/windows_plugin_authenticator/src/com_registration.rs b/apps/desktop/desktop_native/windows_plugin_authenticator/src/com_registration.rs
index 64c3e1e3d4c..f39cd3798c3 100644
--- a/apps/desktop/desktop_native/windows_plugin_authenticator/src/com_registration.rs
+++ b/apps/desktop/desktop_native/windows_plugin_authenticator/src/com_registration.rs
@@ -1,5 +1,6 @@
use std::ptr;
+use base64::{engine::general_purpose::STANDARD, Engine as _};
use windows::Win32::System::Com::*;
use windows_core::{s, ComObjectInterface, GUID, HRESULT, HSTRING, PCWSTR};
@@ -12,6 +13,7 @@ const AUTHENTICATOR_NAME: &str = "Bitwarden Desktop";
const CLSID: &str = "0f7dc5d9-69ce-4652-8572-6877fd695062";
const RPID: &str = "bitwarden.com";
const AAGUID: &str = "d548826e-79b4-db40-a3d8-11116f7e8349";
+const LOGO_SVG: &str = r##""##;
/// Parses a UUID string (with hyphens) into bytes
fn parse_uuid_to_bytes(uuid_str: &str) -> Result, String> {
@@ -184,6 +186,10 @@ pub fn add_authenticator() -> std::result::Result<(), String> {
let relying_party_id: HSTRING = RPID.into();
let relying_party_id_ptr = PCWSTR(relying_party_id.as_ptr()).as_ptr();
+ // Base64-encode the SVG as required by Windows API
+ let logo_b64: String = STANDARD.encode(LOGO_SVG);
+ let logo_b64_buf: Vec = logo_b64.encode_utf16().chain(std::iter::once(0)).collect();
+
// Generate CBOR authenticator info dynamically
let authenticator_info_bytes = generate_cbor_authenticator_info()
.map_err(|e| format!("Failed to generate authenticator info: {}", e))?;
@@ -192,8 +198,8 @@ pub fn add_authenticator() -> std::result::Result<(), String> {
authenticator_name: authenticator_name_ptr,
rclsid: &clsid_guid, // Changed to GUID reference
rpid: relying_party_id_ptr,
- light_theme_logo_svg: ptr::null(), // Renamed field
- dark_theme_logo_svg: ptr::null(), // Renamed field
+ light_theme_logo_svg: logo_b64_buf.as_ptr(),
+ dark_theme_logo_svg: logo_b64_buf.as_ptr(),
cbor_authenticator_info_byte_count: authenticator_info_bytes.len() as u32,
cbor_authenticator_info: authenticator_info_bytes.as_ptr(), // Use as_ptr() not as_mut_ptr()
supported_rp_ids_count: 0, // NEW field: 0 means all RPs supported