mirror of
https://github.com/NixOS/nixpkgs.git
synced 2026-06-05 21:03:40 +00:00
yb: 0.1.0 -> 0.4.2, rewrite in Rust
The Python implementation has been replaced by a Rust rewrite. This updates the package definition accordingly: - Switch from buildPythonApplication to rustPlatform.buildRustPackage - Cargo workspace lives in rust/ subdirectory (cargoRoot = rust) - System dependency is now pcsclite only (no more opensc, openssl, yubico-piv-tool, yubikey-manager) - Install shell completions (bash, zsh, fish) via installShellFiles - Install man pages via yb-gen-man helper binary - Add passthru.tests.integration: NixOS VM test using vsmartcard-vpcd and piv-authenticator to exercise the full PIV stack without hardware - Add nix-update-script for automated version updates
This commit is contained in:
@@ -1811,6 +1811,7 @@ in
|
||||
xterm = runTest ./xterm.nix;
|
||||
xxh = runTest ./xxh.nix;
|
||||
yarr = runTest ./yarr.nix;
|
||||
yb = pkgs.callPackage ./yb.nix { inherit (pkgs.yb.passthru) ybPivHarnessTests testFixtures; };
|
||||
ydotool = import ./ydotool.nix {
|
||||
inherit (pkgs) lib;
|
||||
inherit runTest;
|
||||
|
||||
54
nixos/tests/yb.nix
Normal file
54
nixos/tests/yb.nix
Normal file
@@ -0,0 +1,54 @@
|
||||
{
|
||||
lib,
|
||||
pkgs,
|
||||
ybPivHarnessTests,
|
||||
testFixtures,
|
||||
}:
|
||||
|
||||
pkgs.testers.nixosTest {
|
||||
name = "yb-integration-tests";
|
||||
meta.maintainers = with lib.maintainers; [ douzebis ];
|
||||
|
||||
nodes.machine =
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
services.pcscd = {
|
||||
enable = true;
|
||||
plugins = [
|
||||
pkgs.ccid
|
||||
pkgs.vsmartcard-vpcd
|
||||
];
|
||||
};
|
||||
|
||||
environment.systemPackages = [
|
||||
pkgs.yb
|
||||
ybPivHarnessTests
|
||||
];
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
machine.start()
|
||||
machine.wait_for_unit("pcscd.socket")
|
||||
|
||||
# Tier-2: virtual smart card PIV tests (each test gets a fresh
|
||||
# RAM-backed card via vsmartcard-vpcd). Serialised to avoid
|
||||
# concurrent vpcd connections.
|
||||
out = machine.succeed("RUST_TEST_THREADS=1 hardware_piv_tests 2>&1")
|
||||
print(out)
|
||||
if "test result: ok" not in out:
|
||||
raise Exception("hardware_piv_tests failed:\n" + out)
|
||||
|
||||
# Tier-2: CLI subprocess tests against the Nix-built yb binary.
|
||||
# YB_FIXTURE_DIR points to fixtures in the nix store (the build-sandbox
|
||||
# path baked into CARGO_MANIFEST_DIR is gone at VM runtime).
|
||||
out = machine.succeed(
|
||||
"RUST_TEST_THREADS=1"
|
||||
+ " YB_BIN=${pkgs.yb}/bin/yb"
|
||||
+ " YB_FIXTURE_DIR=${testFixtures}"
|
||||
+ " yb_cli_tests 2>&1"
|
||||
)
|
||||
print(out)
|
||||
if "test result: ok" not in out:
|
||||
raise Exception("yb_cli_tests failed:\n" + out)
|
||||
'';
|
||||
}
|
||||
@@ -1,97 +1,159 @@
|
||||
{
|
||||
lib,
|
||||
python3Packages,
|
||||
rustPlatform,
|
||||
fetchFromGitHub,
|
||||
opensc,
|
||||
openssl,
|
||||
yubico-piv-tool,
|
||||
yubikey-manager,
|
||||
installShellFiles,
|
||||
versionCheckHook,
|
||||
pcsclite,
|
||||
pkg-config,
|
||||
runCommand,
|
||||
llvmPackages,
|
||||
nix-update-script,
|
||||
nixosTests,
|
||||
stdenv,
|
||||
}:
|
||||
|
||||
python3Packages.buildPythonApplication (finalAttrs: {
|
||||
rustPlatform.buildRustPackage (finalAttrs: {
|
||||
pname = "yb";
|
||||
version = "0.1.0";
|
||||
pyproject = true;
|
||||
version = "0.4.2";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "douzebis";
|
||||
repo = "yb";
|
||||
rev = "v${finalAttrs.version}";
|
||||
hash = "sha256-Eq3qFDzi/G4qQ3UUZWyl42zMYAO2C0ipV2yXxt2EAUw=";
|
||||
tag = "v${finalAttrs.version}";
|
||||
hash = "sha256-gX9s1R/75ipaPJFPTBMR2riIxMmw1KfuURx2Up6ovOM=";
|
||||
};
|
||||
|
||||
build-system = with python3Packages; [
|
||||
setuptools
|
||||
wheel
|
||||
];
|
||||
cargoRoot = "rust";
|
||||
|
||||
dependencies = with python3Packages; [
|
||||
click
|
||||
cryptography
|
||||
prompt-toolkit
|
||||
pyscard
|
||||
pyyaml
|
||||
yubikey-manager
|
||||
];
|
||||
cargoHash = "sha256-J91BH0eXuTtGZCSWWLYGM5KHtBjczD1Qu5PxIXAnFRI=";
|
||||
|
||||
nativeCheckInputs = with python3Packages; [
|
||||
pytestCheckHook
|
||||
];
|
||||
|
||||
buildInputs = [
|
||||
opensc
|
||||
openssl
|
||||
yubico-piv-tool
|
||||
yubikey-manager
|
||||
];
|
||||
|
||||
makeWrapperArgs = [
|
||||
"--prefix"
|
||||
"PATH"
|
||||
":"
|
||||
"${lib.makeBinPath [
|
||||
opensc
|
||||
openssl
|
||||
yubico-piv-tool
|
||||
yubikey-manager
|
||||
]}"
|
||||
"--set"
|
||||
"LD_LIBRARY_PATH"
|
||||
"${yubico-piv-tool}/lib"
|
||||
];
|
||||
|
||||
pythonImportsCheck = [
|
||||
# Build and test only the yb crate (not the yb-piv-harness test harness,
|
||||
# which requires a virtual smart card and runs in the NixOS VM test below).
|
||||
buildAndTestSubdir = "rust/yb";
|
||||
cargoBuildFlags = [
|
||||
"-p"
|
||||
"yb"
|
||||
"--features"
|
||||
"self-test"
|
||||
];
|
||||
cargoTestFlags = [
|
||||
"-p"
|
||||
"yb"
|
||||
"--features"
|
||||
"self-test"
|
||||
];
|
||||
|
||||
# Run subset of tests that don't require YubiKey hardware
|
||||
doCheck = true;
|
||||
enabledTestPaths = [
|
||||
"tests"
|
||||
nativeBuildInputs = [
|
||||
pkg-config
|
||||
installShellFiles
|
||||
];
|
||||
|
||||
buildInputs = lib.optionals stdenv.isLinux [ pcsclite ];
|
||||
|
||||
postInstall = lib.optionalString (stdenv.buildPlatform.canExecute stdenv.hostPlatform) ''
|
||||
# Bash completion: patch two clap_complete quirks:
|
||||
# 1. Add `compopt -o filenames` so path arguments complete correctly.
|
||||
# 2. Replace $2 (bash-tokenized word) with the actual typed text up to
|
||||
# the cursor, so arguments with spaces (e.g. --reader "Yubico YubiKey
|
||||
# OTP+FIDO+CCID 00 00") complete correctly.
|
||||
YB_COMPLETE=bash $out/bin/yb > _yb.bash
|
||||
substituteInPlace _yb.bash \
|
||||
--replace-fail ' ) )' ' ) )
|
||||
compopt -o filenames 2>/dev/null' \
|
||||
--replace-fail 'words[COMP_CWORD]="$2"' 'local _cur="''${COMP_LINE:0:''${COMP_POINT}}"
|
||||
_cur="''${_cur##* }"
|
||||
words[COMP_CWORD]="''${_cur}"'
|
||||
installShellCompletion --cmd yb \
|
||||
--bash _yb.bash \
|
||||
--zsh <(YB_COMPLETE=zsh $out/bin/yb) \
|
||||
--fish <(YB_COMPLETE=fish $out/bin/yb)
|
||||
|
||||
# Man pages (generated by the yb-gen-man helper binary, also in this crate).
|
||||
$out/bin/yb-gen-man $out/share/man/man1
|
||||
'';
|
||||
|
||||
nativeInstallCheckInputs = [
|
||||
versionCheckHook
|
||||
];
|
||||
doInstallCheck = true;
|
||||
|
||||
passthru =
|
||||
let
|
||||
# Fixture files needed by yb_cli_tests at VM runtime. rustPlatform vendors
|
||||
# the entire workspace but strips non-Rust files, so the compile-time
|
||||
# CARGO_MANIFEST_DIR path for fixtures is gone at VM time. We ship them as
|
||||
# a separate store path and inject YB_FIXTURE_DIR in the testScript.
|
||||
testFixtures = runCommand "yb-test-fixtures" { } ''
|
||||
mkdir -p $out
|
||||
cp ${finalAttrs.src}/rust/yb-core/tests/fixtures/with_key.yaml $out/with_key.yaml
|
||||
cp ${finalAttrs.src}/rust/yb-core/tests/fixtures/default.yaml $out/default.yaml
|
||||
'';
|
||||
|
||||
# Compile the harness test binaries (--no-run: compiled but not executed
|
||||
# here; the testScript in tests.nix invokes them directly).
|
||||
ybPivHarnessTests = rustPlatform.buildRustPackage {
|
||||
pname = "yb-piv-harness-tests";
|
||||
inherit (finalAttrs)
|
||||
version
|
||||
src
|
||||
cargoRoot
|
||||
cargoHash
|
||||
;
|
||||
|
||||
buildAndTestSubdir = "rust";
|
||||
|
||||
nativeBuildInputs = [
|
||||
pkg-config
|
||||
llvmPackages.libclang
|
||||
];
|
||||
buildInputs = lib.optionals stdenv.isLinux [ pcsclite ];
|
||||
|
||||
LIBCLANG_PATH = "${llvmPackages.libclang.lib}/lib";
|
||||
BINDGEN_EXTRA_CLANG_ARGS = "-I${llvmPackages.libclang.lib}/lib/clang/${lib.versions.major llvmPackages.release_version}/include";
|
||||
|
||||
# Skip the normal build — we only want the test binaries.
|
||||
buildPhase = ''
|
||||
(cd rust && cargo test --no-run \
|
||||
-p yb-piv-harness --features integration-tests \
|
||||
--offline --release)
|
||||
'';
|
||||
|
||||
doCheck = false;
|
||||
|
||||
installPhase = ''
|
||||
mkdir -p $out/bin
|
||||
(cd rust && for name in hardware_piv_tests yb_cli_tests; do
|
||||
bin=$(find target/release/deps -maxdepth 1 -name "$name-*" ! -name "*.d" -type f)
|
||||
if [ -z "$bin" ] || [ ! -f "$bin" ]; then
|
||||
echo "ERROR: could not find $name binary" >&2
|
||||
exit 1
|
||||
fi
|
||||
cp "$bin" $out/bin/$name
|
||||
done)
|
||||
'';
|
||||
};
|
||||
in
|
||||
{
|
||||
inherit ybPivHarnessTests testFixtures;
|
||||
tests.integration = nixosTests.yb;
|
||||
updateScript = nix-update-script { };
|
||||
};
|
||||
|
||||
meta = {
|
||||
description = "CLI tool for securely storing and retrieving binary blobs using YubiKey";
|
||||
description = "Secure blob storage on a YubiKey";
|
||||
longDescription = ''
|
||||
yb is a command-line tool that provides secure blob storage using a YubiKey device.
|
||||
It leverages the YubiKey's PIV (Personal Identity Verification) application to store
|
||||
encrypted or unencrypted binary data in custom PIV data objects. The tool uses hybrid
|
||||
encryption (ECDH + AES-256-CBC) to protect sensitive data with hardware-backed
|
||||
cryptographic keys.
|
||||
|
||||
Features:
|
||||
- Hardware-backed encryption using YubiKey PIV
|
||||
- ~36 KB storage capacity (expandable to ~48 KB)
|
||||
- PIN-protected management key mode
|
||||
- Multi-device support with interactive selection
|
||||
- Shell auto-completion for blob names
|
||||
- Glob pattern filtering
|
||||
Command-line tool for storing encrypted binary blobs on a YubiKey using
|
||||
the PIV application. Uses hybrid encryption (ECDH + AES-256-GCM) with
|
||||
hardware-backed keys, supports PIN-protected management key setup
|
||||
(--protect), glob-pattern blob listing, and shell completions for bash,
|
||||
zsh, and fish.
|
||||
'';
|
||||
homepage = "https://github.com/douzebis/yb";
|
||||
changelog = "https://github.com/douzebis/yb/releases/tag/v${finalAttrs.version}";
|
||||
license = lib.licenses.mit;
|
||||
maintainers = with lib.maintainers; [ douzebis ];
|
||||
mainProgram = "yb";
|
||||
platforms = lib.platforms.linux;
|
||||
platforms = lib.platforms.unix;
|
||||
};
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user