diff --git a/src/mechs/ec/crypto.ts b/src/mechs/ec/crypto.ts index 3dc157d..23c8646 100644 --- a/src/mechs/ec/crypto.ts +++ b/src/mechs/ec/crypto.ts @@ -91,7 +91,7 @@ export class EcCrypto { return ok; } - public static async deriveBits(algorithm: EcdhKeyDeriveParams, baseKey: CryptoKey, length: number): Promise { + public static async deriveBits(algorithm: EcdhKeyDeriveParams, baseKey: CryptoKey, length: number | null): Promise { const cryptoAlg = this.getOpenSSLNamedCurve((baseKey.algorithm as EcKeyAlgorithm).namedCurve); const ecdh = crypto.createECDH(cryptoAlg); @@ -102,6 +102,10 @@ export class EcCrypto { const asnPublicKey = AsnParser.parse((algorithm.public as CryptoKey).data, core.asn1.PublicKeyInfo); const bits = ecdh.computeSecret(Buffer.from(asnPublicKey.publicKey)); + if (length === null) { + return bits; + } + return new Uint8Array(bits).buffer.slice(0, length >> 3); } diff --git a/test/crypto.ts b/test/crypto.ts index 1f2106c..c378b55 100644 --- a/test/crypto.ts +++ b/test/crypto.ts @@ -280,4 +280,23 @@ context("Crypto", () => { }); }); + context("ECDH deriveBits with null", () => { + it("P-256", async () => { + const keyPair = await crypto.subtle.generateKey({ name: "ECDH", namedCurve: "P-256" }, false, ["deriveBits"]); + const bits = await crypto.subtle.deriveBits({ name: keyPair.publicKey.algorithm.name, public: keyPair.publicKey } as globalThis.EcdhKeyDeriveParams, keyPair.privateKey, null); + assert.equal(bits.byteLength, 32); + }); + + it("P-384", async () => { + const keyPair = await crypto.subtle.generateKey({ name: "ECDH", namedCurve: "P-384" }, false, ["deriveBits"]); + const bits = await crypto.subtle.deriveBits({ name: keyPair.publicKey.algorithm.name, public: keyPair.publicKey } as globalThis.EcdhKeyDeriveParams, keyPair.privateKey, null); + assert.equal(bits.byteLength, 48); + }); + + it("P-521", async () => { + const keyPair = await crypto.subtle.generateKey({ name: "ECDH", namedCurve: "P-521" }, false, ["deriveBits"]); + const bits = await crypto.subtle.deriveBits({ name: keyPair.publicKey.algorithm.name, public: keyPair.publicKey } as globalThis.EcdhKeyDeriveParams, keyPair.privateKey, null); + assert.equal(bits.byteLength, 66); + }); + }); });