Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Passkeys improvements #10318

Merged

Conversation

varjolintu
Copy link
Member

@varjolintu varjolintu commented Feb 19, 2024

Refactors the Passkey implementation to include more checks and a structure that is more aligned with the official specification.
Notable changes:

  • BrowserService no longer does the checks by itself. A new class BrowserPasskeysClient constructs the relevant objects, acting as a client. BrowserService only acts as a bridge between the client and BrowserPasskeys (authenticator) and calls the relevant popups for user interaction.
  • A new helper class PasskeyUtils includes the actual checks and parses the objects.
  • BrowserPasskeys is pretty much intact, but some functions have been moved to PasskeyUtils.
  • Fixes Ed25519 encoding in BrowserCBOR.
  • Adds new error messages.
  • User confirmation for Passkey retrieval is also asked even if discouraged is used. This goes against the specification, but currently there's no other way to verify the user.
  • cross-platform is also accepted for compatibility. This could be removed if there's a potential issue with it.
  • Extension data is now handled correctly during Authentication.
  • Allowed and excluded credentials are now handled correctly.
  • KPEX_PASSKEY_GENERATED_USER_ID is renamed to KPEX_PASSKEY_CREDENTIAL_ID
  • Adds a new option "Allow localhost with Passkeys" to Browser Integration -> Advanced tab. By default it's not allowed to access HTTP sites, but http://localhost can be allowed for debugging and testing purposes for local servers.
  • Add tag passkey to a Passkey entry, or an entry with an imported Passkey.

Corresponding KeePassXC-Browser side PR: keepassxreboot/keepassxc-browser#2121

Fixes #10287.

Testing strategy

Automatic tests added. Sites tested manually. I couldn't get the Microsoft Passkeys creation work anymore, even with the old implementation. The site always triggers OS/Browser level dialog that cannot be prevented.

Type of change

  • ✅ Refactor (significant modification to existing code)

src/core/UrlTools.cpp Outdated Show resolved Hide resolved
Copy link

@Ortham Ortham left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry about the flood of comments, but on a positive note I found the changed code much easier to follow than before, and thanks for addressing the issues I'd raised. 👍

src/browser/BrowserAction.cpp Show resolved Hide resolved
src/browser/PasskeyUtils.cpp Show resolved Hide resolved
src/browser/PasskeyUtils.cpp Show resolved Hide resolved
src/browser/PasskeyUtils.cpp Show resolved Hide resolved
src/browser/PasskeyUtils.cpp Outdated Show resolved Hide resolved
src/browser/BrowserService.cpp Outdated Show resolved Hide resolved
src/browser/BrowserService.cpp Outdated Show resolved Hide resolved
src/browser/BrowserPasskeys.cpp Outdated Show resolved Hide resolved
src/browser/BrowserPasskeys.cpp Outdated Show resolved Hide resolved
src/browser/BrowserPasskeys.cpp Outdated Show resolved Hide resolved
src/browser/BrowserAction.cpp Outdated Show resolved Hide resolved
src/browser/BrowserAction.cpp Outdated Show resolved Hide resolved
src/browser/PasskeyUtils.cpp Outdated Show resolved Hide resolved
src/browser/BrowserCbor.cpp Outdated Show resolved Hide resolved
src/browser/BrowserCbor.cpp Outdated Show resolved Hide resolved
src/browser/BrowserCbor.cpp Outdated Show resolved Hide resolved
src/browser/BrowserPasskeys.cpp Show resolved Hide resolved
src/browser/BrowserPasskeys.cpp Show resolved Hide resolved
src/browser/BrowserPasskeysClient.cpp Outdated Show resolved Hide resolved
src/browser/PasskeyUtils.cpp Outdated Show resolved Hide resolved
src/browser/BrowserService.cpp Outdated Show resolved Hide resolved
src/browser/PasskeyUtils.cpp Outdated Show resolved Hide resolved
{
const auto pubKeyCredParams = publicKey["pubKeyCredParams"].toArray();
const auto pubKeyCredParams = credentialCreationOptions["credTypesAndPubKeyAlgs"].toArray();
if (!pubKeyCredParams.isEmpty()) {
const auto alg = pubKeyCredParams.first()["alg"].toInt();
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copied from an earlier comment:

This function doesn't correctly handle the case where the first element of credTypesAndPubKeyAlgs is an unsupported algorithm but a later algorithm is supported. E.g. an RP may prefer PS256 but accept RS256 as its second choice, and in that case KeePassXC should choose RS256 instead of using ES256.

I think this still applies.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you mean we should iterate through the array until we find a supported algorithm, instead of just picking the first element and bailing out if that doesn't work. I agree.

Copy link
Member Author

@varjolintu varjolintu Mar 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to note, the array comes from here: https://github.com/keepassxreboot/keepassxc/pull/10318/files#diff-02fad338f30f066992b2231a0cf4f5a91592313a32a22defedc5574b4a0d6a55R141
So the first element is already from the supported list.

@droidmonkey droidmonkey merged commit ac2b445 into keepassxreboot:develop Mar 6, 2024
11 checks passed
@varjolintu varjolintu deleted the fix/passkeys_improvements branch March 6, 2024 13:22
pull bot pushed a commit to tigerwill90/keepassxc that referenced this pull request Mar 6, 2024
Refactors the Passkey implementation to include more checks and a structure that is more aligned with the official specification.
Notable changes:
- _BrowserService_ no longer does the checks by itself. A new class _BrowserPasskeysClient_ constructs the relevant objects, acting as a client. _BrowserService_ only acts as a bridge between the client and _BrowserPasskeys_ (authenticator) and calls the relevant popups for user interaction.
- A new helper class _PasskeyUtils_ includes the actual checks and parses the objects.
- _BrowserPasskeys_ is pretty much intact, but some functions have been moved to PasskeyUtils.
- Fixes Ed25519 encoding in _BrowserCBOR_.
- Adds new error messages.
- User confirmation for Passkey retrieval is also asked even if `discouraged` is used. This goes against the specification, but currently there's no other way to verify the user.
- `cross-platform` is also accepted for compatibility. This could be removed if there's a potential issue with it.
- Extension data is now handled correctly during Authentication.
- Allowed and excluded credentials are now handled correctly.
- `KPEX_PASSKEY_GENERATED_USER_ID` is renamed to `KPEX_PASSKEY_CREDENTIAL_ID`
- Adds a new option "Allow localhost with Passkeys" to Browser Integration -> Advanced tab. By default it's not allowed to access HTTP sites, but `http://localhost` can be allowed for debugging and testing purposes for local servers.
- Add tag `Passkey` to a Passkey entry, or an entry with an imported Passkey.

Fixes keepassxreboot#10287.
droidmonkey added a commit that referenced this pull request Mar 8, 2024
Refactors the Passkey implementation to include more checks and a structure that is more aligned with the official specification.
Notable changes:
- _BrowserService_ no longer does the checks by itself. A new class _BrowserPasskeysClient_ constructs the relevant objects, acting as a client. _BrowserService_ only acts as a bridge between the client and _BrowserPasskeys_ (authenticator) and calls the relevant popups for user interaction.
- A new helper class _PasskeyUtils_ includes the actual checks and parses the objects.
- _BrowserPasskeys_ is pretty much intact, but some functions have been moved to PasskeyUtils.
- Fixes Ed25519 encoding in _BrowserCBOR_.
- Adds new error messages.
- User confirmation for Passkey retrieval is also asked even if `discouraged` is used. This goes against the specification, but currently there's no other way to verify the user.
- `cross-platform` is also accepted for compatibility. This could be removed if there's a potential issue with it.
- Extension data is now handled correctly during Authentication.
- Allowed and excluded credentials are now handled correctly.
- `KPEX_PASSKEY_GENERATED_USER_ID` is renamed to `KPEX_PASSKEY_CREDENTIAL_ID`
- Adds a new option "Allow localhost with Passkeys" to Browser Integration -> Advanced tab. By default it's not allowed to access HTTP sites, but `http://localhost` can be allowed for debugging and testing purposes for local servers.
- Add tag `Passkey` to a Passkey entry, or an entry with an imported Passkey.

Fixes #10287.
droidmonkey added a commit that referenced this pull request Mar 9, 2024
Refactors the Passkey implementation to include more checks and a structure that is more aligned with the official specification.
Notable changes:
- _BrowserService_ no longer does the checks by itself. A new class _BrowserPasskeysClient_ constructs the relevant objects, acting as a client. _BrowserService_ only acts as a bridge between the client and _BrowserPasskeys_ (authenticator) and calls the relevant popups for user interaction.
- A new helper class _PasskeyUtils_ includes the actual checks and parses the objects.
- _BrowserPasskeys_ is pretty much intact, but some functions have been moved to PasskeyUtils.
- Fixes Ed25519 encoding in _BrowserCBOR_.
- Adds new error messages.
- User confirmation for Passkey retrieval is also asked even if `discouraged` is used. This goes against the specification, but currently there's no other way to verify the user.
- `cross-platform` is also accepted for compatibility. This could be removed if there's a potential issue with it.
- Extension data is now handled correctly during Authentication.
- Allowed and excluded credentials are now handled correctly.
- `KPEX_PASSKEY_GENERATED_USER_ID` is renamed to `KPEX_PASSKEY_CREDENTIAL_ID`
- Adds a new option "Allow localhost with Passkeys" to Browser Integration -> Advanced tab. By default it's not allowed to access HTTP sites, but `http://localhost` can be allowed for debugging and testing purposes for local servers.
- Add tag `Passkey` to a Passkey entry, or an entry with an imported Passkey.

Fixes #10287.
libf-de pushed a commit to libf-de/keepassxc-secretservice-dbus that referenced this pull request Mar 11, 2024
Release 2.7.7

- Support USB Hotplug for Hardware Key interface [keepassxreboot#10092]
- Support 1PUX and Bitwarden import [keepassxreboot#9815]
- Browser: Add support for PassKeys [keepassxreboot#8825, keepassxreboot#9987, keepassxreboot#10318]
- Build System: Move to vcpkg manifest mode [keepassxreboot#10088]

- Fix multiple TOTP issues [keepassxreboot#9874]
- Fix focus loss on save when the editor is not visible anymore [keepassxreboot#10075]
- Fix visual when removing entry from history [keepassxreboot#9947]
- Fix first entry is not selected when a search is performed [keepassxreboot#9868]
- Prevent scrollbars on entry drag/drop [keepassxreboot#9747]
- Prevent duplicate characters in "Also choose from" field of password generator  [keepassxreboot#9803]
- Security: Prevent byte-by-byte and attachment inference side channel attacks [keepassxreboot#10266]
- Browser: Fix raising Update Entry messagebox [keepassxreboot#9853]
- Browser: Fix bugs when returning credentials [keepassxreboot#9136]
- Browser: Fix crash on database open from browser [keepassxreboot#9939]
- Browser: Fix support for referenced URL fields [keepassxreboot#8788]
- MacOS: Fix crash when changing highlight/accent color [keepassxreboot#10348]
- MacOS: Fix TouchID appearing even though lid is closed [keepassxreboot#10092]
- Windows: Fix terminating KeePassXC processes with MSI installer [keepassxreboot#9822]
- FdoSecrets: Fix database merge crash when enabled [keepassxreboot#10136]

# -----BEGIN PGP SIGNATURE-----
#
# iQEzBAABCAAdFiEENIkEDB8MPuq41ValRA/GXy4MbgEFAmXs7VsACgkQRA/GXy4M
# bgHLpwf/brnyPPs3gJxZmD2pn8542D4CCsDh0fTceurOtqCe3J4Y+Fftc5euuoQu
# 6rP4vJdd586l7JX5FnYIPXvGiU9op3MudJh+y+RN/PWwKcXNIXfUItMhpZEka49n
# xnw+Wvbilg1QIHSSmZdIjBpohnEkA67qhWauc3bCacrRyEvIOzVMTxnqDTe4GUDy
# CyauaRMMKezRTpLxSsk63TDAZZgDwK4ci5lC6ysHekc1Za6IbI3fMFjz1BGj+kPU
# tMHMfDCWqK/5JZ27ZWcxy7m8tJY9m3rb+MoCyFRQz9ixaEe29yf5NqYdm9sn1Dlh
# O7aFi7/EJtsBlXdguw5BcTPbsL7XEQ==
# =Cots
# -----END PGP SIGNATURE-----
# gpg: directory '/home/runner/.gnupg' created
# gpg: keybox '/home/runner/.gnupg/pubring.kbx' created
# gpg: Signature made Sat Mar  9 23:14:35 2024 UTC
# gpg:                using RSA key 3489040C1F0C3EEAB8D556A5440FC65F2E0C6E01
# gpg: Can't check signature: No public key
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Security, privacy and other issues with WebAuthn/passkeys support
4 participants