GeezerVison is showing github.com — crypto: ensure invalid SubtleCrypto JWK data import results in DataError · nodejs/node@2f678ea
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, | @@ -277,22 +283,26 @@ async function cfrgImportKey( | 277 | 283 | isPublic, | 278 | 284 | usagesSet); | 279 | 285 |
| 280 | | - const publicKeyObject = createCFRGRawKey( | 281 | | - name, | 282 | | - Buffer.from(keyData.x, 'base64'), | 283 | | - true); | 284 | | - | 285 | | - if (isPublic) { | 286 | | - keyObject = publicKeyObject; | 287 | | - } else { | 288 | | - keyObject = createCFRGRawKey( | | 286 | + try { | | 287 | + const publicKeyObject = createCFRGRawKey( | 289 | 288 | name, | 290 | | - Buffer.from(keyData.d, 'base64'), | 291 | | - false); | 292 | | - | 293 | | - if (!createPublicKey(keyObject).equals(publicKeyObject)) { | 294 | | - throw lazyDOMException('Invalid JWK', 'DataError'); | | 289 | + Buffer.from(keyData.x, 'base64'), | | 290 | + true); | | 291 | + | | 292 | + if (isPublic) { | | 293 | + keyObject = publicKeyObject; | | 294 | + } else { | | 295 | + keyObject = createCFRGRawKey( | | 296 | + name, | | 297 | + Buffer.from(keyData.d, 'base64'), | | 298 | + false); | | 299 | + | | 300 | + if (!createPublicKey(keyObject).equals(publicKeyObject)) { | | 301 | + throw new ERR_CRYPTO_INVALID_JWK(); | | 302 | + } | 295 | 303 | } | | 304 | + } catch (err) { | | 305 | + throw lazyDOMException('Invalid keyData', { name: 'DataError', cause: err }); | 296 | 306 | } | 297 | 307 | break; | 298 | 308 | } | |
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 |
|---|
@@ -275,9 +275,15 @@ async function rsaImportKey( | 275 | 275 | } | 276 | 276 |
| 277 | 277 | const handle = new KeyObjectHandle(); | 278 | | - const type = handle.initJwk(keyData); | | 278 | + let type; | | 279 | + try { | | 280 | + type = handle.initJwk(keyData); | | 281 | + } catch (err) { | | 282 | + throw lazyDOMException( | | 283 | + 'Invalid keyData', { name: 'DataError', cause: err }); | | 284 | + } | 279 | 285 | if (type === undefined) | 280 | | - throw lazyDOMException('Invalid JWK', 'DataError'); | | 286 | + throw lazyDOMException('Invalid keyData', 'DataError'); | 281 | 287 |
| 282 | 288 | keyObject = type === kKeyTypePrivate ? | 283 | 289 | 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 |
|---|
@@ -322,6 +322,15 @@ async function testImportJwk({ name, publicUsages, privateUsages }, extractable) | 322 | 322 | extractable, | 323 | 323 | [/* empty usages */]), | 324 | 324 | { name: 'SyntaxError', message: 'Usages cannot be empty when importing a private key.' }); | | 325 | + | | 326 | + await assert.rejects( | | 327 | + subtle.importKey( | | 328 | + 'jwk', | | 329 | + { kty: jwk.kty, /* missing x */ crv: jwk.crv }, | | 330 | + { name }, | | 331 | + extractable, | | 332 | + publicUsages), | | 333 | + { name: 'DataError', message: 'Invalid keyData' }); | 325 | 334 | } | 326 | 335 |
| 327 | 336 | 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 | |
|