@gaonengwww/jose
Version:
JWA, JWS, JWE, JWT, JWK, JWKS for Node.js, Browser, Cloudflare Workers, Deno, Bun, and other Web-interoperable runtimes
127 lines (125 loc) • 3.56 kB
JavaScript
// src/util/errors.ts
var JOSEError = class extends Error {
/**
* A unique error code for the particular error subclass.
*
* @ignore
*/
static code = "ERR_JOSE_GENERIC";
/** A unique error code for {@link JOSEError}. */
code = "ERR_JOSE_GENERIC";
/** @ignore */
constructor(message, options) {
super(message, options);
this.name = this.constructor.name;
Error.captureStackTrace?.(this, this.constructor);
}
};
var JOSENotSupported = class extends JOSEError {
/** @ignore */
static code = "ERR_JOSE_NOT_SUPPORTED";
/** A unique error code for {@link JOSENotSupported}. */
code = "ERR_JOSE_NOT_SUPPORTED";
};
// src/key/generate_key_pair.ts
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;
}
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([1, 0, 1]),
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([1, 0, 1]),
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([1, 0, 1]),
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":
// Fall through
case "EdDSA": {
keyUsages = ["sign", "verify"];
algorithm = { name: "Ed25519" };
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
);
}
export {
generateKeyPair
};