|
1 | 1 | const jose = require('jose'); |
| 2 | +const crypto = require('crypto'); |
2 | 3 |
|
3 | | -function retrieveSigningKeys(keys) { |
4 | | - const keystore = jose.JWKS.asKeyStore({ keys }, { ignoreErrors: true }); |
| 4 | +async function retrieveSigningKeys(jwks) { |
| 5 | + const results = []; |
5 | 6 |
|
6 | | - return keystore.all({ use: 'sig' }).map((key) => { |
7 | | - return { |
8 | | - kid: key.kid, |
9 | | - alg: key.alg, |
10 | | - get publicKey() { return key.toPEM(false); }, |
11 | | - get rsaPublicKey() { return key.toPEM(false); }, |
12 | | - getPublicKey() { return key.toPEM(false); } |
13 | | - }; |
14 | | - }); |
| 7 | + jwks = jwks |
| 8 | + .filter(({ use }) => use === 'sig' || use === undefined) |
| 9 | + .filter(({ kty }) => kty === 'RSA' || kty === 'EC' || kty === 'OKP'); |
| 10 | + |
| 11 | + for (const jwk of jwks) { |
| 12 | + try { |
| 13 | + // The algorithm is actually not used in the Node.js KeyObject-based runtime |
| 14 | + // passing an arbitrary value here and checking that KeyObject was returned |
| 15 | + // later |
| 16 | + const keyObject = await jose.importJWK(jwk, 'RS256'); |
| 17 | + if (!(keyObject instanceof crypto.KeyObject) || keyObject.type !== 'public') { |
| 18 | + continue; |
| 19 | + } |
| 20 | + const getSpki = () => keyObject.export({ format: 'pem', type: 'spki' }); |
| 21 | + results.push({ |
| 22 | + get publicKey() { return getSpki(); }, |
| 23 | + get rsaPublicKey() { return getSpki(); }, |
| 24 | + getPublicKey() { return getSpki(); }, |
| 25 | + ...(typeof jwk.kid === 'string' && jwk.kid ? { kid: jwk.kid } : undefined), |
| 26 | + ...(typeof jwk.alg === 'string' && jwk.alg ? { alg: jwk.alg } : undefined) |
| 27 | + }); |
| 28 | + } catch (err) { |
| 29 | + continue; |
| 30 | + } |
| 31 | + } |
| 32 | + |
| 33 | + return results; |
15 | 34 | } |
16 | 35 |
|
17 | 36 | module.exports = { |
|
0 commit comments