upd: refetch user keys on signature failure

Reference: https://github.com/misskey-dev/misskey/pull/12051
This commit is contained in:
Mar0xy 2023-10-20 12:50:56 +02:00
parent 4dda43d276
commit 71b7c31958
No known key found for this signature in database
GPG key ID: 56569BBE47D2C828
2 changed files with 28 additions and 3 deletions

View file

@ -12,7 +12,7 @@ import type { MiUserPublickey } from '@/models/UserPublickey.js';
import { CacheService } from '@/core/CacheService.js'; import { CacheService } from '@/core/CacheService.js';
import type { MiNote } from '@/models/Note.js'; import type { MiNote } from '@/models/Note.js';
import { bindThis } from '@/decorators.js'; import { bindThis } from '@/decorators.js';
import { MiLocalUser, MiRemoteUser } from '@/models/User.js'; import type { MiLocalUser, MiRemoteUser } from '@/models/User.js';
import { getApId } from './type.js'; import { getApId } from './type.js';
import { ApPersonService } from './models/ApPersonService.js'; import { ApPersonService } from './models/ApPersonService.js';
import type { IObject } from './type.js'; import type { IObject } from './type.js';
@ -164,6 +164,19 @@ export class ApDbResolverService implements OnApplicationShutdown {
}; };
} }
/**
* Sharkey User -> Refetched Key
*/
@bindThis
public async refetchPublicKeyForApId(user: MiRemoteUser): Promise<MiUserPublickey | null> {
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);
}
return key;
}
@bindThis @bindThis
public dispose(): void { public dispose(): void {
this.publicKeyCache.dispose(); this.publicKeyCache.dispose();

View file

@ -104,12 +104,24 @@ export class InboxProcessorService {
} }
// HTTP-Signatureの検証 // HTTP-Signatureの検証
const httpSignatureValidated = httpSignature.verifySignature(signature, authUser.key.keyPem); let httpSignatureValidated = httpSignature.verifySignature(signature, authUser.key.keyPem);
// また、signatureのsignerは、activity.actorと一致する必要がある // また、signatureのsignerは、activity.actorと一致する必要がある
if (!httpSignatureValidated || authUser.user.uri !== activity.actor) { if (!httpSignatureValidated || authUser.user.uri !== activity.actor) {
let renewKeyFailed = false;
if (!httpSignatureValidated) {
authUser.key = await this.apDbResolverService.refetchPublicKeyForApId(authUser.user);
if (authUser.key != null) {
httpSignatureValidated = httpSignature.verifySignature(signature, authUser.key.keyPem);
} else {
renewKeyFailed = true;
}
}
// 一致しなくても、でもLD-Signatureがありそうならそっちも見る // 一致しなくても、でもLD-Signatureがありそうならそっちも見る
if (activity.signature) { if (activity.signature && renewKeyFailed) {
if (activity.signature.type !== 'RsaSignature2017') { if (activity.signature.type !== 'RsaSignature2017') {
throw new Bull.UnrecoverableError(`skip: unsupported LD-signature type ${activity.signature.type}`); throw new Bull.UnrecoverableError(`skip: unsupported LD-signature type ${activity.signature.type}`);
} }