Skip to content

Commit 9024e87

Browse files
committed
refactor: catch type errors when decoding various base64url strings
1 parent 935e920 commit 9024e87

File tree

5 files changed

+66
-14
lines changed

5 files changed

+66
-14
lines changed

src/jwe/flattened/decrypt.ts

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,11 @@ export async function flattenedDecrypt(
179179

180180
let encryptedKey!: Uint8Array
181181
if (jwe.encrypted_key !== undefined) {
182-
encryptedKey = base64url(jwe.encrypted_key!)
182+
try {
183+
encryptedKey = base64url(jwe.encrypted_key!)
184+
} catch {
185+
throw new JWEInvalid('Failed to base64url decode the encrypted_key')
186+
}
183187
}
184188

185189
let resolvedKey = false
@@ -205,8 +209,18 @@ export async function flattenedDecrypt(
205209
cek = generateCek(enc)
206210
}
207211

208-
const iv = base64url(jwe.iv)
209-
const tag = base64url(jwe.tag)
212+
let iv: Uint8Array
213+
let tag: Uint8Array
214+
try {
215+
iv = base64url(jwe.iv)
216+
} catch {
217+
throw new JWEInvalid('Failed to base64url decode the iv')
218+
}
219+
try {
220+
tag = base64url(jwe.tag)
221+
} catch {
222+
throw new JWEInvalid('Failed to base64url decode the tag')
223+
}
210224

211225
const protectedHeader: Uint8Array = encoder.encode(jwe.protected ?? '')
212226
let additionalData: Uint8Array
@@ -217,7 +231,13 @@ export async function flattenedDecrypt(
217231
additionalData = protectedHeader
218232
}
219233

220-
let plaintext = await decrypt(enc, cek, base64url(jwe.ciphertext), iv, tag, additionalData)
234+
let ciphertext: Uint8Array
235+
try {
236+
ciphertext = base64url(jwe.ciphertext)
237+
} catch {
238+
throw new JWEInvalid('Failed to base64url decode the ciphertext')
239+
}
240+
let plaintext = await decrypt(enc, cek, ciphertext, iv, tag, additionalData)
221241

222242
if (joseHeader.zip === 'DEF') {
223243
plaintext = await (options?.inflateRaw || inflate)(plaintext)
@@ -230,7 +250,11 @@ export async function flattenedDecrypt(
230250
}
231251

232252
if (jwe.aad !== undefined) {
233-
result.additionalAuthenticatedData = base64url(jwe.aad!)
253+
try {
254+
result.additionalAuthenticatedData = base64url(jwe.aad!)
255+
} catch {
256+
throw new JWEInvalid('Failed to base64url decode the aad')
257+
}
234258
}
235259

236260
if (jwe.unprotected !== undefined) {

src/jws/flattened/verify.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ export async function flattenedVerify(
173173
try {
174174
signature = base64url(jws.signature)
175175
} catch {
176-
throw new JWSInvalid('Failed to parse the base64url encoded signature')
176+
throw new JWSInvalid('Failed to base64url decode the signature')
177177
}
178178
const verified = await verify(alg, key, signature, data)
179179

@@ -183,7 +183,11 @@ export async function flattenedVerify(
183183

184184
let payload: Uint8Array
185185
if (b64) {
186-
payload = base64url(jws.payload)
186+
try {
187+
payload = base64url(jws.payload)
188+
} catch {
189+
throw new JWSInvalid('Failed to base64url decode the payload')
190+
}
187191
} else if (typeof jws.payload === 'string') {
188192
payload = encoder.encode(jws.payload)
189193
} else {

src/lib/decrypt_key_management.ts

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,21 @@ async function decryptKeyManagement(
5353
if (joseHeader.apu !== undefined) {
5454
if (typeof joseHeader.apu !== 'string')
5555
throw new JWEInvalid(`JOSE Header "apu" (Agreement PartyUInfo) invalid`)
56-
partyUInfo = base64url(joseHeader.apu)
56+
try {
57+
partyUInfo = base64url(joseHeader.apu)
58+
} catch {
59+
throw new JWEInvalid('Failed to base64url decode the apu')
60+
}
5761
}
5862

5963
if (joseHeader.apv !== undefined) {
6064
if (typeof joseHeader.apv !== 'string')
6165
throw new JWEInvalid(`JOSE Header "apv" (Agreement PartyVInfo) invalid`)
62-
partyVInfo = base64url(joseHeader.apv)
66+
try {
67+
partyVInfo = base64url(joseHeader.apv)
68+
} catch {
69+
throw new JWEInvalid('Failed to base64url decode the apv')
70+
}
6371
}
6472

6573
const sharedSecret = await ECDH.deriveKey(
@@ -105,7 +113,13 @@ async function decryptKeyManagement(
105113
if (typeof joseHeader.p2s !== 'string')
106114
throw new JWEInvalid(`JOSE Header "p2s" (PBES2 Salt) missing or invalid`)
107115

108-
return pbes2Kw(alg, key, encryptedKey, joseHeader.p2c, base64url(joseHeader.p2s))
116+
let p2s: Uint8Array
117+
try {
118+
p2s = base64url(joseHeader.p2s)
119+
} catch {
120+
throw new JWEInvalid('Failed to base64url decode the p2s')
121+
}
122+
return pbes2Kw(alg, key, encryptedKey, joseHeader.p2c, p2s)
109123
}
110124
case 'A128KW':
111125
case 'A192KW':
@@ -127,8 +141,18 @@ async function decryptKeyManagement(
127141
if (typeof joseHeader.tag !== 'string')
128142
throw new JWEInvalid(`JOSE Header "tag" (Authentication Tag) missing or invalid`)
129143

130-
const iv = base64url(joseHeader.iv)
131-
const tag = base64url(joseHeader.tag)
144+
let iv: Uint8Array
145+
try {
146+
iv = base64url(joseHeader.iv)
147+
} catch {
148+
throw new JWEInvalid('Failed to base64url decode the iv')
149+
}
150+
let tag: Uint8Array
151+
try {
152+
tag = base64url(joseHeader.tag)
153+
} catch {
154+
throw new JWEInvalid('Failed to base64url decode the tag')
155+
}
132156

133157
return aesGcmKw(alg, key, encryptedKey, iv, tag)
134158
}

src/runtime/browser/asn1.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ export const fromX509: PEMImportFunction = (pem, alg, options?) => {
243243
spki = getSPKI(pem)
244244
} catch (cause) {
245245
// @ts-ignore
246-
throw new TypeError('failed to parse the X.509 certificate', { cause })
246+
throw new TypeError('Failed to parse the X.509 certificate', { cause })
247247
}
248248
return fromSPKI(spki, alg, options)
249249
}

src/util/decode_jwt.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ export function decodeJwt(jwt: string) {
3333
try {
3434
decoded = base64url(payload)
3535
} catch {
36-
throw new JWTInvalid('Failed to parse the base64url encoded payload')
36+
throw new JWTInvalid('Failed to base64url decode the payload')
3737
}
3838

3939
let result: unknown

0 commit comments

Comments
 (0)