keepassxreboot / keepassxc

KeePassXC is a cross-platform community-driven port of the Windows application “Keepass Password Safe”.
https://keepassxc.org/
Other
21.44k stars 1.48k forks source link

keepass-cli seems to require the yubikey serial number in the latest version even if only one key is connected #10412

Open kevenwyld opened 8 months ago

kevenwyld commented 8 months ago

Overview

Steps to Reproduce

  1. Connect a single yubikey
  2. keepassxc-cli show -y 2 <database_path> <secret>
  3. Receive the error General: Could not find interface for hardware key with serial number 0. Please connect it to continue.

Expected Behavior

The secret or data to be returned

Actual Behavior

General: Could not find interface for hardware key with serial number 0. Please connect it to continue. despite the key actually being connected.

Context

The yubikey is correctly detected in the GUI. Passing the serial number using the suggested help -y, --yubikey <slot[:serial]> works:

keepassxc-cli show -y 2:XXXXXXX <database_path> <secret>

However prior versions would assume the only key connected if you didn't pass the serial number explicitly.

KeePassXC - Version 2.7.7 Revision: 68e2dd8

Operating System: Linux Desktop Env: Sway Windowing System: Wayland

matthewmummert5 commented 8 months ago

I can confirm. I am seeing this issue too.

KeePassXC - Version 2.7.7 Operating System: Linux Desktop Env: KDE Plasma Windowing System: Wayland

marcovergueira commented 8 months ago

Same issue here with, KeePassXC - Version 2.7.7

OS: Arch Desktop Env: Gnome Windowing System: Wayland

kaoneko commented 7 months ago

Same, also on Linux. A temporary workaround: -y 2:$(ykman list -s)

matthewmummert5 commented 7 months ago

I'm completely unfamiliar with keepassxc's codebase, but since keepassxc-cli is part of my backup scripts, I thought I'd take a crack at this. It looks like in src/keys/drivers/Yubikey.cpp:

YubiKey::challenge(YubiKeySlot slot, const QByteArray& challenge, Botan::secure_vector<char>& response)

slot never gets populated with the yubikey's serial number before this method is called, so then

    if (m_usbKeys.contains(slot)) {
        return YubiKeyInterfaceUSB::instance()->challenge(slot, challenge, response);
    }   

just gets skipped over. I'm not sure where slot is supposed to be populated with the serial number, but the serial number gets initialized to 0 in unlockDatabase() in src/cli/Utils.cpp. I tried comparing 2.7.7 vs 2.7.5, but there has been significant refactoring in the Yubikey stuff between those versions, so a bug probably got slipped in.

There should probably be a call to yk_get_serial() somewhere if the serial is not specified on the commandline.

That's as far as I got, and I need to go to bed. If nobody else gets to this, I'll probably look at it some more tomorrow after work.