From 969d3f9b23d2ed2428398be7def49edbf4847d06 Mon Sep 17 00:00:00 2001 From: varjolintu Date: Tue, 12 Mar 2024 20:21:11 +0200 Subject: [PATCH] Passkeys: Do not ask update with a new user handle --- src/browser/BrowserService.cpp | 24 ++++++++++++++++++++---- src/browser/BrowserService.h | 2 ++ 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/browser/BrowserService.cpp b/src/browser/BrowserService.cpp index 7395b72c3..24a65daf4 100644 --- a/src/browser/BrowserService.cpp +++ b/src/browser/BrowserService.cpp @@ -584,12 +584,15 @@ QJsonObject BrowserService::showPasskeysRegisterPrompt(const QJsonObject& public const auto rpId = publicKeyOptions["rp"]["id"].toString(); const auto timeout = publicKeyOptions["timeout"].toInt(); const auto username = credentialCreationOptions["user"].toObject()["name"].toString(); + const auto user = credentialCreationOptions["user"].toObject(); + const auto userId = user["id"].toString(); // Parse excludeCredentialDescriptorList if (!excludeCredentials.isEmpty() && isPasskeyCredentialExcluded(excludeCredentials, rpId, keyList)) { return getPasskeyError(ERROR_PASSKEYS_CREDENTIAL_IS_EXCLUDED); } - const auto existingEntries = getPasskeyEntries(rpId, keyList); + + const auto existingEntries = getPasskeyEntriesWithUserHandle(rpId, userId, keyList); raiseWindow(); BrowserPasskeysConfirmationDialog confirmDialog; @@ -605,9 +608,6 @@ QJsonObject BrowserService::showPasskeysRegisterPrompt(const QJsonObject& public } const auto rpName = publicKeyOptions["rp"]["name"].toString(); - const auto user = credentialCreationOptions["user"].toObject(); - const auto userId = user["id"].toString(); - if (confirmDialog.isPasskeyUpdated()) { addPasskeyToEntry(confirmDialog.getSelectedEntry(), rpId, @@ -1354,6 +1354,22 @@ QList BrowserService::getPasskeyEntries(const QString& rpId, const Strin return entries; } +// Returns all Passkey entries for the current Relying Party and identical user handle +QList BrowserService::getPasskeyEntriesWithUserHandle(const QString& rpId, + const QString& userId, + const StringPairList& keyList) +{ + QList entries; + for (const auto& entry : searchEntries(rpId, "", keyList, true)) { + if (entry->hasPasskey() && entry->attributes()->value(BrowserPasskeys::KPEX_PASSKEY_RELYING_PARTY) == rpId + && entry->attributes()->value(BrowserPasskeys::KPEX_PASSKEY_USER_HANDLE) == userId) { + entries << entry; + } + } + + return entries; +} + // Get all entries for the site that are allowed by the server QList BrowserService::getPasskeyAllowedEntries(const QJsonObject& assertionOptions, const QString& rpId, diff --git a/src/browser/BrowserService.h b/src/browser/BrowserService.h index 424992486..fe840ef8b 100644 --- a/src/browser/BrowserService.h +++ b/src/browser/BrowserService.h @@ -180,6 +180,8 @@ private: #ifdef WITH_XC_BROWSER_PASSKEYS QList getPasskeyEntries(const QString& rpId, const StringPairList& keyList); QList + getPasskeyEntriesWithUserHandle(const QString& rpId, const QString& userId, const StringPairList& keyList); + QList getPasskeyAllowedEntries(const QJsonObject& assertionOptions, const QString& rpId, const StringPairList& keyList); bool isPasskeyCredentialExcluded(const QJsonArray& excludeCredentials, const QString& rpId,