From ad88ee2cd5bcaee3c3e5ec79735c8172ae2725be Mon Sep 17 00:00:00 2001 From: Filip Skokan Date: Mon, 18 Jan 2021 13:23:10 +0100 Subject: [PATCH] perf: use KeyObject.prototype asymmetricKeyDetails when available --- src/runtime/node/check_modulus_length.ts | 7 ++- src/runtime/node/get_named_curve.ts | 61 +++++++++++++++--------- test/jwk/jwk2key.test.mjs | 6 +-- 3 files changed, 47 insertions(+), 27 deletions(-) diff --git a/src/runtime/node/check_modulus_length.ts b/src/runtime/node/check_modulus_length.ts index 95592a2097..a9f92b3341 100644 --- a/src/runtime/node/check_modulus_length.ts +++ b/src/runtime/node/check_modulus_length.ts @@ -48,13 +48,16 @@ const getModulusLength = (key: KeyObject): number => { return weakMap.get(key)! } - const modulusLength = + const modulusLength: number = + // @ts-expect-error + key.asymmetricKeyDetails?.modulusLength ?? (getLengthOfSeqIndex( key.export({ format: 'der', type: 'pkcs1' }), key.type === 'private' ? 1 : 0, ) - 1) << - 3 + 3 + weakMap.set(key, modulusLength) return modulusLength } diff --git a/src/runtime/node/get_named_curve.ts b/src/runtime/node/get_named_curve.ts index c2d4c9d32a..78beffc065 100644 --- a/src/runtime/node/get_named_curve.ts +++ b/src/runtime/node/get_named_curve.ts @@ -8,7 +8,22 @@ const secp256k1 = Buffer.from([43, 129, 4, 0, 10]) export const weakMap: WeakMap = new WeakMap() -const getNamedCurve = (key: KeyObject): string => { +const namedCurveToJOSE = (namedCurve: string) => { + switch (namedCurve) { + case 'prime256v1': + return 'P-256' + case 'secp384r1': + return 'P-384' + case 'secp521r1': + return 'P-521' + case 'secp256k1': + return namedCurve + default: + throw new JOSENotSupported('unsupported curve for this operation') + } +} + +const getNamedCurve = (key: KeyObject, raw?: boolean): string => { if (key.type === 'secret') { throw new TypeError('only "private" or "public" key objects can be used for this operation') } @@ -21,31 +36,33 @@ const getNamedCurve = (key: KeyObject): string => { return `X${key.asymmetricKeyType.substr(1)}` case 'ec': { if (weakMap.has(key)) { - return weakMap.get(key) + return weakMap.get(key)! } - if (key.type === 'private') { - const curve = getNamedCurve(createPublicKey(key)) - weakMap.set(key, curve) - return curve - } + // @ts-expect-error + let namedCurve: string = key.asymmetricKeyDetails?.namedCurve - const buf = key.export({ format: 'der', type: 'spki' }) - const i = buf[1] < 128 ? 14 : 15 - const len = buf[i] - const curveOid = buf.slice(i + 1, i + 1 + len) - let curve: string - if (curveOid.equals(p256)) { - curve = 'P-256' - } else if (curveOid.equals(p384)) { - curve = 'P-384' - } else if (curveOid.equals(p521)) { - curve = 'P-521' - } else if (curveOid.equals(secp256k1)) { - curve = 'secp256k1' - } else { - throw new JOSENotSupported('unsupported curve for this operation') + if (!namedCurve && key.type === 'private') { + namedCurve = getNamedCurve(createPublicKey(key), true) + } else if (!namedCurve) { + const buf = key.export({ format: 'der', type: 'spki' }) + const i = buf[1] < 128 ? 14 : 15 + const len = buf[i] + const curveOid = buf.slice(i + 1, i + 1 + len) + if (curveOid.equals(p256)) { + namedCurve = 'prime256v1' + } else if (curveOid.equals(p384)) { + namedCurve = 'secp384r1' + } else if (curveOid.equals(p521)) { + namedCurve = 'secp521r1' + } else if (curveOid.equals(secp256k1)) { + namedCurve = 'secp256k1' + } } + + if (raw) return namedCurve + + const curve = namedCurveToJOSE(namedCurve) weakMap.set(key, curve) return curve } diff --git a/test/jwk/jwk2key.test.mjs b/test/jwk/jwk2key.test.mjs index 2608fe3bda..a9cddf58d5 100644 --- a/test/jwk/jwk2key.test.mjs +++ b/test/jwk/jwk2key.test.mjs @@ -72,8 +72,8 @@ Promise.all([import(`${root}/jwk/parse`), import(`${root}/jwk/from_key_like`)]). }; t.deepEqual( - await parseJwk(oct, 'HS256'), - Uint8Array.from([ + [...(await parseJwk(oct, 'HS256'))], + [ 23, 32, 170, @@ -106,7 +106,7 @@ Promise.all([import(`${root}/jwk/parse`), import(`${root}/jwk/from_key_like`)]). 17, 146, 114, - ]), + ], ); });