diff --git a/README.md b/README.md index 8d2b2a4bab..14b0d0a3ea 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/docs/README.md b/docs/README.md index d9be0ad07a..d2e999be66 100644 --- a/docs/README.md +++ b/docs/README.md @@ -829,7 +829,8 @@ Verifies the claims and signature of a JSON Web Token. - `clockTolerance`: `` Clock Tolerance for comparing timestamps, provided as timespan string e.g. `120s`, `2 minutes`, etc. **Default:** no clock tolerance - `complete`: `` 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`: `` When true will not be validating the "exp" claim value to be in the @@ -1289,9 +1290,11 @@ Verifies the provided JWE in either serialization with a given `` 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`: `` When true returns a complete object with the parsed headers, verified - AAD and cleartext instead of just the cleartext. **Default:** 'false' -- Returns: `` | `` + - `complete`: `` 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: `` | `` --- diff --git a/lib/jwe/decrypt.js b/lib/jwe/decrypt.js index 214a00f7a0..9832f9e01b 100644 --- a/lib/jwe/decrypt.js +++ b/lib/jwe/decrypt.js @@ -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 diff --git a/test/jwe/complete.test.js b/test/jwe/complete.test.js index ecab4a4334..72fe1ce4ce 100644 --- a/test/jwe/complete.test.js +++ b/test/jwe/complete.test.js @@ -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') diff --git a/types/index.d.ts b/types/index.d.ts index 2685b1666f..708879acad 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -317,6 +317,7 @@ export namespace JWE { interface completeDecrypt { cleartext: Buffer; key: JWK.Key; + cek: JWK.OctKey; aad?: string; header?: object; unprotected?: object;