Skip to content
ratspeakPublic

About

YubiKey PIV identity tools for Reticulum.

Resources

Stars

10 stars

Watchers

0 watching

Forks

Latest commit

 

History

8 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Ratkey

Hardware-backed identities for Python Reticulum applications.

License: MIT Python 3.9+ YubiKey 5

This repository contains the experimental 0.1.0 Python package and rnid-hw tool. It uses a YubiKey's PIV application for Ed25519 signing and X25519 key agreement. Applications must integrate its identity loader and handle PIN entry, disconnection and retries.

The Ratspeak app uses a separate Rust implementation. This tool's 24-word recovery phrase and .hwid files are not the app's 12-word backup flow.

Install

Use Python 3.9 or newer and Git. Create a virtual environment:

python3 -m venv .venv
. .venv/bin/activate
python3 -m pip install "ratkey[yubikey,backup] @ git+https://github.com/ratspeak/ratkey.git"

On Windows, use py -m venv .venv, activate .venv\Scripts\activate in Command Prompt, and run the install command with python -m pip.

The yubikey extra installs YubiKey Manager; backup supplies the mnemonic and key-derivation dependencies for recoverable provisioning and restore. On Debian/Ubuntu, install the smart-card service and development files:

sudo apt install pcscd libpcsclite-dev
sudo systemctl start pcscd

Use a standard, non-FIPS YubiKey 5 with firmware 5.7.0 or later. The required Ed25519/X25519 PIV algorithms are absent from the FIPS model's supported set. Firmware version alone does not establish that another token supports this backend. The Nitrokey backend is an unimplemented placeholder; installing its extra does not make it usable.

Provisioning

Plug in the YubiKey and run:

rnid-hw

The wizard asks for a provisioning method, PIN, PIN policy, separate signing and encryption touch policies, and an output directory. Use a 6–8 character ASCII PIN. A new or reset PIV application has three PIN attempts by default; an existing key may have different retry counters.

  1. Hardware-only generates both keys on the token. Ratkey cannot export them. Losing the token or erasing its PIV application loses this identity.
  2. Recoverable derives keys from a 24-word BIP-39 phrase and imports them. Keep the phrase privately: anyone with it can reconstruct the identity without the token's PIN. The derived keys exist in host memory during creation and restore; Python cannot guarantee that every copy is erased.

rnid-hw restore imports a recoverable identity onto a replacement token. The phrase uses Ratkey's own derivation; a BIP-39 phrase from another application is not automatically compatible.

rnid-hw migrate <identity> imports an existing software identity. Its source file and other copies remain usable unless separately removed. The command offers to delete the source file: keep it until you have tested the hardware identity and decided how to retain your backup.

PIV slots and reset

Ratkey writes signing keys to 9A and encryption keys to 9D. If either slot is occupied, the wizard offers to reset the PIV user credentials, including unrelated keys and certificates. Do not accept that reset unless those credentials can be replaced. It also restores the PIN, PUK and management key defaults.

Provisioning expects the default PIV PIN and management key before setting the chosen PIN. This version does not set a new PUK or management key. An existing customized PIV configuration may therefore require separate administration; do not reset a token merely to clear an unexplained error.

Touch and PIN policies

Policies belong to the key created or imported into each slot. Changing them requires replacing that slot's key. A recoverable phrase or retained software key permits reimporting the same identity with new policies; hardware-only keys cannot be exported for that purpose.

The wizard defaults to never for touch and once for PIN. That favors unattended operations. Choose touch requirements according to how the application will be used:

Touch policy Behavior
never Operations need no physical touch. A compromised host can request operations while the token is connected.
cached One touch permits operations for a 15-second window.
always Each operation requires touch; frequent messaging can require frequent interaction.

When requested, touch the blinking token. Handle a timeout as a failed operation; the application decides whether to retry.

PIN policy Token behavior
once Authenticate once per PIV session. Closing or replacing that session can require the PIN again.
always Authenticate for each private-key operation. The application must arrange this.
never The token does not require PIN authentication for the key operation.

The Python backend still requires verify_pin() before its signing and key-agreement methods, including for never. Registering a PIN callback does not automatically connect or authenticate this backend. These are integration responsibilities in this version.

When the token is needed

Private-key signing and key agreement need the connected token. Public-key operations and established session encryption are different operations; do not assume every packet requires a token interaction.

If the token is absent, the private-key proxy raises HardwareDisconnectedError. It does not wait indefinitely, reconnect automatically or guarantee that a message is retained. The application must preserve pending work, reconnect and authenticate before retrying.

Hardware-only keys reduce exposure from copying identity files. The token does not protect message history, recovery phrases, migrated software copies or a compromised host using an attached token. Touch requirements can restrict unattended use; they do not make the host trustworthy.

CLI

rnid-hw                        Interactive wizard
rnid-hw provision              Provision a new hardware identity
rnid-hw restore                Restore from this tool's 24-word phrase
rnid-hw migrate <identity>     Import an existing software identity
rnid-hw list                   List saved hardware identity configurations
rnid-hw info <hwid-file>       Show saved identity information
rnid-hw verify <hwid-file>     Compare the connected token's public keys
rnid-hw test <hwid-file>       Run signing and decryption operations

Use rnid-hw <command> --help for options. The default output is ~/.reticulum/identities/<identity-hash>/identity.hwid. This file contains public keys and token metadata, not a private-key backup.

For developers

HardwareIdentity subclasses RNS.Identity, but loading it alone does not initialize the hardware session. For an interactive YubiKey application using PIN policy once, load and authenticate explicitly:

from getpass import getpass
from pathlib import Path

from ratkey import HardwareIdentity
from ratkey.backends.yubikey_piv import YubiKeyPIVBackend
from ratkey.hwid import load_hwid

hwid_path = Path("/path/to/identity.hwid")
config = load_hwid(hwid_path)
backend = YubiKeyPIVBackend(serial=config.device_serial)
backend.verify_pin(getpass("PIV PIN: "))
if backend.get_public_keys() != (config.ed25519_pub_bytes, config.x25519_pub_bytes):
    raise ValueError("The token does not match this identity file")
identity = HardwareIdentity.from_hwid(hwid_path, backend=backend)

Handle connection, PIN, touch and smart-card exceptions in your application's UI. Recreate and verify the session after disconnection. Policy always needs authentication before each operation. Test the exact RNS version and the app's signing, receive and Link paths; replacing one loader does not establish complete compatibility. get_private_key() and to_file() deliberately refuse private-key export.

Troubleshooting

Token not detected. Check the smart-card service, USB connection and token model. On Linux, inspect pcscd; reconnect the token before creating a new session.

PIN blocked. A correct PUK can unblock a PIN if PUK attempts remain. Blocking the PUK does not itself erase keys. If both are blocked, PIV reset is the recovery path, and that reset removes PIV user keys and certificates and restores the default PIV credentials. Retry limits are configurable; consult Yubico's PIN and PUK reference rather than assuming ten PUK attempts.

Slot conflict. Check everything stored in PIV before accepting the wizard's reset. Replacing a hardware-only identity changes its address.

Missing mnemonic dependency. Install the backup extra in the same environment as rnid-hw.

License

MIT — Ratspeak Project

About

YubiKey PIV identity tools for Reticulum.

Resources

Stars

10 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages