guest SDK: wrap the full signature surface; the docs stop denying exports - #378
Merged
Conversation
…orts Two doc comments (SigningKeyOptions::extractable, SigningKey:: extractable) said no signing-key export operation exists. The WIT defines export-key-jwk/-pkcs8 on signature.signing-key and both Rust implementations serve them — an SDK consumer reading those docs would conclude the operations are absent from the package, which is false. The docs now name the real exports. The gap behind the drift closes rather than being declared: the SDK wraps the whole signature surface it sat inside of — - VerifyingKey::export_key_spki/_jwk beside the existing _raw; - SigningKey::export_key_jwk/_pkcs8 and to_wrap_input_jwk/_pkcs8, matching the other extractability-gated key types; - ed25519/ecdsa import_verifying_key_spki/_jwk, import_signing_key_pkcs8/_jwk, and unwrap_signing_key_pkcs8/_jwk, mirroring the sibling modules' constructor-per-WIT-function shape. crypto-demo executes every new wrapper, per its harness role. The ed25519 checks extend in place (RFC 8032 test 2's seed: deterministic signatures make the round trips exact) and run on every leg including composed. The ECDSA signing mints join the host-only build (the provider withholds ecdsa-sign — class D), so the demo feature and artifact rename from rsa-oaep to host-only, after the conformance architecture's host-only suite; RFC 6979 A.2.5's key signs and the paired public half verifies (ECDSA signatures are not deterministic across implementations). The signing-key wrap tours use an AEAD kek: AES-KW takes only 8-byte multiples, which the private serializations do not promise (the P-256 PKCS#8 form is 138 bytes), and private export round-trips compare semantically — PKCS#8 v1/v2 forms differ across providers — via signatures instead of bytes. Fixes #228
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.
The drift (#228's actively misleading half)
Two SDK doc comments (
SigningKeyOptions::extractable,SigningKey::extractable) stated there is no signing-key export operation. The WIT definesexport-key-jwk/-pkcs8onsignature.signing-key(wit/webcrypto.wit:730,734) and both Rust implementations serve them. The docs now name the real exports and keep the keystore note.The gap (resolved as: close it)
Ruling per the issue's option 1 — the surface is stable pre-publication, the wrappers are thin forwarders, and an SDK wrapping
import-verifying-key-rawbut not-spki/-jwkpushes consumers back to raw bindings for adjacent calls:VerifyingKey::export_key_spki/_jwkbeside the existing_rawSigningKey::export_key_jwk/_pkcs8+to_wrap_input_jwk/_pkcs8(matching Mac/CipherKey/DecryptionKey's gated-export shape)ed25519/ecdsa:import_verifying_key_spki/_jwk,import_signing_key_pkcs8/_jwk,unwrap_signing_key_pkcs8/_jwk— the unwrap mints included for symmetry with the sibling modules (aes_gcm, hmac_sha2), which all wrap theirsDemo coverage (every new wrapper executes)
ed25519-sign): public spki/jwk imports verify RFC 8032 test 2; raw/SPKI exports round-trip byte-for-byte (canonical encodings), JWK export re-imports; private pkcs8/jwk imports from the test-2 seed sign to the known signature byte-for-byte (Ed25519 is deterministic); non-extractable export failsNotExtractable; extractable exports round-trip semantically (PKCS#8 v1/v2 differs across providers); both wrap tours transit the key through an AEAD kek without the material reaching the caller.ecdsa-sign-mints) join the host-only build — the provider withholdsecdsa-sign(class D) — with RFC 6979 A.2.5's key: each minted key's signature verifies against the paired public half (ECDSA bytes are implementation-dependent by design, so no byte KAT).rsa-oaep→host-only(after the conformance architecture's host-only suite): the opt-in set now has two members, so it is named for the category — checks whose imports the in-guest provider withholds. Polarity unchanged from crypto-demo: exercise the rsa_oaep wrappers in an opt-in build #377: off by default, serving hosts opt in.Found while building: the signing-key wrap tours cannot use AES-KW — RFC 3394 wraps only 8-byte multiples and the P-256 PKCS#8 form is 138 bytes (the WIT's stated contract, surfaced by the gate) — so they wrap under AES-GCM with per-wrap nonces.
Verification
just demo::test-composed: 21 checks (extended ed25519 surface runs in-guest)cargo test -p wasmtime-demo+just demo::wasmtime: 23 checks incl.ecdsa-sign-mints,rsa-oaep-key-transportjust demo::test-node(Node 24.19): 23 checksjust fmt-check,just clippyclean;cargo doc -p polymorph-webcrypto-guestadds no new warnings; artifact WITs: 0 withheld-interface mentions in the default build, 6 in host-onlyFixes #228