From 689a9ce5f977b00d3a2a47cfcce086ff6fa8582a Mon Sep 17 00:00:00 2001 From: tamaina Date: Tue, 5 Mar 2024 15:53:24 +0000 Subject: [PATCH] PrivateKeyPem --- packages/backend/package.json | 2 +- packages/backend/src/core/AccountUpdateService.ts | 4 ++-- packages/backend/src/core/QueueService.ts | 12 ++++++------ packages/backend/src/core/RelayService.ts | 6 +++--- packages/backend/src/core/UserKeypairService.ts | 12 +++++------- packages/backend/src/core/UserSuspendService.ts | 4 ++-- .../src/core/activitypub/ApDeliverManagerService.ts | 9 +++++---- .../src/core/activitypub/ApRendererService.ts | 8 ++++---- .../backend/src/core/activitypub/ApRequestService.ts | 12 ++++++------ packages/backend/src/core/activitypub/type.ts | 5 ----- packages/backend/src/queue/types.ts | 6 +++--- pnpm-lock.yaml | 8 ++++---- 12 files changed, 41 insertions(+), 47 deletions(-) diff --git a/packages/backend/package.json b/packages/backend/package.json index 8b310c2d61..912768c934 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -79,7 +79,7 @@ "@fastify/multipart": "8.1.0", "@fastify/static": "6.12.0", "@fastify/view": "8.2.0", - "@misskey-dev/node-http-message-signatures": "0.0.3", + "@misskey-dev/node-http-message-signatures": "0.0.4", "@misskey-dev/sharp-read-bmp": "1.2.0", "@misskey-dev/summaly": "5.0.3", "@nestjs/common": "10.3.3", diff --git a/packages/backend/src/core/AccountUpdateService.ts b/packages/backend/src/core/AccountUpdateService.ts index 208131ed6e..d4a7b14554 100644 --- a/packages/backend/src/core/AccountUpdateService.ts +++ b/packages/backend/src/core/AccountUpdateService.ts @@ -13,7 +13,7 @@ import { RelayService } from '@/core/RelayService.js'; import { ApDeliverManagerService } from '@/core/activitypub/ApDeliverManagerService.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; import { bindThis } from '@/decorators.js'; -import type { PrivateKey } from './activitypub/type.js'; +import type { PrivateKeyWithPem } from '@misskey-dev/node-http-message-signatures'; @Injectable() export class AccountUpdateService implements OnModuleInit { @@ -40,7 +40,7 @@ export class AccountUpdateService implements OnModuleInit { * @param userId ユーザーID * @param isKeyUpdation Ed25519キーの作成など公開鍵のアップデートによる呼び出しか? trueにするとメインキーを使うようになる */ - public async publishToFollowers(userId: MiUser['id'], deliverKey?: PrivateKey) { + public async publishToFollowers(userId: MiUser['id'], deliverKey?: PrivateKeyWithPem) { const user = await this.usersRepository.findOneBy({ id: userId }); if (user == null) throw new Error('user not found'); diff --git a/packages/backend/src/core/QueueService.ts b/packages/backend/src/core/QueueService.ts index afea871575..a0ec9987a7 100644 --- a/packages/backend/src/core/QueueService.ts +++ b/packages/backend/src/core/QueueService.ts @@ -5,7 +5,7 @@ import { randomUUID } from 'node:crypto'; import { Inject, Injectable } from '@nestjs/common'; -import type { IActivity, PrivateKey } from '@/core/activitypub/type.js'; +import type { IActivity } from '@/core/activitypub/type.js'; import type { MiDriveFile } from '@/models/DriveFile.js'; import type { MiWebhook, webhookEventTypes } from '@/models/Webhook.js'; import type { Config } from '@/config.js'; @@ -15,7 +15,7 @@ import type { Antenna } from '@/server/api/endpoints/i/import-antennas.js'; import type { DbQueue, DeliverQueue, EndedPollNotificationQueue, InboxQueue, ObjectStorageQueue, RelationshipQueue, SystemQueue, WebhookDeliverQueue } from './QueueModule.js'; import type { DbJobData, DeliverJobData, RelationshipJobData, ThinUser } from '../queue/types.js'; import type * as Bull from 'bullmq'; -import { genRFC3230DigestHeader, type ParsedSignature } from '@misskey-dev/node-http-message-signatures'; +import { genRFC3230DigestHeader, type PrivateKeyWithPem, type ParsedSignature } from '@misskey-dev/node-http-message-signatures'; @Injectable() export class QueueService { @@ -70,7 +70,7 @@ export class QueueService { } @bindThis - public async deliver(user: ThinUser, content: IActivity | null, to: string | null, isSharedInbox: boolean, privateKey?: PrivateKey) { + public async deliver(user: ThinUser, content: IActivity | null, to: string | null, isSharedInbox: boolean, privateKey?: PrivateKeyWithPem) { if (content == null) return null; if (to == null) return null; @@ -84,7 +84,7 @@ export class QueueService { digest: await genRFC3230DigestHeader(contentBody, 'SHA-256'), to, isSharedInbox, - privateKey: privateKey && { keyId: privateKey.keyId, privateKey: privateKey.privateKey }, + privateKey: privateKey && { keyId: privateKey.keyId, privateKeyPem: privateKey.privateKeyPem }, }; return this.deliverQueue.add(to, data, { @@ -106,7 +106,7 @@ export class QueueService { * @returns void */ @bindThis - public async deliverMany(user: ThinUser, content: IActivity | null, inboxes: Map, privateKey?: PrivateKey) { + public async deliverMany(user: ThinUser, content: IActivity | null, inboxes: Map, privateKey?: PrivateKeyWithPem) { if (content == null) return null; const contentBody = JSON.stringify(content); @@ -126,7 +126,7 @@ export class QueueService { content: contentBody, to: d[0], isSharedInbox: d[1], - privateKey: privateKey && { keyId: privateKey.keyId, privateKey: privateKey.privateKey }, + privateKey: privateKey && { keyId: privateKey.keyId, privateKeyPem: privateKey.privateKeyPem }, } as DeliverJobData, opts, }))); diff --git a/packages/backend/src/core/RelayService.ts b/packages/backend/src/core/RelayService.ts index f106ae1669..5e4b6d36ae 100644 --- a/packages/backend/src/core/RelayService.ts +++ b/packages/backend/src/core/RelayService.ts @@ -17,7 +17,7 @@ import { DI } from '@/di-symbols.js'; import { deepClone } from '@/misc/clone.js'; import { bindThis } from '@/decorators.js'; import { UserKeypairService } from './UserKeypairService.js'; -import type { PrivateKey } from './activitypub/type.js'; +import type { PrivateKeyWithPem } from '@misskey-dev/node-http-message-signatures'; const ACTOR_USERNAME = 'relay.actor' as const; @@ -114,7 +114,7 @@ export class RelayService { } @bindThis - public async deliverToRelays(user: { id: MiUser['id']; host: null; }, activity: any, privateKey?: PrivateKey): Promise { + public async deliverToRelays(user: { id: MiUser['id']; host: null; }, activity: any, privateKey?: PrivateKeyWithPem): Promise { if (activity == null) return; const relays = await this.relaysCache.fetch(() => this.relaysRepository.findBy({ @@ -124,7 +124,7 @@ export class RelayService { const copy = deepClone(activity); if (!copy.to) copy.to = ['https://www.w3.org/ns/activitystreams#Public']; - privateKey = privateKey ?? await this.userKeypairService.getLocalUserKeypairWithKeyId(user.id); + privateKey = privateKey ?? await this.userKeypairService.getLocalUserPrivateKeyPem(user.id); const signed = await this.apRendererService.attachLdSignature(copy, user, privateKey); this.queueService.deliverMany(user, signed, new Map(relays.map(({ inbox }) => [inbox, false])), privateKey); diff --git a/packages/backend/src/core/UserKeypairService.ts b/packages/backend/src/core/UserKeypairService.ts index 6ec9a8b333..00f97143c8 100644 --- a/packages/backend/src/core/UserKeypairService.ts +++ b/packages/backend/src/core/UserKeypairService.ts @@ -5,7 +5,7 @@ import { Inject, Injectable, OnApplicationShutdown } from '@nestjs/common'; import * as Redis from 'ioredis'; -import { genEd25519KeyPair } from '@misskey-dev/node-http-message-signatures'; +import { genEd25519KeyPair, PrivateKeyWithPem } from '@misskey-dev/node-http-message-signatures'; import type { MiUser } from '@/models/User.js'; import type { UserKeypairsRepository } from '@/models/_.js'; import { RedisKVCache } from '@/misc/cache.js'; @@ -53,9 +53,9 @@ export class UserKeypairService implements OnApplicationShutdown { * @returns */ @bindThis - public async getLocalUserKeypairWithKeyId( + public async getLocalUserPrivateKeyPem( userIdOrHint: MiUser['id'] | MiUserKeypair, preferType?: string, - ): Promise<{ keyId: string; publicKey: string; privateKey: string; }> { + ): Promise { const keypair = typeof userIdOrHint === 'string' ? await this.getUserKeypair(userIdOrHint) : userIdOrHint; if ( preferType && ['01', '11', 'ed25519'].includes(preferType.toLowerCase()) && @@ -63,14 +63,12 @@ export class UserKeypairService implements OnApplicationShutdown { ) { return { keyId: `${this.userEntityService.genLocalUserUri(keypair.userId)}#ed25519-key`, - publicKey: keypair.ed25519PublicKey, - privateKey: keypair.ed25519PrivateKey, + privateKeyPem: keypair.ed25519PrivateKey, }; } return { keyId: `${this.userEntityService.genLocalUserUri(keypair.userId)}#main-key`, - publicKey: keypair.publicKey, - privateKey: keypair.privateKey, + privateKeyPem: keypair.privateKey, }; } diff --git a/packages/backend/src/core/UserSuspendService.ts b/packages/backend/src/core/UserSuspendService.ts index 7abeb3d46d..fc5a68c72e 100644 --- a/packages/backend/src/core/UserSuspendService.ts +++ b/packages/backend/src/core/UserSuspendService.ts @@ -32,7 +32,7 @@ export class UserSuspendService { const manager = this.apDeliverManagerService.createDeliverManager(user, content); manager.addAllKnowingSharedInboxRecipe(); // process deliver時にはキーペアが消去されているはずなので、ここで挿入する - const privateKey = await this.userKeypairService.getLocalUserKeypairWithKeyId(user.id, 'main'); + const privateKey = await this.userKeypairService.getLocalUserPrivateKeyPem(user.id, 'main'); manager.execute({ privateKey }); } } @@ -46,7 +46,7 @@ export class UserSuspendService { const manager = this.apDeliverManagerService.createDeliverManager(user, content); manager.addAllKnowingSharedInboxRecipe(); // process deliver時にはキーペアが消去されているはずなので、ここで挿入する - const privateKey = await this.userKeypairService.getLocalUserKeypairWithKeyId(user.id, 'main'); + const privateKey = await this.userKeypairService.getLocalUserPrivateKeyPem(user.id, 'main'); manager.execute({ privateKey }); } } diff --git a/packages/backend/src/core/activitypub/ApDeliverManagerService.ts b/packages/backend/src/core/activitypub/ApDeliverManagerService.ts index 4b0dd1403d..e09b548d3a 100644 --- a/packages/backend/src/core/activitypub/ApDeliverManagerService.ts +++ b/packages/backend/src/core/activitypub/ApDeliverManagerService.ts @@ -10,12 +10,13 @@ import type { FollowingsRepository } from '@/models/_.js'; import type { MiLocalUser, MiRemoteUser, MiUser } from '@/models/User.js'; import { QueueService } from '@/core/QueueService.js'; import { bindThis } from '@/decorators.js'; -import type { IActivity, PrivateKey } from '@/core/activitypub/type.js'; +import type { IActivity } from '@/core/activitypub/type.js'; import { ThinUser } from '@/queue/types.js'; import { AccountUpdateService } from '@/core/AccountUpdateService.js'; import type Logger from '@/logger.js'; import { UserKeypairService } from '../UserKeypairService.js'; import { ApLoggerService } from './ApLoggerService.js'; +import type { PrivateKeyWithPem } from '@misskey-dev/node-http-message-signatures'; interface IRecipe { type: string; @@ -128,7 +129,7 @@ class DeliverManager { * Execute delivers */ @bindThis - public async execute(opts?: { privateKey?: PrivateKey }): Promise { + public async execute(opts?: { privateKey?: PrivateKeyWithPem }): Promise { //#region MIGRATION if (!opts?.privateKey) { /** @@ -139,7 +140,7 @@ class DeliverManager { // createdが存在するということは新規作成されたということなので、フォロワーに配信する this.logger.info(`ed25519 key pair created for user ${this.actor.id} and publishing to followers`); // リモートに配信 - const keyPair = await this.userKeypairService.getLocalUserKeypairWithKeyId(created, 'main'); + const keyPair = await this.userKeypairService.getLocalUserPrivateKeyPem(created, 'main'); await this.accountUpdateService.publishToFollowers(this.actor.id, keyPair); } } @@ -230,7 +231,7 @@ export class ApDeliverManagerService { * @param forceMainKey Force to use main (rsa) key */ @bindThis - public async deliverToFollowers(actor: { id: MiLocalUser['id']; host: null; }, activity: IActivity, privateKey?: PrivateKey): Promise { + public async deliverToFollowers(actor: { id: MiLocalUser['id']; host: null; }, activity: IActivity, privateKey?: PrivateKeyWithPem): Promise { const manager = new DeliverManager( this.userKeypairService, this.followingsRepository, diff --git a/packages/backend/src/core/activitypub/ApRendererService.ts b/packages/backend/src/core/activitypub/ApRendererService.ts index e4b3074abd..5d9ca74fe1 100644 --- a/packages/backend/src/core/activitypub/ApRendererService.ts +++ b/packages/backend/src/core/activitypub/ApRendererService.ts @@ -22,7 +22,6 @@ import { UserKeypairService } from '@/core/UserKeypairService.js'; import { MfmService } from '@/core/MfmService.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; import { DriveFileEntityService } from '@/core/entities/DriveFileEntityService.js'; -import type { MiUserKeypair } from '@/models/UserKeypair.js'; import type { UsersRepository, UserProfilesRepository, NotesRepository, DriveFilesRepository, PollsRepository } from '@/models/_.js'; import { bindThis } from '@/decorators.js'; import { CustomEmojiService } from '@/core/CustomEmojiService.js'; @@ -30,7 +29,8 @@ import { isNotNull } from '@/misc/is-not-null.js'; import { IdService } from '@/core/IdService.js'; import { LdSignatureService } from './LdSignatureService.js'; import { ApMfmService } from './ApMfmService.js'; -import type { IAccept, IActivity, IAdd, IAnnounce, IApDocument, IApEmoji, IApHashtag, IApImage, IApMention, IBlock, ICreate, IDelete, IFlag, IFollow, IKey, ILike, IMove, IObject, IPost, IQuestion, IReject, IRemove, ITombstone, IUndo, IUpdate, PrivateKey } from './type.js'; +import type { IAccept, IActivity, IAdd, IAnnounce, IApDocument, IApEmoji, IApHashtag, IApImage, IApMention, IBlock, ICreate, IDelete, IFlag, IFollow, IKey, ILike, IMove, IObject, IPost, IQuestion, IReject, IRemove, ITombstone, IUndo, IUpdate } from './type.js'; +import type { PrivateKeyWithPem } from '@misskey-dev/node-http-message-signatures'; @Injectable() export class ApRendererService { @@ -657,10 +657,10 @@ export class ApRendererService { } @bindThis - public async attachLdSignature(activity: any, user: { id: MiUser['id']; host: null; }, key: PrivateKey): Promise { + public async attachLdSignature(activity: any, user: { id: MiUser['id']; host: null; }, key: PrivateKeyWithPem): Promise { const ldSignature = this.ldSignatureService.use(); ldSignature.debug = false; - activity = await ldSignature.signRsaSignature2017(activity, key.privateKey, key.keyId); + activity = await ldSignature.signRsaSignature2017(activity, key.privateKeyPem, key.keyId); return activity; } diff --git a/packages/backend/src/core/activitypub/ApRequestService.ts b/packages/backend/src/core/activitypub/ApRequestService.ts index c9bcbd961a..892e11b2d0 100644 --- a/packages/backend/src/core/activitypub/ApRequestService.ts +++ b/packages/backend/src/core/activitypub/ApRequestService.ts @@ -15,7 +15,7 @@ import { LoggerService } from '@/core/LoggerService.js'; import { bindThis } from '@/decorators.js'; import type Logger from '@/logger.js'; import { validateContentTypeSetAsActivityPub } from '@/core/activitypub/misc/validator.js'; -import type { PrivateKey } from './type.js'; +import type { PrivateKeyWithPem, PrivateKey } from '@misskey-dev/node-http-message-signatures'; export async function createSignedPost(args: { level: string; key: PrivateKey; url: string; body: string; digest?: string, additionalHeaders: Record }) { const u = new URL(args.url); @@ -36,7 +36,7 @@ export async function createSignedPost(args: { level: string; key: PrivateKey; u const result = await signAsDraftToRequest( request, - { keyId: args.key.keyId, privateKeyPem: args.key.privateKey }, + args.key, ['(request-target)', 'date', 'host', 'digest'], ); @@ -62,7 +62,7 @@ export async function createSignedGet(args: { level: string; key: PrivateKey; ur // TODO: httpMessageSignaturesImplementationLevelによって新規格で通信をするようにする const result = await signAsDraftToRequest( request, - { keyId: args.key.keyId, privateKeyPem: args.key.privateKey }, + args.key, ['(request-target)', 'date', 'host', 'accept'], ); @@ -89,9 +89,9 @@ export class ApRequestService { } @bindThis - public async signedPost(user: { id: MiUser['id'] }, url: string, object: unknown, level: string, digest?: string, key?: PrivateKey): Promise { + public async signedPost(user: { id: MiUser['id'] }, url: string, object: unknown, level: string, digest?: string, key?: PrivateKeyWithPem): Promise { const body = typeof object === 'string' ? object : JSON.stringify(object); - key = key ?? await this.userKeypairService.getLocalUserKeypairWithKeyId(user.id, level); + key = key ?? await this.userKeypairService.getLocalUserPrivateKeyPem(user.id, level); const req = await createSignedPost({ level, key, @@ -124,7 +124,7 @@ export class ApRequestService { */ @bindThis public async signedGet(url: string, user: { id: MiUser['id'] }, level: string): Promise { - const key = await this.userKeypairService.getLocalUserKeypairWithKeyId(user.id, level); + const key = await this.userKeypairService.getLocalUserPrivateKeyPem(user.id, level); const req = await createSignedGet({ level, key, diff --git a/packages/backend/src/core/activitypub/type.ts b/packages/backend/src/core/activitypub/type.ts index 6fd5ada9fe..0b34fd7664 100644 --- a/packages/backend/src/core/activitypub/type.ts +++ b/packages/backend/src/core/activitypub/type.ts @@ -326,8 +326,3 @@ export const isAnnounce = (object: IObject): object is IAnnounce => getApType(ob export const isBlock = (object: IObject): object is IBlock => getApType(object) === 'Block'; export const isFlag = (object: IObject): object is IFlag => getApType(object) === 'Flag'; export const isMove = (object: IObject): object is IMove => getApType(object) === 'Move'; - -export type PrivateKey = { - privateKey: string; - keyId: string; -}; diff --git a/packages/backend/src/queue/types.ts b/packages/backend/src/queue/types.ts index 12e3136270..85b1c4924b 100644 --- a/packages/backend/src/queue/types.ts +++ b/packages/backend/src/queue/types.ts @@ -8,8 +8,8 @@ import type { MiDriveFile } from '@/models/DriveFile.js'; import type { MiNote } from '@/models/Note.js'; import type { MiUser } from '@/models/User.js'; import type { MiWebhook } from '@/models/Webhook.js'; -import type { IActivity, PrivateKey } from '@/core/activitypub/type.js'; -import type { ParsedSignature } from '@misskey-dev/node-http-message-signatures'; +import type { IActivity } from '@/core/activitypub/type.js'; +import type { ParsedSignature, PrivateKeyWithPem } from '@misskey-dev/node-http-message-signatures'; /** * @peertube/http-signature 時代の古いデータにも対応しておく @@ -39,7 +39,7 @@ export type DeliverJobData = { /** whether it is sharedInbox */ isSharedInbox: boolean; /** force to use main (rsa) key */ - privateKey?: PrivateKey; + privateKey?: PrivateKeyWithPem; }; export type InboxJobData = { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1ba0cfcf74..b9f77b46d4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -111,8 +111,8 @@ importers: specifier: 8.2.0 version: 8.2.0 '@misskey-dev/node-http-message-signatures': - specifier: 0.0.3 - version: 0.0.3 + specifier: 0.0.4 + version: 0.0.4 '@misskey-dev/sharp-read-bmp': specifier: 1.2.0 version: 1.2.0 @@ -4754,8 +4754,8 @@ packages: eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.1.0)(eslint@8.57.0) dev: true - /@misskey-dev/node-http-message-signatures@0.0.3: - resolution: {integrity: sha512-IDsdj01d0Jz/D5L4ubHGOeBLEjbIpHpGIrS7p0t2Z36ahP5cvzeawkxZW2ZuqyWQI4JendJWhGnSmDrH4N3IFg==} + /@misskey-dev/node-http-message-signatures@0.0.4: + resolution: {integrity: sha512-hAQFaJZwJsg63JAY1RZ/yvcaxHbpZg8fLvNdJFucS270TZGunKYv7I16tuNQMKV7+BYLQNxiE7uL11KVZ9jfrg==} engines: {node: '>=18.4.0'} dependencies: '@lapo/asn1js': 1.2.4