diff --git a/public/language/en-GB/error.json b/public/language/en-GB/error.json index c353fb6964..1a337304e6 100644 --- a/public/language/en-GB/error.json +++ b/public/language/en-GB/error.json @@ -277,5 +277,6 @@ "api.reauth-required": "The resource you are trying to access requires (re-)authentication.", "activitypub.invalid-id": "Unable to resolve the input id, likely as it is malformed.", - "activitypub.get-failed": "Unable to retrieve the specified resource." + "activitypub.get-failed": "Unable to retrieve the specified resource.", + "activitypub.pubKey-not-found": "Unable to resolve public key, so payload verification cannot take place." } diff --git a/src/activitypub/index.js b/src/activitypub/index.js index c42663c9ca..d738553bde 100644 --- a/src/activitypub/index.js +++ b/src/activitypub/index.js @@ -89,12 +89,16 @@ ActivityPub.getPrivateKey = async (uid) => { ActivityPub.fetchPublicKey = async (uri) => { // Used for retrieving the public key from the passed-in keyId uri - const { body } = await request.get(uri, { + const { res, body } = await request.get(uri, { headers: { Accept: 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"', }, }); + if (!String(res.statusCode).startsWith('2') || !body.hasOwnProperty('publicKey')) { + throw new Error('[[error:activitypub.pubKey-not-found]]'); + } + return body.publicKey; }; @@ -143,9 +147,6 @@ ActivityPub.verify = async (req) => { return memo; }, {}); - // Retrieve public key from remote instance - const { publicKeyPem } = await ActivityPub.fetchPublicKey(keyId); - // Re-construct signature string const signed_string = headers.split(' ').reduce((memo, cur) => { if (cur === '(request-target)') { @@ -159,6 +160,9 @@ ActivityPub.verify = async (req) => { // Verify the signature string via public key try { + // Retrieve public key from remote instance + const { publicKeyPem } = await ActivityPub.fetchPublicKey(keyId); + const verify = createVerify('sha256'); verify.update(signed_string); verify.end();