GeezerVison is showing github.com — crypto: ensure invalid SubtleCrypto JWK data import results in DataError · nodejs/node@c50f013
File treeExpand file treeCollapse file tree Open diff view settings Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboardExpand all lines: lib/internal/crypto/aes.js +6-1Lines changed: 6 additions & 1 deletion | Original file line number | Diff line number | Diff line change |
|---|
@@ -296,7 +296,12 @@ async function aesImportKey( | 296 | 296 | } | 297 | 297 |
| 298 | 298 | const handle = new KeyObjectHandle(); | 299 | | - handle.initJwk(keyData); | | 299 | + try { | | 300 | + handle.initJwk(keyData); | | 301 | + } catch (err) { | | 302 | + throw lazyDOMException( | | 303 | + 'Invalid keyData', { name: 'DataError', cause: err }); | | 304 | + } | 300 | 305 |
| 301 | 306 | ({ length } = handle.keyDetail({ })); | 302 | 307 | validateKeyLength(length); | |
Collapse file Copy file name to clipboardExpand all lines: lib/internal/crypto/cfrg.js +24-14Lines changed: 24 additions & 14 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -17,6 +17,12 @@ const { | 17 | 17 | kSignJobModeVerify, | 18 | 18 | } = internalBinding('crypto'); | 19 | 19 |
| | 20 | +const { | | 21 | + codes: { | | 22 | + ERR_CRYPTO_INVALID_JWK, | | 23 | + }, | | 24 | +} = require('internal/errors'); | | 25 | + | 20 | 26 | const { | 21 | 27 | getUsagesUnion, | 22 | 28 | hasAnyNotIn, | @@ -292,22 +298,26 @@ async function cfrgImportKey( | 292 | 298 | isPublic, | 293 | 299 | usagesSet); | 294 | 300 |
| 295 | | - const publicKeyObject = createCFRGRawKey( | 296 | | - name, | 297 | | - Buffer.from(keyData.x, 'base64'), | 298 | | - true); | 299 | | - | 300 | | - if (isPublic) { | 301 | | - keyObject = publicKeyObject; | 302 | | - } else { | 303 | | - keyObject = createCFRGRawKey( | | 301 | + try { | | 302 | + const publicKeyObject = createCFRGRawKey( | 304 | 303 | name, | 305 | | - Buffer.from(keyData.d, 'base64'), | 306 | | - false); | 307 | | - | 308 | | - if (!createPublicKey(keyObject).equals(publicKeyObject)) { | 309 | | - throw lazyDOMException('Invalid JWK', 'DataError'); | | 304 | + Buffer.from(keyData.x, 'base64'), | | 305 | + true); | | 306 | + | | 307 | + if (isPublic) { | | 308 | + keyObject = publicKeyObject; | | 309 | + } else { | | 310 | + keyObject = createCFRGRawKey( | | 311 | + name, | | 312 | + Buffer.from(keyData.d, 'base64'), | | 313 | + false); | | 314 | + | | 315 | + if (!createPublicKey(keyObject).equals(publicKeyObject)) { | | 316 | + throw new ERR_CRYPTO_INVALID_JWK(); | | 317 | + } | 310 | 318 | } | | 319 | + } catch (err) { | | 320 | + throw lazyDOMException('Invalid keyData', { name: 'DataError', cause: err }); | 311 | 321 | } | 312 | 322 | break; | 313 | 323 | } | |
Collapse file Copy file name to clipboardExpand all lines: lib/internal/crypto/ec.js +8-2Lines changed: 8 additions & 2 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -240,9 +240,15 @@ async function ecImportKey( | 240 | 240 | } | 241 | 241 |
| 242 | 242 | const handle = new KeyObjectHandle(); | 243 | | - const type = handle.initJwk(keyData, namedCurve); | | 243 | + let type; | | 244 | + try { | | 245 | + type = handle.initJwk(keyData, namedCurve); | | 246 | + } catch (err) { | | 247 | + throw lazyDOMException( | | 248 | + 'Invalid keyData', { name: 'DataError', cause: err }); | | 249 | + } | 244 | 250 | if (type === undefined) | 245 | | - throw lazyDOMException('Invalid JWK', 'DataError'); | | 251 | + throw lazyDOMException('Invalid keyData', 'DataError'); | 246 | 252 | keyObject = type === kKeyTypePrivate ? | 247 | 253 | new PrivateKeyObject(handle) : | 248 | 254 | new PublicKeyObject(handle); | |
Collapse file Copy file name to clipboardExpand all lines: lib/internal/crypto/mac.js +6-1Lines changed: 6 additions & 1 deletion | Original file line number | Diff line number | Diff line change |
|---|
@@ -145,7 +145,12 @@ async function hmacImportKey( | 145 | 145 | } | 146 | 146 |
| 147 | 147 | const handle = new KeyObjectHandle(); | 148 | | - handle.initJwk(keyData); | | 148 | + try { | | 149 | + handle.initJwk(keyData); | | 150 | + } catch (err) { | | 151 | + throw lazyDOMException( | | 152 | + 'Invalid keyData', { name: 'DataError', cause: err }); | | 153 | + } | 149 | 154 | keyObject = new SecretKeyObject(handle); | 150 | 155 | break; | 151 | 156 | } | |
Collapse file Copy file name to clipboardExpand all lines: lib/internal/crypto/rsa.js +8-2Lines changed: 8 additions & 2 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -273,9 +273,15 @@ async function rsaImportKey( | 273 | 273 | } | 274 | 274 |
| 275 | 275 | const handle = new KeyObjectHandle(); | 276 | | - const type = handle.initJwk(keyData); | | 276 | + let type; | | 277 | + try { | | 278 | + type = handle.initJwk(keyData); | | 279 | + } catch (err) { | | 280 | + throw lazyDOMException( | | 281 | + 'Invalid keyData', { name: 'DataError', cause: err }); | | 282 | + } | 277 | 283 | if (type === undefined) | 278 | | - throw lazyDOMException('Invalid JWK', 'DataError'); | | 284 | + throw lazyDOMException('Invalid keyData', 'DataError'); | 279 | 285 |
| 280 | 286 | keyObject = type === kKeyTypePrivate ? | 281 | 287 | new PrivateKeyObject(handle) : | |
Collapse file Copy file name to clipboardExpand all lines: test/parallel/test-webcrypto-export-import-cfrg.js +9Lines changed: 9 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -329,6 +329,15 @@ async function testImportJwk({ name, publicUsages, privateUsages }, extractable) | 329 | 329 | extractable, | 330 | 330 | [/* empty usages */]), | 331 | 331 | { name: 'SyntaxError', message: 'Usages cannot be empty when importing a private key.' }); | | 332 | + | | 333 | + await assert.rejects( | | 334 | + subtle.importKey( | | 335 | + 'jwk', | | 336 | + { kty: jwk.kty, /* missing x */ crv: jwk.crv }, | | 337 | + { name }, | | 338 | + extractable, | | 339 | + publicUsages), | | 340 | + { name: 'DataError', message: 'Invalid keyData' }); | 332 | 341 | } | 333 | 342 |
| 334 | 343 | async function testImportRaw({ name, publicUsages }) { | |
Collapse file Copy file name to clipboardExpand all lines: test/parallel/test-webcrypto-export-import-ec.js +9Lines changed: 9 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -330,6 +330,15 @@ async function testImportJwk( | 330 | 330 | extractable, | 331 | 331 | [/* empty usages */]), | 332 | 332 | { name: 'SyntaxError', message: 'Usages cannot be empty when importing a private key.' }); | | 333 | + | | 334 | + await assert.rejects( | | 335 | + subtle.importKey( | | 336 | + 'jwk', | | 337 | + { kty: jwk.kty, /* missing x */ y: jwk.y, crv: jwk.crv }, | | 338 | + { name, namedCurve }, | | 339 | + extractable, | | 340 | + publicUsages), | | 341 | + { name: 'DataError', message: 'Invalid keyData' }); | 333 | 342 | } | 334 | 343 |
| 335 | 344 | async function testImportRaw({ name, publicUsages }, namedCurve) { | |
Collapse file Copy file name to clipboardExpand all lines: test/parallel/test-webcrypto-export-import-rsa.js +9Lines changed: 9 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -513,6 +513,15 @@ async function testImportJwk( | 513 | 513 | extractable, | 514 | 514 | [/* empty usages */]), | 515 | 515 | { name: 'SyntaxError', message: 'Usages cannot be empty when importing a private key.' }); | | 516 | + | | 517 | + await assert.rejects( | | 518 | + subtle.importKey( | | 519 | + 'jwk', | | 520 | + { kty: jwk.kty, /* missing e */ n: jwk.n }, | | 521 | + { name, hash }, | | 522 | + extractable, | | 523 | + publicUsages), | | 524 | + { name: 'DataError', message: 'Invalid keyData' }); | 516 | 525 | } | 517 | 526 |
| 518 | 527 | // combinations to test | |
|