Merge pull request #26 from Lab-8916100448256/main

Add documentation and fix issue #20
This commit is contained in:
Suyog Tandel
2026-01-22 15:52:00 +05:30
committed by GitHub
4 changed files with 96 additions and 3 deletions
+4
View File
@@ -168,6 +168,10 @@ nix-build -E 'with import <nixpkgs> {}; callPackage ./package.nix { }'
The compiled binary will be available at: `result/bin/picoforge`
### 4. Nix-shell developement environment
Alternatively, you can use the shell.nix file that is at the root of the repository to enter a developement environement with all the required dependencies by simply running `nix-shell`
Then you can build from source and run the application with `deno task tauri dev`.
## Project Structure
```
+4
View File
@@ -47,6 +47,10 @@ Regardless of the installation method you choose below, your **host operating sy
# Command may vary by distro, commonly:
sudo systemctl enable --now pcscd
```
To have the pcscd service, you may need to install pcsc-lite if it is not installed by default on your Linux distribution.
- On Debian : `sudo apt install pcscd`
- On NixOS, add this line in your /etc/nixos/configuration.nix : `services.pcscd.enable = true;`
### Option 1: [COPR Repository](https://copr.fedorainfracloud.org/coprs/lockedmutex/picoforge/) (Recommended for Fedora, openSUSE, and RHEL-based distros)
+76
View File
@@ -0,0 +1,76 @@
# Troubleshooting
## My key is not detected by picoforge
The pico-fido firmware uses by default "generic" USB Vendor ID (VID) and Product ID (PID) that are not not registered IDs and so not known by pcsc-lite.
This means that if you flash on your key a stock pico-fido firmware it will not be recognized by pcsc-lite.
With the latest version of picoforge implements a fallback, with limited functionalites, to connect to the key via the fido protocol instead of pcsc.
When this happens the device status on the lower left corner of the application will show an orange badge with the indication "Online - fido" instead of the green "Online" badge.
There are several ways to work around this issue
### 1. Flash a firmware that you build from source with USB VID/PID known by pcsc-lite
Legaly speaking, we cannot distribute the pico-fido firmware with USB VID and PID that we do not own. And it is quite expensive to register a USB vendorID.
This is why the pico-fido firmware is distributed with the so-called "generic" VID/PID
But if you build a firmware from the source code for your own use you can choose to build it with known VID/PID that will be recognized by pcsc-lite.
Refer to the the pico-fido firmware documentation for how to do that.
### 2. Use the fido fallback implemented in picoforge to update the VID and PID
When connected to the key with the fido fallback there are some limitations. Only a limited set of configuration parameters can be read or written.
While in this mode it is possible to change the VID/PID to use the ones of a known vendor.
Then after unplugging and re-plugging the key for the change to be taken into account, the key should be correctly detected by pcsc and you will be able to access to the full set of configuration parameters
Be mindfull of the legal implications if you do that on a key that you plan to distribute to somebody else. You will probably want to set it back to the genric VID/PID before you distribute it.
### 3. Add the "generic" USB VID/PID of pico-fido to pcsc-lite CCID driver
There is a workwround to have pcsc-lite recorgnize a key that is using the "generic" VID/PID
#### On a Linux distribution where you can modify the files installed by system packages
You can manually add the generic VID and PID to the CCID driver Info.plist file.
Depending on your distribution this file may be located in a path like this :
- /usr/lib64/pcsc/drivers/ifd-ccid.bundle/Contents/Info.plist (Fedora)
- /usr/lib/pcsc/drivers/ifd-ccid.bundle/Contents/Info.plist (Debian)
Once you have located this file you need to :
1. Add the VID in end of `ifdVendorID` array:
```xml
<key>ifdVendorID</key>
<array>
<string>0xFEFF</string>
</array>
```
2. Add the PID at the end of `ifdProductID` array:
```xml
<key>ifdProductID</key>
<array>
<string>0xFCFD</string>
</array>
```
3. Add a friendly name at the end of `ifdFriendlyName` array:
<key>ifdFriendlyName</key>
<array>
<string>Pico Key</string>
</array>
4. Then restart the pcsc daemon:
```bash
sudo systemctl restart pcscd
```
#### On NixOS
On NixOS the Info.plist is located in the nix store that is immutable. So it cannot be manually edited.
To pach the file you can add the following to your /etc/nixos/configuration.nix file :
```nix
# Override the pcscd plugin list to use your patched CCID driver with pico-fido firmware generic VID/PID
services.pcscd.plugins = pkgs.lib.mkForce [
(pkgs.ccid.overrideAttrs (oldAttrs: {
nativeBuildInputs = (oldAttrs.nativeBuildInputs or []) ++ [ pkgs.xmlstarlet ];
postInstall = (oldAttrs.postInstall or "") + ''
plist="$out/pcsc/drivers/ifd-ccid.bundle/Contents/Info.plist"
xmlstarlet ed -L -s "//key[text()='ifdVendorID']/following-sibling::array[1]" -t elem -n string -v "0xFEFF" "$plist"
xmlstarlet ed -L -s "//key[text()='ifdProductID']/following-sibling::array[1]" -t elem -n string -v "0xFCFD" "$plist"
xmlstarlet ed -L -s "//key[text()='ifdFriendlyName']/following-sibling::array[1]" -t elem -n string -v "Pico Key" "$plist"
'';
}))
];
```
+12 -3
View File
@@ -98,9 +98,18 @@ pub(crate) fn get_credentials(pin: String) -> Result<Vec<StoredCredential>, Stri
let device = FidoKeyHidFactory::create(&cfg)
.map_err(|e| format!("Failed to connect to FIDO device: {:?}", e))?;
let rps = device
.credential_management_enumerate_rps(Some(&pin))
.map_err(|e| format!("Failed to enumerate Relying Parties: {:?}", e))?;
let rps = match device.credential_management_enumerate_rps(Some(&pin)) {
Ok(rps) => rps,
Err(e) => {
// CTAP2_ERR_NO_CREDENTIALS (0x2E) means no credentials exist - return empty list
let err_str = format!("{:?}", e);
if err_str.contains("0x2E") || err_str.contains("NO_CREDENTIALS") {
log::info!("No credentials stored on device (CTAP2_ERR_NO_CREDENTIALS)");
return Ok(Vec::new());
}
return Err(format!("Failed to enumerate Relying Parties: {:?}", e));
}
};
let mut all_credentials = Vec::new();