#pragma once #include #include #include #include #include #include #include #include #include "PluginRegistrationManager.h" #include #include #include #include #include #include namespace winrt { using namespace winrt::Microsoft::UI::Xaml::Controls; } const DWORD maxWebAuthnWStringSize = 64; constexpr wchar_t c_pluginLocalAppDataDBDir[] = L"CredentialsDB"; constexpr wchar_t c_credentialsFileName[] = L"credentials.dat"; struct PluginCredentialDetailsDeleter { void operator()(EXPERIMENTAL_PWEBAUTHN_PLUGIN_CREDENTIAL_DETAILS p) { delete[](p->pbCredentialId); free(p->pwszRpId); free(p->pwszRpName); delete[](p->pbUserId); free(p->pwszUserName); free(p->pwszUserDisplayName); } }; using unique_plugin_credential_details = std::unique_ptr; struct CredentialDetailsDeleter { void operator()(PWEBAUTHN_CREDENTIAL_DETAILS p) { delete[](p->pbCredentialID); delete[](p->pUserInformation->pbId); delete[](reinterpret_cast(const_cast(p->pRpInformation->pwszId))); delete[](reinterpret_cast(const_cast(p->pRpInformation->pwszName))); delete[](reinterpret_cast(const_cast(p->pUserInformation->pwszName))); delete[](reinterpret_cast(const_cast(p->pUserInformation->pwszDisplayName))); delete p->pUserInformation; delete p->pRpInformation; } }; using unique_credential_details = std::unique_ptr; namespace winrt::PasskeyManager::implementation { class PluginCredentialManager { public: static PluginCredentialManager& getInstance() { static PluginCredentialManager instance; return instance; } HRESULT Initialize() { if (!m_initialized) { ReloadRegistryValues(); ReloadCredentialManager(); m_initialized = true; return S_OK; } RETURN_HR(E_FAIL); } bool IsLocalCredentialMetadataLoaded() { std::lock_guard lock(m_pluginLocalCredentialsOperationMutex); return m_localCredentialsLoaded; } bool IsCachedCredentialsMetadataLoaded() { std::lock_guard lock(m_pluginCachedCredentialsOperationMutex); return m_cachedCredentialsLoaded; } void ReloadRegistryValues() { std::lock_guard lock(m_pluginOperationConfigMutex); auto opt = wil::reg::try_get_value_dword(HKEY_CURRENT_USER, c_pluginRegistryPath, c_windowsPluginSilentOperationRegKeyName); m_silentOperation = opt.value_or(m_silentOperation) != 0; opt = wil::reg::try_get_value_dword(HKEY_CURRENT_USER, c_pluginRegistryPath, c_windowsPluginVaultLockedRegKeyName); m_vaultLocked = opt.value_or(m_vaultLocked) != 0; } HRESULT AddAllPluginCredentials(); HRESULT AddPluginCredentialById(const std::vector> &credentialIdList); HRESULT DeleteAllPluginCredentials(); HRESULT DeletePluginCredentialById(const std::vector> &credentialIdList, bool deleteEverywhere); HRESULT RefreshAutofillPluginCredentialsList(); bool IsPluginCredentialIdAutofillSupported(DWORD cbCredentialId, PBYTE pbCredentialId) const; // Local credential metadata management bool GetCredentialStorageFilePath(std::wstring& filePath); bool SaveCredentialMetadataToMockDB(const WEBAUTHN_CREDENTIAL_DETAILS& newCredential); void GetLocalCredsByRpIdAndAllowList(PCWSTR rpId, PWEBAUTHN_CREDENTIAL_EX* ppCredentialList, DWORD pcCredentials, std::vector& matchingCredentials); bool ResetLocalCredentialsStore(); DWORD GetLocalCredentialCount() { std::lock_guard lock(m_pluginLocalCredentialsOperationMutex); return static_cast(m_pluginLocalCredentialMetadataMap.size()); } DWORD GetCachedCredentialCount() { std::lock_guard lock(m_pluginCachedCredentialsOperationMutex); return static_cast(m_pluginCachedCredentialMetadataMap.size()); } void ReloadCredentialManager() { LoadSavedCredentialsFromMockDatabase(); RefreshAutofillPluginCredentialsList(); } bool GetCredentialStorageFolderPath(std::wstring& outPath) { Windows::Storage::ApplicationData appData = Windows::Storage::ApplicationData::Current(); Windows::Storage::StorageFolder localFolder = appData.LocalFolder(); std::wstring localFolderPath = localFolder.Path().c_str(); outPath = localFolderPath + L"\\" + c_pluginLocalAppDataDBDir; return true; } // UI Related Functions std::vector< winrt::com_ptr> GetCredentialListViewModel(); // Plugin Operations Toggles HRESULT SetVaultLock(bool lock); bool GetVaultLock(); HRESULT SetSilentOperation(bool silent); bool GetSilentOperation(); private: PluginCredentialManager(); ~PluginCredentialManager(); PluginCredentialManager(const PluginCredentialManager&) = delete; PluginCredentialManager& operator=(const PluginCredentialManager&) = delete; bool m_initialized = false; //Local Credential Metadata Management bool LoadSavedCredentialsFromMockDatabase(); bool RecreateCredentialMetadataFile(); std::mutex m_pluginLocalCredentialsOperationMutex; _Guarded_by_(m_pluginLocalCredentialsOperationMutex) bool m_localCredentialsLoaded = false; _Guarded_by_(m_pluginLocalCredentialsOperationMutex) std::map, unique_credential_details> m_pluginLocalCredentialMetadataMap; //Cached Credential Metadata Management std::mutex m_pluginCachedCredentialsOperationMutex; _Guarded_by_(m_pluginCachedCredentialsOperationMutex) bool m_cachedCredentialsLoaded = false; _Guarded_by_(m_pluginCachedCredentialsOperationMutex) std::map, unique_plugin_credential_details> m_pluginCachedCredentialMetadataMap; std::mutex m_pluginOperationConfigMutex; _Guarded_by_(m_pluginOperationConfigMutex) bool m_vaultLocked = false; _Guarded_by_(m_pluginOperationConfigMutex) bool m_silentOperation = false; wil::unique_hmodule m_webAuthnDll; }; }