Skip to content

Commit

Permalink
feat: return resolved key when verify and decrypt resolve functions a…
Browse files Browse the repository at this point in the history
…re used
  • Loading branch information
panva committed Sep 25, 2021
1 parent 6c17d7f commit 49fb62c
Show file tree
Hide file tree
Showing 13 changed files with 209 additions and 26 deletions.
28 changes: 25 additions & 3 deletions src/jwe/compact/decrypt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import type {
GetKeyFunction,
FlattenedJWE,
CompactDecryptResult,
ResolvedKey,
} from '../../types.d'

/**
Expand All @@ -20,7 +21,7 @@ export interface CompactDecryptGetKey extends GetKeyFunction<JWEHeaderParameters
* Decrypts a Compact JWE.
*
* @param jwe Compact JWE.
* @param key Private Key or Secret, or a function resolving one, to decrypt the JWE with.
* @param key Private Key or Secret to decrypt the JWE with.
* @param options JWE Decryption options.
*
* @example ESM import
Expand Down Expand Up @@ -49,11 +50,26 @@ export interface CompactDecryptGetKey extends GetKeyFunction<JWEHeaderParameters
* console.log(decoder.decode(plaintext))
* ```
*/
async function compactDecrypt(
jwe: string | Uint8Array,
key: KeyLike,
options?: DecryptOptions,
): Promise<CompactDecryptResult>
/**
* @param jwe Compact JWE.
* @param getKey Function resolving Private Key or Secret to decrypt the JWE with.
* @param options JWE Decryption options.
*/
async function compactDecrypt(
jwe: string | Uint8Array,
getKey: CompactDecryptGetKey,
options?: DecryptOptions,
): Promise<CompactDecryptResult & ResolvedKey>
async function compactDecrypt(
jwe: string | Uint8Array,
key: KeyLike | CompactDecryptGetKey,
options?: DecryptOptions,
): Promise<CompactDecryptResult> {
) {
if (jwe instanceof Uint8Array) {
jwe = decoder.decode(jwe)
}
Expand Down Expand Up @@ -86,7 +102,13 @@ async function compactDecrypt(
options,
)

return { plaintext: decrypted.plaintext, protectedHeader: decrypted.protectedHeader! }
const result = { plaintext: decrypted.plaintext, protectedHeader: decrypted.protectedHeader! }

if (typeof key === 'function') {
return { ...result, key: decrypted.key }
}

return result
}

export { compactDecrypt }
Expand Down
26 changes: 24 additions & 2 deletions src/jwe/flattened/decrypt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import type {
JWEHeaderParameters,
DecryptOptions,
GetKeyFunction,
ResolvedKey,
} from '../../types.d'
import { encoder, decoder, concat } from '../../lib/buffer_utils.js'
import cekFactory from '../../lib/cek.js'
Expand All @@ -36,7 +37,7 @@ export interface FlattenedDecryptGetKey
* Decrypts a Flattened JWE.
*
* @param jwe Flattened JWE.
* @param key Public Key or Secret, or a function resolving one, to decrypt the JWE with.
* @param key Private Key or Secret to decrypt the JWE with.
* @param options JWE Decryption options.
*
* @example ESM import
Expand Down Expand Up @@ -77,11 +78,26 @@ export interface FlattenedDecryptGetKey
* console.log(decoder.decode(additionalAuthenticatedData))
* ```
*/
function flattenedDecrypt(
jwe: FlattenedJWE,
key: KeyLike,
options?: DecryptOptions,
): Promise<FlattenedDecryptResult>
/**
* @param jwe Flattened JWE.
* @param getKey Function resolving Private Key or Secret to decrypt the JWE with.
* @param options JWE Decryption options.
*/
function flattenedDecrypt(
jwe: FlattenedJWE,
getKey: FlattenedDecryptGetKey,
options?: DecryptOptions,
): Promise<FlattenedDecryptResult & ResolvedKey>
async function flattenedDecrypt(
jwe: FlattenedJWE,
key: KeyLike | FlattenedDecryptGetKey,
options?: DecryptOptions,
): Promise<FlattenedDecryptResult> {
) {
if (!isObject(jwe)) {
throw new JWEInvalid('Flattened JWE must be an object')
}
Expand Down Expand Up @@ -183,8 +199,10 @@ async function flattenedDecrypt(
encryptedKey = base64url(jwe.encrypted_key!)
}

let resolvedKey = false
if (typeof key === 'function') {
key = await key(parsedProt, jwe)
resolvedKey = true
}

let cek: KeyLike
Expand Down Expand Up @@ -240,6 +258,10 @@ async function flattenedDecrypt(
result.unprotectedHeader = jwe.header
}

if (resolvedKey) {
return { ...result, key }
}

return result
}

Expand Down
20 changes: 18 additions & 2 deletions src/jwe/general/decrypt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import type {
FlattenedJWE,
GeneralJWE,
GeneralDecryptResult,
ResolvedKey,
} from '../../types.d'
import isObject from '../../lib/is_object.js'

Expand All @@ -21,7 +22,7 @@ export interface GeneralDecryptGetKey extends GetKeyFunction<JWEHeaderParameters
* Decrypts a General JWE.
*
* @param jwe General JWE.
* @param key Private Key or Secret, or a function resolving one, to decrypt the JWE with.
* @param key Private Key or Secret to decrypt the JWE with.
* @param options JWE Decryption options.
*
* @example ESM import
Expand Down Expand Up @@ -66,11 +67,26 @@ export interface GeneralDecryptGetKey extends GetKeyFunction<JWEHeaderParameters
* console.log(decoder.decode(additionalAuthenticatedData))
* ```
*/
function generalDecrypt(
jwe: GeneralJWE,
key: KeyLike,
options?: DecryptOptions,
): Promise<GeneralDecryptResult>
/**
* @param jwe General JWE.
* @param getKey Function resolving Private Key or Secret to decrypt the JWE with.
* @param options JWE Decryption options.
*/
function generalDecrypt(
jwe: GeneralJWE,
getKey: GeneralDecryptGetKey,
options?: DecryptOptions,
): Promise<GeneralDecryptResult & ResolvedKey>
async function generalDecrypt(
jwe: GeneralJWE,
key: KeyLike | GeneralDecryptGetKey,
options?: DecryptOptions,
): Promise<GeneralDecryptResult> {
) {
if (!isObject(jwe)) {
throw new JWEInvalid('General JWE must be an object')
}
Expand Down
28 changes: 25 additions & 3 deletions src/jws/compact/verify.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import type {
JWSHeaderParameters,
KeyLike,
VerifyOptions,
ResolvedKey,
} from '../../types.d'

/**
Expand All @@ -24,7 +25,7 @@ export interface CompactVerifyGetKey
* Verifies the signature and format of and afterwards decodes the Compact JWS.
*
* @param jws Compact JWS.
* @param key Key, or a function resolving a key, to verify the JWS with.
* @param key Key to verify the JWS with.
* @param options JWS Verify options.
*
* @example ESM import
Expand Down Expand Up @@ -53,11 +54,26 @@ export interface CompactVerifyGetKey
* console.log(decoder.decode(payload))
* ```
*/
function compactVerify(
jws: string | Uint8Array,
key: KeyLike,
options?: VerifyOptions,
): Promise<CompactVerifyResult>
/**
* @param jws Compact JWS.
* @param getKey Function resolving a key to verify the JWS with.
* @param options JWS Verify options.
*/
function compactVerify(
jws: string | Uint8Array,
getKey: CompactVerifyGetKey,
options?: VerifyOptions,
): Promise<CompactVerifyResult & ResolvedKey>
async function compactVerify(
jws: string | Uint8Array,
key: KeyLike | CompactVerifyGetKey,
options?: VerifyOptions,
): Promise<CompactVerifyResult> {
) {
if (jws instanceof Uint8Array) {
jws = decoder.decode(jws)
}
Expand All @@ -81,7 +97,13 @@ async function compactVerify(
options,
)

return { payload: verified.payload, protectedHeader: verified.protectedHeader! }
const result = { payload: verified.payload, protectedHeader: verified.protectedHeader! }

if (typeof key === 'function') {
return { ...result, key: verified.key }
}

return result
}

export { compactVerify }
Expand Down
26 changes: 24 additions & 2 deletions src/jws/flattened/verify.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import type {
JWSHeaderParameters,
VerifyOptions,
GetKeyFunction,
ResolvedKey,
} from '../../types.d'

const checkExtensions = validateCrit.bind(undefined, JWSInvalid, new Map([['b64', true]]))
Expand All @@ -35,7 +36,7 @@ export interface FlattenedVerifyGetKey
* Verifies the signature and format of and afterwards decodes the Flattened JWS.
*
* @param jws Flattened JWS.
* @param key Key, or a function resolving a key, to verify the JWS with.
* @param key Key to verify the JWS with.
* @param options JWS Verify options.
*
* @example ESM import
Expand Down Expand Up @@ -68,11 +69,26 @@ export interface FlattenedVerifyGetKey
* console.log(decoder.decode(payload))
* ```
*/
function flattenedVerify(
jws: FlattenedJWSInput,
key: KeyLike,
options?: VerifyOptions,
): Promise<FlattenedVerifyResult>
/**
* @param jws Flattened JWS.
* @param getKey Function resolving a key to verify the JWS with.
* @param options JWS Verify options.
*/
function flattenedVerify(
jws: FlattenedJWSInput,
getKey: FlattenedVerifyGetKey,
options?: VerifyOptions,
): Promise<FlattenedVerifyResult & ResolvedKey>
async function flattenedVerify(
jws: FlattenedJWSInput,
key: KeyLike | FlattenedVerifyGetKey,
options?: VerifyOptions,
): Promise<FlattenedVerifyResult> {
) {
if (!isObject(jws)) {
throw new JWSInvalid('Flattened JWS must be an object')
}
Expand Down Expand Up @@ -149,8 +165,10 @@ async function flattenedVerify(
throw new JWSInvalid('JWS Payload must be a string or an Uint8Array instance')
}

let resolvedKey = false
if (typeof key === 'function') {
key = await key(parsedProt, jws)
resolvedKey = true
}

checkKeyType(alg, key, 'verify')
Expand Down Expand Up @@ -186,6 +204,10 @@ async function flattenedVerify(
result.unprotectedHeader = jws.header
}

if (resolvedKey) {
return { ...result, key }
}

return result
}

Expand Down
20 changes: 18 additions & 2 deletions src/jws/general/verify.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import type {
JWSHeaderParameters,
KeyLike,
VerifyOptions,
ResolvedKey,
} from '../../types.d'
import { JWSInvalid, JWSSignatureVerificationFailed } from '../../util/errors.js'
import isObject from '../../lib/is_object.js'
Expand All @@ -25,7 +26,7 @@ export interface GeneralVerifyGetKey
* Verifies the signature and format of and afterwards decodes the General JWS.
*
* @param jws General JWS.
* @param key Key, or a function resolving a key, to verify the JWS with.
* @param key Key to verify the JWS with.
* @param options JWS Verify options.
*
* @example ESM import
Expand Down Expand Up @@ -62,11 +63,26 @@ export interface GeneralVerifyGetKey
* console.log(decoder.decode(payload))
* ```
*/
function generalVerify(
jws: GeneralJWSInput,
key: KeyLike,
options?: VerifyOptions,
): Promise<GeneralVerifyResult>
/**
* @param jws General JWS.
* @param getKey Function resolving a key to verify the JWS with.
* @param options JWS Verify options.
*/
function generalVerify(
jws: GeneralJWSInput,
getKey: GeneralVerifyGetKey,
options?: VerifyOptions,
): Promise<GeneralVerifyResult & ResolvedKey>
async function generalVerify(
jws: GeneralJWSInput,
key: KeyLike | GeneralVerifyGetKey,
options?: VerifyOptions,
): Promise<GeneralVerifyResult> {
) {
if (!isObject(jws)) {
throw new JWSInvalid('General JWS must be an object')
}
Expand Down

0 comments on commit 49fb62c

Please sign in to comment.