yb-core 0.7.1

Secure blob storage on a YubiKey — core library
docs.rs failed to build yb-core-0.7.1
Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
Visit the last successful build: yb-core-0.6.0

yb-core

Named blobs on a YubiKey, encrypted and signed by it, from Rust.

crates.io docs.rs license

yb-core keeps small files (secrets, keys, a password database) in a YubiKey 5's PIV data objects: about 50 KB in all, under names you choose. Each blob can be encrypted with a key that never leaves the YubiKey, or derived by it, and is signed or sealed by it, so that tampering is detected before use. It is the library under the yb command and libyubiblob, its C interface.

Guarantees

Each one is documented, and checked by regression tests against emulated YubiKeys (the invariants):

Interrupted writes lose nothing A YubiKey pulled out, or its memory full, mid-write: the previous version stays.
Several programs, one YubiKey Operations take the card's lock, and their outcome is that of running them one at a time.
Tampering is detected before use A blob altered on the YubiKey is refused before it is decrypted or returned.
Reading never writes Listing and fetching change nothing on the YubiKey.
The management key is never lost Changing it is interruption-safe, and it is held in memory that is wiped after use.

Features

  • Two kinds of store:
    • legacy: P-256 ECDH and AES-256-GCM, with ECDSA signatures;
    • post-quantum: symmetric keys derived by the YubiKey's FIDO2 application (hmac-secret), one touch per blob.
  • Blobs of any content, compressed when it helps (brotli or xz), listed with their sizes and modification times.
  • PINs only when needed: listing needs none; writing and decrypting need the PIN.
  • Snapshots and conditional writes: read the store once, and write only if a blob is still as you last saw it.
  • Testing without a YubiKey: VirtualPiv, a simulated YubiKey in memory (feature virtual-piv).

Example

The YubiKey must first be set up with yb format --post-quantum (from the yb command), with its FIDO2 PIN set.

use yb_core::{orchestrator, store::Store, Compression, Context, ContextOptions, OutputOptions};

fn main() -> anyhow::Result<()> {
    let mut ctx = Context::new(
        ContextOptions::default(),
        Box::new(|| Ok(None)),     // no PIV PIN: not used by a post-quantum store
        Box::new(|_, _| Ok(None)), // the only YubiKey connected
        OutputOptions::default(),
    )?;
    ctx.fido2_pin_fn = Box::new(|| Ok(std::env::var("YB_PIN").ok()));
    ctx.on_touch = Box::new(|| eprintln!("Touch your YubiKey…"));

    let mut store = Store::from_device(&ctx.reader, ctx.piv.as_ref())?;
    let descriptor = store.descriptor().cloned().expect("a post-quantum store");
    let session = ctx.post_quantum_session()?; // asks for the FIDO2 PIN, once
    let protection = session.protection(&ctx, &descriptor);

    // Store a blob, encrypted and sealed: one touch.
    let stored = orchestrator::store_blob_with(
        &mut store,
        ctx.piv.as_ref(),
        &protection,
        "greeting",
        b"Hello, YubiKey!",
        true, // encrypted
        Compression::Auto,
        None, // the management key: the protection unwraps the store's copy
    )?;
    assert!(stored, "the store is full");

    // List: no PIN, no touch.
    for blob in orchestrator::list_blobs(&store) {
        println!("{}: {} bytes", blob.name, blob.plain_size);
    }

    // Fetch: its seal checked, then decrypted: one touch.
    let data = orchestrator::fetch_blob_with(&store, &protection, "greeting")?;
    assert_eq!(data.as_deref(), Some(&b"Hello, YubiKey!"[..]));
    Ok(())
}

Legacy stores (yb format, no touch), removal, snapshots and the other operations: see the documentation.

Building

yb-core links two system libraries, found with pkg-config:

PC/SC libfido2
Debian, Ubuntu libpcsclite-dev libfido2-dev
Fedora pcsc-lite-devel libfido2-devel
Arch pcsclite libfido2
macOS (Homebrew) built in libfido2
NixOS pcsclite libfido2

At run time, PC/SC's daemon (pcscd) must be running on Linux. On Windows, only legacy stores are supported, without libfido2.

Which crate?

  • yb: the command (yb store, yb fetch, yb ls…), to set up a YubiKey and manage its blobs.
  • yb-core: this library, for Rust programs.
  • yubiblob: libyubiblob, the same store for C and C++ programs (used by KeePassYB, a KeePassXC with its database on a YubiKey).

More: the storage format, the changelog.

License

MIT.