From a7ecc464d5adb9e25332fec15e9f6e3df79097a6 Mon Sep 17 00:00:00 2001 From: ieow Date: Tue, 11 Mar 2025 17:54:11 +0800 Subject: [PATCH] fix: add stringified value check serialize metadata.tss --- packages/core/src/metadata.ts | 2 +- packages/core/src/tssMetadata.ts | 65 ++++++++++++++++++----- packages/core/test/metadataFormat.test.js | 9 ++-- 3 files changed, 58 insertions(+), 18 deletions(-) diff --git a/packages/core/src/metadata.ts b/packages/core/src/metadata.ts index 1ffe09ef..40af9baf 100644 --- a/packages/core/src/metadata.ts +++ b/packages/core/src/metadata.ts @@ -354,7 +354,7 @@ export class Metadata implements IMetadata { version: METADATA_VERSION, }; - return Object.keys(this.tss ?? {}).length > 0 ? { ...jsonObject, tss: this.tss } : jsonObject; + return Object.keys(this.tss ?? {}).length > 0 ? { ...jsonObject, tss: JSON.parse(JSON.stringify(this.tss)) } : jsonObject; } /** diff --git a/packages/core/src/tssMetadata.ts b/packages/core/src/tssMetadata.ts index 31fc70f5..65b427d4 100644 --- a/packages/core/src/tssMetadata.ts +++ b/packages/core/src/tssMetadata.ts @@ -1,4 +1,29 @@ -import { FactorEnc, ISerializable, ITssMetadata, KeyType, Point, StringifiedType } from "@tkey/common-types"; +import { EncryptedMessage, FactorEnc, FactorEncType, ISerializable, ITssMetadata, KeyType, Point, StringifiedType } from "@tkey/common-types"; + +export const FromJsonEncryptedMessage = (value: StringifiedType): EncryptedMessage => { + const { ciphertext, ephemPublicKey, iv, mac } = value; + if (typeof ciphertext !== "string") throw new Error("ciphertext is not a string"); + if (typeof ephemPublicKey !== "string") throw new Error("ephemPublicKey is not a string"); + if (typeof iv !== "string") throw new Error("iv is not a string"); + if (typeof mac !== "string") throw new Error("mac is not a string"); + + return { + ciphertext, + ephemPublicKey, + iv, + mac, + }; +}; + +export const FromJsonFactorEnc = (value: StringifiedType): FactorEnc => { + const { tssIndex, type, userEnc, serverEncs } = value; + if (typeof tssIndex !== "number") throw new Error("tssIndex is not a number"); + if (typeof type !== "string") throw new Error("type is not a string"); + if (typeof userEnc !== "object") throw new Error("userEnc is not a string"); + if (!Array.isArray(serverEncs)) throw new Error("serverEncs is not an array"); + + return { type: type as FactorEncType, tssIndex, userEnc: FromJsonEncryptedMessage(userEnc), serverEncs: serverEncs.map(FromJsonEncryptedMessage) }; +}; export class TssMetadata implements ITssMetadata, ISerializable { tssTag: string; @@ -27,24 +52,36 @@ export class TssMetadata implements ITssMetadata, ISerializable { static fromJSON(value: StringifiedType): TssMetadata { const { tssTag, tssKeyType, tssPolyCommits, tssNonce, factorPubs, factorEncs } = value; + if (typeof tssTag !== "string") throw new Error("tssTag is not a string"); + if (typeof tssNonce !== "number") throw new Error("tssNonce is not a number"); + if (typeof factorEncs !== "object") throw new Error("factorEncs is not an object"); + + if (!(tssKeyType in KeyType)) { + throw new Error("tssKeyType is not a valid KeyType"); + } + + if (!Array.isArray(tssPolyCommits)) { + throw new Error("tssPolyCommits is not an array"); + } + + if (!Array.isArray(factorPubs)) { + throw new Error("factorPubs is not an array"); + } + + for (const key in factorEncs) { + const factorEnc = factorEncs[key]; + factorEncs[key] = FromJsonFactorEnc(factorEnc); + } + const tssMetadata = new TssMetadata({ tssTag, tssKeyType, tssNonce, - tssPolyCommits, + tssPolyCommits: (tssPolyCommits as Point[]).map((obj) => Point.fromJSON(obj)), + factorPubs: (factorPubs as Point[]).map((obj) => Point.fromJSON(obj)), factorEncs, - factorPubs, }); - if (tssPolyCommits) { - tssMetadata.tssPolyCommits = (tssPolyCommits as Point[]).map((obj) => new Point(obj.x, obj.y)); - } - if (factorPubs) { - tssMetadata.factorPubs = (factorPubs as Point[]).map((obj) => new Point(obj.x, obj.y)); - } - - if (factorEncs) tssMetadata.factorEncs = factorEncs; - return tssMetadata; } @@ -53,8 +90,8 @@ export class TssMetadata implements ITssMetadata, ISerializable { tssTag: this.tssTag, tssKeyType: this.tssKeyType, tssNonce: this.tssNonce, - tssPolyCommits: this.tssPolyCommits, - factorPubs: this.factorPubs, + tssPolyCommits: this.tssPolyCommits.map((pub) => pub.toJSON()), + factorPubs: this.factorPubs.map((pub) => pub.toJSON()), factorEncs: this.factorEncs, }; } diff --git a/packages/core/test/metadataFormat.test.js b/packages/core/test/metadataFormat.test.js index 101554be..336a9bfc 100644 --- a/packages/core/test/metadataFormat.test.js +++ b/packages/core/test/metadataFormat.test.js @@ -45,12 +45,14 @@ describe("Metadata new Formatting tests", function () { it("#should able to deserialize legacy JSON", async function () { const legacyInstance = LegacyMetadata.fromJSON(JSON.parse(legacyJSONEd25519)); const legacyInstanceSerialized = legacyInstance.toJSON(); - equal(JSON.stringify(legacyInstanceSerialized), legacyJSONEd25519); + deepEqual(legacyInstanceSerialized, JSON.parse(legacyJSONEd25519)); + // equal(JSON.stringify(legacyInstanceSerialized), JSON.stringify(JSON.parse(legacyJSONEd25519))); const legacyInstance1 = LegacyMetadata.fromJSON(JSON.parse(legacyJSONSecp256k1)); const legacyInstanceSerialized1 = legacyInstance1.toJSON(); - equal(JSON.stringify(legacyInstanceSerialized1), legacyJSONSecp256k1); + deepEqual(legacyInstanceSerialized1, JSON.parse(legacyJSONSecp256k1)); + // equal(JSON.stringify(legacyInstanceSerialized1), legacyJSONSecp256k1); const instance1 = Metadata.fromJSON(JSON.parse(legacyJSONSecp256k1)); @@ -67,7 +69,8 @@ describe("Metadata new Formatting tests", function () { it("#should able to deserialize new JSON format with multicurve", async function () { const instance = Metadata.fromJSON(JSON.parse(multiCurveJson)); const instanceSerialized = instance.toJSON(); - equal(JSON.stringify(instanceSerialized), multiCurveJson); + deepEqual(instanceSerialized, JSON.parse(multiCurveJson)); + // equal(JSON.stringify(instanceSerialized), multiCurveJson); }); // to add: add tests for different and multple tags and keytypes\ it("#should able to deserialize new JSON format with backwardcompability test", async function () {