Support passkeys with Bitwarden import (#11401)

This commit is contained in:
Sami Vänttinen 2024-10-25 03:12:47 +03:00 committed by GitHub
parent 95bae8377c
commit 6e0baf9f2c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 180 additions and 47 deletions

View file

@ -24,6 +24,7 @@
#include "BrowserHost.h"
#include "BrowserMessageBuilder.h"
#include "BrowserSettings.h"
#include "core/EntryAttributes.h"
#include "core/Tools.h"
#include "gui/MainWindow.h"
#include "gui/MessageBox.h"
@ -763,9 +764,9 @@ QJsonObject BrowserService::showPasskeysAuthenticationPrompt(const QJsonObject&
return getPasskeyError(ERROR_PASSKEYS_UNKNOWN_ERROR);
}
const auto privateKeyPem = selectedEntry->attributes()->value(BrowserPasskeys::KPEX_PASSKEY_PRIVATE_KEY_PEM);
const auto privateKeyPem = selectedEntry->attributes()->value(EntryAttributes::KPEX_PASSKEY_PRIVATE_KEY_PEM);
const auto credentialId = passkeyUtils()->getCredentialIdFromEntry(selectedEntry);
const auto userHandle = selectedEntry->attributes()->value(BrowserPasskeys::KPEX_PASSKEY_USER_HANDLE);
const auto userHandle = selectedEntry->attributes()->value(EntryAttributes::KPEX_PASSKEY_USER_HANDLE);
auto publicKeyCredential =
browserPasskeys()->buildGetPublicKeyCredential(assertionOptions, credentialId, userHandle, privateKeyPem);
@ -843,11 +844,11 @@ void BrowserService::addPasskeyToEntry(Entry* entry,
entry->beginUpdate();
entry->attributes()->set(BrowserPasskeys::KPEX_PASSKEY_USERNAME, username);
entry->attributes()->set(BrowserPasskeys::KPEX_PASSKEY_CREDENTIAL_ID, credentialId, true);
entry->attributes()->set(BrowserPasskeys::KPEX_PASSKEY_PRIVATE_KEY_PEM, privateKey, true);
entry->attributes()->set(BrowserPasskeys::KPEX_PASSKEY_RELYING_PARTY, rpId);
entry->attributes()->set(BrowserPasskeys::KPEX_PASSKEY_USER_HANDLE, userHandle, true);
entry->attributes()->set(EntryAttributes::KPEX_PASSKEY_USERNAME, username);
entry->attributes()->set(EntryAttributes::KPEX_PASSKEY_CREDENTIAL_ID, credentialId, true);
entry->attributes()->set(EntryAttributes::KPEX_PASSKEY_PRIVATE_KEY_PEM, privateKey, true);
entry->attributes()->set(EntryAttributes::KPEX_PASSKEY_RELYING_PARTY, rpId);
entry->attributes()->set(EntryAttributes::KPEX_PASSKEY_USER_HANDLE, userHandle, true);
entry->addTag(tr("Passkey"));
entry->endUpdate();
@ -1042,7 +1043,7 @@ QList<Entry*> BrowserService::searchEntries(const QSharedPointer<Database>& db,
#ifdef WITH_XC_BROWSER_PASSKEYS
// With Passkeys, check for the Relying Party instead of URL
if (passkey && entry->attributes()->value(BrowserPasskeys::KPEX_PASSKEY_RELYING_PARTY) != siteUrl) {
if (passkey && entry->attributes()->value(EntryAttributes::KPEX_PASSKEY_RELYING_PARTY) != siteUrl) {
continue;
}
#endif
@ -1384,7 +1385,7 @@ QList<Entry*> BrowserService::getPasskeyEntries(const QString& rpId, const Strin
{
QList<Entry*> entries;
for (const auto& entry : searchEntries(rpId, "", keyList, true)) {
if (entry->hasPasskey() && entry->attributes()->value(BrowserPasskeys::KPEX_PASSKEY_RELYING_PARTY) == rpId) {
if (entry->hasPasskey() && entry->attributes()->value(EntryAttributes::KPEX_PASSKEY_RELYING_PARTY) == rpId) {
entries << entry;
}
}
@ -1399,8 +1400,8 @@ QList<Entry*> BrowserService::getPasskeyEntriesWithUserHandle(const QString& rpI
{
QList<Entry*> 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) {
if (entry->hasPasskey() && entry->attributes()->value(EntryAttributes::KPEX_PASSKEY_RELYING_PARTY) == rpId
&& entry->attributes()->value(EntryAttributes::KPEX_PASSKEY_USER_HANDLE) == userId) {
entries << entry;
}
}
@ -1425,7 +1426,7 @@ QList<Entry*> BrowserService::getPasskeyAllowedEntries(const QJsonObject& assert
// See: https://w3c.github.io/webauthn/#dom-authenticatorassertionresponse-userhandle
if (allowedCredentials.contains(passkeyUtils()->getCredentialIdFromEntry(entry))
|| (allowedCredentials.isEmpty()
&& entry->attributes()->hasKey(BrowserPasskeys::KPEX_PASSKEY_USER_HANDLE))) {
&& entry->attributes()->hasKey(EntryAttributes::KPEX_PASSKEY_USER_HANDLE))) {
entries << entry;
}
}