From 8852c9eebf911fbccc62dd71831dfcd3314cf33c Mon Sep 17 00:00:00 2001
From: mei23 <m@m544.net>
Date: Thu, 30 Aug 2018 20:52:35 +0900
Subject: [PATCH] Add host/digest to HTTP signature

---
 src/remote/activitypub/request.ts | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/src/remote/activitypub/request.ts b/src/remote/activitypub/request.ts
index 6238d3acb..d739d08e1 100644
--- a/src/remote/activitypub/request.ts
+++ b/src/remote/activitypub/request.ts
@@ -2,6 +2,7 @@ import { request } from 'https';
 const { sign } = require('http-signature');
 import { URL } from 'url';
 import * as debug from 'debug';
+const crypto = require('crypto');
 
 import config from '../../config';
 import { ILocalUser } from '../../models/user';
@@ -13,6 +14,12 @@ export default (user: ILocalUser, url: string, object: any) => new Promise((reso
 
 	const { protocol, hostname, port, pathname, search } = new URL(url);
 
+	const data = JSON.stringify(object);
+
+	const sha256 = crypto.createHash('sha256');
+	sha256.update(data);
+	const hash = sha256.digest('base64');
+
 	const req = request({
 		protocol,
 		hostname,
@@ -20,7 +27,8 @@ export default (user: ILocalUser, url: string, object: any) => new Promise((reso
 		method: 'POST',
 		path: pathname + search,
 		headers: {
-			'Content-Type': 'application/activity+json'
+			'Content-Type': 'application/activity+json',
+			'Digest': `SHA-256=${hash}`
 		}
 	}, res => {
 		log(`${url} --> ${res.statusCode}`);
@@ -35,7 +43,8 @@ export default (user: ILocalUser, url: string, object: any) => new Promise((reso
 	sign(req, {
 		authorizationHeaderName: 'Signature',
 		key: user.keypair,
-		keyId: `${config.url}/users/${user._id}/publickey`
+		keyId: `${config.url}/users/${user._id}/publickey`,
+		headers: ['date', 'host', 'digest']
 	});
 
 	// Signature: Signature ... => Signature: ...
@@ -43,5 +52,5 @@ export default (user: ILocalUser, url: string, object: any) => new Promise((reso
 	sig = sig.replace(/^Signature /, '');
 	req.setHeader('Signature', sig);
 
-	req.end(JSON.stringify(object));
+	req.end(data);
 });