jco host: import taxonomy, stream-drop pin, key-material persistence note - #382
Merged
Conversation
…sistence note Import-failure taxonomy: `invalidKey` routed every platform import rejection to `invalid-key`, so an engine declining an algorithm at importKey reported "bad key" where the host's own taxonomy (platformCall) says `unsupported`. NotSupportedError now maps to `unsupported`. No conformance platform can observe the branch (they all serve what the host mints), so the pin is a host-direct test with a stubbed platform importKey, both directions. Stream drop: the assumption that the jco runtime lowers a guest dropping a returned stream onto ReadableStream.cancel() has ridden three toolchain generations (0.5.2, fork 0.6.2, upstream 0.7.0) unwritten and untested. It is now a named convention in the header's list, and the admission suite pins the host half: a cancelled, undrained output releases its reservation — a regression there means abandoned outputs leak pool capacity. Key-material persistence (the last item of the host-hardening list): the raw-export-derives-from-JWK mechanic the item was filed about no longer exists (signature keys export jwk/pkcs8 only), so what remains is documentation. A header section states which paths materialize secrets in immortal JS strings — JWK exports and to-wrap-input-jwk, inherent to serving a string format on a JS platform — and which stay in ArrayBuffers (raw, pkcs8), with the consumer-side pkcs8 route for threat models that include host-memory persistence. The four secret-JWK export sites point at the section. Doc polish: the stale EcdsaAlgorithm curve-OID claim (typedef and ECDSA_VARIANTS prose — no OID member exists), eleven split JSDoc blocks merged so the prose attaches to its symbol, and configure()'s objection-answering clause dropped.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #28, Closes #288 — the two jco-host maintenance lists, rolled up now that #28's remainder is documentation (per maintainer direction: the consumer-side pkcs8 route replaces host-side DER parsing). One file, textually overlapping small diffs; a PR apiece would pay two review passes on the same surface.
#288
invalidKeymapped every platform import rejection toinvalid-key; a platformNotSupportedError— the engine declining the algorithm or form, not judging the material — now maps tounsupported, the taxonomyplatformCallalready documents. No conformance platform can observe the branch (every engine on the matrix serves what the host mints, so theirimportKeynever reports NotSupportedError), hence the pin is a host-direct test with a stubbed platformimportKey, both directions (test/import-failure-taxonomy.test.js).ReadableStream'scancel(), relying on the jco runtime lowering guest-side stream drop ontocancel()— an assumption that has ridden three toolchain generations (0.5.2 → fork 0.6.2 → upstream 0.7.0) as neither a documented convention nor a test. It is now the fourth entry in the header's jco-conventions list, and the admission suite pins the host half: a cancelled, undrained output releases its capacity (a regression means abandoned outputs leak the pool). The drop→cancel lowering itself remains a version-anchored convention — pinning it end-to-end needs a transpiled guest that drops a result stream, which no current harness produces; the header now says exactly that much honestly.EcdsaAlgorithmtypedef and theECDSA_VARIANTSprose both claimed a curve-OID member "for the PKCS#8 wrapping" — no OID member exists and PKCS#8 imports are platform pass-throughs; eleven split prose-+-bare-@typeJSDoc blocks merged so the prose attaches to its symbol (the count grew from the issue's list — a new one had accreted since);configure()'s objection-answering clause dropped (the rationale already lives in admission.test.js).errMessageTooLongordering nit and the stale 0.5.2 header anchor resolved themselves in earlier PRs (Modernize the jco legs: fork transpiler, -I async, runtime import binding #347/Move the jco toolchain to upstream jco-transpile 0.7.0; drop the fork pins #368), per the issue's comment trail.#28 (item 3, the last open box)
The item was filed when signing-key raw export derived from the platform JWK (
d+atob) — that mechanic no longer exists (signing-keyexportsjwk/pkcs8only, andb64urlDecodetouches only a public point), so what remains is the exposure inherent to JWK itself. A "Key-material persistence" header section now states it:export-key-jwkandto-wrap-input-jwk(the caller never sees that JWK, but the host still builds it) materialize secret members —k,d, the RSA CRT set — in JS strings, which are immutable, unscrubable, and live until GC. The platform's ownexportKey("jwk")already returns strings, so this is inherent to serving JWK on a JS host.raw(symmetric) andpkcs8(private) exports and wrap-inputs stay inArrayBuffers end to end.pkcs8and parse the fixed-layout DER themselves.The four secret-JWK export sites carry one-line pointers to the section. The deltic host module mirrors the same platform techniques but is deliberately untouched: it is upstreamed verbatim from lann/deltic (its header's port-provenance rule), and its JWK helpers already reference this host's docs by convention, so the note travels with the reference rather than diverging the port.
Verification
just jco::test-host— 30 tests (27 baseline + the 3 added here), all passjust jco::typecheck— cleanjust demo::test-node— 23 checks through the real transpiled componentjust conformance-ct::run-jco— jco-node, both suites: 19,089 + 770 results, 0 failed (the taxonomy change is invisible where platforms serve everything, as designed)rsa-verify-8192decline probe deliberately pins no error variant, and the Firefox/WebKit ledger classes fail at operation stage or withDataError-class import rejections, so the engine legs (CI) see no verdict changes