test(doubles): land the wave-1 in-memory seams + unified ed25519 fixtures

The `w1-test-doubles` task: the in-memory seams every later wave's
contract tests run against, behind their production seams.

- tests/common/mod.rs — the doubles, test-only (nothing reachable from
  lib.rs, no feature): MemIdentityProvider (registered fingerprints ->
  alkcall Identity resolutions over the IdentityProvider trait; token
  path resolves none per ADR-004), TestVault (a wrapper over alkvault
  0.1's shipped in-memory construction — resolving the flagged
  vault-double question: wrap, not re-impl), MemHostKeyPolicy
  (exact (host, fingerprint) rules + explicit default verdict,
  fail-closed by default, inspectable decision log), and the fixture
  table. Module docs record the location/vault/fixture decisions and
  the row/stamp discipline (greppable Contract stamps).
- tests/vectors/ — one unified fixture set: four ssh-keygen-minted
  ed25519 keypairs (committed .key + .pub + fingerprints.txt recorded
  from ssh-keygen -lf, OpenSSH_9.6p1). The previous inline PEM
  constants in src/key_source.rs were rejected by OpenSSH itself
  (russh-only decodable); all keys were re-minted and the overlapping
  vector set retired — one fixture set now serves the parity tests,
  the custody round-trip, and every later auth/mapping test
  (src-unit tests share it via include_str!).
- tests/doubles.rs — the end-to-end rows: register -> resolve,
  seal -> source -> decode (+ locked/absent/tampered postures),
  host-key set in order, policy verdicts honored-and-logged.
- tests/fingerprint_parity.rs and src/key_source.rs tests moved onto
  the shared fixture files; src changes are #cfg(test) only.

Verification: cargo test (33 + 9 + 5 green; --all-features also green),
cargo clippy --all-targets -- -D warnings clean, cargo fmt --check
clean, taskgraph validate ok (12 tasks).
This commit is contained in:
glm-5.3-flash committed 2026-10-28 07:09:17 +00:00
1 parent 949d0bbbe4
commit 214690b9c2
14 files changed
+933 -113

No files matched your search

+32 -33
View File
@@ -235,39 +235,18 @@ mod tests {
use crate::error::KeySourceError;
use crate::fingerprint::fingerprint;
/// Throwaway test fixtures generated at vector time with
/// `ssh-keygen -t ed25519` (OpenSSH 9.6p1); recorded here as
/// committed test constants — throwaway secrets, never deployed,
/// never registered anywhere real (the w1-test-doubles posture).
/// `ALPHA` is the client-dial fixture; `BRAVO`/`CHARLIE` are two
/// independent host-key fixtures.
const ALPHA_PEM: &str = concat!(
"-----BEGIN OPENSSH PRIVATE KEY-----\n",
"b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW\n",
"QyNTUxOQAAACA7vQRGU0CqQMrqRUJef/2aZK/bR2mxnzBWWZHMUkq8/wAAAJgexTRBHsU0\n",
"QQAAAAtzc2gtZWQyNTUxOQAAACA7vQRGU0CqQMrqRUJef/2aZK/bR2mxnzBWWZHMUkq8/w\n",
"AAAEAjImC/Ay2J2FejKJYNoRllIF9+ed5Qmdd7erLCisK03Du9BEZTQKpAyupFQl5//Zpk\n",
"r9tHabGfMFZZkcxSSrz/AAAAEmFsa3NzaC13MS1rcy1hbHBoYQECAw==\n",
"-----END OPENSSH PRIVATE KEY-----\n",
);
const BRAVO_PEM: &str = concat!(
"-----BEGIN OPENSSH PRIVATE KEY-----\n",
"b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW\n",
"QyNTUxOQAAACDqobhDdf1GvNXSd8tK6HHp9tIlhWooOWSp+MS8jRTlTAAAAJjsjCqp7Iwq\n",
"qQAAAAtzc2gtZWQyNTUxOQAAACDqobhDdf1GvNXSd8tK6HHp9tIlhWooOWSp+MS8jRTlTA\n",
"AAAEDe5J9K933yhWNUQmQ6VdT1zBN9eu3/39IoR0Q+4hXpheqhuEN1/Ua81dJ3y0rocen2\n",
"0iWFaig5ZKn4xLyNFOVMAAAAEmFsa3NzaC13MS1rcy1icmF2bwECAw==\n",
"-----END OPENSSH PRIVATE KEY-----\n",
);
const CHARLIE_PEM: &str = concat!(
"-----BEGIN OPENSSH PRIVATE KEY-----\n",
"b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW\n",
"QyNTUxOQAAACAnkAMvpNU6zs25fONkvgqt5E0V8eR8ySnFzv5OOdU2OQAAAJi/2ytvv9sr\n",
"bwAAAAtzc2gtZWQyNTUxOQAAACAnkAMvpNU6zs25fONkvgqt5E0V8eR8ySnFzv5OOdU2OQ\n",
"AAAEBqCsZ6AAe7S+AedrAYPjMBIcW10vHlaEWdIGH7jJQefCeQAy+k1TrOzbl842S+Cq3k\n",
"TRXx5HzJKcXO/k451TY5AAAAFGFsa3NzaC13MS1rcy1jaGFybGllAQ==\n",
"-----END OPENSSH PRIVATE KEY-----\n",
);
/// The committed test-key fixtures (`tests/vectors/`) — the
/// wave-1 fixture set, read by this `#[cfg(test)]` module through
/// `include_str!` (the `tests/common/mod.rs` double module is the
/// tests/-side owner; src-unit tests never own fixture copies).
/// Throwaway `ssh-keygen`-minted keys, never registered anywhere
/// real (`ALPHA` is the client-dial fixture; `BRAVO`/`CHARLIE`
/// the host-key pair). Their `ssh-keygen -lf` fingerprints are
/// recorded in `tests/vectors/fingerprints.txt` — the fixture
/// parity row below asserts this module sees the same values.
const ALPHA_PEM: &str = include_str!("../tests/vectors/alpha.key");
const BRAVO_PEM: &str = include_str!("../tests/vectors/bravo.key");
const CHARLIE_PEM: &str = include_str!("../tests/vectors/charlie.key");
fn unlocked_vault() -> alkvault::VaultServiceHandle {
let vault = alkvault::VaultServiceHandle::new();
@@ -275,6 +254,26 @@ mod tests {
vault
}
/// Fixture parity for this module's `include_str!` reads: the
/// computed fingerprints match the independent-issuer record
/// (`ssh-keygen -lf`, `tests/vectors/fingerprints.txt`).
#[test]
fn fixture_keys_match_their_ssh_keygen_recorded_fingerprints() {
let manifest = include_str!("../tests/vectors/fingerprints.txt");
for (name, pem) in [
("alpha", ALPHA_PEM),
("bravo", BRAVO_PEM),
("charlie", CHARLIE_PEM),
] {
let key = russh::keys::decode_secret_key(pem, None).expect("fixture PEM decodes");
let fp = fingerprint(key.public_key());
assert!(
manifest.contains(&format!("{name}.pub {fp}")),
"{name}'s computed fingerprint is not the recorded value"
);
}
}
fn encrypt(vault: &alkvault::VaultServiceHandle, pem: &str) -> alkvault::EncryptedData {
vault
.encrypt(pem, CURRENT_KEY_VERSION)