GeezerVison is showing github.com — lib: add and test [EnforceRange] in webcrypto dictionaries · nodejs/node@424fe2b
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/webcrypto.js +6-1Lines changed: 6 additions & 1 deletion | Original file line number | Diff line number | Diff line change |
|---|
@@ -256,7 +256,11 @@ function deriveBitsImpl(algorithm, baseKey, length = null) { | 256 | 256 | prefix, 'AlgorithmIdentifier', algorithm, i++); | 257 | 257 | baseKey = convertSubtleArgument(prefix, 'CryptoKey', baseKey, i++); | 258 | 258 | if (length !== null) { | 259 | | - length = convertSubtleArgument(prefix, 'unsigned long', length, i++); | | 259 | + length = webidl.converters['unsigned long'](length, { | | 260 | + prefix, | | 261 | + context: kArgumentContexts[i++], | | 262 | + enforceRange: true, | | 263 | + }); | 260 | 264 | } | 261 | 265 |
| 262 | 266 | const normalizedAlgorithm = normalizeAlgorithm(algorithm, 'deriveBits'); | @@ -1696,6 +1700,7 @@ class SubtleCrypto { | 1696 | 1700 | length = webidl.converters['unsigned long'](length, { | 1697 | 1701 | prefix, | 1698 | 1702 | context: '3rd argument', | | 1703 | + enforceRange: true, | 1699 | 1704 | }); | 1700 | 1705 | } | 1701 | 1706 | } else if (operation === 'getPublicKey') { | |
Collapse file Copy file name to clipboard +35Lines changed: 35 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| | 1 | +'use strict'; | | 2 | + | | 3 | +const common = require('../common'); | | 4 | + | | 5 | +if (!common.hasCrypto) | | 6 | + common.skip('missing crypto'); | | 7 | + | | 8 | +const assert = require('assert'); | | 9 | +const { SubtleCrypto } = globalThis; | | 10 | +const { subtle } = globalThis.crypto; | | 11 | + | | 12 | +const algorithm = { | | 13 | + name: 'HKDF', | | 14 | + hash: 'SHA-256', | | 15 | + info: new Uint8Array(), | | 16 | + salt: new Uint8Array(32), | | 17 | +}; | | 18 | +const invalidLength = 2 ** 32; | | 19 | +const expectedError = { | | 20 | + code: 'ERR_OUT_OF_RANGE', | | 21 | + name: 'TypeError', | | 22 | +}; | | 23 | + | | 24 | +assert.throws( | | 25 | + () => SubtleCrypto.supports('deriveBits', algorithm, invalidLength), | | 26 | + expectedError); | | 27 | + | | 28 | +(async () => { | | 29 | + const key = await subtle.importKey( | | 30 | + 'raw', new Uint8Array(32), 'HKDF', false, ['deriveBits']); | | 31 | + | | 32 | + await assert.rejects( | | 33 | + subtle.deriveBits(algorithm, key, invalidLength), | | 34 | + expectedError); | | 35 | +})().then(common.mustCall()); |
Collapse file Copy file name to clipboardExpand all lines: test/parallel/test-webcrypto-webidl.js +98Lines changed: 98 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -119,6 +119,104 @@ function assertJsonWebKey(actual, expected) { | 119 | 119 | } | 120 | 120 | } | 121 | 121 |
| | 122 | +// [EnforceRange] integer dictionary members | | 123 | +{ | | 124 | + const kOctetMax = 2 ** 8 - 1; | | 125 | + const kUnsignedShortMax = 2 ** 16 - 1; | | 126 | + const kUnsignedLongMax = 2 ** 32 - 1; | | 127 | + const empty = Buffer.alloc(0); | | 128 | + const rsaKeyGen = { | | 129 | + name: 'RSA-PSS', | | 130 | + modulusLength: 2048, | | 131 | + publicExponent: new Uint8Array([1, 0, 1]), | | 132 | + }; | | 133 | + const aesKeyParams = { name: 'AES-GCM', length: 128 }; | | 134 | + const hmacKeyParams = { | | 135 | + name: 'HMAC', | | 136 | + hash: 'SHA-256', | | 137 | + length: 128, | | 138 | + }; | | 139 | + const kmacKeyParams = { name: 'KMAC128', length: 128 }; | | 140 | + const cases = [ | | 141 | + ['RsaKeyGenParams', rsaKeyGen, | | 142 | + { modulusLength: kUnsignedLongMax }], | | 143 | + ['RsaHashedKeyGenParams', { ...rsaKeyGen, hash: 'SHA-256' }, | | 144 | + { modulusLength: kUnsignedLongMax }], | | 145 | + ['AesKeyGenParams', aesKeyParams, | | 146 | + { length: kUnsignedShortMax }], | | 147 | + ['RsaPssParams', { name: 'RSA-PSS', saltLength: 20 }, | | 148 | + { saltLength: kUnsignedLongMax }], | | 149 | + ['HmacKeyGenParams', hmacKeyParams, | | 150 | + { length: kUnsignedLongMax }], | | 151 | + ['HmacImportParams', hmacKeyParams, | | 152 | + { length: kUnsignedLongMax }], | | 153 | + ['CShakeParams', { name: 'cSHAKE128', outputLength: 256 }, | | 154 | + { outputLength: kUnsignedLongMax }], | | 155 | + ['Pbkdf2Params', { | | 156 | + name: 'PBKDF2', | | 157 | + salt: empty, | | 158 | + iterations: 1, | | 159 | + hash: 'SHA-256', | | 160 | + }, { iterations: kUnsignedLongMax }], | | 161 | + ['AesDerivedKeyParams', aesKeyParams, | | 162 | + { length: kUnsignedShortMax }], | | 163 | + ['AeadParams', { | | 164 | + name: 'AES-GCM', | | 165 | + iv: Buffer.alloc(12), | | 166 | + tagLength: 128, | | 167 | + }, { tagLength: kOctetMax }], | | 168 | + ['AesCtrParams', { | | 169 | + name: 'AES-CTR', | | 170 | + counter: Buffer.alloc(16), | | 171 | + length: 128, | | 172 | + }, { length: kOctetMax }], | | 173 | + ['Argon2Params', { | | 174 | + name: 'Argon2id', | | 175 | + nonce: Buffer.alloc(8), | | 176 | + parallelism: 1, | | 177 | + memory: 8, | | 178 | + passes: 1, | | 179 | + version: 0x13, | | 180 | + }, { | | 181 | + parallelism: kUnsignedLongMax, | | 182 | + memory: kUnsignedLongMax, | | 183 | + passes: kUnsignedLongMax, | | 184 | + version: kOctetMax, | | 185 | + }], | | 186 | + ['KmacKeyGenParams', kmacKeyParams, | | 187 | + { length: kUnsignedLongMax }], | | 188 | + ['KmacImportParams', kmacKeyParams, | | 189 | + { length: kUnsignedLongMax }], | | 190 | + ['KmacParams', { name: 'KMAC128', outputLength: 256 }, | | 191 | + { outputLength: kUnsignedLongMax }], | | 192 | + ['KangarooTwelveParams', { name: 'KT128', outputLength: 256 }, | | 193 | + { outputLength: kUnsignedLongMax }], | | 194 | + ['TurboShakeParams', { | | 195 | + name: 'TurboSHAKE128', | | 196 | + outputLength: 256, | | 197 | + domainSeparation: 0x1f, | | 198 | + }, { | | 199 | + outputLength: kUnsignedLongMax, | | 200 | + domainSeparation: kOctetMax, | | 201 | + }], | | 202 | + ]; | | 203 | + | | 204 | + for (const [dictionary, base, members] of cases) { | | 205 | + const converter = converters[dictionary]; | | 206 | + assertIdlDictionary(converter(base, opts), base); | | 207 | + | | 208 | + for (const [member, max] of Object.entries(members)) { | | 209 | + assert.throws( | | 210 | + () => converter({ ...base, [member]: -1 }, opts), { | | 211 | + name: 'TypeError', | | 212 | + code: 'ERR_OUT_OF_RANGE', | | 213 | + message: `${prefix}: ${member} in ${context} is outside ` + | | 214 | + `the expected range of 0 to ${max}.`, | | 215 | + }); | | 216 | + } | | 217 | + } | | 218 | +} | | 219 | + | 122 | 220 | // DOMString | 123 | 221 | { | 124 | 222 | assert.strictEqual(converters.DOMString(1), '1'); | |
|