diff --git a/server/helpers/core-utils.ts b/server/helpers/core-utils.ts
index 00bc0bdda..224e4fe92 100644
--- a/server/helpers/core-utils.ts
+++ b/server/helpers/core-utils.ts
@@ -5,7 +5,7 @@
import * as bcrypt from 'bcrypt'
import * as createTorrent from 'create-torrent'
-import { createHash, pseudoRandomBytes } from 'crypto'
+import { createHash, HexBase64Latin1Encoding, pseudoRandomBytes } from 'crypto'
import { isAbsolute, join } from 'path'
import * as pem from 'pem'
import { URL } from 'url'
@@ -126,8 +126,8 @@ function peertubeTruncate (str: string, maxLength: number) {
return truncate(str, options)
}
-function sha256 (str: string) {
- return createHash('sha256').update(str).digest('hex')
+function sha256 (str: string, encoding: HexBase64Latin1Encoding = 'hex') {
+ return createHash('sha256').update(str).digest(encoding)
}
function promisify0 (func: (cb: (err: any, result: A) => void) => void): () => Promise {
diff --git a/server/lib/job-queue/handlers/activitypub-http-broadcast.ts b/server/lib/job-queue/handlers/activitypub-http-broadcast.ts
index 03a9e12a4..abbd89b3b 100644
--- a/server/lib/job-queue/handlers/activitypub-http-broadcast.ts
+++ b/server/lib/job-queue/handlers/activitypub-http-broadcast.ts
@@ -3,7 +3,7 @@ import * as Bluebird from 'bluebird'
import { logger } from '../../../helpers/logger'
import { doRequest } from '../../../helpers/requests'
import { ActorFollowModel } from '../../../models/activitypub/actor-follow'
-import { buildSignedRequestOptions, computeBody } from './utils/activitypub-http-utils'
+import { buildGlobalHeaders, buildSignedRequestOptions, computeBody } from './utils/activitypub-http-utils'
import { BROADCAST_CONCURRENCY, JOB_REQUEST_TIMEOUT } from '../../../initializers'
export type ActivitypubHttpBroadcastPayload = {
@@ -25,7 +25,8 @@ async function processActivityPubHttpBroadcast (job: Bull.Job) {
uri: '',
json: body,
httpSignature: httpSignatureOptions,
- timeout: JOB_REQUEST_TIMEOUT
+ timeout: JOB_REQUEST_TIMEOUT,
+ headers: buildGlobalHeaders(body)
}
const badUrls: string[] = []
diff --git a/server/lib/job-queue/handlers/activitypub-http-unicast.ts b/server/lib/job-queue/handlers/activitypub-http-unicast.ts
index c90d735f6..d36479032 100644
--- a/server/lib/job-queue/handlers/activitypub-http-unicast.ts
+++ b/server/lib/job-queue/handlers/activitypub-http-unicast.ts
@@ -2,7 +2,7 @@ import * as Bull from 'bull'
import { logger } from '../../../helpers/logger'
import { doRequest } from '../../../helpers/requests'
import { ActorFollowModel } from '../../../models/activitypub/actor-follow'
-import { buildSignedRequestOptions, computeBody } from './utils/activitypub-http-utils'
+import { buildGlobalHeaders, buildSignedRequestOptions, computeBody } from './utils/activitypub-http-utils'
import { JOB_REQUEST_TIMEOUT } from '../../../initializers'
export type ActivitypubHttpUnicastPayload = {
@@ -25,7 +25,8 @@ async function processActivityPubHttpUnicast (job: Bull.Job) {
uri,
json: body,
httpSignature: httpSignatureOptions,
- timeout: JOB_REQUEST_TIMEOUT
+ timeout: JOB_REQUEST_TIMEOUT,
+ headers: buildGlobalHeaders(body)
}
try {
diff --git a/server/lib/job-queue/handlers/utils/activitypub-http-utils.ts b/server/lib/job-queue/handlers/utils/activitypub-http-utils.ts
index 36092665e..d71c91a24 100644
--- a/server/lib/job-queue/handlers/utils/activitypub-http-utils.ts
+++ b/server/lib/job-queue/handlers/utils/activitypub-http-utils.ts
@@ -1,8 +1,11 @@
import { buildSignedActivity } from '../../../../helpers/activitypub'
import { getServerActor } from '../../../../helpers/utils'
import { ActorModel } from '../../../../models/activitypub/actor'
+import { sha256 } from '../../../../helpers/core-utils'
-async function computeBody (payload: { body: any, signatureActorId?: number }) {
+type Payload = { body: any, signatureActorId?: number }
+
+async function computeBody (payload: Payload) {
let body = payload.body
if (payload.signatureActorId) {
@@ -14,7 +17,7 @@ async function computeBody (payload: { body: any, signatureActorId?: number }) {
return body
}
-async function buildSignedRequestOptions (payload: { signatureActorId?: number }) {
+async function buildSignedRequestOptions (payload: Payload) {
let actor: ActorModel | null
if (payload.signatureActorId) {
actor = await ActorModel.load(payload.signatureActorId)
@@ -29,11 +32,21 @@ async function buildSignedRequestOptions (payload: { signatureActorId?: number }
algorithm: 'rsa-sha256',
authorizationHeaderName: 'Signature',
keyId,
- key: actor.privateKey
+ key: actor.privateKey,
+ headers: [ 'date', 'host', 'digest', '(request-target)' ]
+ }
+}
+
+function buildGlobalHeaders (body: object) {
+ const digest = 'SHA-256=' + sha256(JSON.stringify(body), 'base64')
+
+ return {
+ 'Digest': digest
}
}
export {
+ buildGlobalHeaders,
computeBody,
buildSignedRequestOptions
}