Skip to content

Repository files navigation

Cellulose

OpenSSF Scorecard OpenSSF Baseline Code Coverage

A memory-safe tool to backup and restore GPG keys using QR codes. Inspired by the paperkey utility.

Table of Contents

Purpose

Traditional GPG secret key backups are often stored on digital media, which can fail or be compromised. This tool allows you to print your secret key material as QR codes on physical paper, making it durable and offline.

Features

  • Backup: Extract secret material from GPG (stripping redundant public info) and generate a professional PDF with indexed QR codes and a human-readable hex dump.
  • Restore: Scan QR codes from images or PDF to reassemble the GPG secret key.
  • Manual Recovery: Guided line-by-line entry mode using the printed hex dump, with CRC-24 validation for 100% data integrity assurance even when QR codes are unreadable.
  • Durability: Integrated Reed-Solomon error correction allows recovery even if some QR codes are lost or damaged.

Security

  • Memory Safety: Written in pure Rust.
  • Cryptography: Uses Sequoia-PGP with the Nettle backend (constant-time primitives).
  • Anti-Forensics:
    • Proactive Zeroization of all sensitive buffers in memory.
    • Targeted Memory Protection: Uses Zeroizing<T> wrappers to ensure sensitive data (GPG keys, QR images, PDF buffers) is immediately wiped from RAM after use.
    • In-Memory Processing: QR code images and PDF pages are generated and processed entirely in memory buffers, avoiding disk traces.

Reproducibility

Cellulose is designed for forensic stability:

  • Reproducible Builds: All official binaries are bit-for-bit identical to those built from source in our verified dev container.
  • Deterministic PDFs: Backup documents are bit-for-bit identical when given identical input and a fixed timestamp via the SOURCE_DATE_EPOCH environment variable.

Input Limits

To prevent resource exhaustion (DoS) and ensure QR code scannability, Cellulose enforces a hard 48KB limit on stdin ingestion.

Documentation

A comprehensive manual page is available.

Generate the man page (requires pandoc):

just man

View the man page without installing:

man ./cellulose.1

Development Setup

1. Prerequisites (Manual Setup)

  • Install Rust and Cargo.
  • Install the Nettle development library.
  • Install just (task runner).
  • Install Git LFS.

2. Development Container (Alternative Setup)

If you prefer not to install dependencies locally, you can use the pre-configured development container:

just dev

This drops you into a shell with all prerequisites (including just, nettle, and cargo-deny) installed. It uses persistent container volumes for the Cargo cache for efficient builds and stores artifacts in target/container.

3. Build & Lint

We use just to manage all development tasks.

Build the project in release mode:

just build

Run the full security and quality audit (Recommended):

# Performs fmt, clippy, cargo-deny, and cargo-audit in a verified container
just lint

Auto-format code locally:

# Run this before committing to ensure style consistency
cargo fmt --all

The binary will be available at target/release/cellulose.

4. Containerized Workflows

For reproducible environments and complex tasks, we provide several container-based workflows (compatible with podman and docker).

Quality Assurance (Linting)

Our primary validation gate is a containerized auditing suite that ensures consistent results across all developer environments.

# Run all checks (rustfmt, clippy, cargo-deny, cargo-audit)
just lint

# Generate automated security advisory impact reports
# (Includes reachability analysis for ignored advisories)
just advisories

# Run a specific sub-task
just lint clippy
just lint deny
just lint audit

Automated PDFium Update

To update the vendored PDFium library (x86_64) with automated attestation verification:

# Update to default version
just update-pdfium

# Update to a specific version
just update-pdfium chromium/7825

Formal Verification

Run formal verification tools (Flux, Creusot, Hegel) without local setup:

just verify         # Defaults to flux
just hegel          # Run Hegel global soundness checks
just verify creusot # Run Creusot deductive verification

Fuzz Testing & Coverage

Execute intensive fuzz tests or generate a code coverage report in an isolated environment:

just fuzz   # Runs all 8 specialized fuzzer targets
just coverage

Usage

For detailed command syntax and a full list of security features, consult the manual page.

Quick Start

1. Create a physical backup:

gpg --export-secret-key YOUR_KEY_ID | cellulose backup --output backup.pdf.age

2. Verify backup integrity:

cellulose verify backup.pdf.age --pubkey my_public_key.asc

3. Restore and import into GPG:

cellulose restore backup.pdf.age --pubkey my_public_key.asc --import

4. Last-resort manual recovery:

# Guided line-by-line entry using the printed hex dump
cellulose restore --manual --pubkey my_public_key.asc --import

Warning

Using the --output flag during restoration (instead of --import) will write your unencrypted secret key directly to the disk. Always prefer --import to keep secrets in RAM.

Verification

To ensure the integrity and authenticity of the build artifacts:

1. GitHub Attestations

gh attestation verify cellulose --repo dawud/cellulose

2. Cosign

cosign verify-blob cellulose \
  --signature cellulose.sig \
  --certificate cellulose.pem \
  --certificate-identity "https://github.com/dawud/cellulose/.github/workflows/ci.yml@refs/heads/main" \
  --certificate-oidc-issuer "https://token.actions.githubusercontent.com"

Attributions

License

This project is licensed under the GNU General Public License v3.0 - see the LICENSE file for details.

About

A memory-safe tool to backup and restore GPG keys using QR codes. Inspired by the `paperkey` utility

Topics

Resources

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages