]>
Commit | Line | Data |
---|---|---|
1 | /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ | |
2 | ||
3 | import { expect } from 'chai' | |
4 | import { cloneDeep } from 'lodash' | |
5 | import { signAndContextify } from '@server/lib/activitypub/send' | |
6 | import { buildRequestStub } from '@server/tests/shared' | |
7 | import { buildAbsoluteFixturePath } from '@shared/core-utils' | |
8 | import { isHTTPSignatureVerified, isJsonLDSignatureVerified, parseHTTPSignature } from '../../../helpers/peertube-crypto' | |
9 | ||
10 | describe('Test activity pub helpers', function () { | |
11 | ||
12 | describe('When checking the Linked Signature', function () { | |
13 | ||
14 | it('Should fail with an invalid Mastodon signature', async function () { | |
15 | const body = require(buildAbsoluteFixturePath('./ap-json/mastodon/create-bad-signature.json')) | |
16 | const publicKey = require(buildAbsoluteFixturePath('./ap-json/mastodon/public-key.json')).publicKey | |
17 | const fromActor = { publicKey, url: 'http://localhost:9002/accounts/peertube' } | |
18 | ||
19 | const result = await isJsonLDSignatureVerified(fromActor as any, body) | |
20 | ||
21 | expect(result).to.be.false | |
22 | }) | |
23 | ||
24 | it('Should fail with an invalid public key', async function () { | |
25 | const body = require(buildAbsoluteFixturePath('./ap-json/mastodon/create.json')) | |
26 | const publicKey = require(buildAbsoluteFixturePath('./ap-json/mastodon/bad-public-key.json')).publicKey | |
27 | const fromActor = { publicKey, url: 'http://localhost:9002/accounts/peertube' } | |
28 | ||
29 | const result = await isJsonLDSignatureVerified(fromActor as any, body) | |
30 | ||
31 | expect(result).to.be.false | |
32 | }) | |
33 | ||
34 | it('Should succeed with a valid Mastodon signature', async function () { | |
35 | const body = require(buildAbsoluteFixturePath('./ap-json/mastodon/create.json')) | |
36 | const publicKey = require(buildAbsoluteFixturePath('./ap-json/mastodon/public-key.json')).publicKey | |
37 | const fromActor = { publicKey, url: 'http://localhost:9002/accounts/peertube' } | |
38 | ||
39 | const result = await isJsonLDSignatureVerified(fromActor as any, body) | |
40 | ||
41 | expect(result).to.be.true | |
42 | }) | |
43 | ||
44 | it('Should fail with an invalid PeerTube signature', async function () { | |
45 | const keys = require(buildAbsoluteFixturePath('./ap-json/peertube/invalid-keys.json')) | |
46 | const body = require(buildAbsoluteFixturePath('./ap-json/peertube/announce-without-context.json')) | |
47 | ||
48 | const actorSignature = { url: 'http://localhost:9002/accounts/peertube', privateKey: keys.privateKey } | |
49 | const signedBody = await signAndContextify(actorSignature as any, body, 'Announce') | |
50 | ||
51 | const fromActor = { publicKey: keys.publicKey, url: 'http://localhost:9002/accounts/peertube' } | |
52 | const result = await isJsonLDSignatureVerified(fromActor as any, signedBody) | |
53 | ||
54 | expect(result).to.be.false | |
55 | }) | |
56 | ||
57 | it('Should succeed with a valid PeerTube signature', async function () { | |
58 | const keys = require(buildAbsoluteFixturePath('./ap-json/peertube/keys.json')) | |
59 | const body = require(buildAbsoluteFixturePath('./ap-json/peertube/announce-without-context.json')) | |
60 | ||
61 | const actorSignature = { url: 'http://localhost:9002/accounts/peertube', privateKey: keys.privateKey } | |
62 | const signedBody = await signAndContextify(actorSignature as any, body, 'Announce') | |
63 | ||
64 | const fromActor = { publicKey: keys.publicKey, url: 'http://localhost:9002/accounts/peertube' } | |
65 | const result = await isJsonLDSignatureVerified(fromActor as any, signedBody) | |
66 | ||
67 | expect(result).to.be.true | |
68 | }) | |
69 | }) | |
70 | ||
71 | describe('When checking HTTP signature', function () { | |
72 | it('Should fail with an invalid http signature', async function () { | |
73 | const req = buildRequestStub() | |
74 | req.method = 'POST' | |
75 | req.url = '/accounts/ronan/inbox' | |
76 | ||
77 | const mastodonObject = cloneDeep(require(buildAbsoluteFixturePath('./ap-json/mastodon/bad-http-signature.json'))) | |
78 | req.body = mastodonObject.body | |
79 | req.headers = mastodonObject.headers | |
80 | ||
81 | const parsed = parseHTTPSignature(req, 3600 * 1000 * 365 * 10) | |
82 | const publicKey = require(buildAbsoluteFixturePath('./ap-json/mastodon/public-key.json')).publicKey | |
83 | ||
84 | const actor = { publicKey } | |
85 | const verified = isHTTPSignatureVerified(parsed, actor as any) | |
86 | ||
87 | expect(verified).to.be.false | |
88 | }) | |
89 | ||
90 | it('Should fail with an invalid public key', async function () { | |
91 | const req = buildRequestStub() | |
92 | req.method = 'POST' | |
93 | req.url = '/accounts/ronan/inbox' | |
94 | ||
95 | const mastodonObject = cloneDeep(require(buildAbsoluteFixturePath('./ap-json/mastodon/http-signature.json'))) | |
96 | req.body = mastodonObject.body | |
97 | req.headers = mastodonObject.headers | |
98 | ||
99 | const parsed = parseHTTPSignature(req, 3600 * 1000 * 365 * 10) | |
100 | const publicKey = require(buildAbsoluteFixturePath('./ap-json/mastodon/bad-public-key.json')).publicKey | |
101 | ||
102 | const actor = { publicKey } | |
103 | const verified = isHTTPSignatureVerified(parsed, actor as any) | |
104 | ||
105 | expect(verified).to.be.false | |
106 | }) | |
107 | ||
108 | it('Should fail because of clock skew', async function () { | |
109 | const req = buildRequestStub() | |
110 | req.method = 'POST' | |
111 | req.url = '/accounts/ronan/inbox' | |
112 | ||
113 | const mastodonObject = cloneDeep(require(buildAbsoluteFixturePath('./ap-json/mastodon/http-signature.json'))) | |
114 | req.body = mastodonObject.body | |
115 | req.headers = mastodonObject.headers | |
116 | ||
117 | let errored = false | |
118 | try { | |
119 | parseHTTPSignature(req) | |
120 | } catch { | |
121 | errored = true | |
122 | } | |
123 | ||
124 | expect(errored).to.be.true | |
125 | }) | |
126 | ||
127 | it('Should with a scheme', async function () { | |
128 | const req = buildRequestStub() | |
129 | req.method = 'POST' | |
130 | req.url = '/accounts/ronan/inbox' | |
131 | ||
132 | const mastodonObject = cloneDeep(require(buildAbsoluteFixturePath('./ap-json/mastodon/http-signature.json'))) | |
133 | req.body = mastodonObject.body | |
134 | req.headers = mastodonObject.headers | |
135 | req.headers = 'Signature ' + mastodonObject.headers | |
136 | ||
137 | let errored = false | |
138 | try { | |
139 | parseHTTPSignature(req, 3600 * 1000 * 365 * 10) | |
140 | } catch { | |
141 | errored = true | |
142 | } | |
143 | ||
144 | expect(errored).to.be.true | |
145 | }) | |
146 | ||
147 | it('Should succeed with a valid signature', async function () { | |
148 | const req = buildRequestStub() | |
149 | req.method = 'POST' | |
150 | req.url = '/accounts/ronan/inbox' | |
151 | ||
152 | const mastodonObject = cloneDeep(require(buildAbsoluteFixturePath('./ap-json/mastodon/http-signature.json'))) | |
153 | req.body = mastodonObject.body | |
154 | req.headers = mastodonObject.headers | |
155 | ||
156 | const parsed = parseHTTPSignature(req, 3600 * 1000 * 365 * 10) | |
157 | const publicKey = require(buildAbsoluteFixturePath('./ap-json/mastodon/public-key.json')).publicKey | |
158 | ||
159 | const actor = { publicKey } | |
160 | const verified = isHTTPSignatureVerified(parsed, actor as any) | |
161 | ||
162 | expect(verified).to.be.true | |
163 | }) | |
164 | ||
165 | }) | |
166 | ||
167 | }) |