| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 66b1356 commit 3ef38c4
34 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -2,6 +2,10 @@ | |||
| 2 | 2 | ||
| 3 | 3 | <!-- YAML | |
| 4 | 4 | changes: | |
| 5 | + - version: REPLACEME | ||
| 6 | + pr-url: https://github.com/nodejs/node/pull/46067 | ||
| 7 | + description: Arguments are now coersed and validated as per their WebIDL | ||
| 8 | + definitions like in other Web Crypto API implementations. | ||
| 5 | 9 | - version: v19.0.0 | |
| 6 | 10 | pr-url: https://github.com/nodejs/node/pull/44897 | |
| 7 | 11 | description: No longer experimental except for the `Ed25519`, `Ed448`, | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -32,7 +32,6 @@ const { | |||
| 32 | 32 | } = internalBinding('crypto'); | |
| 33 | 33 | ||
| 34 | 34 | const { | |
| 35 | - getArrayBufferOrView, | ||
| 36 | 35 | hasAnyNotIn, | |
| 37 | 36 | jobPromise, | |
| 38 | 37 | validateByteLength, | |
@@ -112,13 +111,10 @@ function getVariant(name, length) { | |||
| 112 | 111 | } | |
| 113 | 112 | ||
| 114 | 113 | function asyncAesCtrCipher(mode, key, data, { counter, length }) { | |
| 115 | - counter = getArrayBufferOrView(counter, 'algorithm.counter'); | ||
| 116 | 114 | validateByteLength(counter, 'algorithm.counter', 16); | |
| 117 | 115 | // The length must specify an integer between 1 and 128. While | |
| 118 | 116 | // there is no default, this should typically be 64. | |
| 119 | - if (typeof length !== 'number' || | ||
| 120 | - length <= 0 || | ||
| 121 | - length > kMaxCounterLength) { | ||
| 117 | + if (length === 0 || length > kMaxCounterLength) { | ||
| 122 | 118 | throw lazyDOMException( | |
| 123 | 119 | 'AES-CTR algorithm.length must be between 1 and 128', | |
| 124 | 120 | 'OperationError'); | |
@@ -135,7 +131,6 @@ function asyncAesCtrCipher(mode, key, data, { counter, length }) { | |||
| 135 | 131 | } | |
| 136 | 132 | ||
| 137 | 133 | function asyncAesCbcCipher(mode, key, data, { iv }) { | |
| 138 | - iv = getArrayBufferOrView(iv, 'algorithm.iv'); | ||
| 139 | 134 | validateByteLength(iv, 'algorithm.iv', 16); | |
| 140 | 135 | return jobPromise(() => new AESCipherJob( | |
| 141 | 136 | kCryptoJobAsync, | |
@@ -166,12 +161,9 @@ function asyncAesGcmCipher( | |||
| 166 | 161 | 'OperationError')); | |
| 167 | 162 | } | |
| 168 | 163 | ||
| 169 | - iv = getArrayBufferOrView(iv, 'algorithm.iv'); | ||
| 170 | 164 | validateMaxBufferLength(iv, 'algorithm.iv'); | |
| 171 | 165 | ||
| 172 | 166 | if (additionalData !== undefined) { | |
| 173 | - additionalData = | ||
| 174 | - getArrayBufferOrView(additionalData, 'algorithm.additionalData'); | ||
| 175 | 167 | validateMaxBufferLength(additionalData, 'algorithm.additionalData'); | |
| 176 | 168 | } | |
| 177 | 169 | ||
@@ -281,24 +273,26 @@ async function aesImportKey( | |||
| 281 | 273 | break; | |
| 282 | 274 | } | |
| 283 | 275 | case 'jwk': { | |
| 284 | - if (keyData == null || typeof keyData !== 'object') | ||
| 285 | - throw lazyDOMException('Invalid JWK keyData', 'DataError'); | ||
| 276 | + if (!keyData.kty) | ||
| 277 | + throw lazyDOMException('Invalid keyData', 'DataError'); | ||
| 286 | 278 | ||
| 287 | 279 | if (keyData.kty !== 'oct') | |
| 288 | - throw lazyDOMException('Invalid key type', 'DataError'); | ||
| 280 | + throw lazyDOMException('Invalid JWK "kty" Parameter', 'DataError'); | ||
| 289 | 281 | ||
| 290 | 282 | if (usagesSet.size > 0 && | |
| 291 | 283 | keyData.use !== undefined && | |
| 292 | 284 | keyData.use !== 'enc') { | |
| 293 | - throw lazyDOMException('Invalid use type', 'DataError'); | ||
| 285 | + throw lazyDOMException('Invalid JWK "use" Parameter', 'DataError'); | ||
| 294 | 286 | } | |
| 295 | 287 | ||
| 296 | 288 | validateKeyOps(keyData.key_ops, usagesSet); | |
| 297 | 289 | ||
| 298 | 290 | if (keyData.ext !== undefined && | |
| 299 | 291 | keyData.ext === false && | |
| 300 | 292 | extractable === true) { | |
| 301 | - throw lazyDOMException('JWK is not extractable', 'DataError'); | ||
| 293 | + throw lazyDOMException( | ||
| 294 | + 'JWK "ext" Parameter and extractable mismatch', | ||
| 295 | + 'DataError'); | ||
| 302 | 296 | } | |
| 303 | 297 | ||
| 304 | 298 | const handle = new KeyObjectHandle(); | |
@@ -308,10 +302,10 @@ async function aesImportKey( | |||
| 308 | 302 | validateKeyLength(length); | |
| 309 | 303 | ||
| 310 | 304 | if (keyData.alg !== undefined) { | |
| 311 | - if (typeof keyData.alg !== 'string') | ||
| 312 | - throw lazyDOMException('Invalid alg', 'DataError'); | ||
| 313 | 305 | if (keyData.alg !== getAlgorithmName(algorithm.name, length)) | |
| 314 | - throw lazyDOMException('Algorithm mismatch', 'DataError'); | ||
| 306 | + throw lazyDOMException( | ||
| 307 | + 'JWK "alg" does not match the requested algorithm', | ||
| 308 | + 'DataError'); | ||
| 315 | 309 | } | |
| 316 | 310 | ||
| 317 | 311 | keyObject = new SecretKeyObject(handle); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -18,7 +18,6 @@ const { | |||
| 18 | 18 | } = internalBinding('crypto'); | |
| 19 | 19 | ||
| 20 | 20 | const { | |
| 21 | - getArrayBufferOrView, | ||
| 22 | 21 | getUsagesUnion, | |
| 23 | 22 | hasAnyNotIn, | |
| 24 | 23 | jobPromise, | |
@@ -73,7 +72,6 @@ function verifyAcceptableCfrgKeyUse(name, isPublic, usages) { | |||
| 73 | 72 | ||
| 74 | 73 | function createCFRGRawKey(name, keyData, isPublic) { | |
| 75 | 74 | const handle = new KeyObjectHandle(); | |
| 76 | - keyData = getArrayBufferOrView(keyData, 'keyData'); | ||
| 77 | 75 | ||
| 78 | 76 | switch (name) { | |
| 79 | 77 | case 'Ed25519': | |
@@ -237,12 +235,13 @@ async function cfrgImportKey( | |||
| 237 | 235 | break; | |
| 238 | 236 | } | |
| 239 | 237 | case 'jwk': { | |
| 240 | - if (keyData == null || typeof keyData !== 'object') | ||
| 241 | - throw lazyDOMException('Invalid JWK keyData', 'DataError'); | ||
| 238 | + if (!keyData.kty) | ||
| 239 | + throw lazyDOMException('Invalid keyData', 'DataError'); | ||
| 242 | 240 | if (keyData.kty !== 'OKP') | |
| 243 | - throw lazyDOMException('Invalid key type', 'DataError'); | ||
| 241 | + throw lazyDOMException('Invalid JWK "kty" Parameter', 'DataError'); | ||
| 244 | 242 | if (keyData.crv !== name) | |
| 245 | - throw lazyDOMException('Subtype mismatch', 'DataError'); | ||
| 243 | + throw lazyDOMException( | ||
| 244 | + 'JWK "crv" Parameter and algorithm name mismatch', 'DataError'); | ||
| 246 | 245 | const isPublic = keyData.d === undefined; | |
| 247 | 246 | ||
| 248 | 247 | if (usagesSet.size > 0 && keyData.use !== undefined) { | |
@@ -260,30 +259,32 @@ async function cfrgImportKey( | |||
| 260 | 259 | break; | |
| 261 | 260 | } | |
| 262 | 261 | if (keyData.use !== checkUse) | |
| 263 | - throw lazyDOMException('Invalid use type', 'DataError'); | ||
| 262 | + throw lazyDOMException('Invalid JWK "use" Parameter', 'DataError'); | ||
| 264 | 263 | } | |
| 265 | 264 | ||
| 266 | 265 | validateKeyOps(keyData.key_ops, usagesSet); | |
| 267 | 266 | ||
| 268 | 267 | if (keyData.ext !== undefined && | |
| 269 | 268 | keyData.ext === false && | |
| 270 | 269 | extractable === true) { | |
| 271 | - throw lazyDOMException('JWK is not extractable', 'DataError'); | ||
| 270 | + throw lazyDOMException( | ||
| 271 | + 'JWK "ext" Parameter and extractable mismatch', | ||
| 272 | + 'DataError'); | ||
| 272 | 273 | } | |
| 273 | 274 | ||
| 274 | 275 | if (keyData.alg !== undefined) { | |
| 275 | - if (typeof keyData.alg !== 'string') | ||
| 276 | - throw lazyDOMException('Invalid alg', 'DataError'); | ||
| 277 | 276 | if ( | |
| 278 | 277 | (name === 'Ed25519' || name === 'Ed448') && | |
| 279 | 278 | keyData.alg !== 'EdDSA' | |
| 280 | 279 | ) { | |
| 281 | - throw lazyDOMException('Invalid alg', 'DataError'); | ||
| 280 | + throw lazyDOMException( | ||
| 281 | + 'JWK "alg" does not match the requested algorithm', | ||
| 282 | + 'DataError'); | ||
| 282 | 283 | } | |
| 283 | 284 | } | |
| 284 | 285 | ||
| 285 | 286 | if (!isPublic && typeof keyData.x !== 'string') { | |
| 286 | - throw lazyDOMException('Invalid JWK keyData', 'DataError'); | ||
| 287 | + throw lazyDOMException('Invalid JWK', 'DataError'); | ||
| 287 | 288 | } | |
| 288 | 289 | ||
| 289 | 290 | verifyAcceptableCfrgKeyUse( | |
@@ -305,7 +306,7 @@ async function cfrgImportKey( | |||
| 305 | 306 | false); | |
| 306 | 307 | ||
| 307 | 308 | if (!createPublicKey(keyObject).equals(publicKeyObject)) { | |
| 308 | - throw lazyDOMException('Invalid JWK keyData', 'DataError'); | ||
| 309 | + throw lazyDOMException('Invalid JWK', 'DataError'); | ||
| 309 | 310 | } | |
| 310 | 311 | } | |
| 311 | 312 | break; | |
@@ -336,13 +337,9 @@ function eddsaSignVerify(key, data, { name, context }, signature) { | |||
| 336 | 337 | if (key.type !== type) | |
| 337 | 338 | throw lazyDOMException(`Key must be a ${type} key`, 'InvalidAccessError'); | |
| 338 | 339 | ||
| 339 | - if (name === 'Ed448' && context !== undefined) { | ||
| 340 | - context = | ||
| 341 | - getArrayBufferOrView(context, 'algorithm.context'); | ||
| 342 | - if (context.byteLength !== 0) { | ||
| 343 | - throw lazyDOMException( | ||
| 344 | - 'Non zero-length context is not yet supported.', 'NotSupportedError'); | ||
| 345 | - } | ||
| 340 | + if (name === 'Ed448' && context?.byteLength) { | ||
| 341 | + throw lazyDOMException( | ||
| 342 | + 'Non zero-length context is not yet supported.', 'NotSupportedError'); | ||
| 346 | 343 | } | |
| 347 | 344 | ||
| 348 | 345 | return jobPromise(() => new SignJob( | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -34,7 +34,6 @@ const { | |||
| 34 | 34 | validateInt32, | |
| 35 | 35 | validateObject, | |
| 36 | 36 | validateString, | |
| 37 | - validateUint32, | ||
| 38 | 37 | } = require('internal/validators'); | |
| 39 | 38 | ||
| 40 | 39 | const { | |
@@ -48,7 +47,6 @@ const { | |||
| 48 | 47 | ||
| 49 | 48 | const { | |
| 50 | 49 | KeyObject, | |
| 51 | - isCryptoKey, | ||
| 52 | 50 | } = require('internal/crypto/keys'); | |
| 53 | 51 | ||
| 54 | 52 | const { | |
@@ -320,13 +318,6 @@ function diffieHellman(options) { | |||
| 320 | 318 | async function ecdhDeriveBits(algorithm, baseKey, length) { | |
| 321 | 319 | const { 'public': key } = algorithm; | |
| 322 | 320 | ||
| 323 | - // Null means that we're not asking for a specific number of bits, just | ||
| 324 | - // give us everything that is generated. | ||
| 325 | - if (length !== null) | ||
| 326 | - validateUint32(length, 'length'); | ||
| 327 | - if (!isCryptoKey(key)) | ||
| 328 | - throw new ERR_INVALID_ARG_TYPE('algorithm.public', 'CryptoKey', key); | ||
| 329 | - | ||
| 330 | 321 | if (key.type !== 'public') { | |
| 331 | 322 | throw lazyDOMException( | |
| 332 | 323 | 'algorithm.public must be a public key', 'InvalidAccessError'); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -18,13 +18,6 @@ const { | |||
| 18 | 18 | } = internalBinding('crypto'); | |
| 19 | 19 | ||
| 20 | 20 | const { | |
| 21 | - codes: { | ||
| 22 | - ERR_MISSING_OPTION, | ||
| 23 | - } | ||
| 24 | - } = require('internal/errors'); | ||
| 25 | - | ||
| 26 | - const { | ||
| 27 | - getArrayBufferOrView, | ||
| 28 | 21 | getUsagesUnion, | |
| 29 | 22 | hasAnyNotIn, | |
| 30 | 23 | jobPromise, | |
@@ -76,7 +69,6 @@ function verifyAcceptableEcKeyUse(name, isPublic, usages) { | |||
| 76 | 69 | ||
| 77 | 70 | function createECPublicKeyRaw(namedCurve, keyData) { | |
| 78 | 71 | const handle = new KeyObjectHandle(); | |
| 79 | - keyData = getArrayBufferOrView(keyData, 'keyData'); | ||
| 80 | 72 | ||
| 81 | 73 | if (!handle.initECRaw(kNamedCurveAliases[namedCurve], keyData)) { | |
| 82 | 74 | throw lazyDOMException('Invalid keyData', 'DataError'); | |
@@ -204,50 +196,53 @@ async function ecImportKey( | |||
| 204 | 196 | break; | |
| 205 | 197 | } | |
| 206 | 198 | case 'jwk': { | |
| 207 | - if (keyData == null || typeof keyData !== 'object') | ||
| 208 | - throw lazyDOMException('Invalid JWK keyData', 'DataError'); | ||
| 199 | + if (!keyData.kty) | ||
| 200 | + throw lazyDOMException('Invalid keyData', 'DataError'); | ||
| 209 | 201 | if (keyData.kty !== 'EC') | |
| 210 | - throw lazyDOMException('Invalid key type', 'DataError'); | ||
| 202 | + throw lazyDOMException('Invalid JWK "kty" Parameter', 'DataError'); | ||
| 211 | 203 | if (keyData.crv !== namedCurve) | |
| 212 | - throw lazyDOMException('Named curve mismatch', 'DataError'); | ||
| 204 | + throw lazyDOMException( | ||
| 205 | + 'JWK "crv" does not match the requested algorithm', | ||
| 206 | + 'DataError'); | ||
| 213 | 207 | ||
| 214 | 208 | verifyAcceptableEcKeyUse( | |
| 215 | 209 | name, | |
| 216 | 210 | keyData.d === undefined, | |
| 217 | 211 | usagesSet); | |
| 218 | 212 | ||
| 219 | 213 | if (usagesSet.size > 0 && keyData.use !== undefined) { | |
| 220 | - if (algorithm.name === 'ECDSA' && keyData.use !== 'sig') | ||
| 221 | - throw lazyDOMException('Invalid use type', 'DataError'); | ||
| 222 | - if (algorithm.name === 'ECDH' && keyData.use !== 'enc') | ||
| 223 | - throw lazyDOMException('Invalid use type', 'DataError'); | ||
| 214 | + const checkUse = name === 'ECDH' ? 'enc' : 'sig'; | ||
| 215 | + if (keyData.use !== checkUse) | ||
| 216 | + throw lazyDOMException('Invalid JWK "use" Parameter', 'DataError'); | ||
| 224 | 217 | } | |
| 225 | 218 | ||
| 226 | 219 | validateKeyOps(keyData.key_ops, usagesSet); | |
| 227 | 220 | ||
| 228 | 221 | if (keyData.ext !== undefined && | |
| 229 | 222 | keyData.ext === false && | |
| 230 | 223 | extractable === true) { | |
| 231 | - throw lazyDOMException('JWK is not extractable', 'DataError'); | ||
| 224 | + throw lazyDOMException( | ||
| 225 | + 'JWK "ext" Parameter and extractable mismatch', | ||
| 226 | + 'DataError'); | ||
| 232 | 227 | } | |
| 233 | 228 | ||
| 234 | 229 | if (algorithm.name === 'ECDSA' && keyData.alg !== undefined) { | |
| 235 | - if (typeof keyData.alg !== 'string') | ||
| 236 | - throw lazyDOMException('Invalid alg', 'DataError'); | ||
| 237 | 230 | let algNamedCurve; | |
| 238 | 231 | switch (keyData.alg) { | |
| 239 | 232 | case 'ES256': algNamedCurve = 'P-256'; break; | |
| 240 | 233 | case 'ES384': algNamedCurve = 'P-384'; break; | |
| 241 | 234 | case 'ES512': algNamedCurve = 'P-521'; break; | |
| 242 | 235 | } | |
| 243 | 236 | if (algNamedCurve !== namedCurve) | |
| 244 | - throw lazyDOMException('Named curve mismatch', 'DataError'); | ||
| 237 | + throw lazyDOMException( | ||
| 238 | + 'JWK "alg" does not match the requested algorithm', | ||
| 239 | + 'DataError'); | ||
| 245 | 240 | } | |
| 246 | 241 | ||
| 247 | 242 | const handle = new KeyObjectHandle(); | |
| 248 | 243 | const type = handle.initJwk(keyData, namedCurve); | |
| 249 | 244 | if (type === undefined) | |
| 250 | - throw lazyDOMException('Invalid JWK keyData', 'DataError'); | ||
| 245 | + throw lazyDOMException('Invalid JWK', 'DataError'); | ||
| 251 | 246 | keyObject = type === kKeyTypePrivate ? | |
| 252 | 247 | new PrivateKeyObject(handle) : | |
| 253 | 248 | new PublicKeyObject(handle); | |
@@ -289,8 +284,6 @@ function ecdsaSignVerify(key, data, { name, hash }, signature) { | |||
| 289 | 284 | if (key.type !== type) | |
| 290 | 285 | throw lazyDOMException(`Key must be a ${type} key`, 'InvalidAccessError'); | |
| 291 | 286 | ||
| 292 | - if (hash === undefined) | ||
| 293 | - throw new ERR_MISSING_OPTION('algorithm.hash'); | ||
| 294 | 287 | const hashname = normalizeHashName(hash.name); | |
| 295 | 288 | ||
| 296 | 289 | return jobPromise(() => new SignJob( | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -14,11 +14,9 @@ const { | |||
| 14 | 14 | } = internalBinding('crypto'); | |
| 15 | 15 | ||
| 16 | 16 | const { | |
| 17 | - getArrayBufferOrView, | ||
| 18 | 17 | getDefaultEncoding, | |
| 19 | 18 | getStringOption, | |
| 20 | 19 | jobPromise, | |
| 21 | - normalizeAlgorithm, | ||
| 22 | 20 | normalizeHashName, | |
| 23 | 21 | validateMaxBufferLength, | |
| 24 | 22 | kHandle, | |
@@ -168,13 +166,8 @@ Hmac.prototype._transform = Hash.prototype._transform; | |||
| 168 | 166 | // Implementation for WebCrypto subtle.digest() | |
| 169 | 167 | ||
| 170 | 168 | async function asyncDigest(algorithm, data) { | |
| 171 | - algorithm = normalizeAlgorithm(algorithm); | ||
| 172 | - data = getArrayBufferOrView(data, 'data'); | ||
| 173 | 169 | validateMaxBufferLength(data, 'data'); | |
| 174 | 170 | ||
| 175 | - if (algorithm.length !== undefined) | ||
| 176 | - validateUint32(algorithm.length, 'algorithm.length'); | ||
| 177 | - | ||
| 178 | 171 | switch (algorithm.name) { | |
| 179 | 172 | case 'SHA-1': | |
| 180 | 173 | // Fall through | |
@@ -186,11 +179,10 @@ async function asyncDigest(algorithm, data) { | |||
| 186 | 179 | return jobPromise(() => new HashJob( | |
| 187 | 180 | kCryptoJobAsync, | |
| 188 | 181 | normalizeHashName(algorithm.name), | |
| 189 | - data, | ||
| 190 | - algorithm.length)); | ||
| 182 | + data)); | ||
| 191 | 183 | } | |
| 192 | 184 | ||
| 193 | - throw lazyDOMException('Unrecognized name.', 'NotSupportedError'); | ||
| 185 | + throw lazyDOMException('Unrecognized algorithm name', 'NotSupportedError'); | ||
| 194 | 186 | } | |
| 195 | 187 | ||
| 196 | 188 | module.exports = { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -19,7 +19,6 @@ const { | |||
| 19 | 19 | const { kMaxLength } = require('buffer'); | |
| 20 | 20 | ||
| 21 | 21 | const { | |
| 22 | - getArrayBufferOrView, | ||
| 23 | 22 | normalizeHashName, | |
| 24 | 23 | toBuf, | |
| 25 | 24 | validateByteSource, | |
@@ -45,7 +44,6 @@ const { | |||
| 45 | 44 | codes: { | |
| 46 | 45 | ERR_INVALID_ARG_TYPE, | |
| 47 | 46 | ERR_OUT_OF_RANGE, | |
| 48 | - ERR_MISSING_OPTION, | ||
| 49 | 47 | }, | |
| 50 | 48 | hideStackFrames, | |
| 51 | 49 | } = require('internal/errors'); | |
@@ -140,11 +138,7 @@ function hkdfSync(hash, key, salt, info, length) { | |||
| 140 | 138 | ||
| 141 | 139 | const hkdfPromise = promisify(hkdf); | |
| 142 | 140 | async function hkdfDeriveBits(algorithm, baseKey, length) { | |
| 143 | - const { hash } = algorithm; | ||
| 144 | - const salt = getArrayBufferOrView(algorithm.salt, 'algorithm.salt'); | ||
| 145 | - const info = getArrayBufferOrView(algorithm.info, 'algorithm.info'); | ||
| 146 | - if (hash === undefined) | ||
| 147 | - throw new ERR_MISSING_OPTION('algorithm.hash'); | ||
| 141 | + const { hash, salt, info } = algorithm; | ||
| 148 | 142 | ||
| 149 | 143 | if (length === 0) | |
| 150 | 144 | throw lazyDOMException('length cannot be zero', 'OperationError'); | |
| Back | FazBrowse Home | New Git URL |
0 commit comments