From 78a75171c2e0a7eb42e22bb34f8194e0bb31e163 Mon Sep 17 00:00:00 2001 From: Hazelnoot Date: Mon, 14 Oct 2024 14:40:54 -0400 Subject: [PATCH 1/4] remove cached public keys after deletion --- packages/backend/src/core/activitypub/ApDbResolverService.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/backend/src/core/activitypub/ApDbResolverService.ts b/packages/backend/src/core/activitypub/ApDbResolverService.ts index 2cb558dbff..12e58efdc2 100644 --- a/packages/backend/src/core/activitypub/ApDbResolverService.ts +++ b/packages/backend/src/core/activitypub/ApDbResolverService.ts @@ -176,9 +176,7 @@ export class ApDbResolverService implements OnApplicationShutdown { public async refetchPublicKeyForApId(user: MiRemoteUser): Promise { await this.apPersonService.updatePerson(user.uri); const key = await this.userPublickeysRepository.findOneBy({ userId: user.id }); - if (key != null) { - await this.publicKeyByUserIdCache.set(user.id, key); - } + this.publicKeyByUserIdCache.set(user.id, key); return key; } From 5eb9a263e25b174aba1fb417ff73780f1bc88946 Mon Sep 17 00:00:00 2001 From: Hazelnoot Date: Mon, 14 Oct 2024 14:41:16 -0400 Subject: [PATCH 2/4] fix public key re-fetch logic --- .../queue/processors/InboxProcessorService.ts | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/packages/backend/src/queue/processors/InboxProcessorService.ts b/packages/backend/src/queue/processors/InboxProcessorService.ts index 8b3d2ebb50..8c116f82b9 100644 --- a/packages/backend/src/queue/processors/InboxProcessorService.ts +++ b/packages/backend/src/queue/processors/InboxProcessorService.ts @@ -118,19 +118,15 @@ export class InboxProcessorService implements OnApplicationShutdown { // HTTP-Signatureの検証 let httpSignatureValidated = httpSignature.verifySignature(signature, authUser.key.keyPem); - // また、signatureのsignerは、activity.actorと一致する必要がある - if (!httpSignatureValidated || authUser.user.uri !== activity.actor) { - let renewKeyFailed = true; - - if (!httpSignatureValidated) { - authUser.key = await this.apDbResolverService.refetchPublicKeyForApId(authUser.user); - - if (authUser.key != null) { - httpSignatureValidated = httpSignature.verifySignature(signature, authUser.key.keyPem); - renewKeyFailed = false; - } + if (!httpSignatureValidated) { + authUser.key = await this.apDbResolverService.refetchPublicKeyForApId(authUser.user); + if (authUser.key != null) { + httpSignatureValidated = httpSignature.verifySignature(signature, authUser.key.keyPem); } + } + // また、signatureのsignerは、activity.actorと一致する必要がある + if (!httpSignatureValidated || authUser.user.uri !== getApId(activity.actor)) { // 一致しなくても、でもLD-Signatureがありそうならそっちも見る const ldSignature = activity.signature; if (ldSignature) { From c0a5955e0ace35b300eff4b85157918211c20ccc Mon Sep 17 00:00:00 2001 From: Hazelnoot Date: Mon, 14 Oct 2024 14:45:12 -0400 Subject: [PATCH 3/4] log key rotation --- packages/backend/src/core/activitypub/ApDbResolverService.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/backend/src/core/activitypub/ApDbResolverService.ts b/packages/backend/src/core/activitypub/ApDbResolverService.ts index 12e58efdc2..4209c6b3e3 100644 --- a/packages/backend/src/core/activitypub/ApDbResolverService.ts +++ b/packages/backend/src/core/activitypub/ApDbResolverService.ts @@ -16,6 +16,7 @@ import type { MiLocalUser, MiRemoteUser } from '@/models/User.js'; import { getApId } from './type.js'; import { ApPersonService } from './models/ApPersonService.js'; import type { IObject } from './type.js'; +import { ApLoggerService } from '@/core/activitypub/ApLoggerService.js'; export type UriParseResult = { /** wether the URI was generated by us */ @@ -53,6 +54,7 @@ export class ApDbResolverService implements OnApplicationShutdown { private cacheService: CacheService, private apPersonService: ApPersonService, + private apLoggerService: ApLoggerService, ) { this.publicKeyCache = new MemoryKVCache(1000 * 60 * 60 * 12); // 12h this.publicKeyByUserIdCache = new MemoryKVCache(1000 * 60 * 60 * 12); // 12h @@ -174,6 +176,7 @@ export class ApDbResolverService implements OnApplicationShutdown { */ @bindThis public async refetchPublicKeyForApId(user: MiRemoteUser): Promise { + this.apLoggerService.logger.info('Re-fetching public key for user', { userId: user.id }); await this.apPersonService.updatePerson(user.uri); const key = await this.userPublickeysRepository.findOneBy({ userId: user.id }); this.publicKeyByUserIdCache.set(user.id, key); From 27b502fab57ba86d606b58fc7f7f482f011d3819 Mon Sep 17 00:00:00 2001 From: Hazelnoot Date: Tue, 15 Oct 2024 13:49:51 -0400 Subject: [PATCH 4/4] normalize re-fetch logic between InboxProcessorService and ActivityPubServerService --- .../backend/src/core/activitypub/ApDbResolverService.ts | 9 ++++++++- .../src/queue/processors/InboxProcessorService.ts | 1 + packages/backend/src/server/ActivityPubServerService.ts | 6 +----- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/packages/backend/src/core/activitypub/ApDbResolverService.ts b/packages/backend/src/core/activitypub/ApDbResolverService.ts index 4209c6b3e3..8c97cc8ce8 100644 --- a/packages/backend/src/core/activitypub/ApDbResolverService.ts +++ b/packages/backend/src/core/activitypub/ApDbResolverService.ts @@ -176,10 +176,17 @@ export class ApDbResolverService implements OnApplicationShutdown { */ @bindThis public async refetchPublicKeyForApId(user: MiRemoteUser): Promise { - this.apLoggerService.logger.info('Re-fetching public key for user', { userId: user.id }); + this.apLoggerService.logger.debug('Re-fetching public key for user', { userId: user.id, uri: user.uri }); await this.apPersonService.updatePerson(user.uri); + const key = await this.userPublickeysRepository.findOneBy({ userId: user.id }); this.publicKeyByUserIdCache.set(user.id, key); + + if (key) { + this.apLoggerService.logger.info('Re-fetched public key for user', { userId: user.id, uri: user.uri }); + } else { + this.apLoggerService.logger.warn('Failed to re-fetch key for user', { userId: user.id, uri: user.uri }); + } return key; } diff --git a/packages/backend/src/queue/processors/InboxProcessorService.ts b/packages/backend/src/queue/processors/InboxProcessorService.ts index 8c116f82b9..11b00bb683 100644 --- a/packages/backend/src/queue/processors/InboxProcessorService.ts +++ b/packages/backend/src/queue/processors/InboxProcessorService.ts @@ -118,6 +118,7 @@ export class InboxProcessorService implements OnApplicationShutdown { // HTTP-Signatureの検証 let httpSignatureValidated = httpSignature.verifySignature(signature, authUser.key.keyPem); + // maybe they changed their key? refetch it if (!httpSignatureValidated) { authUser.key = await this.apDbResolverService.refetchPublicKeyForApId(authUser.user); if (authUser.key != null) { diff --git a/packages/backend/src/server/ActivityPubServerService.ts b/packages/backend/src/server/ActivityPubServerService.ts index 8d52cf27e6..52592c47c6 100644 --- a/packages/backend/src/server/ActivityPubServerService.ts +++ b/packages/backend/src/server/ActivityPubServerService.ts @@ -205,15 +205,11 @@ export class ActivityPubServerService { let httpSignatureValidated = httpSignature.verifySignature(signature, authUser.key.keyPem); + // maybe they changed their key? refetch it if (!httpSignatureValidated) { - this.authlogger.info(`${logPrefix} failed to validate signature, re-fetching the key for ${authUser.user.uri}`); - // maybe they changed their key? refetch it authUser.key = await this.apDbResolverService.refetchPublicKeyForApId(authUser.user); - if (authUser.key != null) { httpSignatureValidated = httpSignature.verifySignature(signature, authUser.key.keyPem); - } else { - this.authlogger.warn(`${logPrefix} failed to re-fetch key for ${authUser.user}`); } }