From dc5e51602cbf548af0051abfa01223b877f8e983 Mon Sep 17 00:00:00 2001 From: Shibo Lyu Date: Sat, 12 Apr 2025 22:12:21 +0800 Subject: [PATCH] fix: Verify profile signatures use correct identity key Add validation to check that profile's signee ID matches identity key. Includes new test to ensure profiles signed with incorrect keys are rejected properly. --- identity/identity.test.ts | 18 +++++++++++++++++- identity/identity.ts | 8 ++++---- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/identity/identity.test.ts b/identity/identity.test.ts index dce5cbd..637cc50 100644 --- a/identity/identity.test.ts +++ b/identity/identity.test.ts @@ -1,5 +1,5 @@ import { expect } from "@std/expect"; -import { BlahKeyPair } from "../crypto/mod.ts"; +import { BlahKeyPair, type BlahSignedPayload } from "../crypto/mod.ts"; import { BlahIdentity } from "./identity.ts"; import type { BlahIdentityDescription, BlahProfile } from "./mod.ts"; @@ -48,6 +48,9 @@ Deno.test("created identity profile signed correctly", async () => { Deno.test("parse identity description", async () => { identityFromFile = await BlahIdentity.fromIdentityDescription(identityDesc); + expect(identityFromFile.idPublicKey.id).toBe(idKeyPair.id); + expect(identityFromFile.actKeys[0].publicKey.id).toBe(actKeyPair.id); + expect(identityFromFile.profileSigValid).toBe(true); }); Deno.test("identity description profile sigs are properly verfied", async () => { @@ -62,6 +65,19 @@ Deno.test("identity description profile sigs are properly verfied", async () => expect(identityWithProfileInvalidProfileSig.profileSigValid).toBe(false); }); +Deno.test("identity description profile must be signed with correct id_key", async () => { + const rawProfile: BlahProfile = identityDesc.profile.signee.payload; + const profileSignedWithActKeyAsIdKey: BlahSignedPayload = + await actKeyPair.signPayload(rawProfile); + const identityDescWithWrongIdKey: BlahIdentityDescription = { + ...identityDesc, + profile: profileSignedWithActKeyAsIdKey, + }; + const identityWithWrongIdKey = await BlahIdentity + .fromIdentityDescription(identityDescWithWrongIdKey); + expect(identityWithWrongIdKey.profileSigValid).toBe(false); +}); + Deno.test("identity description act key sigs are properly verfied", async () => { const identityDescWithActKeyInvalidActKeySig: BlahIdentityDescription = { ...identityDesc, diff --git a/identity/identity.ts b/identity/identity.ts index afd2562..f3a873d 100644 --- a/identity/identity.ts +++ b/identity/identity.ts @@ -81,7 +81,7 @@ export class BlahIdentity { ); let profileSigValid = false; - if (profileSigningKey) { + if (profileSigningKey && rawProfile.signee.id_key === idKey.id) { try { await profileSigningKey.verifyPayload(rawProfile); profileSigValid = true; @@ -95,18 +95,18 @@ export class BlahIdentity { static async create( idKeyPair: BlahKeyPair, - firstActKey: BlahKeyPair, + firstActKeyPair: BlahKeyPair, profile: BlahProfile, firstActKeyConfig?: ActKeyUpdate, ): Promise { const actKey = await BlahActKey.create( - firstActKey, + firstActKeyPair, idKeyPair, firstActKeyConfig, ); const parsedProfile = blahProfileSchema.parse(profile); - const profileRecord = await firstActKey.signPayload(parsedProfile); + const profileRecord = await actKey.signPayload(parsedProfile); return new BlahIdentity(idKeyPair, [actKey], profileRecord, true); }