-
Notifications
You must be signed in to change notification settings - Fork 236
/
Copy pathutils.js
80 lines (70 loc) · 1.85 KB
/
utils.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
const jose = require('jose');
const JwksError = require('./errors/JwksError');
function resolveAlg(jwk) {
if (jwk.alg) {
return jwk.alg;
}
if (jwk.kty === 'RSA') {
return 'RS256';
}
if (jwk.kty === 'EC') {
switch (jwk.crv) {
case 'P-256':
return 'ES256';
case 'secp256k1':
return 'ES256K';
case 'P-384':
return 'ES384';
case 'P-521':
return 'ES512';
}
}
if (jwk.kty === 'OKP') {
switch (jwk.crv) {
case 'Ed25519':
case 'Ed448':
return 'EdDSA';
}
}
throw new JwksError('Unsupported JWK');
}
async function retrieveSigningKeys(jwks) {
const results = [];
jwks = jwks
.filter(({ use }) => use === 'sig' || use === undefined)
.filter(({ kty }) => kty === 'RSA' || kty === 'EC' || kty === 'OKP');
for (const jwk of jwks) {
try {
const key = await jose.importJWK({ ...jwk, ext: true }, resolveAlg(jwk));
if (key.type !== 'public') {
continue;
}
let getSpki;
switch (key[Symbol.toStringTag]) {
case 'CryptoKey': {
const spki = await jose.exportSPKI(key);
getSpki = () => spki;
break;
}
case 'KeyObject':
// Assume legacy Node.js version without the Symbol.toStringTag backported
// Fall through
default:
getSpki = () => key.export({ format: 'pem', type: 'spki' });
}
results.push({
get publicKey() { return getSpki(); },
get rsaPublicKey() { return getSpki(); },
getPublicKey() { return getSpki(); },
...(typeof jwk.kid === 'string' && jwk.kid ? { kid: jwk.kid } : undefined),
...(typeof jwk.alg === 'string' && jwk.alg ? { alg: jwk.alg } : undefined)
});
} catch (err) {
continue;
}
}
return results;
}
module.exports = {
retrieveSigningKeys
};