UNPKG

jose

Version:

JWA, JWS, JWE, JWT, JWK, JWKS for Node.js, Browser, Cloudflare Workers, Deno, Bun, and other Web-interoperable runtimes

98 lines (97 loc) 3.54 kB
import { JOSENotSupported } from '../util/errors.js'; function getModulusLengthOption(options) { const modulusLength = options?.modulusLength ?? 2048; if (typeof modulusLength !== 'number' || modulusLength < 2048) { throw new JOSENotSupported('Invalid or unsupported modulusLength option provided, 2048 bits or larger keys must be used'); } return modulusLength; } export async function generateKeyPair(alg, options) { let algorithm; let keyUsages; switch (alg) { case 'PS256': case 'PS384': case 'PS512': algorithm = { name: 'RSA-PSS', hash: `SHA-${alg.slice(-3)}`, publicExponent: new Uint8Array([0x01, 0x00, 0x01]), modulusLength: getModulusLengthOption(options), }; keyUsages = ['sign', 'verify']; break; case 'RS256': case 'RS384': case 'RS512': algorithm = { name: 'RSASSA-PKCS1-v1_5', hash: `SHA-${alg.slice(-3)}`, publicExponent: new Uint8Array([0x01, 0x00, 0x01]), modulusLength: getModulusLengthOption(options), }; keyUsages = ['sign', 'verify']; break; case 'RSA-OAEP': case 'RSA-OAEP-256': case 'RSA-OAEP-384': case 'RSA-OAEP-512': algorithm = { name: 'RSA-OAEP', hash: `SHA-${parseInt(alg.slice(-3), 10) || 1}`, publicExponent: new Uint8Array([0x01, 0x00, 0x01]), modulusLength: getModulusLengthOption(options), }; keyUsages = ['decrypt', 'unwrapKey', 'encrypt', 'wrapKey']; break; case 'ES256': algorithm = { name: 'ECDSA', namedCurve: 'P-256' }; keyUsages = ['sign', 'verify']; break; case 'ES384': algorithm = { name: 'ECDSA', namedCurve: 'P-384' }; keyUsages = ['sign', 'verify']; break; case 'ES512': algorithm = { name: 'ECDSA', namedCurve: 'P-521' }; keyUsages = ['sign', 'verify']; break; case 'Ed25519': case 'EdDSA': { keyUsages = ['sign', 'verify']; algorithm = { name: 'Ed25519' }; break; } case 'ML-DSA-44': case 'ML-DSA-65': case 'ML-DSA-87': { keyUsages = ['sign', 'verify']; algorithm = { name: alg }; break; } case 'ECDH-ES': case 'ECDH-ES+A128KW': case 'ECDH-ES+A192KW': case 'ECDH-ES+A256KW': { keyUsages = ['deriveBits']; const crv = options?.crv ?? 'P-256'; switch (crv) { case 'P-256': case 'P-384': case 'P-521': { algorithm = { name: 'ECDH', namedCurve: crv }; break; } case 'X25519': algorithm = { name: 'X25519' }; break; default: throw new JOSENotSupported('Invalid or unsupported crv option provided, supported values are P-256, P-384, P-521, and X25519'); } break; } default: throw new JOSENotSupported('Invalid or unsupported JWK "alg" (Algorithm) Parameter value'); } return crypto.subtle.generateKey(algorithm, options?.extractable ?? false, keyUsages); }