Pure, safe Rust reimplementation of nitropy - the CLI for Nitrokey devices. Goal: 100% feature parity.
Design Priorities
- Safe code (first priority): No unsafe Rust, no undefined behavior
- Secure code & minimal crates (second priority): Auditability, minimal dependencies
- Usability (third priority): UX only when compatible with safety
Quality & Build
- Binary name:
patina - Code must pass:
No dead code allowed.cargo clippy --all-targets -- -W clippy::all -W clippy::pedantic -W clippy::nursery -D dead-code -D unused - Reproducible builds: Cargo.lock locked versions
Feature Parity: nitropy vs patina
The patina binary has device-specific subcommands: patina nk3 ..., patina nkpk ..., etc.
| Feature | nitropy (Python) | patina (Rust) | Status |
|---|---|---|---|
| Global | |||
list |
✅ | ✅ | ✅ Complete |
version |
✅ | ✅ | ✅ Complete |
Nitrokey 3 (nitropy nk3 / patina nk3) |
|||
list |
✅ | ✅ | ✅ Complete |
wink |
✅ | ✅ | ✅ Complete |
status |
✅ | ✅ | ✅ Complete |
version |
✅ | ✅ | ✅ Complete |
rng |
✅ | ✅ | ✅ Complete |
uuid |
✅ | ✅ | ✅ Complete |
reboot |
✅ | ✅ | ✅ Complete |
list-config-fields |
✅ | ✅ | ✅ Complete |
get-config |
✅ | ✅ | ✅ Complete |
set-config |
✅ | ✅ | ✅ Complete |
factory-reset |
✅ | ✅ | ✅ Complete |
factory-reset-app |
✅ | ✅ | ✅ Complete |
test |
✅ | ✅ | ✅ Complete (SE050 + FIDO2 connectivity) |
fetch-update |
✅ | Helpful message | 🟡 Stub (manual workflow available: download ZIP from GitHub releases) |
update |
✅ | Enhanced stub | 🟡 Enhanced (validates firmware, detects device variant, shows compatibility) |
validate-update |
✅ | ✅ | 🟡 Enhanced (parses manifest, maps images to hardware variants, detects formats) |
provision |
✅ | Helpful message | 🟡 Stub (production-only, APP_PROVISIONER) |
Nitrokey Passkey (nitropy nkpk / patina nkpk) |
|||
| (Same commands as nk3) | ✅ | CLI stub only | ⏳ Planned |
FIDO2 (nitropy fido2 / patina fido2) |
|||
list, update |
✅ | CLI stub only | ⏳ Planned |
Nitrokey Start (nitropy start / patina start) |
|||
list, rng, set-identity, update |
✅ | CLI stub only | ⏳ Planned |
| Nitrokey Pro / Storage | |||
list |
✅ | CLI stub only | ⏳ Planned |
NetHSM (nitropy nethsm / patina nethsm) |
|||
unlock |
✅ | CLI stub only | ⏳ Planned |
| Platform Support | |||
| Linux | ✅ | ✅ | ✅ Complete |
| FreeBSD | ✅ | ✅ | ✅ Supported by hidapi |
| OpenBSD | ✅ | ✅ | ✅ Supported by hidapi |
| macOS | ✅ | ⚠️ | ⏳ Needs macos-shared-* hidapi feature |
| Windows | ✅ | ⚠️ | ⏳ Needs windows-native hidapi feature |
| NetBSD | ❌ | ❌ | ❌ hidapi crate doesn't support NetBSD |
Platform Support
| OS | Support | Notes |
|---|---|---|
| Linux | ✅ Fully tested | Uses hidraw via hidapi |
| FreeBSD | ✅ Supported | Uses system hidapi package |
| OpenBSD | ✅ Supported | Uses system hidapi-libusb package |
| macOS | ⚠️ Incomplete | Needs macos-shared-* hidapi feature enabled at build time |
| Windows | ⚠️ Incomplete | Needs windows-native hidapi feature enabled at build time |
| NetBSD | ❌ Unsupported | hidapi crate doesn't support NetBSD |
Current Status
Working (tested with actual Nitrokey 3):
- Device enumeration via
cargo run -- list - CTAPHID (FIDO2 HID) protocol communication
nk3 winkcommand (blinks the device LED)- Full CLI argument parsing matching original nitropy
Dependencies
- Linux:
libudev,pkg-config - FreeBSD/OpenBSD: install
hidapisystem package - Cross-platform HID via
hidapicrate
Build & Run
Reproducible build:
cargo build --release --frozen
Binary:
./target/release/patina list
./target/release/patina nk3 wink
./target/release/patina help
Install:
cargo install --frozen --path .
patina list
Developers only (debug build):
cargo build
./target/debug/patina list
License
BSD-3-Clause