id: d0aa76f4f7c14171b1f3aa01463c361f
parent_id: f37483476a0d47d690ffa12e5d8077b5
item_type: 1
item_id: bb3506f46ead40df8a7f965a73339928
item_updated_time: 1786962659015
title_diff: "[]"
body_diff: "[{\"diffs\":[[0,\"08-1\"],[-1,\"4 17:50 (pre-Monday hardening committed: 15d2b77 + 2de34cf, pushed)\\\n\\\n## TOP BLOCKER — KLMS generateContainer HTTP 500 (since their card-ready deployment)\\\n\\\n`POST /cryptoContainers` returns 500 \\\"Failed to generate the requested CryptoContainer or\\\ninsufficient rights\\\" on every attempt (both retries in a session). Our request is byte-identical\\\nto the HW-verified pre-deployment run. Evidence pack for the KLMS team:\\\n- Log 2026-08-14 15:23:17Z: `typeID=0x0900`, `productSerial=KF-0447\"],[1,\"7 12:30 (bridge removal committed: 065ee6b, pushed; HW-verified on two fobs)\\\n\\\n## CLOSED — private key format (M5/M10), fully resolved 2026-08-17\\\n\\\nThe complete chain now works end-to-end, verified on hardware with **two fobs**\\\n(`04478c7ae11d90`, `044b\"],[0,\"8c7a\"]],\"start1\":61,\"start2\":61,\"length1\":489,\"length2\":258},{\"diffs\":[[0,\"d90`\"],[-1,\", 7-byte uid in extra,\\\n  HTTP 500 twice (after pointless re-install — now fixed, see below)\\\n- Empty container UUID/CID in our log = headers absent from the 500 error response (not redaction);\\\n  `RUST_LOG=debug` now prints the full request form + every response header for proof\\\n- Questions for them: new typeID for card-ready containers? keyBundleType renamed? 7-vs-10-byte UID\\\n  expectation? (the failing fob returned a 7-byte card UID via the chip-UID fallback)\\\n- Blank serials in their admin: likely the serial column fills via the usage PUT (report_usage,\\\n  unwired by our choice) — or our productSerial form field is ignored server-side\\\n\\\n## KLMS Team — RESOLVED & OPEN items\\\n\\\n**RESOLVED — M5/M10 private key format (2026-08-14):** KLMS delivers field[8] (DGI A003)\\\n**card-ready**: 48-byte AES-128-ECB + ISO 9797-1 M2-encrypted 32-byte EC scalar. Station\\\n(commit 3bc2f97): `worker.rs::card_ready_private_key` validates structure (48 B, `0x80||0*15`\\\ntail) and forwards as-is, `encrypt_with_dek: false` — zero local crypto; CBC-decrypt/`04 20`\\\nworkaround deleted. Awaiting first successful container to HW-verify end-to-end.\\\n\\\n**Still open (external — KLMS team):**\\\n\\\n| # | Issue | What's needed |\\\n|---|-------|---------------|\\\n| — | generateContainer HTTP 500 | Server-side fix / expected typeID or fields (top blocker above) |\\\n| C1 | `danger_\"],[1,\"):\\\n- KLMS delivers field[8] (DGI A003) card-ready as **AES-128-CBC, IV=0, ISO 9797-1 M2**\\\n  over the 32-byte scalar — the card-verified format.\\\n- Station (`worker.rs::prepare_card_ready_private_key`): verifies structure only\\\n  (48-byte length, S-DEK decrypt → M2-padded 32-byte scalar) and **forwards the blob\\\n  untouched** — zero re-encryption.\\\n- Evidence (2026-08-17 10:20Z): `AES-CBC(IV=0)+M2 — forwarded as-is`, 9 STORE DATA\\\n  blocks, FACTORY transition, 2 post-perso commands, certs/FESN/SPID read back,\\\n  **GA ECDSA verify: true**, `Provisioning succeeded (24 APDUs)` — on both fobs.\\\n- The ECB→CBC compatibility bridge is **removed** (065ee6b); a regression test now\\\n  asserts ECB blobs are rejected. History: original spec said ECB (our error),\\\n  KLMS delivered ECB (6A80 rejections), bridge converted locally, KLMS switched to\\\n  CBC, bridge deleted.\\\n\\\nThe HW smoke run open since 2026-08-14 is thereby complete.\\\n\\\n## KLMS Team — remaining OPEN items (external)\\\n\\\n| # | Issue | What's needed |\\\n|---|-------|---------------|\\\n| C1 | `\"],[0,\"acce\"]],\"start1\":322,\"start2\":322,\"length1\":1352,\"length2\":1044},{\"diffs\":[[0,\"side is \"],[-1,\"now \"],[0,\"config-r\"]],\"start1\":1430,\"start2\":1430,\"length1\":20,\"length2\":16},{\"diffs\":[[0,\"dy (\"],[-1,\"see below)\"],[1,\"default secure, dev config opts in). Note: without the flag the server errors \\\"client error (Connect)\\\"; the p12 may contain the missing intermediate\"],[0,\" |\\\n|\"]],\"start1\":1448,\"start2\":1448,\"length1\":18,\"length2\":156},{\"diffs\":[[0,\"ate \"],[-1,\"with container UUID \"],[0,\"(`va\"]],\"start1\":1653,\"start2\":1653,\"length1\":28,\"length2\":8},{\"diffs\":[[0,\"key \"],[-1,\"matches dev KLMS \"],[0,\"(`ve\"]],\"start1\":1757,\"start2\":1757,\"length1\":25,\"length2\":8},{\"diffs\":[[0,\"x03 \"],[-1,\"so verification can be wired \"],[0,\"|\\\n| \"]],\"start1\":1876,\"start2\":1876,\"length1\":37,\"length2\":8},{\"diffs\":[[0,\"sion\"],[-1,\") |\\\n\\\n## Pre-Monday hardening (15d2b77 + 2de34cf, 2026-08-14)\\\n\\\n1. **productSerial from the 7-byte PC/SC chip UID** (`KF-<chip uid hex>`), fallback to card-UID\\\n   prefix; `product serial: ...` log line; debug logging of generate/\"],[1,\"; likely why admin serials are blank) |\\\n| — | getVersions / getContainerTypes return empty | 200 OK but zero entries — \"],[0,\"re\"],[1,\"s\"],[0,\"po\"],[-1,\"rt request forms.\\\n2. **Config-driven `container_type_id` + `key_bundle_type`** (klms-config.toml `[klms]` section,\\\n   defaults 0x0900 / dev): if the KLMS expects a new typeID or bundle tag after their deployment,\\\n   Monday is a config edit + restart, no rebuild.\\\n3. **TLS C1 prep**: `accept_invalid_certs` config flag, default **false** (secure). Dev config\\\n   sets true (loud warning at connect) until a valid CA arrives; flipping to verification is a\\\n   config change.\\\n4. **Retry classification**: `FlowError` distinguishes card-stage (SELECT/INIT UPDATE/STORE DATA/\\\n   validation → re-install + retry, unchanged) from server-stage (HTTP/container/key-mismatch →\\\n   single plain retry, **no pointless applet re-install**). Fixes the observed 500 behavior of\\\n   re-installing the applet before retrying a dead server.\\\n\\\n## Documented as Intentional (won't fix)\\\n\\\n| # | Issue | Resolution |\\\n|---|-------|------------|\\\n| H1 | \"],[1,\"nse shape or permissions? (minor, ask when convenient) |\\\n\\\n## Session log\\\n\\\n**2026-08-17:** KLMS switched to CBC; bridge removed (065ee6b); two-fob HW verification\\\nwith GA signatures passing — private-key workstream closed.\\\n**2026-08-14:** KLMS REST 500 fixed their side; 6A80 root-caused to ECB-vs-CBC spec error\\\n(ours); bridge committed (ae5531f); pre-Monday hardening (config typeID/keyBundleType/TLS\\\nflag, retry classification, chip-UID serial, debug logging); full audit — clippy 0 ×3\\\nvariants, 105 tests, fmt/doc clean; ECB test-vector defect found and fixed; notes\\\nconsolidated into the single \\\"Key Fob Station\\\" notebook.\\\n\\\n## Documented as Intentional (won't fix)\\\n\\\n\"],[0,\"IAM \"]],\"start1\":1977,\"start2\":1977,\"length1\":1162,\"length2\":802},{\"diffs\":[[0,\"user\"],[-1,\"name\"],[0,\"/pass\"],[-1,\"word |\"],[0,\" \"],[1,\"(\"],[0,\"mTLS\"]],\"start1\":2785,\"start2\":2785,\"length1\":24,\"length2\":15},{\"diffs\":[[0,\"ient\"],[-1,\", matches Clypeum reference |\\\n| H4 | T\"],[1,\") · t\"],[0,\"extb\"]],\"start1\":2810,\"start2\":2810,\"length1\":46,\"length2\":13},{\"diffs\":[[0,\"RSA \"],[-1,\"signature \"],[0,\"verify \"],[-1,\"| \"],[1,\"(\"],[0,\"Clypeum \"],[-1,\"container format |\\\n| M17 | Wrapper key KDF (NIST 800-108, zero LABEL/CONTEXT) | Works, constants documented |\\\n| — | kf-provision local\"],[1,\"format) · wrapper KDF\\\nzero LABEL/CONTEXT ·\"],[0,\" KF_\"]],\"start1\":2827,\"start2\":2827,\"length1\":169,\"length2\":66},{\"diffs\":[[0,\"ID copy \"],[-1,\"| D\"],[1,\"(d\"],[0,\"ependenc\"]],\"start1\":2908,\"start2\":2908,\"length1\":19,\"length2\":18},{\"diffs\":[[0,\"irection\"],[-1,\" |\\\n| — |\"],[1,\") ·\"],[0,\" STATIC_\"]],\"start1\":2929,\"start2\":2929,\"length1\":24,\"length2\":19},{\"diffs\":[[0,\"Y_TABLE \"],[1,\"test\\\n\"],[0,\"duplicat\"]],\"start1\":2950,\"start2\":2950,\"length1\":16,\"length2\":21},{\"diffs\":[[0,\"ion \"],[-1,\"in kf-klms | Test isolation |\\\n| — | ISD SELECT variants (empty vs explicit AID) | Deliberate,\"],[1,\"· ISD SELECT variants\"],[0,\" via\"]],\"start1\":2971,\"start2\":2971,\"length1\":101,\"length2\":29},{\"diffs\":[[0,\"lect\"],[-1,\"(None/Some)` |\\\n| — |\"],[1,\"` ·\"],[0,\" pro\"]],\"start1\":3014,\"start2\":3014,\"length1\":28,\"length2\":11},{\"diffs\":[[0,\"opy \"],[-1,\"| Gated `dev-keys` feature |\\\n| — | \"],[1,\"·\\\n\"],[0,\"Prov\"]],\"start1\":3045,\"start2\":3045,\"length1\":43,\"length2\":10},{\"diffs\":[[0,\"rors\"],[-1,\" | Dev/prod pipelines evolve independently |\"],[1,\".\"],[0,\"\\\n\\\n##\"]],\"start1\":3096,\"start2\":3096,\"length1\":52,\"length2\":9},{\"diffs\":[[0,\"oc (\"],[-1,\"all \"],[0,\"HW-v\"]],\"start1\":3182,\"start2\":3182,\"length1\":12,\"length2\":8},{\"diffs\":[[0,\") · \"],[-1,\"M6/M7/M11/M17'/L12/L15\\\nclosed in a\"],[1,\"A\"],[0,\"udit\"]],\"start1\":3197,\"start2\":3197,\"length1\":42,\"length2\":9},{\"diffs\":[[0,\"b6):\"],[-1,\" \"],[1,\"\\\n\"],[0,\"error\"],[-1,\"-enum\"],[0,\" uni\"]],\"start1\":3221,\"start2\":3221,\"length1\":19,\"length2\":14},{\"diffs\":[[0,\" helper,\"],[-1,\"\\\n\"],[1,\" \"],[0,\"builders\"]],\"start1\":3268,\"start2\":3268,\"length1\":17,\"length2\":17},{\"diffs\":[[0,\"l-closed\"],[-1,\" \"],[1,\"\\\n\"],[0,\"validati\"]],\"start1\":3313,\"start2\":3313,\"length1\":17,\"length2\":17},{\"diffs\":[[0,\"nic-safe\"],[-1,\"\\\n\"],[1,\" \"],[0,\"workers,\"]],\"start1\":3365,\"start2\":3365,\"length1\":17,\"length2\":17},{\"diffs\":[[0,\"\\\n\\\n- \"],[-1,\"HW smoke run of the card-ready private key path — blocked on the 500 fix; first successful tap\\\n  after their fix = verification (GA signature check proves correct S-DEK encryption)\"],[1,\"None blocking. Optional polish from the round-5 audit backlog: shared AES block-size\\\n  constant, dedupe config-default placeholders in app.rs.\"],[0,\"\\\n\\\n##\"]],\"start1\":3421,\"start2\":3421,\"length1\":188,\"length2\":150},{\"diffs\":[[0,\"orkspace\"],[-1,\"\\\n\\\n\"],[1,\" & Notes\\\n\\\n- \"],[0,\"Single c\"]],\"start1\":3573,\"start2\":3573,\"length1\":18,\"length2\":28},{\"diffs\":[[0,\"tation`\\\n\"],[1,\"  \"],[0,\"(origin \"]],\"start1\":3670,\"start2\":3670,\"length1\":16,\"length2\":18},{\"diffs\":[[0,\".1.2\"],[-1,\"). Obsolete `rusteworkspace` scratch copy deleted 2026-08-14\"],[1,\", pushed through 065ee6b)\\\n- All project notes in the **Key Fob Station** notebook: this audit note (live state),\\\n  Project Status, KLMS REST API Flow, Container Binary Format, Production (Files)\\\n  Reference Flow, PlantUML Diagram Sources, Locked-Fob Incident, Windows Configuration,\\\n  Implementation Plan (historical). \\\"KLMS Known Issues and Debug Notes\\\" was merged into\\\n  this note + Project Status on 2026-08-17 (500/cipher-mode content resolved; TLS detail\\\n  and ops data preserved) and deleted\"],[0,\".\\\n\\\n#\"]],\"start1\":3701,\"start2\":3701,\"length1\":68,\"length2\":505},{\"diffs\":[[0,\"mit \"],[-1,\"2de34cf\"],[1,\"065ee6b\"],[0,\")\\\n\\\n-\"]],\"start1\":4226,\"start2\":4226,\"length1\":15,\"length2\":15},{\"diffs\":[[0,\"tfmt\"],[-1,\"/doc\"],[0,\" clean;\"],[-1,\" 104\"],[0,\" tes\"]],\"start1\":4288,\"start2\":4288,\"length1\":23,\"length2\":15},{\"diffs\":[[0,\"sts pass\"],[1,\" (12 in kf-dev-station)\"],[0,\"\\\n- Deplo\"]],\"start1\":4302,\"start2\":4302,\"length1\":16,\"length2\":39},{\"diffs\":[[0,\".bat\"],[-1,\" (release build verified); debug logging via RUST_LOG=debug\"],[1,\"; debug evidence via RUST_LOG=debug (tracing goes to stderr —\\\n  not visible when launched as a detached GUI process)\\\n- Fobs #2 and #3 provisioned + validated; #1 remains locked (GP counter — see incident note)\"]],\"start1\":4355,\"start2\":4355,\"length1\":63,\"length2\":213}]"
metadata_diff: {"new":{"is_locked":0,"extracted_resource_ids":""},"deleted":["user_data"]}
encryption_cipher_text: 
encryption_applied: 0
updated_time: 2026-08-17T10:39:06.175Z
created_time: 2026-08-17T10:39:06.175Z
is_locked: 0
type_: 13