mirror of
https://github.com/hanzoai/openid-client.git
synced 2026-09-24 17:01:10 +00:00
This attempts to work around: - missing Node.js APIs in Bun - Bun's bugs in url.parse(..., true) - Bun loading `jose`'s bun target instead of the require one It is not possible to run openid-client's test suite due to other Bun Node.js compatibility bugs which is why this is "experimental" Refs #622 Refs #623
98 lines
2.6 KiB
JavaScript
98 lines
2.6 KiB
JavaScript
const jose = require('jose');
|
|
const crypto = require('crypto');
|
|
const base64url = require('../lib/helpers/base64url');
|
|
|
|
module.exports = class KeyStore {
|
|
constructor({ keys } = {}) {
|
|
this.keys = keys || [];
|
|
}
|
|
|
|
async generate(kty, crvOrSize, { alg, kid, use } = {}) {
|
|
let kp;
|
|
if (kty !== 'oct' && alg) {
|
|
kp = await jose.generateKeyPair(alg);
|
|
} else {
|
|
switch (kty) {
|
|
case 'EC': {
|
|
switch (crvOrSize) {
|
|
case undefined:
|
|
case 'P-256':
|
|
kp = await jose.generateKeyPair('ES256', { extractable: true });
|
|
break;
|
|
case 'P-384':
|
|
kp = await jose.generateKeyPair('ES384', { extractable: true });
|
|
break;
|
|
case 'P-521':
|
|
kp = await jose.generateKeyPair('ES512', { extractable: true });
|
|
break;
|
|
case 'secp256k1':
|
|
kp = await jose.generateKeyPair('ES256K', { extractable: true });
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 'oct': {
|
|
const secret = crypto.randomBytes((crvOrSize || 256) >> 3);
|
|
const jwk = {
|
|
kty: 'oct',
|
|
use: use,
|
|
alg,
|
|
k: base64url.encode(secret),
|
|
};
|
|
jwk.kid = kid || (await jose.calculateJwkThumbprint(jwk));
|
|
this.keys.push(jwk);
|
|
return;
|
|
}
|
|
case 'RSA': {
|
|
kp = await jose.generateKeyPair('RS256', { modulusLength: crvOrSize, extractable: true });
|
|
break;
|
|
}
|
|
case 'OKP': {
|
|
switch (crvOrSize) {
|
|
case undefined:
|
|
case 'Ed25519':
|
|
case 'Ed448':
|
|
kp = await jose.generateKeyPair('EdDSA', { crv: crvOrSize, extractable: true });
|
|
break;
|
|
case 'X25519':
|
|
case 'X448':
|
|
kp = await jose.generateKeyPair('ECDH-ES', { crv: crvOrSize, extractable: true });
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
const jwk = {
|
|
...(await jose.exportJWK(kp.privateKey)),
|
|
kid,
|
|
};
|
|
jwk.kid || (jwk.kid = await jose.calculateJwkThumbprint(jwk));
|
|
if (use) jwk.use = use;
|
|
this.keys.push(jwk);
|
|
}
|
|
|
|
get(query) {
|
|
if (!query) {
|
|
return this.keys[0];
|
|
}
|
|
const { kty } = query || {};
|
|
return this.keys.find((jwk) => {
|
|
return jwk.kty === kty;
|
|
});
|
|
}
|
|
|
|
toJWKS(includePrivate) {
|
|
if (includePrivate) {
|
|
return { keys: this.keys };
|
|
}
|
|
|
|
return {
|
|
keys: this.keys.map((privateKey) => {
|
|
const { k, d, dp, dq, p, q, qi, ...jwk } = privateKey;
|
|
return jwk;
|
|
}),
|
|
};
|
|
}
|
|
};
|