WARN: Not everything has been fully tested with a SoloKey v1 yet, so use at your own risk.
This is a port of the official solokeys/solo1-cli Python tool to Rust.
Claude did all the hard yards porting the protocol implementation, working through the bootloader protocol details, and debugging firmware update issues along the way.
A Rust CLI for managing SoloKeys Solo 1 hardware security keys. Supports firmware updates, FIDO2 operations, credential management, and low-level bootloader/DFU programming.
cargo build --releaseThe binary ends up at target/release/solo1.
solo1 [OPTIONS] <COMMAND>Global options:
| Flag | Description |
|---|---|
-v, --verbose |
Enable verbose output (HID frames, bootloader packets, etc.) |
--timeout <SECS> |
Timeout in seconds for device responses (default: 30) |
--json is available on commands that produce structured output (version, genkey, ls, and all key subcommands). Commands that always output JSON (sign) or produce no structured output (mergehex, monitor, program) do not expose this flag.
solo1 version [--json] # Print library versionsolo1 ls [--json] # List connected Solo devicessolo1 key version # Get firmware version
solo1 key wink # Blink LED
solo1 key ping [--count N] [--data HEX] # Ping and measure RTT
solo1 key rng hexbytes <N> # Print N random bytes as hex
solo1 key rng raw # Stream raw entropy to stdout
solo1 key rng feedkernel # Feed entropy to /dev/random (Linux)
solo1 key verify # Verify key authenticity via attestation
solo1 key reset # Factory reset (destructive)
solo1 key set-pin # Set PIN on unpinned key
solo1 key change-pin # Change existing PIN
solo1 key disable-updates # Permanently disable firmware updates
solo1 key keyboard <DATA> # Program keyboard sequence (max 64 bytes)
solo1 key probe <HASH_TYPE> <FILE> # Calculate hash on device (sha256|sha512|rsa2048|ed25519, file <=6144 bytes)
solo1 key sign-file <CREDENTIAL_ID> <FILE> # Sign file with resident credential
solo1 key update [--firmware FILE] # Update firmware (downloads latest if omitted)solo1 key credential info # Get credential slot info
solo1 key credential ls # List resident credentials
solo1 key credential rm <ID> # Remove credential by base64 ID
solo1 key credential rm --host <HOST> --user <USER>
# Remove credential by relying party and username
solo1 key credential create --host <HOST> --user <USER> [--prompt <TEXT>]
# Create FIDO2 credential with hmac-secretsolo1 key challenge-response <CREDENTIAL_ID> <CHALLENGE> [--host <HOST>]
# HMAC-secret challenge-response using an existing credential
# CREDENTIAL_ID: hex string from credential create output
# CHALLENGE: string to hash
# --host defaults to "solokeys.dev"# Flash firmware via Solo bootloader (device must be in bootloader mode)
solo1 program bootloader <firmware.json>
# Flash firmware via ST DFU
solo1 program dfu <firmware.hex>
# Auxiliary bootloader commands
solo1 program aux enter-bootloader
solo1 program aux leave-bootloader
solo1 program aux enter-dfu
solo1 program aux leave-dfu
solo1 program aux reboot
solo1 program aux bootloader-version# Generate ECDSA P-256 keypair (PEM)
solo1 genkey [-o OUTPUT] [--entropy FILE] [--json]
# Sign firmware HEX file, output JSON {firmware, signature}
solo1 sign <KEY.pem> <firmware.hex>
# Merge Intel HEX files
solo1 mergehex -o OUTPUT [--attestation-key FILE] [--attestation-cert FILE] INPUT...
# Monitor serial output
solo1 monitor <PORT>- Firmware JSON files are available from the solo1 releases page.
- The bootloader enforces anti-rollback protection — you cannot downgrade to a firmware version older than what is currently installed.
- If
key updateis used without--firmware, the latest release is downloaded automatically.
solo1 key verify performs attestation by making a FIDO2 credential and checking the
attestation certificate against known fingerprints. Two fingerprint types are computed:
- Full-DER fingerprint — SHA-256 of the complete certificate DER bytes. Changes if the certificate is reissued.
- SPKI fingerprint — SHA-256 of the
SubjectPublicKeyInfostructure only. Stable across certificate renewals as long as the key is the same. Intended for future certificate pinning.
| Device type | SPKI fingerprint (SHA-256) |
|---|---|
| Solo Tap | 6b50560fef4c768b6e9a7a7749415a7c01d39842be3e4f7b8e859ba2a4be7049 |
| Solo 1 | not yet collected (see #3) |
| Solo Mu | not yet collected |
| Solo ≤v3.0.0 | not yet collected |
| Solo Hacker | not yet collected |
| Emulation/simulation | not yet collected |
The missing values must be obtained by running solo1 key verify --json against real
hardware and reading the spki_fingerprint field from the output. If you have one of
these devices please contribute the value via the issue linked above.
Verification still works without the SPKI fingerprints — full-DER fingerprints are used for device identification today. The SPKI constants are reserved for a future pinning mode that will tolerate certificate renewal without requiring a tool update.