Skip to content

Commit 0cdb851

Browse files
committed
refactor: cleanly reject invalid PBES2 p2c
1 parent a0b261e commit 0cdb851

3 files changed

Lines changed: 40 additions & 1 deletion

File tree

src/lib/pbes2kw.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ async function deriveKey(
2828
if (!(p2s instanceof Uint8Array) || p2s.length < 8) {
2929
throw new JWEInvalid('PBES2 Salt Input must be 8 or more octets')
3030
}
31+
if (!Number.isSafeInteger(p2c) || Math.sign(p2c) !== 1) {
32+
throw new JWEInvalid('PBES2 Count Input must be a positive integer')
33+
}
3134

3235
const salt = concatSalt(alg, p2s)
3336
const keylen = parseInt(alg.slice(13, 16), 10)

test/jwe/flattened.decrypt.test.ts

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import test from 'ava'
22
import * as crypto from 'crypto'
33

4-
import { FlattenedEncrypt, flattenedDecrypt } from '../../src/index.js'
4+
import { FlattenedEncrypt, base64url, flattenedDecrypt } from '../../src/index.js'
55

66
test.before(async (t) => {
77
const encode = TextEncoder.prototype.encode.bind(new TextEncoder())
@@ -251,6 +251,27 @@ test('decrypt PBES2 p2c limit', async (t) => {
251251
)
252252
})
253253

254+
test('PBES2 p2c must be a positive integer on decrypt', async (t) => {
255+
const jwe = await new FlattenedEncrypt(new Uint8Array(0))
256+
.setProtectedHeader({ alg: 'PBES2-HS256+A128KW', enc: 'A128CBC-HS256' })
257+
.setKeyManagementParameters({ p2c: 1 })
258+
.encrypt(new Uint8Array(32))
259+
260+
const protectedHeader = JSON.parse(new TextDecoder().decode(base64url.decode(jwe.protected!)))
261+
protectedHeader.p2c = 1.5
262+
jwe.protected = base64url.encode(JSON.stringify(protectedHeader))
263+
264+
await t.throwsAsync(
265+
flattenedDecrypt(jwe, new Uint8Array(32), {
266+
keyManagementAlgorithms: ['PBES2-HS256+A128KW'],
267+
}),
268+
{
269+
code: 'ERR_JWE_INVALID',
270+
message: 'PBES2 Count Input must be a positive integer',
271+
},
272+
)
273+
})
274+
254275
test('decrypt with PBES2 is not allowed by default', async (t) => {
255276
const jwe = await new FlattenedEncrypt(new Uint8Array(0))
256277
.setProtectedHeader({ alg: 'PBES2-HS256+A128KW', enc: 'A128CBC-HS256' })

test/jwe/flattened.encrypt.test.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,3 +225,18 @@ test('Default PBES2 Count', async (t) => {
225225
2048,
226226
)
227227
})
228+
229+
test('PBES2 p2c must be a positive integer on encrypt', async (t) => {
230+
for (const p2c of [0, -1, 1.5]) {
231+
await t.throwsAsync(
232+
new FlattenedEncrypt(t.context.plaintext)
233+
.setProtectedHeader({ alg: 'PBES2-HS256+A128KW', enc: 'A128GCM' })
234+
.setKeyManagementParameters({ p2c })
235+
.encrypt(t.context.secret),
236+
{
237+
code: 'ERR_JWE_INVALID',
238+
message: 'PBES2 Count Input must be a positive integer',
239+
},
240+
)
241+
}
242+
})

0 commit comments

Comments
 (0)