Fix Windows Hello bugs

* Fix #7977 - wrap key signing request in try/catch block to prevent crashes on some machines.
* Fix #8120 - try 3 times to bring Windows Hello prompt to front. This may be necessary on older machines that are slow to bring up the prompt window.

Also remove defunct code on macOS to prevent window focus issues.
This commit is contained in:
Jonathan White 2022-08-11 21:59:12 -04:00
parent 14f12b0a25
commit ed693e146d
2 changed files with 20 additions and 16 deletions

View File

@ -209,12 +209,6 @@ bool Application::event(QEvent* event)
emit openFile(static_cast<QFileOpenEvent*>(event)->file());
return true;
}
#ifdef Q_OS_MACOS
// restore main window when clicking on the docker icon
else if (event->type() == QEvent::ApplicationActivate) {
emit applicationActivated();
}
#endif
return QApplication::event(event);
}

View File

@ -41,6 +41,7 @@ using namespace Windows::Storage::Streams;
namespace
{
const std::wstring s_winHelloKeyName{L"keepassxc_winhello"};
int g_promptFocusCount = 0;
void queueSecurityPromptFocus(int delay = 500)
{
@ -48,7 +49,11 @@ namespace
auto hWnd = ::FindWindowA("Credential Dialog Xaml Host", nullptr);
if (hWnd) {
::SetForegroundWindow(hWnd);
} else if (++g_promptFocusCount <= 3) {
queueSecurityPromptFocus();
return;
}
g_promptFocusCount = 0;
});
}
@ -71,18 +76,23 @@ namespace
return false;
}
const auto signature = result.Credential().RequestSignAsync(challengeBuffer).get();
if (signature.Status() != KeyCredentialStatus::Success) {
error = QObject::tr("Failed to sign challenge using Windows Hello.");
try {
const auto signature = result.Credential().RequestSignAsync(challengeBuffer).get();
if (signature.Status() != KeyCredentialStatus::Success) {
error = QObject::tr("Failed to sign challenge using Windows Hello.");
return false;
}
// Use the SHA-256 hash of the challenge signature as the encryption key
const auto response = signature.Result();
CryptoHash hasher(CryptoHash::Sha256);
hasher.addData({reinterpret_cast<const char*>(response.data()), static_cast<int>(response.Length())});
key = hasher.result();
return true;
} catch (winrt::hresult_error const& ex) {
error = QString::fromStdString(winrt::to_string(ex.message()));
return false;
}
// Use the SHA-256 hash of the challenge signature as the encryption key
const auto response = signature.Result();
CryptoHash hasher(CryptoHash::Sha256);
hasher.addData({reinterpret_cast<const char*>(response.data()), static_cast<int>(response.Length())});
key = hasher.result();
return true;
});
}
} // namespace