phase 2: task decomposition — 8-task port graph

- crate-init: skeleton, feature gates (ADR-003), TlsError (ADR-002)
- three parallel foundation ports: identity types, fingerprint, pem+signing
- port-server / port-client in parallel (each consumes the foundation;
  client also carries credentials.rs per ADR-005 co-location)
- integration-suite: invariant pins + feature-matrix + seam round-trips
- review-impl: spec-conformance gate — the API-freeze point before the
  alknet rewrite consumes the crate
- validated: taskgraph topo (5 generations), no cycles, critical path
  len 5, risk-path 1.45; medium risk concentrated on the two broad
  ports + the suite (each a diff against a fixed extraction source,
  not open-ended work)
This commit is contained in:
2026-09-10 06:32:44 +00:00
parent d74a27f764
commit 05b3832c88
8 changed files with 706 additions and 0 deletions
+75
View File
@@ -0,0 +1,75 @@
---
id: port-fingerprint
name: Port fingerprint helpers + DER parser (src/fingerprint.rs)
status: pending
depends_on: [crate-init]
scope: narrow
risk: low
impact: component
level: implementation
tags: [fingerprint, port]
---
## Description
Port the fingerprint module from alknet-core
(`crates/alknet-core/src/fingerprint.rs`) into `src/fingerprint.rs`
per ADR-005: `fingerprint_from_cert_der(&[u8]) -> Option<String>`
(`ed25519:<hex>` for RFC 7250 Ed25519 SPKI, `SHA256:<hex>` for
anything else — the normalized formats from alknet ADR-030 §6),
`extract_ed25519_raw_key_from_spki(&[u8]) -> Option<[u8; 32]>`, and
the private manual DER parser (`DerParser`).
### Invariants
- Production code stays `sha2` + manual DER — no `rustls::` imports in
the module's non-test code (the extracted module's purity; ADR-006).
- The Ed25519 OID constant is `[0x2b, 0x65, 0x70]` (`1.3.101.112`);
the SPKI BIT STRING is 33 bytes (one unused-bits `0x00` + the
32-byte key). These are the RFC 7250 wire facts the parser encodes.
- `extract_ed25519_raw_key_from_spki` returns `None` for non-Ed25519
SPKI / malformed DER / X.509 certs; `fingerprint_from_cert_der`
falls back to SHA-256-hashing the full DER (returns `None` only for
empty input).
- Port the extracted in-module DER parser tests verbatim (they cover
the malformed-input edges: truncated headers, long-form lengths,
wrong OIDs, bad BIT STRING lengths).
## Work
1. Port the module wholesale (it is self-contained).
2. Port the extracted tests; assert `ed25519:<hex>` and `SHA256:<hex>`
normalization on representative inputs.
3. Confirm no `rustls::` import outside `#[cfg(test)]`.
## Verification
- [ ] Ported tests green (`cargo test fingerprint`)
- [ ] Round-trip: an Ed25519 SPKI built by `signing.rs`'s
`spki_public_key()` yields `ed25519:<hex>` matching the source
key (integration assert — this pins the normalization across
the raw-key paths)
- [ ] Malformed-DER inputs yield `None` / SHA fallback (ported edge
tests)
- [ ] `cargo clippy --all-targets -- -D warnings`, `cargo fmt --check`
## Acceptance Criteria
- [ ] The module compiles without `rustls` in production code
- [ ] Both normalized fingerprint formats are test-pinned
- [ ] `lib.rs` re-exports the two public functions
## References
- docs/architecture/decisions/005-config-types-move-into-alktls.md
- docs/architecture/decisions/006-module-layout-and-tests.md
- alknet ADR-030 §6 (fingerprint normalization — the reference)
- Prior art: `/workspace/@alkdev/alknet/crates/alknet-core/src/fingerprint.rs`
## Notes
> Agent fills this during implementation.
## Summary
> Agent fills this on completion.