Skip to content

Commit

Permalink
Add support for Windows Hello
Browse files Browse the repository at this point in the history
* Special thanks to @HexF and @smlu for their contributions towards this feature.

* Add MVP support for Windows Hello as a Quick Unlock solution using the WinRT API. This works by signing a random challenge vector with the Windows Hello protected key store (typically from TPM). The signed challenge is hashed using SHA-256 and then used as the encryption key to encrypt the database credentials. Credentials are encrypted using AES-256/GCM. This ensures the database password can only be decrypted following a successful authentication with Windows Hello in the future.

* Unify Touch ID and Windows Hello behavior under the Quick Unlock branding. Remove all timeout features of Touch ID as they are unnecessary and complicate the feature for no security gain.

* Quick Unlock is automatically reset only when the database key is changed vice whenever database settings are modified.

* Don't set database unlock dialog as always on top. This allows Touch ID and Windows Hello prompts to appear above the dialog properly.

* Prevent quick unlock when using AutoOpen or opening from the command line.
  • Loading branch information
droidmonkey committed Feb 22, 2022
1 parent a76daeb commit 4f07103
Show file tree
Hide file tree
Showing 33 changed files with 1,036 additions and 712 deletions.
6 changes: 0 additions & 6 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,6 @@ option(WITH_XC_UPDATECHECK "Include automatic update checks; disable for control
if(UNIX AND NOT APPLE)
option(WITH_XC_FDOSECRETS "Implement freedesktop.org Secret Storage Spec server side API." OFF)
endif()
if(APPLE)
option(WITH_XC_TOUCHID "Include TouchID support for macOS." OFF)
endif()
option(WITH_XC_DOCS "Enable building of documentation" ON)

if(WITH_CCACHE)
Expand All @@ -81,9 +78,6 @@ if(WITH_XC_ALL)
set(WITH_XC_YUBIKEY ON)
set(WITH_XC_SSHAGENT ON)
set(WITH_XC_KEESHARE ON)
if(APPLE)
set(WITH_XC_TOUCHID ON)
endif()
if(UNIX AND NOT APPLE)
set(WITH_XC_FDOSECRETS ON)
endif()
Expand Down
3 changes: 2 additions & 1 deletion COPYING
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ Files: share/icons/badges/2_Expired.svg
share/icons/database/C46_Help.svg
share/icons/database/C53_Apply.svg
share/icons/database/C61_Services.svg
Copyright: 2020 KeePassXC Team <team@keepassxc.org>
Copyright: 2022 KeePassXC Team <team@keepassxc.org>
License: MIT

Files: share/icons/application/scalable/actions/chevron-double-down.svg
Expand All @@ -166,6 +166,7 @@ Files: share/icons/application/scalable/actions/chevron-double-down.svg
share/icons/application/scalable/actions/entry-edit.svg
share/icons/application/scalable/actions/entry-new.svg
share/icons/application/scalable/actions/favicon-download.svg
share/icons/application/scalable/actions/fingerprint.svg
share/icons/application/scalable/actions/group-clone.svg
share/icons/application/scalable/actions/group-delete.svg
share/icons/application/scalable/actions/group-edit.svg
Expand Down
1 change: 0 additions & 1 deletion INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,6 @@ These steps place the compiled KeePassXC binary inside the `./build/src/` direct
-DWITH_XC_BROWSER=[ON|OFF] Enable/Disable KeePassXC-Browser extension support (default: OFF)
-DWITH_XC_NETWORKING=[ON|OFF] Enable/Disable Networking support (e.g., favicon downloading) (default: OFF)
-DWITH_XC_SSHAGENT=[ON|OFF] Enable/Disable SSHAgent support (default: OFF)
-DWITH_XC_TOUCHID=[ON|OFF] (macOS Only) Enable/Disable Touch ID unlock (default:OFF)
-DWITH_XC_FDOSECRETS=[ON|OFF] (Linux Only) Enable/Disable Freedesktop.org Secrets Service support (default:OFF)
-DWITH_XC_KEESHARE=[ON|OFF] Enable/Disable KeeShare group synchronization extension (default: OFF)
-DWITH_XC_ALL=[ON|OFF] Enable/Disable compiling all plugins above (default: OFF)
Expand Down
1 change: 1 addition & 0 deletions share/icons/application/scalable/actions/fingerprint.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion share/icons/icons.qrc
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
<file>application/scalable/actions/entry-edit.svg</file>
<file>application/scalable/actions/entry-new.svg</file>
<file>application/scalable/actions/favicon-download.svg</file>
<file>application/scalable/actions/fingerprint.svg</file>
<file>application/scalable/actions/getting-started.svg</file>
<file>application/scalable/actions/group-delete.svg</file>
<file>application/scalable/actions/group-edit.svg</file>
Expand Down Expand Up @@ -80,7 +81,6 @@
<file>application/scalable/actions/username-copy.svg</file>
<file>application/scalable/actions/view-history.svg</file>
<file>application/scalable/actions/web.svg</file>

<file>application/scalable/apps/freedesktop.svg</file>
<file>application/scalable/apps/internet-web-browser.svg</file>
<file>application/scalable/apps/keepassxc.svg</file>
Expand Down
83 changes: 55 additions & 28 deletions share/translations/keepassxc_en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -508,14 +508,6 @@
<source>Lock databases after inactivity of</source>
<translation>Lock databases after inactivity of</translation>
</message>
<message>
<source> min</source>
<translation> min</translation>
</message>
<message>
<source>Forget TouchID after inactivity of</source>
<translation>Forget TouchID after inactivity of</translation>
</message>
<message>
<source>Convenience</source>
<translation>Convenience</translation>
Expand All @@ -524,10 +516,6 @@
<source>Lock databases when session is locked or lid is closed</source>
<translation>Lock databases when session is locked or lid is closed</translation>
</message>
<message>
<source>Forget TouchID when session is locked or lid is closed</source>
<translation>Forget TouchID when session is locked or lid is closed</translation>
</message>
<message>
<source>Lock databases after minimizing the window</source>
<translation>Lock databases after minimizing the window</translation>
Expand All @@ -552,10 +540,6 @@
<source>Clipboard clear seconds</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Touch ID inactivity reset</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Database lock timeout seconds</source>
<translation type="unfinished"></translation>
Expand Down Expand Up @@ -589,6 +573,10 @@
<source>Enable double click to copy the username/password entry columns</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Enable database quick unlock (Touch ID / Windows Hello)</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>AutoType</name>
Expand Down Expand Up @@ -1474,10 +1462,6 @@ Backup database located at %2</source>
<source>Hardware key help</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>TouchID for Quick Unlock</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unlock failed and no password given</source>
<translation type="unfinished"></translation>
Expand All @@ -1501,10 +1485,6 @@ To prevent this error from appearing, you must go to &quot;Database Settings / S
<source>Key file help</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>?</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Cannot use database file as key file</source>
<translation type="unfinished"></translation>
Expand Down Expand Up @@ -1577,6 +1557,26 @@ We recommend you update your KeePassXC installation.</source>
<source>Database unlock canceled.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unlock</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Failed to authenticate with Windows Hello</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unlock Database</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Cancel</source>
<translation type="unfinished">Cancel</translation>
</message>
<message>
<source>Failed to authenticate with Touch ID</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>DatabaseSettingWidgetMetaData</name>
Expand Down Expand Up @@ -6837,10 +6837,6 @@ Kernel: %3 %4</source>
<source>YubiKey</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>TouchID</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>None</source>
<translation type="unfinished"></translation>
Expand Down Expand Up @@ -7770,6 +7766,18 @@ Please consider generating a new key file.</source>
<source>Browser Statistics</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Quick Unlock</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Failed to create Windows Hello credential.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Failed to sign challenge using Windows Hello.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>QtIOCompressor</name>
Expand Down Expand Up @@ -8762,6 +8770,25 @@ Example: JBSWY3DPEHPK3PXP</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>WindowsHello</name>
<message>
<source>Failed to init KeePassXC crypto.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Failed to encrypt key data.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Failed to get Windows Hello credential.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Failed to decrypt key data.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>YubiKey</name>
<message>
Expand Down
24 changes: 10 additions & 14 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,9 @@ if(WIN32)
${keepassx_SOURCES}
gui/osutils/winutils/ScreenLockListenerWin.cpp
gui/osutils/winutils/WinUtils.cpp)
if (MSVC)
list(APPEND keepassx_SOURCES winhello/WindowsHello.cpp)
endif()
endif()

set(keepassx_SOURCES ${keepassx_SOURCES}
Expand All @@ -234,9 +237,6 @@ add_feature_info(UpdateCheck WITH_XC_UPDATECHECK "Automatic update checking")
if(UNIX AND NOT APPLE)
add_feature_info(FdoSecrets WITH_XC_FDOSECRETS "Implement freedesktop.org Secret Storage Spec server side API.")
endif()
if(APPLE)
add_feature_info(TouchID WITH_XC_TOUCHID "TouchID integration")
endif()

add_subdirectory(browser)
add_subdirectory(proxy)
Expand Down Expand Up @@ -308,7 +308,7 @@ if(WITH_XC_NETWORKING)
updatecheck/UpdateChecker.cpp)
endif()

if(WITH_XC_TOUCHID)
if(APPLE)
list(APPEND keepassx_SOURCES touchid/TouchID.mm)
# TODO: Remove -Wno-error once deprecation warnings have been resolved.
set_source_files_properties(touchid/TouchID.mm PROPERTY COMPILE_FLAGS "-Wno-old-style-cast -Wno-error")
Expand Down Expand Up @@ -347,13 +347,10 @@ if(WITH_XC_KEESHARE)
endif()

if(APPLE)
target_link_libraries(keepassx_core "-framework Foundation -framework AppKit -framework Carbon")
target_link_libraries(keepassx_core "-framework Foundation -framework AppKit -framework Carbon -framework Security -framework LocalAuthentication")
if(Qt5MacExtras_FOUND)
target_link_libraries(keepassx_core Qt5::MacExtras)
endif()
if(WITH_XC_TOUCHID)
target_link_libraries(keepassx_core "-framework Security -framework LocalAuthentication")
endif()
endif()
if(HAIKU)
target_link_libraries(keepassx_core network)
Expand All @@ -364,6 +361,9 @@ if(UNIX AND NOT APPLE)
endif()
if(WIN32)
target_link_libraries(keepassx_core Wtsapi32.lib Ws2_32.lib)
if (MSVC)
target_link_libraries(keepassx_core WindowsApp.lib)
endif()
endif()

if(WIN32)
Expand All @@ -388,12 +388,8 @@ if(APPLE AND WITH_APP_BUNDLE)
configure_file(${CMAKE_SOURCE_DIR}/share/macosx/Info.plist.cmake ${CMAKE_CURRENT_BINARY_DIR}/Info.plist)
set_target_properties(${PROGNAME} PROPERTIES
MACOSX_BUNDLE ON
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_BINARY_DIR}/Info.plist)

if(WITH_XC_TOUCHID)
set_target_properties(${PROGNAME} PROPERTIES
CPACK_BUNDLE_APPLE_ENTITLEMENTS "${CMAKE_SOURCE_DIR}/share/macosx/keepassxc.entitlements")
endif()
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_BINARY_DIR}/Info.plist
CPACK_BUNDLE_APPLE_ENTITLEMENTS "${CMAKE_SOURCE_DIR}/share/macosx/keepassxc.entitlements")

if(QT_MAC_USE_COCOA AND EXISTS "${QT_LIBRARY_DIR}/Resources/qt_menu.nib")
install(DIRECTORY "${QT_LIBRARY_DIR}/Resources/qt_menu.nib"
Expand Down
1 change: 0 additions & 1 deletion src/config-keepassx.h.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
#cmakedefine WITH_XC_SSHAGENT
#cmakedefine WITH_XC_KEESHARE
#cmakedefine WITH_XC_UPDATECHECK
#cmakedefine WITH_XC_TOUCHID
#cmakedefine WITH_XC_FDOSECRETS

#cmakedefine KEEPASSXC_BUILD_TYPE "@KEEPASSXC_BUILD_TYPE@"
Expand Down
14 changes: 6 additions & 8 deletions src/core/Config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,6 @@ static const QHash<Config::ConfigKey, ConfigDirective> configStrings = {
{Config::GlobalAutoTypeRetypeTime,{QS("GlobalAutoTypeRetypeTime"), Roaming, 15}},
{Config::FaviconDownloadTimeout,{QS("FaviconDownloadTimeout"), Roaming, 10}},
{Config::UpdateCheckMessageShown,{QS("UpdateCheckMessageShown"), Roaming, false}},
{Config::UseTouchID,{QS("UseTouchID"), Roaming, false}},

{Config::LastDatabases, {QS("LastDatabases"), Local, {}}},
{Config::LastKeyFiles, {QS("LastKeyFiles"), Local, {}}},
Expand Down Expand Up @@ -140,11 +139,9 @@ static const QHash<Config::ConfigKey, ConfigDirective> configStrings = {
{Config::Security_HidePasswordPreviewPanel, {QS("Security/HidePasswordPreviewPanel"), Roaming, true}},
{Config::Security_AutoTypeAsk, {QS("Security/AutotypeAsk"), Roaming, true}},
{Config::Security_IconDownloadFallback, {QS("Security/IconDownloadFallback"), Roaming, false}},
{Config::Security_ResetTouchId, {QS("Security/ResetTouchId"), Roaming, false}},
{Config::Security_ResetTouchIdTimeout, {QS("Security/ResetTouchIdTimeout"), Roaming, 30}},
{Config::Security_ResetTouchIdScreenlock,{QS("Security/ResetTouchIdScreenlock"), Roaming, true}},
{Config::Security_NoConfirmMoveEntryToRecycleBin,{QS("Security/NoConfirmMoveEntryToRecycleBin"), Roaming, true}},
{Config::Security_EnableCopyOnDoubleClick,{QS("Security/EnableCopyOnDoubleClick"), Roaming, false}},
{Config::Security_QuickUnlock, {QS("Security/QuickUnlock"), Local, true}},

// Browser
{Config::Browser_Enabled, {QS("Browser/Enabled"), Roaming, false}},
Expand Down Expand Up @@ -329,9 +326,6 @@ static const QHash<QString, Config::ConfigKey> deprecationMap = {
{QS("security/HidePasswordPreviewPanel"), Config::Security_HidePasswordPreviewPanel},
{QS("security/passwordsrepeat"), Config::Security_PasswordsRepeatVisible},
{QS("security/hidenotes"), Config::Security_HideNotes},
{QS("security/resettouchid"), Config::Security_ResetTouchId},
{QS("security/resettouchidtimeout"), Config::Security_ResetTouchIdTimeout},
{QS("security/resettouchidscreenlock"), Config::Security_ResetTouchIdScreenlock},
{QS("KeeShare/Settings.own"), Config::KeeShare_Own},
{QS("KeeShare/Settings.foreign"), Config::KeeShare_Foreign},
{QS("KeeShare/Settings.active"), Config::KeeShare_Active},
Expand Down Expand Up @@ -369,7 +363,11 @@ static const QHash<QString, Config::ConfigKey> deprecationMap = {
{QS("LastAttachmentDir"), Config::Deleted},
{QS("KeeShare/LastDir"), Config::Deleted},
{QS("KeeShare/LastKeyDir"), Config::Deleted},
{QS("KeeShare/LastShareDir"), Config::Deleted}};
{QS("KeeShare/LastShareDir"), Config::Deleted},
{QS("UseTouchID"), Config::Deleted},
{QS("Security/ResetTouchId"), Config::Deleted},
{QS("Security/ResetTouchIdTimeout"), Config::Deleted},
{QS("Security/ResetTouchIdScreenlock"), Config::Deleted}};

/**
* Migrate settings from previous versions.
Expand Down
5 changes: 1 addition & 4 deletions src/core/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ class Config : public QObject
GlobalAutoTypeRetypeTime,
FaviconDownloadTimeout,
UpdateCheckMessageShown,
UseTouchID,

LastDatabases,
LastKeyFiles,
Expand Down Expand Up @@ -120,11 +119,9 @@ class Config : public QObject
Security_HidePasswordPreviewPanel,
Security_AutoTypeAsk,
Security_IconDownloadFallback,
Security_ResetTouchId,
Security_ResetTouchIdTimeout,
Security_ResetTouchIdScreenlock,
Security_NoConfirmMoveEntryToRecycleBin,
Security_EnableCopyOnDoubleClick,
Security_QuickUnlock,

Browser_Enabled,
Browser_ShowNotification,
Expand Down
4 changes: 2 additions & 2 deletions src/core/Tools.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,8 @@ namespace Tools
#ifdef WITH_XC_YUBIKEY
extensions += "\n- " + QObject::tr("YubiKey");
#endif
#ifdef WITH_XC_TOUCHID
extensions += "\n- " + QObject::tr("TouchID");
#if defined(Q_OS_MACOS) || defined(Q_CC_MSVC)
extensions += "\n- " + QObject::tr("Quick Unlock");
#endif
#ifdef WITH_XC_FDOSECRETS
extensions += "\n- " + QObject::tr("Secret Service Integration");
Expand Down
Loading

0 comments on commit 4f07103

Please sign in to comment.