/** * Get canonical representation of an ES256 public key JWK * * @param jwk - The JWK to parse (stringified JSON or JSON object) * @returns The canonical JWK */ export function getCanonicalJwk(jwk: unknown) { let jwkObject: unknown; if (typeof jwk === "string") { try { jwkObject = JSON.parse(jwk.trim()); } catch { throw new Error("The JWK can't be parsed"); } } else { jwkObject = jwk; } if (typeof jwkObject !== "object" || !jwkObject) { throw new TypeError("The JWK is not an object"); } if ("alg" in jwkObject && jwkObject.alg !== "ES256") { throw new Error(`Unsupported JWK, alg must be ES256`); } if (!("kty" in jwkObject) || jwkObject.kty !== "EC") { throw new Error(`Unsupported JWK, kty must be EC`); } if (!("crv" in jwkObject) || jwkObject.crv !== "P-256") { throw new Error(`Unsupported JWK, crv must be P-256`); } if (!("x" in jwkObject) || typeof jwkObject.x !== "string") { throw new Error(`Unsupported JWK, missing x`); } if (!("y" in jwkObject) || typeof jwkObject.y !== "string") { throw new Error(`Unsupported JWK, missing y`); } if ("use" in jwkObject && jwkObject.use !== "sig") { throw new Error(`Unsupported JWK, use must be sig`); } return { crv: jwkObject.crv, kty: jwkObject.kty, x: jwkObject.x, y: jwkObject.y, } as const; }