crypto-demo: exercise the rsa_oaep wrappers in an opt-in build - #377
Merged
Conversation
The rsa_oaep SDK module (every constructor plus the EncryptionKey/ DecryptionKey op wrappers) was the one guest-SDK surface no gate executed. It cannot join the demo unconditionally: a component's imports are derived from the calls it makes, and the in-guest provider withholds all four RSA op interfaces (class D), so a demo calling OAEP stops composing at wac plug. The demo therefore gains an rsa-oaep cargo feature (default on) and build-component produces two artifacts: the default build adds the rsa-oaep-key-transport check — the Wycheproof known answer under both private-key imports, both public-key imports encrypting back to it, label binding, and a generated pair's round trip — and the --no-default-features composable build keeps the OAEP interfaces out of the call graph for the in-guest composition. The wasmtime and jco legs run the full build (22 checks); the composed leg runs the composable one (21). Fixes #285 — the other five modules the issue lists gained checks in earlier changes; rsa_oaep was the remainder.
Default-on read as an endorsement — as if enabling the withheld RSA op interfaces were the normal choice a consumer opts out of. The posture everywhere else is the reverse: the SDK's rsa-oaep-decrypt feature, the WIT gate behind it, and add_to_linker all default off, and test builds opt in deliberately. The demo now matches: the default build is the composable artifact (crypto-demo.component.wasm, what the in-guest composition plugs), and the --features rsa-oaep build exists as the separate crypto-demo-rsa-oaep.component.wasm, run only by the legs whose hosts deliberately serve those interfaces (the wasmtime-demo tests, the jco demo on Node). The clippy line lints the demo --all-features so the gated check stays covered.
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.
Premise check on #285
The issue lists six never-executed SDK modules, but five (
aes_cbc,hmac_sha1,hkdf_sha1,pbkdf2_sha1,sha1_checked) gained demo checks in changes since it was filed. The remainder isrsa_oaep— and the issue's "cheapest close: extend crypto-demo's checks" runs into a structural constraint: a component's imports are derived from the calls it makes, and the in-guest provider withholds all four RSA op interfaces (class D, includingrsa-oaep-encrypt— the class-d gate's own probe list). A demo that calls any OAEP constructor therefore stops composing atwac plug, killingdemo::test-composed. This is #215's mechanism, encountered from the consumer side.The shape
One crate, two artifacts — the class-D split the conformance architecture already uses (guest-ct vs signing-guest-ct), applied to the demo, with the gate's polarity matching the rest of the repository (the SDK's
rsa-oaep-decrypt, the WIT gate, andadd_to_linkerall default off; serving is the deliberate act):rsa-oaepcargo feature, off by default (forwards to the SDK'srsa-oaep-decrypt). The default build is the standard, composable artifact —crypto-demo.component.wasm, whatdemo::composeplugs.build-componentadditionally producescrypto-demo-rsa-oaep.component.wasm(--features rsa-oaep), which adds thersa-oaep-key-transportcheck and with it the withheld-by-default imports. Only the legs whose hosts deliberately serve those interfaces run it: the wasmtime-demo tests /demo::wasmtime(the standalone embedding opts into every gated interface) and the jco demo on Node. Verified structurally: 0rsa-oaepmentions in the default artifact's WIT, 4 in the opt-in one.The check covers every
rsa_oaepconstructor and both op wrappers: the Wycheproof known answer (rsa_oaep_2048_sha256_mgf1sha256, tcId 2 — the group key is the same 2048-bit modulus as the demo's existingRSA_SPKI) decrypts under both private-key imports (PKCS#8, full-CRT JWK); the public half imported as SPKI and as a public JWK encrypts back to the vector key; a ciphertext decrypts only under its label (mismatch failsAuthenticationFailed, per RFC 8017's indistinguishability rule); and a generated pair round-trips (OAEP is randomized — generation has no known-answer form).Verification
just demo::test-composed: 21 checks pass (default build, no OAEP)cargo test -p wasmtime-demo+just demo::wasmtime: 22 checks pass includingrsa-oaep-key-transport(opt-in build); the summary self-consistency assertions holdjust demo::test-node(Node 24.19): 22 checks pass (opt-in build) — Node's WebCrypto serves the gated decrypt interfaces (the jco-node posture)just fmt-check,just clippy(now--all-featureson the demo, so the gated check stays linted) cleanFixes #285