Skip to content

Commit

Permalink
feat: return the CEK from JWE.decrypt operation with { complete: true }
Browse files Browse the repository at this point in the history
  • Loading branch information
panva committed Nov 23, 2019
1 parent 097cf56 commit c3eb845
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 24 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,7 @@ in terms of performance and API (not having well defined errors).
[spec-jws]: https://tools.ietf.org/html/rfc7515
[spec-jwt]: https://tools.ietf.org/html/rfc7519
[spec-okp]: https://tools.ietf.org/html/rfc8037
[draft-secp256k1]: https://tools.ietf.org/html/draft-ietf-cose-webauthn-algorithms-01
[draft-secp256k1]: https://tools.ietf.org/html/draft-ietf-cose-webauthn-algorithms-03
[draft-ietf-oauth-access-token-jwt]: https://tools.ietf.org/html/draft-ietf-oauth-access-token-jwt
[draft-jarm]: https://openid.net/specs/openid-financial-api-jarm.html
[spec-thumbprint]: https://tools.ietf.org/html/rfc7638
Expand Down
11 changes: 7 additions & 4 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -829,7 +829,8 @@ Verifies the claims and signature of a JSON Web Token.
- `clockTolerance`: `<string>` Clock Tolerance for comparing timestamps, provided as timespan
string e.g. `120s`, `2 minutes`, etc. **Default:** no clock tolerance
- `complete`: `<Boolean>` When false only the parsed payload is returned, otherwise an object with
a parsed header, payload, the matched key and the base64url encoded signature will be returned
a parsed header, payload, the key that verified and the base64url encoded signature will be
returned
**Default:** 'false'
- `crit`: `string[]` Array of Critical Header Parameter names to recognize. **Default:** '[]'
- `ignoreExp`: `<Boolean>` When true will not be validating the "exp" claim value to be in the
Expand Down Expand Up @@ -1289,9 +1290,11 @@ Verifies the provided JWE in either serialization with a given `<JWK.Key>` or `<
- `algorithms`: `string[]` Array of Algorithms to accept, when the JWE does not use an
Key Management algorithm from this list the decryption will fail. **Default:** 'undefined' -
accepts all algorithms available on the keys
- `complete`: `<boolean>` When true returns a complete object with the parsed headers, verified
AAD and cleartext instead of just the cleartext. **Default:** 'false'
- Returns: `<string>` &vert; `<Object>`
- `complete`: `<boolean>` When true returns an object with the parsed headers, verified
AAD, the content encryption key, the key that was used to unwrap or derive the content
encryption key, and cleartext instead of just the cleartext.
**Default:** 'false'
- Returns: `<Buffer>` &vert; `<Object>`

---

Expand Down
2 changes: 1 addition & 1 deletion lib/jwe/decrypt.js
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ const jweDecrypt = (skipValidateHeaders, serialization, jwe, key, { crit = [], c
}

if (complete) {
const result = { cleartext, key }
const result = { cleartext, key, cek }
if (aad) result.aad = aad
if (header) result.header = header
if (unprotected) result.unprotected = unprotected
Expand Down
36 changes: 18 additions & 18 deletions test/jwe/complete.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,38 +34,38 @@ const complete = (t, jwe, k, ...keys) => {
t.true(Buffer.isBuffer(decrypted.cleartext))
}

test('compact', complete, () => JWE.encrypt('foo', key), 'cleartext', 'protected', 'key')
test('flattened', complete, () => JWE.encrypt.flattened('foo', key), 'cleartext', 'protected', 'key')
test('flattened w/ aad', complete, () => JWE.encrypt.flattened('foo', key, undefined, undefined, 'bar'), 'cleartext', 'protected', 'aad', 'key')
test('flattened w/ unprotected', complete, () => JWE.encrypt.flattened('foo', key, undefined, { foo: 'bar' }), 'cleartext', 'protected', 'unprotected', 'key')
test('compact', complete, () => JWE.encrypt('foo', key), 'cleartext', 'protected', 'key', 'cek')
test('flattened', complete, () => JWE.encrypt.flattened('foo', key), 'cleartext', 'protected', 'key', 'cek')
test('flattened w/ aad', complete, () => JWE.encrypt.flattened('foo', key, undefined, undefined, 'bar'), 'cleartext', 'protected', 'aad', 'key', 'cek')
test('flattened w/ unprotected', complete, () => JWE.encrypt.flattened('foo', key, undefined, { foo: 'bar' }), 'cleartext', 'protected', 'unprotected', 'key', 'cek')
test('flattened w/ header', complete, () => {
const enc = new JWE.Encrypt('foo')
enc.recipient(key, { foo: 'bar' })
return enc.encrypt('flattened')
}, 'cleartext', 'protected', 'header', 'key')
test('general', complete, () => JWE.encrypt.general('foo', key), 'cleartext', 'protected', 'key')
test('general w/ aad', complete, () => JWE.encrypt.general('foo', key, undefined, undefined, 'bar'), 'cleartext', 'protected', 'aad', 'key')
test('general w/ unprotected', complete, () => JWE.encrypt.general('foo', key, undefined, { foo: 'bar' }), 'cleartext', 'protected', 'unprotected', 'key')
}, 'cleartext', 'protected', 'header', 'key', 'cek')
test('general', complete, () => JWE.encrypt.general('foo', key), 'cleartext', 'protected', 'key', 'cek')
test('general w/ aad', complete, () => JWE.encrypt.general('foo', key, undefined, undefined, 'bar'), 'cleartext', 'protected', 'aad', 'key', 'cek')
test('general w/ unprotected', complete, () => JWE.encrypt.general('foo', key, undefined, { foo: 'bar' }), 'cleartext', 'protected', 'unprotected', 'key', 'cek')
test('general w/ header', complete, () => {
const enc = new JWE.Encrypt('foo')
enc.recipient(key, { foo: 'bar' })
return enc.encrypt('general')
}, 'cleartext', 'protected', 'header', 'key')
}, 'cleartext', 'protected', 'header', 'key', 'cek')

test('with keystore > compact', complete, () => JWE.encrypt('foo', key), ks, 'cleartext', 'protected', 'key')
test('with keystore > flattened', complete, () => JWE.encrypt.flattened('foo', key), ks, 'cleartext', 'protected', 'key')
test('with keystore > flattened w/ aad', complete, () => JWE.encrypt.flattened('foo', key, undefined, undefined, 'bar'), ks, 'cleartext', 'protected', 'aad', 'key')
test('with keystore > flattened w/ unprotected', complete, () => JWE.encrypt.flattened('foo', key, undefined, { foo: 'bar' }), ks, 'cleartext', 'protected', 'unprotected', 'key')
test('with keystore > compact', complete, () => JWE.encrypt('foo', key), ks, 'cleartext', 'protected', 'key', 'cek')
test('with keystore > flattened', complete, () => JWE.encrypt.flattened('foo', key), ks, 'cleartext', 'protected', 'key', 'cek')
test('with keystore > flattened w/ aad', complete, () => JWE.encrypt.flattened('foo', key, undefined, undefined, 'bar'), ks, 'cleartext', 'protected', 'aad', 'key', 'cek')
test('with keystore > flattened w/ unprotected', complete, () => JWE.encrypt.flattened('foo', key, undefined, { foo: 'bar' }), ks, 'cleartext', 'protected', 'unprotected', 'key', 'cek')
test('with keystore > flattened w/ header', complete, () => {
const enc = new JWE.Encrypt('foo')
enc.recipient(key, { foo: 'bar' })
return enc.encrypt('flattened')
}, ks, 'cleartext', 'protected', 'header', 'key')
test('with keystore > general', complete, () => JWE.encrypt.general('foo', key), ks, 'cleartext', 'protected', 'key')
test('with keystore > general w/ aad', complete, () => JWE.encrypt.general('foo', key, undefined, undefined, 'bar'), ks, 'cleartext', 'protected', 'aad', 'key')
test('with keystore > general w/ unprotected', complete, () => JWE.encrypt.general('foo', key, undefined, { foo: 'bar' }), ks, 'cleartext', 'protected', 'unprotected', 'key')
}, ks, 'cleartext', 'protected', 'header', 'key', 'cek')
test('with keystore > general', complete, () => JWE.encrypt.general('foo', key), ks, 'cleartext', 'protected', 'key', 'cek')
test('with keystore > general w/ aad', complete, () => JWE.encrypt.general('foo', key, undefined, undefined, 'bar'), ks, 'cleartext', 'protected', 'aad', 'key', 'cek')
test('with keystore > general w/ unprotected', complete, () => JWE.encrypt.general('foo', key, undefined, { foo: 'bar' }), ks, 'cleartext', 'protected', 'unprotected', 'key', 'cek')
test('with keystore > general w/ header', complete, () => {
const enc = new JWE.Encrypt('foo')
enc.recipient(key, { foo: 'bar' })
return enc.encrypt('general')
}, ks, 'cleartext', 'protected', 'header', 'key')
}, ks, 'cleartext', 'protected', 'header', 'key', 'cek')
1 change: 1 addition & 0 deletions types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,7 @@ export namespace JWE {
interface completeDecrypt {
cleartext: Buffer;
key: JWK.Key;
cek: JWK.OctKey;
aad?: string;
header?: object;
unprotected?: object;
Expand Down

0 comments on commit c3eb845

Please sign in to comment.