From b916ea42b49e6300dd68cefc397c243e0f2083c5 Mon Sep 17 00:00:00 2001 From: Javad Khalilian Date: Fri, 24 May 2024 13:58:08 +0200 Subject: [PATCH] improve(hd-wallet): verify that the derivation path template includes (#2168) --- .changeset/pretty-crabs-jog.md | 5 +++++ .../src/SLIP10/kadenaGenKeypairFromSeed.ts | 8 ++++++++ .../hd-wallet/src/SLIP10/kadenaGetPublic.ts | 5 +++++ .../libs/hd-wallet/src/SLIP10/kadenaSign.ts | 4 ++++ .../utils/isDerivationPathTemplateValid.ts | 8 ++++++++ .../tests/isDerivationPathTemplateValid.test.ts | 17 +++++++++++++++++ 6 files changed, 47 insertions(+) create mode 100644 .changeset/pretty-crabs-jog.md create mode 100644 packages/libs/hd-wallet/src/SLIP10/utils/isDerivationPathTemplateValid.ts create mode 100644 packages/libs/hd-wallet/src/SLIP10/utils/tests/isDerivationPathTemplateValid.test.ts diff --git a/.changeset/pretty-crabs-jog.md b/.changeset/pretty-crabs-jog.md new file mode 100644 index 0000000000..759cd631cf --- /dev/null +++ b/.changeset/pretty-crabs-jog.md @@ -0,0 +1,5 @@ +--- +"@kadena/hd-wallet": patch +--- + +Verify that the derivation path template includes `` diff --git a/packages/libs/hd-wallet/src/SLIP10/kadenaGenKeypairFromSeed.ts b/packages/libs/hd-wallet/src/SLIP10/kadenaGenKeypairFromSeed.ts index 1d3e3b626c..1530b59672 100644 --- a/packages/libs/hd-wallet/src/SLIP10/kadenaGenKeypairFromSeed.ts +++ b/packages/libs/hd-wallet/src/SLIP10/kadenaGenKeypairFromSeed.ts @@ -1,6 +1,7 @@ import type { BinaryLike } from '../utils/crypto.js'; import type { EncryptedString } from '../utils/kadenaEncryption.js'; import { kadenaDecrypt, kadenaEncrypt } from '../utils/kadenaEncryption.js'; +import { isDerivationPathTemplateValid } from './utils/isDerivationPathTemplateValid.js'; import { deriveKeyPair } from './utils/sign.js'; async function genKeypairFromSeed( @@ -9,6 +10,9 @@ async function genKeypairFromSeed( index: number, derivationPathTemplate: string, ): Promise<[string, EncryptedString]> { + if (!isDerivationPathTemplateValid(derivationPathTemplate)) { + throw new Error('Invalid derivation path template.'); + } const derivationPath = derivationPathTemplate.replace( '', index.toString(), @@ -66,6 +70,10 @@ export async function kadenaGenKeypairFromSeed( throw new Error('NO_SEED: No seed provided.'); } + if (!isDerivationPathTemplateValid(derivationPathTemplate)) { + throw new Error('Invalid derivation path template.'); + } + const seedBuffer = await kadenaDecrypt(password, seed); if (typeof indexOrRange === 'number') { diff --git a/packages/libs/hd-wallet/src/SLIP10/kadenaGetPublic.ts b/packages/libs/hd-wallet/src/SLIP10/kadenaGetPublic.ts index cc5b0ba4bf..390ee10c0b 100644 --- a/packages/libs/hd-wallet/src/SLIP10/kadenaGetPublic.ts +++ b/packages/libs/hd-wallet/src/SLIP10/kadenaGetPublic.ts @@ -1,5 +1,6 @@ import type { BinaryLike } from '../utils/crypto.js'; import { kadenaDecrypt } from '../utils/kadenaEncryption.js'; +import { isDerivationPathTemplateValid } from './utils/isDerivationPathTemplateValid.js'; import { deriveKeyPair } from './utils/sign.js'; function genPublicKeyFromSeed( @@ -7,6 +8,10 @@ function genPublicKeyFromSeed( index: number, derivationPathTemplate: string, ): string { + if (!isDerivationPathTemplateValid(derivationPathTemplate)) { + throw new Error('Invalid derivation path template.'); + } + const derivationPath = derivationPathTemplate.replace( '', index.toString(), diff --git a/packages/libs/hd-wallet/src/SLIP10/kadenaSign.ts b/packages/libs/hd-wallet/src/SLIP10/kadenaSign.ts index 22466fffb8..018e5251ec 100644 --- a/packages/libs/hd-wallet/src/SLIP10/kadenaSign.ts +++ b/packages/libs/hd-wallet/src/SLIP10/kadenaSign.ts @@ -2,6 +2,7 @@ import { verifySig } from '@kadena/cryptography-utils'; import type { BinaryLike } from '../utils/crypto.js'; import type { EncryptedString } from '../utils/kadenaEncryption.js'; import { kadenaDecrypt } from '../utils/kadenaEncryption.js'; +import { isDerivationPathTemplateValid } from './utils/isDerivationPathTemplateValid.js'; import type { ISignatureWithPublicKey } from './utils/sign.js'; import { signWithKeyPair, signWithSeed } from './utils/sign.js'; @@ -63,6 +64,9 @@ export function kadenaSignWithSeed( decryptedSeed.catch(() => { console.error('Could not decrypt private key'); }); + if (!isDerivationPathTemplateValid(derivationPathTemplate)) { + throw new Error('Invalid derivation path template.'); + } if (typeof index === 'number') { return async (hash: string) => signWithSeed( diff --git a/packages/libs/hd-wallet/src/SLIP10/utils/isDerivationPathTemplateValid.ts b/packages/libs/hd-wallet/src/SLIP10/utils/isDerivationPathTemplateValid.ts new file mode 100644 index 0000000000..629413fc0f --- /dev/null +++ b/packages/libs/hd-wallet/src/SLIP10/utils/isDerivationPathTemplateValid.ts @@ -0,0 +1,8 @@ +export function isDerivationPathTemplateValid( + derivationPathTemplate: string, +): boolean { + return ( + typeof derivationPathTemplate === 'string' && + derivationPathTemplate.includes('') + ); +} diff --git a/packages/libs/hd-wallet/src/SLIP10/utils/tests/isDerivationPathTemplateValid.test.ts b/packages/libs/hd-wallet/src/SLIP10/utils/tests/isDerivationPathTemplateValid.test.ts new file mode 100644 index 0000000000..66c8c77bef --- /dev/null +++ b/packages/libs/hd-wallet/src/SLIP10/utils/tests/isDerivationPathTemplateValid.test.ts @@ -0,0 +1,17 @@ +import { describe, expect, it } from 'vitest'; +import { isDerivationPathTemplateValid } from '../isDerivationPathTemplateValid.js'; + +describe('isDerivationPathTemplateValid', () => { + it("should return true if derivationPathTemplate is a string and includes ''", () => { + expect(isDerivationPathTemplateValid("m'/44'/626'/'")).toBe(true); + }); + it('should return false if derivationPathTemplate is not a string', () => { + expect(isDerivationPathTemplateValid(123 as unknown as string)).toBe(false); + }); + it("should return false if derivationPathTemplate does not include ''", () => { + expect(isDerivationPathTemplateValid("m'/44'/626'/index'")).toBe(false); + }); + it('returns false if derivationPathTemplate is an empty string', () => { + expect(isDerivationPathTemplateValid('')).toBe(false); + }); +});