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.
This commit is contained in:
Shibo Lyu 2025-04-12 22:12:21 +08:00
parent 549162d223
commit dc5e51602c
2 changed files with 21 additions and 5 deletions

View file

@ -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<BlahProfile> =
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,

View file

@ -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<BlahIdentity> {
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);
}