fix: required-arg checks, validation ordering, and length=null in subtle#1024
Merged
Conversation
Aligns subtle.* with WebCrypto spec and Node webcrypto.js commits 856231e8c40 (required-arg counts) and 4cb1f284136 (validation ordering). - B.6: every public Subtle method throws TypeError when called with fewer than the spec-required arguments. - B.8: sign/verify and encrypt/decrypt now check algorithm-mismatch before usage, throwing 'Key algorithm mismatch' first; the combined check moved out of cipherOrWrap so each call site enforces order. - B.9: wrapKey/unwrapKey gain the missing algorithm-mismatch check (with 'wrapKey'→'encrypt' / 'unwrapKey'→'decrypt' fallback). - B.10: deriveBits accepts length=null (default), per-algorithm gating rejects null for HKDF/PBKDF2/Argon2 with OperationError; ECDH and X25519/X448 return the full shared secret. - B.11: getKeyLength throws OperationError on invalid AES (non 128/192/256) and HMAC (length === 0) lengths instead of silently defaulting; HMAC without length now uses the hash block size. Issue #1003.
- wrapKey/unwrapKey: remove try/catch fallback to 'encrypt'/'decrypt' op during normalizeAlgorithm — the operation parameter is unused inside normalizeAlgorithm, so the catch was unreachable. - cipherOrWrap: drop the unused _op parameter (and the four pass-through args at the call sites). Algorithm/usage validation already lives at the public-method boundaries. - subtle.deriveBits: use baseKey.usages (matches the rest of the file) instead of the keyUsages alias. No behavior change.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
🤖 End-to-End Test Results - AndroidStatus: ✅ Passed 📸 Final Test ScreenshotScreenshot automatically captured from End-to-End tests and will expire in 30 days This comment is automatically updated on each test run. |
Contributor
🤖 End-to-End Test Results - iOSStatus: ✅ Passed 📸 Final Test ScreenshotScreenshot automatically captured from End-to-End tests and will expire in 30 days This comment is automatically updated on each test run. |
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.


Summary
Aligns
SubtleCryptowith Node'swebcrypto.js(commits856231e8c40,4cb1f284136) for argument-count validation, validation-step ordering, andlength=nullhandling. Closes #1003.Changes
TypeErrors. NewrequireArgs(actual, required, method)helper throws plainTypeError(matching webidl) when asubtle.*call is missing required positional args. Wired intoimportKey,exportKey,encrypt,decrypt,sign,verify,digest,deriveBits,deriveKey,wrapKey,unwrapKey,generateKey,getPublicKey, and the KEM methods.cipherOrWrap/signVerifyand into the public methods (encrypt/decrypt/sign/verify/wrapKey/unwrapKey) so the spec ordering is preserved: algorithm-mismatch first ('Key algorithm mismatch'), then usage ('Unable to use this key to <op>'). Both throwInvalidAccessError.wrapKey/unwrapKeyalgorithm match.wrapKey/unwrapKeynow reject whenwrappingKey.algorithm.namedoesn't match the (normalized) wrap algorithm name.deriveBitslength=null.lengthis nownumber | nullwith defaultnull. ECDH/X25519/X448 with null returns the full natural shared secret; PBKDF2/HKDF/Argon2 throwOperationError("length cannot be null").getKeyLengthhardening. Returnsnumber | null(null for HKDF/PBKDF2/Argon2 KDF targets), throwsOperationErroron invalid AES (not 128/192/256) and HMAC (length === 0) inputs instead of silently coercing to 256. NewgetHmacBlockSizehelper for the HMAC default (block size of the named hash).subtle.deriveBitsusage gate. Now requires'deriveBits'specifically — the oldderiveBits || deriveKeyaccept-either branch silently promoted deriveKey-only keys.throw new Error(...)inderiveBits/deriveKeywithlazyDOMExceptioncarrying the right error name (InvalidAccessError,NotSupportedError,OperationError).try/catchfallback inwrapKey/unwrapKeyand the unused_opparameter fromcipherOrWrap.Test plan
bun tsc --noEmitclean across both packagesexample/src/tests/subtle/validation_ordering.ts(19 tests):importKey/generateKey/sign/verify/encrypt/decrypt/deriveBits/deriveKey/wrapKey/unwrapKey/exportKey/digest/getPublicKeyall throwTypeErrorwhen called with too few argssignwith mismatched algorithm throws'Key algorithm mismatch'(not the usage error) — confirms orderingsignwith correct algorithm but missing usage throws the usage errorencrypt/wrapKey/unwrapKeymismatched-algorithm cases all throw'Key algorithm mismatch'firstderiveBitsECDH withlength=nullreturns full 32-byte P-256 shared secretderiveBitsECDH with length omitted defaults to null (full secret)deriveBitsHKDF / PBKDF2 withlength=nullthrowOperationErrorderiveKeyto AES-GCM with invalid length 100 throwsOperationError("Invalid key length")deriveKeyto HMAC withlength=0throwsOperationError("Invalid key length")encrypt_decryptassertions migrated from English-message snippets toInvalidAccessError(theDOMException.name)