diff --git a/packages/signature/src/lib/typeguards.ts b/packages/signature/src/lib/typeguards.ts index 08edfb972..fe344902e 100644 --- a/packages/signature/src/lib/typeguards.ts +++ b/packages/signature/src/lib/typeguards.ts @@ -5,19 +5,6 @@ function isAlg(alg: unknown): alg is SigningAlg { return typeof alg === 'string' && Object.values(SigningAlg).includes(alg as SigningAlg) } -export function isJwk(jwk: unknown): jwk is JWK { - return ( - typeof jwk === 'object' && - jwk !== null && - 'kty' in jwk && - 'kid' in jwk && - 'alg' in jwk && - isStringNonNull(jwk.kty) && - isStringNonNull(jwk.kid) && - isAlg(jwk.alg) - ) -} - function isStringNonNull(kid: unknown): kid is string { return typeof kid === 'string' && kid.length > 0 } diff --git a/packages/signature/src/lib/types.ts b/packages/signature/src/lib/types.ts index 6c6fc79a7..50c440c9f 100644 --- a/packages/signature/src/lib/types.ts +++ b/packages/signature/src/lib/types.ts @@ -6,6 +6,7 @@ import { p256PublicKeySchema, privateKeySchema, publicKeySchema, + rsaPrivateKeySchema, secp256k1KeySchema, secp256k1PrivateKeySchema, secp256k1PublicKeySchema diff --git a/packages/signature/src/lib/utils.ts b/packages/signature/src/lib/utils.ts index d6828a5c0..9ab6be8fc 100644 --- a/packages/signature/src/lib/utils.ts +++ b/packages/signature/src/lib/utils.ts @@ -17,7 +17,8 @@ import { RsaPrivateKey, Secp256k1KeySchema, Secp256k1PrivateKey, - Secp256k1PublicKey + Secp256k1PublicKey, + Use } from './types' import { validate } from './validate' @@ -143,16 +144,10 @@ export const base64UrlToBytes = (base64Url: string): Buffer => { } const rsaKeyToKid = (jwk: Jwk) => { - // Concatenate the 'n' and 'e' values - const dataToHash = `${jwk.n}${jwk.e}` + // Concatenate the 'n' and 'e' values, splitted by ':' + const dataToHash = `${jwk.n}:${jwk.e}` - // Convert base64url to regular base64 - const base64 = dataToHash.replace(/-/g, '+').replace(/_/g, '/') - - // Convert base64 to binary data - const binaryData = Buffer.from(base64, 'base64') - - // Compute SHA-256 hash of the binary data + const binaryData = base64UrlToBytes(dataToHash) const hash = sha256Hash(binaryData) return toHex(hash) } @@ -160,11 +155,12 @@ const rsaKeyToKid = (jwk: Jwk) => { const generateRsaKeyPair = async ( opts: { keyId?: string - modulusLength?: number + modulusLength?: number, + use?: Use, } = { modulusLength: 2048 } -) => { +): Promise => { const { privateKey } = await generateKeyPair(Alg.RS256, { modulusLength: opts.modulusLength, extractable: true @@ -174,23 +170,25 @@ const generateRsaKeyPair = async ( if (!partialJwk.n) { throw new JwtError({ message: 'Invalid JWK; missing n', context: { partialJwk } }) } - const jwk = { + const jwk: Jwk = { ...partialJwk, alg: Alg.RS256, - kid: opts.keyId || rsaKeyToKid(partialJwk), - kty: KeyTypes.RSA + kty: KeyTypes.RSA, + crv: undefined, + use: opts.use || undefined, } - if (!isJwk(jwk)) { - throw new JwtError({ message: 'Invalid JWK', context: { jwk } }) - } - return jwk + jwk.kid = opts.keyId || rsaKeyToKid(jwk); + + const pk = validate(rsaPrivateKeySchema, jwk, 'Invalid RSA Private Key JWK') + return pk } export const generateJwk = async ( alg: Alg, opts?: { keyId?: string - modulusLength?: number + modulusLength?: number, + use?: Use, } ): Promise => { switch (alg) {