feat: add opt-in objects to verify using embedded JWS Header public keys

This commit is contained in:
Filip Skokan 2020-05-04 22:37:11 +02:00
parent 5c7888869f
commit 7c1cab196e
13 changed files with 351 additions and 20 deletions

View file

@ -52,6 +52,8 @@ If you or your business use `jose`, please consider becoming a [sponsor][support
- [JWK.generateSync(kty[, crvOrSize[, options[, private]]])](#jwkgeneratesynckty-crvorsize-options-private)
- [JWK.isKey(object)](#jwkiskeyobject)
- [JWK.None](#jwknone)
- [JWK.EmbeddedJWK](#jwkembeddedjwk)
- [JWK.EmbeddedX5C](#jwkembeddedx5c)
<!-- TOC JWK END -->
All sign and encrypt operations require `<JWK.Key>` or `JWK.asKey()` compatible input.
@ -623,6 +625,28 @@ JWS.verify(unsecuredJWS, None)
---
#### `JWK.EmbeddedJWK`
`JWK.EmbeddedJWK` is a special key object that can be used with the JWS/JWT verify operations
whenever you want to opt-in to verify signatures with a public key embedded in the JWS Header `jwk`
parameter. It is recommended to combine this with the verify `algorithms` option to whitelist
JWS algorithms to accept as well as the `complete` option set to `true` if you need to work with the
instantiated `JWK.Key` from the token.
---
#### `JWK.EmbeddedX5C`
`JWK.EmbeddedX5C` is a special key object that can be used with the JWS/JWT verify operations
whenever you want to opt-in to verify signatures with a public key embedded in the first JWS Header
`x5c` parameter. It is recommended to combine this with the verify `algorithms` option to whitelist
JWS algorithms to accept as well as the `complete` option set to `true` if you need to work with the
instantiated `JWK.Key` from the token. ⚠️ the x5c members are all validated to be certificates but
their chain or trust is not validated. Unfortunately Node.js does not have any good tools to do that
reliably.
---
## JWKS (JSON Web Key Set)
<!-- TOC JWKS START -->

View file

@ -30,7 +30,7 @@ if (keyObjectSupported) {
}
const pemToDer = pem => Buffer.from(pem.replace(/(?:-----(?:BEGIN|END)(?: (?:RSA|EC))? (?:PRIVATE|PUBLIC) KEY-----|\s)/g, ''), 'base64')
const derToPem = (der, label) => `-----BEGIN ${label}-----${EOL}${der.toString('base64').match(/.{1,64}/g).join(EOL)}${EOL}-----END ${label}-----`
const derToPem = (der, label) => `-----BEGIN ${label}-----${EOL}${(der.toString('base64').match(/.{1,64}/g) || []).join(EOL)}${EOL}-----END ${label}-----`
const unsupported = (input) => {
const label = typeof input === 'string' ? input : `OID ${input.join('.')}`
throw new errors.JOSENotSupported(`${label} is not supported in your Node.js runtime version`)

View file

@ -10,7 +10,7 @@ const asn1 = require('./asn1')
const computePrimes = require('./rsa_primes')
const { OKP_CURVES, EC_CURVES } = require('../registry')
const formatPem = (base64pem, descriptor) => `-----BEGIN ${descriptor} KEY-----${EOL}${base64pem.match(/.{1,64}/g).join(EOL)}${EOL}-----END ${descriptor} KEY-----`
const formatPem = (base64pem, descriptor) => `-----BEGIN ${descriptor} KEY-----${EOL}${(base64pem.match(/.{1,64}/g) || []).join(EOL)}${EOL}-----END ${descriptor} KEY-----`
const okpToJWK = {
private (crv, keyObject) {

View file

@ -1,5 +1,7 @@
const Key = require('./key/base')
const None = require('./key/none')
const EmbeddedJWK = require('./key/embedded.jwk')
const EmbeddedX5C = require('./key/embedded.x5c')
const importKey = require('./import')
const generate = require('./generate')
@ -7,7 +9,9 @@ module.exports = {
...generate,
asKey: importKey,
isKey: input => input instanceof Key,
None
None,
EmbeddedJWK,
EmbeddedX5C
}
/* deprecated */

View file

@ -61,7 +61,7 @@ class Key {
let publicKey
try {
publicKey = createPublicKey({
key: `-----BEGIN CERTIFICATE-----${EOL}${cert.match(/.{1,64}/g).join(EOL)}${EOL}-----END CERTIFICATE-----`, format: 'pem'
key: `-----BEGIN CERTIFICATE-----${EOL}${(cert.match(/.{1,64}/g) || []).join(EOL)}${EOL}-----END CERTIFICATE-----`, format: 'pem'
})
} catch (err) {
throw new errors.JWKInvalid(`\`x5c\` member at index ${i} is not a valid base64-encoded DER PKIX certificate`)

View file

@ -0,0 +1,27 @@
const { inspect } = require('util')
const Key = require('./base')
class EmbeddedJWK extends Key {
constructor () {
super({ type: 'embedded' })
Object.defineProperties(this, {
kid: { value: undefined },
kty: { value: undefined },
thumbprint: { value: undefined },
toJWK: { value: undefined },
toPEM: { value: undefined }
})
}
/* c8 ignore next 3 */
[inspect.custom] () {
return 'Embedded.JWK {}'
}
algorithms () {
return new Set()
}
}
module.exports = new EmbeddedJWK()

View file

@ -0,0 +1,27 @@
const { inspect } = require('util')
const Key = require('./base')
class EmbeddedX5C extends Key {
constructor () {
super({ type: 'embedded' })
Object.defineProperties(this, {
kid: { value: undefined },
kty: { value: undefined },
thumbprint: { value: undefined },
toJWK: { value: undefined },
toPEM: { value: undefined }
})
}
/* c8 ignore next 3 */
[inspect.custom] () {
return 'Embedded.X5C {}'
}
algorithms () {
return new Set()
}
}
module.exports = new EmbeddedX5C()

View file

@ -7,6 +7,7 @@ class NoneKey extends Key {
super({ type: 'unsecured' }, { alg: 'none' })
Object.defineProperties(this, {
kid: { value: undefined },
kty: { value: undefined },
thumbprint: { value: undefined },
toJWK: { value: undefined },
toPEM: { value: undefined }
@ -30,4 +31,4 @@ class NoneKey extends Key {
}
}
module.exports = new NoneKey({ type: 'unsecured' }, { alg: 'none' })
module.exports = new NoneKey()

View file

@ -3,7 +3,7 @@ const { deprecate, inspect } = require('util')
const isObject = require('../help/is_object')
const { generate, generateSync } = require('../jwk/generate')
const { USES_MAPPING } = require('../help/consts')
const { None, isKey, asKey: importKey } = require('../jwk')
const { isKey, asKey: importKey } = require('../jwk')
const keyscore = (key, { alg, use, ops }) => {
let score = 0
@ -35,7 +35,7 @@ class KeyStore {
return acc
}, [])
}
if (keys.some(k => !isKey(k) || k === None)) {
if (keys.some(k => !isKey(k) || !k.kty)) {
throw new TypeError('all keys must be instances of a key instantiated by JWK.asKey')
}
@ -107,7 +107,7 @@ class KeyStore {
}
add (key) {
if (!isKey(key) || key === None) {
if (!isKey(key) || !key.kty) {
throw new TypeError('key must be an instance of a key instantiated by JWK.asKey')
}

View file

@ -1,10 +1,14 @@
const { EOL } = require('os')
const base64url = require('../help/base64url')
const isDisjoint = require('../help/is_disjoint')
const isObject = require('../help/is_object')
let validateCrit = require('../help/validate_crit')
const getKey = require('../help/get_key')
const { KeyStore } = require('../jwks')
const errors = require('../errors')
const { check, verify } = require('../jwa')
const JWK = require('../jwk')
const { detect: resolveSerialization } = require('./serializers')
@ -125,6 +129,24 @@ const jwsVerify = (skipDisjointCheck, serialization, jws, key, { crit = [], comp
}
}
if (key === JWK.EmbeddedJWK) {
if (!isObject(combinedHeader.jwk)) {
throw new errors.JWSInvalid('JWS Header Parameter "jwk" must be a JSON object')
}
key = JWK.asKey(combinedHeader.jwk)
if (key.type !== 'public') {
throw new errors.JWSInvalid('JWS Header Parameter "jwk" must be a public key')
}
} else if (key === JWK.EmbeddedX5C) {
if (!Array.isArray(combinedHeader.x5c) || !combinedHeader.x5c.length || combinedHeader.x5c.some(c => typeof c !== 'string' || !c)) {
throw new errors.JWSInvalid('JWS Header Parameter "x5c" must be a JSON array of certificate value strings')
}
key = JWK.asKey(
`-----BEGIN CERTIFICATE-----${EOL}${(combinedHeader.x5c[0].match(/.{1,64}/g) || []).join(EOL)}${EOL}-----END CERTIFICATE-----`,
{ x5c: combinedHeader.x5c }
)
}
check(key, 'verify', alg)
const toBeVerified = Buffer.concat([

189
test/jwk/embedded.test.js Normal file
View file

@ -0,0 +1,189 @@
const test = require('ava')
const { errors, JWK, JWS, JWT, JWKS } = require('../..')
const { keyObjectSupported } = require('../../lib/help/runtime_support')
test('JWK.EmbeddedJWK', t => {
const k = JWK.EmbeddedJWK
t.truthy(k)
t.true(JWK.isKey(k))
t.is(k.kty, undefined)
for (const prop of ['kid', 'kty', 'thumbprint', 'toJWK', 'toPEM']) {
k[prop] = 'foo'
t.is(k[prop], undefined)
}
t.deepEqual([...k.algorithms()], [])
k.type = 'foo'
t.is(k.type, 'embedded')
t.throws(() => new JWKS.KeyStore(k), { instanceOf: TypeError })
const ks = new JWKS.KeyStore()
t.throws(() => ks.add(k), { instanceOf: TypeError })
})
test('JWK.EmbeddedJWK JWS.verify pass', async t => {
const key = await JWK.generate('EC', 'P-256')
const { kid, ...jwk } = key.toJWK()
const jws = JWS.sign('foo', key, { jwk })
t.notThrows(() => JWS.verify(jws, JWK.EmbeddedJWK))
t.throws(
() => JWS.verify(jws, JWK.EmbeddedJWK, { algorithms: ['EdDSA'] }),
{ instanceOf: errors.JOSEAlgNotWhitelisted, code: 'ERR_JOSE_ALG_NOT_WHITELISTED', message: 'alg not whitelisted' }
)
const { key: embedded } = JWS.verify(jws, JWK.EmbeddedJWK, { complete: true })
t.false(key === embedded)
t.deepEqual(key.toJWK(), embedded.toJWK())
})
test('JWK.EmbeddedJWK JWT.verify pass', async t => {
const key = await JWK.generate('EC', 'P-256')
const { kid, ...jwk } = key.toJWK()
const jws = JWT.sign({}, key, { header: { jwk } })
t.notThrows(() => JWT.verify(jws, JWK.EmbeddedJWK))
t.throws(
() => JWT.verify(jws, JWK.EmbeddedJWK, { algorithms: ['EdDSA'] }),
{ instanceOf: errors.JOSEAlgNotWhitelisted, code: 'ERR_JOSE_ALG_NOT_WHITELISTED', message: 'alg not whitelisted' }
)
const { key: embedded } = JWT.verify(jws, JWK.EmbeddedJWK, { complete: true })
t.false(key === embedded)
t.deepEqual(key.toJWK(), embedded.toJWK())
})
test('JWK.EmbeddedJWK key must be a public key', async t => {
const key = await JWK.generate('EC', 'P-256')
const { kid, ...jwk } = key.toJWK(true)
{
const jws = JWS.sign('foo', key, { jwk })
t.throws(
() => JWS.verify(jws, JWK.EmbeddedJWK),
{ instanceOf: errors.JWSInvalid, code: 'ERR_JWS_INVALID', message: 'JWS Header Parameter "jwk" must be a public key' }
)
}
{
const jws = JWS.sign('foo', key, { jwk: { kty: 'oct', k: 'foo' } })
t.throws(
() => JWS.verify(jws, JWK.EmbeddedJWK),
{ instanceOf: errors.JWSInvalid, code: 'ERR_JWS_INVALID', message: 'JWS Header Parameter "jwk" must be a public key' }
)
}
{
const jws = JWS.sign('foo', key, { jwk: { kty: 'oct' } })
t.throws(
() => JWS.verify(jws, JWK.EmbeddedJWK),
{ instanceOf: errors.JWSInvalid, code: 'ERR_JWS_INVALID', message: 'JWS Header Parameter "jwk" must be a public key' }
)
}
{
const jws = JWS.sign('foo', key, { jwk: { kty: 'foo' } })
t.throws(
() => JWS.verify(jws, JWK.EmbeddedJWK),
{ instanceOf: errors.JOSENotSupported, code: 'ERR_JOSE_NOT_SUPPORTED', message: 'unsupported key type: foo' }
)
}
{
const invalidEc = key.toJWK()
delete invalidEc.y
const jws = JWS.sign('foo', key, { jwk: invalidEc })
t.throws(
() => JWS.verify(jws, JWK.EmbeddedJWK),
{ instanceOf: errors.JWKImportFailed, code: 'ERR_JWK_IMPORT_FAILED', message: 'key import failed' }
)
}
})
test('JWK.EmbeddedJWK key invalid inputs', async t => {
const key = await JWK.generate('EC', 'P-256')
for (const jwk of [undefined, '', null, false, true, 1, 3.14, 'pi']) {
const jws = JWS.sign('foo', key, { jwk })
t.throws(
() => JWS.verify(jws, JWK.EmbeddedJWK),
{ instanceOf: errors.JWSInvalid, code: 'ERR_JWS_INVALID', message: 'JWS Header Parameter "jwk" must be a JSON object' }
)
}
})
if (keyObjectSupported) {
test('JWK.EmbeddedX5C', t => {
const k = JWK.EmbeddedX5C
t.truthy(k)
t.true(JWK.isKey(k))
t.is(k.kty, undefined)
for (const prop of ['kid', 'kty', 'thumbprint', 'toJWK', 'toPEM']) {
k[prop] = 'foo'
t.is(k[prop], undefined)
}
t.deepEqual([...k.algorithms()], [])
k.type = 'foo'
t.is(k.type, 'embedded')
t.throws(() => new JWKS.KeyStore(k), { instanceOf: TypeError })
const ks = new JWKS.KeyStore()
t.throws(() => ks.add(k), { instanceOf: TypeError })
})
const rsa = {
e: 'AQAB',
n: 'u4kSwZDMd93b1fvd6CXUfHa-rF0DBd03tCCpWN31giKCskP09c7VigwkyHu34X__1rA7CNMaSrXQn4ChkhulSxzQyojBc3t06AjyKe_Nzpd72zaGFjaLfN-C2U5QmmaXn_2dOiQTH3aTaHDA5I8zd7ZEwrln9G6DD9KtbAcal-RWN_XT-dD-hHUSH4X4iHIvVC1El6lOtu9yjpmQtAvU3mpvxKK6AUGEA9wCWmIEcpfosOCpgHiwVeuPwJwAmuHRFA-h5N4wWw1KQuW66ocgeTzwKZ33DuMWeLap3AEeDVErInAwPPjzLSj3i3DvtveGlGZQH10wAZMAQrcUhHS06Q',
d: 'e_PUztXbH5snc58fBBMFCCMgUiLEHbsi108DP7atUA9pXVRnc5T7NVxjb5O-bTDCM--VhXaqmRjlRJerszvMnAH2yvdrDd5a3gcTsL5MxLEBb1nxdHsm5SmCfgkyY2tN6rShmE1BynkAY3arOCaieQyjFCWh3UCyJeI1OALWA_AJP1kOrmrM9Cpd3FYNkKN163_D7Nv5g2PuMMO1T6Zx8xdgC1C6OxXfmVpvNtOI4pnkODRcQhTspHJLzGTtp2yYPRHCsBhF7i3XsbQ4D8a8t_vZ3yLt-3ZkJnHnRQeCeyBlALUcnFFo43CA96ohOk6NhjYNbi8uJbZyxWVXllwV5Q',
p: '5kZFOcFl6jrZ7XQWDoHipOqHyACKRCdk1V-JBi8_iOZYpDXiTWCAdl_XAqMLI8vrcceOi2TLbdFBASVQVWwvOPUkpZ5BvNI6Zpzvv7PRjQlhBBogC06zwCcMi0f1RVZrvtt1_URwMgSuc7OaJFEIcIllVaXKa2KhmBBlQnDVSXc',
q: '0Hx9Ccd1iaESKbfv6Wsx1emCaKcIBpxYe41jNWbmtGNixaZHyCr0_FFAOwzbfe_W_kuX6Tk5rmDDivG92Rm0QcRas70CvXP8m64R3Z3qV7mKY8QZpwooPFoOaZfjl0--w_HEdtf-epm43kCIXtqgaIj4aUFEEdEe4AVnTyZpjJ8',
dp: '1zYhiKLpXwn1lukBnDlj2wGeORvYHW473PdWlsMdvBKcEYySngJszTUxO7Opu6DfwQziegCP52jEOg_njo53a-Igh_DqO1C3aCOQJjgmxotXcoAAJtE9SX61SI7N-imUtWFiWnvV58lcSaI3k21wV8zxOiSik84wfHAGUxwlGm0',
dq: 'Q9_DdWOSSHQ_zYUsffmAB_w1kIyQeFZ-F_s3yTLu-NtCVMaFqA0UJPDu0EqnSqDChZdmpW8T8ElgX-PDwuIzZRXf0ZQ_SB5yptxMxLGckWK-QyycjV0pLDzFZGsmlSRJHtGe_HHlT1Sscu7fdsIGZwHwnZO57XL_cj9QGtyOkFE',
qi: 'qhNTCBRZi6zC-2nyVuleB5DAfzza_HSqa_FvSZpzbxv_cIgI52FIB2Vn6u6c8M-n0PEVpCOwVOD2VuRqWhidfOJsFbGLyGtEg9ZRE-bQoOPvRIeUqOt5jTe3bqboG84vNcmw5m0zbCw8upUmu2LK0NIFDxrjognJEwIlMoAgALE',
kty: 'RSA'
}
const x5c = ['MIIDmjCCAoKgAwIBAgIJfEZch1k3018JMA0GCSqGSIb3DQEBBQUAMGkxFDASBgNVBAMTC2V4YW1wbGUub3JnMQswCQYDVQQGEwJVUzERMA8GA1UECBMIVmlyZ2luaWExEzARBgNVBAcTCkJsYWNrc2J1cmcxDTALBgNVBAoTBFRlc3QxDTALBgNVBAsTBFRlc3QwHhcNMjAwNTA1MTI0MTQ2WhcNMjEwNTA1MTI0MTQ2WjBpMRQwEgYDVQQDEwtleGFtcGxlLm9yZzELMAkGA1UEBhMCVVMxETAPBgNVBAgTCFZpcmdpbmlhMRMwEQYDVQQHEwpCbGFja3NidXJnMQ0wCwYDVQQKEwRUZXN0MQ0wCwYDVQQLEwRUZXN0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu4kSwZDMd93b1fvd6CXUfHa+rF0DBd03tCCpWN31giKCskP09c7VigwkyHu34X//1rA7CNMaSrXQn4ChkhulSxzQyojBc3t06AjyKe/Nzpd72zaGFjaLfN+C2U5QmmaXn/2dOiQTH3aTaHDA5I8zd7ZEwrln9G6DD9KtbAcal+RWN/XT+dD+hHUSH4X4iHIvVC1El6lOtu9yjpmQtAvU3mpvxKK6AUGEA9wCWmIEcpfosOCpgHiwVeuPwJwAmuHRFA+h5N4wWw1KQuW66ocgeTzwKZ33DuMWeLap3AEeDVErInAwPPjzLSj3i3DvtveGlGZQH10wAZMAQrcUhHS06QIDAQABo0UwQzAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIC9DAmBgNVHREEHzAdhhtodHRwOi8vZXhhbXBsZS5vcmcvd2ViaWQjbWUwDQYJKoZIhvcNAQEFBQADggEBAA3oxXuMEXdi/5ndPuoJYe1eK3KHIFRajZOrMxSz65ErlkiIt9K0weoYSywufuIdP71kc+S/x/NUpXzaZ1XvUDK3IvwKxf/dnLgtDJRABCWHBQ+81YvtxJVzDSq9grVdGby7IRzuDaayvEo0YFc5xh0r8Jc/Dlaz4ZUhXLxpKZeyT47aPyk6Ys+d/2vEFDhOwyipqKI+xtfrdPaBi9FXk/QA+Th16DKx9Uxau+sXbAVSG3YZtUUkadi1sP/oKqQcJ6VTSGt+8Yg+DJwY8ZnX+QgVyEtqpTwfJNjt3G4qOtAr8LpNTN+r2BG4XYN3bck9SVfjDky5dXJo3NY2pT9AO58=']
test('JWK.EmbeddedX5C JWS.verify pass', async t => {
const key = JWK.asKey({ ...rsa, x5c })
const jws = JWS.sign('foo', key, { x5c })
t.notThrows(() => JWS.verify(jws, JWK.EmbeddedX5C))
t.throws(
() => JWS.verify(jws, JWK.EmbeddedX5C, { algorithms: ['EdDSA'] }),
{ instanceOf: errors.JOSEAlgNotWhitelisted, code: 'ERR_JOSE_ALG_NOT_WHITELISTED', message: 'alg not whitelisted' }
)
const { key: embedded } = JWS.verify(jws, JWK.EmbeddedX5C, { complete: true })
t.false(key === embedded)
t.deepEqual(key.toJWK(), embedded.toJWK())
})
test('JWK.EmbeddedX5C JWT.verify pass', async t => {
const key = JWK.asKey({ ...rsa, x5c })
const jws = JWT.sign({}, key, { header: { x5c } })
t.notThrows(() => JWT.verify(jws, JWK.EmbeddedX5C))
t.throws(
() => JWT.verify(jws, JWK.EmbeddedX5C, { algorithms: ['EdDSA'] }),
{ instanceOf: errors.JOSEAlgNotWhitelisted, code: 'ERR_JOSE_ALG_NOT_WHITELISTED', message: 'alg not whitelisted' }
)
const { key: embedded } = JWT.verify(jws, JWK.EmbeddedX5C, { complete: true })
t.false(key === embedded)
t.deepEqual(key.toJWK(), embedded.toJWK())
})
test('JWK.EmbeddedJWK key must be a properly formatted cert value', async t => {
const key = JWK.asKey({ ...rsa, x5c })
const jws = JWS.sign('foo', key, { x5c: [x5c[0].slice(0, 16)] })
t.throws(
() => JWS.verify(jws, JWK.EmbeddedX5C),
{ instanceOf: errors.JWKImportFailed, code: 'ERR_JWK_IMPORT_FAILED', message: 'key import failed' }
)
})
test('JWK.EmbeddedX5C key invalid inputs', async t => {
const key = JWK.asKey({ ...rsa, x5c })
for (const x5c of [undefined, '', null, false, true, 1, 3.14, []]) {
{
const jws = JWS.sign('foo', key, { x5c })
t.throws(
() => JWS.verify(jws, JWK.EmbeddedX5C),
{ instanceOf: errors.JWSInvalid, code: 'ERR_JWS_INVALID', message: 'JWS Header Parameter "x5c" must be a JSON array of certificate value strings' }
)
}
{
const jws = JWS.sign('foo', key, { x5c: [x5c] })
t.throws(
() => JWS.verify(jws, JWK.EmbeddedX5C),
{ instanceOf: errors.JWSInvalid, code: 'ERR_JWS_INVALID', message: 'JWS Header Parameter "x5c" must be a JSON array of certificate value strings' }
)
}
}
})
}

20
test/jwk/none.test.js Normal file
View file

@ -0,0 +1,20 @@
const test = require('ava')
const { JWK, JWKS } = require('../..')
test('JWK.None', t => {
const k = JWK.None
t.truthy(k)
t.true(JWK.isKey(k))
t.is(k.kty, undefined)
for (const prop of ['kid', 'kty', 'thumbprint', 'toJWK', 'toPEM']) {
k[prop] = 'foo'
t.is(k[prop], undefined)
}
t.deepEqual([...k.algorithms()], ['none'])
k.type = 'foo'
t.is(k.type, 'unsecured')
t.throws(() => new JWKS.KeyStore(k), { instanceOf: TypeError })
const ks = new JWKS.KeyStore()
t.throws(() => ks.add(k), { instanceOf: TypeError })
})

41
types/index.d.ts vendored
View file

@ -27,6 +27,9 @@ export type KeyInput = PrivateKeyInput | PublicKeyInput | string | Buffer;
export type ProduceKeyInput = JWK.Key | KeyObject | KeyInput | JWKOctKey | JWKRSAKey | JWKECKey | JWKOKPKey;
export type ConsumeKeyInput = ProduceKeyInput | JWKS.KeyStore;
export type NoneKey = JWK.NoneKey;
export type EmbeddedJWK = JWK.EmbeddedJWK;
export type EmbeddedX5C = JWK.EmbeddedX5C;
export type EmbeddedVerifyKeys = EmbeddedJWK | EmbeddedX5C;
export type ProduceKeyInputWithNone = ProduceKeyInput | NoneKey;
export type ConsumeKeyInputWithNone = ConsumeKeyInput | NoneKey;
@ -216,6 +219,20 @@ export namespace JWK {
const None: NoneKey;
interface EmbeddedJWK {
readonly type: 'embedded';
algorithms(operation?: keyOperation): Set<string>;
}
const EmbeddedJWK: EmbeddedJWK;
interface EmbeddedX5C {
readonly type: 'embedded';
algorithms(operation?: keyOperation): Set<string>;
}
const EmbeddedX5C: EmbeddedX5C;
function isKey(object: any): boolean;
function asKey(key: KeyObject | KeyInput, parameters?: KeyParameters): RSAKey | ECKey | OKPKey | OctKey;
@ -340,10 +357,10 @@ export namespace JWS {
header?: object;
}
function verify(jws: string | FlattenedJWS | GeneralJWS, key: ConsumeKeyInputWithNone, options?: VerifyOptions): string | object;
function verify(jws: string | FlattenedJWS | GeneralJWS, key: ConsumeKeyInputWithNone, options?: VerifyOptions<false, false>): Buffer;
function verify(jws: string | FlattenedJWS | GeneralJWS, key: ConsumeKeyInput, options?: VerifyOptions<true>): completeVerification<string | object, JWK.Key>;
function verify(jws: string | FlattenedJWS | GeneralJWS, key: ConsumeKeyInput, options?: VerifyOptions<true, false>): completeVerification<Buffer, JWK.Key>;
function verify(jws: string | FlattenedJWS | GeneralJWS, key: ConsumeKeyInputWithNone | EmbeddedVerifyKeys, options?: VerifyOptions): string | object;
function verify(jws: string | FlattenedJWS | GeneralJWS, key: ConsumeKeyInputWithNone | EmbeddedVerifyKeys, options?: VerifyOptions<false, false>): Buffer;
function verify(jws: string | FlattenedJWS | GeneralJWS, key: ConsumeKeyInput | EmbeddedVerifyKeys, options?: VerifyOptions<true>): completeVerification<string | object, JWK.Key>;
function verify(jws: string | FlattenedJWS | GeneralJWS, key: ConsumeKeyInput | EmbeddedVerifyKeys, options?: VerifyOptions<true, false>): completeVerification<Buffer, JWK.Key>;
function verify(jws: string | FlattenedJWS | GeneralJWS, key: NoneKey, options?: VerifyOptions<true>): completeVerification<string | object, NoneKey>;
function verify(jws: string | FlattenedJWS | GeneralJWS, key: NoneKey, options?: VerifyOptions<true, false>): completeVerification<Buffer, NoneKey>;
}
@ -440,8 +457,8 @@ export namespace JWT {
profile?: JWTProfiles;
}
function verify(jwt: string, key: ConsumeKeyInputWithNone, options?: VerifyOptions<false>): object;
function verify(jwt: string, key: ConsumeKeyInput, options?: VerifyOptions<true>): completeResult;
function verify(jwt: string, key: ConsumeKeyInputWithNone | EmbeddedVerifyKeys, options?: VerifyOptions<false>): object;
function verify(jwt: string, key: ConsumeKeyInput | EmbeddedVerifyKeys, options?: VerifyOptions<true>): completeResult;
function verify(jwt: string, key: NoneKey, options?: VerifyOptions<true>): completeResult<NoneKey>;
interface SignOptions {
@ -468,20 +485,20 @@ export namespace JWT {
}
namespace IdToken {
function verify(jwt: string, key: ConsumeKeyInputWithNone, options: VerifyOptions<false> & VerifyProfileOptions<'id_token'>): object;
function verify(jwt: string, key: ConsumeKeyInput, options: VerifyOptions<true> & VerifyProfileOptions<'id_token'>): completeResult;
function verify(jwt: string, key: ConsumeKeyInputWithNone | EmbeddedVerifyKeys, options: VerifyOptions<false> & VerifyProfileOptions<'id_token'>): object;
function verify(jwt: string, key: ConsumeKeyInput | EmbeddedVerifyKeys, options: VerifyOptions<true> & VerifyProfileOptions<'id_token'>): completeResult;
function verify(jwt: string, key: NoneKey, options: VerifyOptions<true> & VerifyProfileOptions<'id_token'>): completeResult<NoneKey>;
}
namespace LogoutToken {
function verify(jwt: string, key: ConsumeKeyInputWithNone, options: VerifyOptions<false> & VerifyProfileOptions<'logout_token'>): object;
function verify(jwt: string, key: ConsumeKeyInput, options: VerifyOptions<true> & VerifyProfileOptions<'logout_token'>): completeResult;
function verify(jwt: string, key: ConsumeKeyInputWithNone | EmbeddedVerifyKeys, options: VerifyOptions<false> & VerifyProfileOptions<'logout_token'>): object;
function verify(jwt: string, key: ConsumeKeyInput | EmbeddedVerifyKeys, options: VerifyOptions<true> & VerifyProfileOptions<'logout_token'>): completeResult;
function verify(jwt: string, key: NoneKey, options: VerifyOptions<true> & VerifyProfileOptions<'logout_token'>): completeResult<NoneKey>;
}
namespace AccessToken {
function verify(jwt: string, key: ConsumeKeyInputWithNone, options: VerifyOptions<false> & VerifyProfileOptions<'at+JWT'>): object;
function verify(jwt: string, key: ConsumeKeyInput, options: VerifyOptions<true> & VerifyProfileOptions<'at+JWT'>): completeResult;
function verify(jwt: string, key: ConsumeKeyInputWithNone | EmbeddedVerifyKeys, options: VerifyOptions<false> & VerifyProfileOptions<'at+JWT'>): object;
function verify(jwt: string, key: ConsumeKeyInput | EmbeddedVerifyKeys, options: VerifyOptions<true> & VerifyProfileOptions<'at+JWT'>): completeResult;
function verify(jwt: string, key: NoneKey, options: VerifyOptions<true> & VerifyProfileOptions<'at+JWT'>): completeResult<NoneKey>;
}
}