@towns-protocol/encryption 0.0.191

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. package/LICENSE.txt +21 -0
  2. package/README.md +3 -0
  3. package/dist/base.d.ts +64 -0
  4. package/dist/base.d.ts.map +1 -0
  5. package/dist/base.js +44 -0
  6. package/dist/base.js.map +1 -0
  7. package/dist/cryptoAesGcm.d.ts +9 -0
  8. package/dist/cryptoAesGcm.d.ts.map +1 -0
  9. package/dist/cryptoAesGcm.js +30 -0
  10. package/dist/cryptoAesGcm.js.map +1 -0
  11. package/dist/cryptoStore.d.ts +52 -0
  12. package/dist/cryptoStore.d.ts.map +1 -0
  13. package/dist/cryptoStore.js +131 -0
  14. package/dist/cryptoStore.js.map +1 -0
  15. package/dist/decryptionExtensions.d.ts +200 -0
  16. package/dist/decryptionExtensions.d.ts.map +1 -0
  17. package/dist/decryptionExtensions.js +687 -0
  18. package/dist/decryptionExtensions.js.map +1 -0
  19. package/dist/derivedEncryption.d.ts +2 -0
  20. package/dist/derivedEncryption.d.ts.map +1 -0
  21. package/dist/derivedEncryption.js +2 -0
  22. package/dist/derivedEncryption.js.map +1 -0
  23. package/dist/encryptionDelegate.d.ts +20 -0
  24. package/dist/encryptionDelegate.d.ts.map +1 -0
  25. package/dist/encryptionDelegate.js +86 -0
  26. package/dist/encryptionDelegate.js.map +1 -0
  27. package/dist/encryptionDevice.d.ts +264 -0
  28. package/dist/encryptionDevice.d.ts.map +1 -0
  29. package/dist/encryptionDevice.js +742 -0
  30. package/dist/encryptionDevice.js.map +1 -0
  31. package/dist/encryptionTypes.d.ts +20 -0
  32. package/dist/encryptionTypes.d.ts.map +1 -0
  33. package/dist/encryptionTypes.js +2 -0
  34. package/dist/encryptionTypes.js.map +1 -0
  35. package/dist/groupDecryption.d.ts +34 -0
  36. package/dist/groupDecryption.d.ts.map +1 -0
  37. package/dist/groupDecryption.js +84 -0
  38. package/dist/groupDecryption.js.map +1 -0
  39. package/dist/groupEncryption.d.ts +36 -0
  40. package/dist/groupEncryption.d.ts.map +1 -0
  41. package/dist/groupEncryption.js +90 -0
  42. package/dist/groupEncryption.js.map +1 -0
  43. package/dist/groupEncryptionCrypto.d.ts +119 -0
  44. package/dist/groupEncryptionCrypto.d.ts.map +1 -0
  45. package/dist/groupEncryptionCrypto.js +256 -0
  46. package/dist/groupEncryptionCrypto.js.map +1 -0
  47. package/dist/hybridGroupDecryption.d.ts +33 -0
  48. package/dist/hybridGroupDecryption.d.ts.map +1 -0
  49. package/dist/hybridGroupDecryption.js +84 -0
  50. package/dist/hybridGroupDecryption.js.map +1 -0
  51. package/dist/hybridGroupEncryption.d.ts +30 -0
  52. package/dist/hybridGroupEncryption.d.ts.map +1 -0
  53. package/dist/hybridGroupEncryption.js +92 -0
  54. package/dist/hybridGroupEncryption.js.map +1 -0
  55. package/dist/index.d.ts +19 -0
  56. package/dist/index.d.ts.map +1 -0
  57. package/dist/index.js +19 -0
  58. package/dist/index.js.map +1 -0
  59. package/dist/olmLib.d.ts +35 -0
  60. package/dist/olmLib.d.ts.map +1 -0
  61. package/dist/olmLib.js +37 -0
  62. package/dist/olmLib.js.map +1 -0
  63. package/dist/storeTypes.d.ts +27 -0
  64. package/dist/storeTypes.d.ts.map +1 -0
  65. package/dist/storeTypes.js +2 -0
  66. package/dist/storeTypes.js.map +1 -0
  67. package/dist/tests/cryptoAesGcm.test.d.ts +2 -0
  68. package/dist/tests/cryptoAesGcm.test.d.ts.map +1 -0
  69. package/dist/tests/cryptoAesGcm.test.js +71 -0
  70. package/dist/tests/cryptoAesGcm.test.js.map +1 -0
  71. package/dist/tests/cryptoStore.test.d.ts +5 -0
  72. package/dist/tests/cryptoStore.test.d.ts.map +1 -0
  73. package/dist/tests/cryptoStore.test.js +114 -0
  74. package/dist/tests/cryptoStore.test.js.map +1 -0
  75. package/dist/tests/decryptionExtensions.test.d.ts +2 -0
  76. package/dist/tests/decryptionExtensions.test.d.ts.map +1 -0
  77. package/dist/tests/decryptionExtensions.test.js +355 -0
  78. package/dist/tests/decryptionExtensions.test.js.map +1 -0
  79. package/dist/tests/encryption-protocol.test.d.ts +2 -0
  80. package/dist/tests/encryption-protocol.test.d.ts.map +1 -0
  81. package/dist/tests/encryption-protocol.test.js +150 -0
  82. package/dist/tests/encryption-protocol.test.js.map +1 -0
  83. package/dist/tests/encryptionDelegate.test.d.ts +2 -0
  84. package/dist/tests/encryptionDelegate.test.d.ts.map +1 -0
  85. package/dist/tests/encryptionDelegate.test.js +78 -0
  86. package/dist/tests/encryptionDelegate.test.js.map +1 -0
  87. package/dist/tests/group-encryption-protocol.test.d.ts +2 -0
  88. package/dist/tests/group-encryption-protocol.test.d.ts.map +1 -0
  89. package/dist/tests/group-encryption-protocol.test.js +103 -0
  90. package/dist/tests/group-encryption-protocol.test.js.map +1 -0
  91. package/dist/tests/group-encryptionDelegate.test.d.ts +2 -0
  92. package/dist/tests/group-encryptionDelegate.test.d.ts.map +1 -0
  93. package/dist/tests/group-encryptionDelegate.test.js +23 -0
  94. package/dist/tests/group-encryptionDelegate.test.js.map +1 -0
  95. package/dist/tests/pk.test.d.ts +2 -0
  96. package/dist/tests/pk.test.d.ts.map +1 -0
  97. package/dist/tests/pk.test.js +103 -0
  98. package/dist/tests/pk.test.js.map +1 -0
  99. package/package.json +54 -0
@@ -0,0 +1,355 @@
1
+ import { BaseDecryptionExtensions, DecryptionStatus, makeSessionKeys, } from '../decryptionExtensions';
2
+ import { SessionKeysSchema, UserInboxPayload_GroupEncryptionSessionsSchema, } from '@towns-protocol/proto';
3
+ import { GroupEncryptionAlgorithmId, } from '../olmLib';
4
+ import { bin_fromHexString, bin_toHexString, dlog, shortenHexString } from '@towns-protocol/dlog';
5
+ import { CryptoStore } from '../cryptoStore';
6
+ import EventEmitter from 'events';
7
+ import { GroupEncryptionCrypto } from '../groupEncryptionCrypto';
8
+ import { customAlphabet } from 'nanoid';
9
+ import { create, toJsonString } from '@bufbuild/protobuf';
10
+ const log = dlog('test:decryptionExtensions:');
11
+ describe.concurrent('TestDecryptionExtensions', () => {
12
+ // test should iterate over all the algorithms
13
+ it.each(Object.values(GroupEncryptionAlgorithmId))('should be able to make key solicitation request', async (algorithm) => {
14
+ // arrange
15
+ const clientDiscoveryService = {};
16
+ const streamId = genStreamId();
17
+ const alice = genUserId('Alice');
18
+ const aliceUserAddress = stringToArray(alice);
19
+ const bob = genUserId('Bob');
20
+ const bobsPlaintext = "bob's plaintext";
21
+ const { client: aliceClient, decryptionExtension: aliceDex } = await createCryptoMocks(alice, clientDiscoveryService);
22
+ const { crypto: bobCrypto, decryptionExtension: bobDex } = await createCryptoMocks(bob, clientDiscoveryService);
23
+ // act
24
+ aliceDex.start();
25
+ // bob starts the decryption extension
26
+ bobDex.start();
27
+ // bob encrypts a message
28
+ const encryptedData = await bobCrypto.encryptGroupEvent(streamId, new TextEncoder().encode(bobsPlaintext), algorithm);
29
+ const encryptedData_V0 = await bobCrypto.encryptGroupEvent_deprecated_v0(streamId, bobsPlaintext, algorithm);
30
+ const sessionId = encryptedData.sessionId;
31
+ // alice doesn't have the session key
32
+ // alice sends a key solicitation request
33
+ const keySolicitationData = {
34
+ deviceKey: aliceDex.userDevice.deviceKey,
35
+ fallbackKey: aliceDex.userDevice.fallbackKey,
36
+ isNewDevice: true,
37
+ sessionIds: [sessionId],
38
+ };
39
+ const keySolicitation = aliceClient.sendKeySolicitation(keySolicitationData);
40
+ // pretend bob receives a key solicitation request from alice, and starts processing it.
41
+ await bobDex.handleKeySolicitationRequest(streamId, '', alice, aliceUserAddress, keySolicitationData, {
42
+ hash: new Uint8Array(),
43
+ signature: new Uint8Array(),
44
+ event: {
45
+ creatorAddress: new Uint8Array(),
46
+ delegateSig: new Uint8Array(),
47
+ delegateExpiryEpochMs: 0n,
48
+ },
49
+ });
50
+ // alice waits for the response
51
+ await keySolicitation;
52
+ // after alice gets the session key,
53
+ // try to decrypt the message
54
+ const decrypted = await aliceDex.crypto.decryptGroupEvent(streamId, encryptedData);
55
+ const decrypted_V0 = await aliceDex.crypto.decryptGroupEvent(streamId, encryptedData_V0);
56
+ if (typeof decrypted === 'string') {
57
+ throw new Error('decrypted is a string'); // v1 should be bytes
58
+ }
59
+ if (typeof decrypted_V0 !== 'string') {
60
+ throw new Error('decrypted_V0 is a string'); // v0 should be bytes
61
+ }
62
+ // stop the decryption extensions
63
+ await bobDex.stop();
64
+ await aliceDex.stop();
65
+ // assert
66
+ expect(new TextDecoder().decode(decrypted)).toBe(bobsPlaintext);
67
+ expect(decrypted_V0).toBe(bobsPlaintext);
68
+ expect(bobDex.seenStates).toContain(DecryptionStatus.working);
69
+ expect(aliceDex.seenStates).toContain(DecryptionStatus.working);
70
+ });
71
+ // test should iterate over all the algorithms
72
+ it.each(Object.values(GroupEncryptionAlgorithmId))('should be able to export/import stream room key', async (algorithm) => {
73
+ // arrange
74
+ const clientDiscoveryService = {};
75
+ const streamId = genStreamId();
76
+ const alice = genUserId('Alice');
77
+ const bob = genUserId('Bob');
78
+ const bobsPlaintext = "bob's plaintext";
79
+ const { decryptionExtension: aliceDex } = await createCryptoMocks(alice, clientDiscoveryService);
80
+ const { crypto: bobCrypto, decryptionExtension: bobDex } = await createCryptoMocks(bob, clientDiscoveryService);
81
+ // act
82
+ aliceDex.start();
83
+ // bob starts the decryption extension
84
+ bobDex.start();
85
+ // bob encrypts a message
86
+ const encryptedData = await bobCrypto.encryptGroupEvent(streamId, new TextEncoder().encode(bobsPlaintext), algorithm);
87
+ const encryptedData_V0 = await bobCrypto.encryptGroupEvent_deprecated_v0(streamId, bobsPlaintext, algorithm);
88
+ // alice doesn't have the session key
89
+ // alice imports the keys exported by bob
90
+ const roomKeys = await bobDex.crypto.exportRoomKeys();
91
+ if (roomKeys) {
92
+ await aliceDex.crypto.importRoomKeys(roomKeys);
93
+ }
94
+ // after alice gets the session key,
95
+ // try to decrypt the message
96
+ const decrypted = await aliceDex.crypto.decryptGroupEvent(streamId, encryptedData);
97
+ if (typeof decrypted === 'string') {
98
+ throw new Error('decrypted is a string'); // v1 should be bytes
99
+ }
100
+ const decrypted_V0 = await aliceDex.crypto.decryptGroupEvent(streamId, encryptedData_V0);
101
+ if (typeof decrypted_V0 !== 'string') {
102
+ throw new Error('decrypted_V0 is a string'); // v0 should be bytes
103
+ }
104
+ // stop the decryption extensions
105
+ await bobDex.stop();
106
+ await aliceDex.stop();
107
+ // assert
108
+ expect(new TextDecoder().decode(decrypted)).toBe(bobsPlaintext);
109
+ expect(decrypted_V0).toBe(bobsPlaintext);
110
+ });
111
+ });
112
+ async function createCryptoMocks(userId, clientDiscoveryService) {
113
+ const cryptoStore = new CryptoStore(`db_${userId}`, userId);
114
+ const entitlementDelegate = new MockEntitlementsDelegate();
115
+ const client = new MockGroupEncryptionClient(clientDiscoveryService);
116
+ const crypto = new GroupEncryptionCrypto(client, cryptoStore);
117
+ await crypto.init();
118
+ const userDevice = crypto.getUserDevice();
119
+ const decryptionExtension = new MockDecryptionExtensions(userId, crypto, entitlementDelegate, userDevice, client);
120
+ client.crypto = crypto;
121
+ client.decryptionExtensions = decryptionExtension;
122
+ clientDiscoveryService[userDevice.deviceKey] = client;
123
+ return {
124
+ client,
125
+ crypto,
126
+ cryptoStore,
127
+ decryptionExtension,
128
+ userDevice,
129
+ };
130
+ }
131
+ class MicroTask {
132
+ resolve;
133
+ startState;
134
+ endState;
135
+ isStarted = false;
136
+ _isCompleted = false;
137
+ constructor(resolve, startState, endState) {
138
+ this.resolve = resolve;
139
+ this.startState = startState;
140
+ this.endState = endState;
141
+ }
142
+ get isCompleted() {
143
+ return this._isCompleted;
144
+ }
145
+ tick(state) {
146
+ if (state === this.startState) {
147
+ this.isStarted = true;
148
+ }
149
+ if (this.isStarted && state === this.endState) {
150
+ this.resolve();
151
+ this._isCompleted = true;
152
+ }
153
+ }
154
+ }
155
+ class MockDecryptionExtensions extends BaseDecryptionExtensions {
156
+ inProgress = {};
157
+ client;
158
+ _upToDateStreams;
159
+ constructor(userId, crypto, entitlementDelegate, userDevice, client) {
160
+ const upToDateStreams = new Set();
161
+ const logId = shortenHexString(userId);
162
+ super(client, crypto, entitlementDelegate, userDevice, userId, upToDateStreams, logId);
163
+ this._upToDateStreams = upToDateStreams;
164
+ this.client = client;
165
+ this._onStopFn = () => {
166
+ log('onStopFn');
167
+ };
168
+ client.on('decryptionExtStatusChanged', () => {
169
+ this.statusChangedTick();
170
+ });
171
+ }
172
+ seenStates = [];
173
+ shouldPauseTicking() {
174
+ return false;
175
+ }
176
+ newGroupSessions(sessions, senderId) {
177
+ log('newGroupSessions', sessions, senderId);
178
+ const streamId = bin_toHexString(sessions.streamId);
179
+ this.markStreamUpToDate(streamId);
180
+ const p = new Promise((resolve) => {
181
+ this.inProgress[streamId] = new MicroTask(resolve, DecryptionStatus.working, DecryptionStatus.done);
182
+ // start processing the new sessions
183
+ this.enqueueNewGroupSessions(sessions, senderId);
184
+ });
185
+ return p;
186
+ }
187
+ ackNewGroupSession(session) {
188
+ log('newGroupSessionsDone', session.streamId);
189
+ return Promise.resolve();
190
+ }
191
+ async handleKeySolicitationRequest(streamId, eventHashStr, fromUserId, fromUserAddress, keySolicitation, sigBundle) {
192
+ log('keySolicitationRequest', streamId, keySolicitation);
193
+ this.markStreamUpToDate(streamId);
194
+ const p = new Promise((resolve) => {
195
+ this.inProgress[streamId] = new MicroTask(resolve, DecryptionStatus.working, DecryptionStatus.done);
196
+ // start processing the request
197
+ this.enqueueKeySolicitation(streamId, eventHashStr, fromUserId, fromUserAddress, keySolicitation, sigBundle);
198
+ });
199
+ return p;
200
+ }
201
+ hasStream(streamId) {
202
+ log('canProcessStream', streamId, true);
203
+ return this._upToDateStreams.has(streamId);
204
+ }
205
+ isValidEvent(item) {
206
+ log('isValidEvent', item);
207
+ return { isValid: true };
208
+ }
209
+ decryptGroupEvent(_streamId, _eventId, _kind, _encryptedData) {
210
+ log('decryptGroupEvent');
211
+ return Promise.resolve();
212
+ }
213
+ downloadNewMessages() {
214
+ log('downloadNewMessages');
215
+ return Promise.resolve();
216
+ }
217
+ getKeySolicitations(_streamId) {
218
+ log('getKeySolicitations');
219
+ return [];
220
+ }
221
+ isUserEntitledToKeyExchange(_streamId, _userId) {
222
+ log('isUserEntitledToKeyExchange');
223
+ return Promise.resolve(true);
224
+ }
225
+ onDecryptionError(_item, _err) {
226
+ log('onDecryptionError', 'item:', _item, 'err:', _err);
227
+ }
228
+ sendKeySolicitation(args) {
229
+ log('sendKeySolicitation', args);
230
+ return Promise.resolve();
231
+ }
232
+ sendKeyFulfillment(args) {
233
+ log('sendKeyFulfillment', args);
234
+ return Promise.resolve({});
235
+ }
236
+ encryptAndShareGroupSessions(args) {
237
+ log('encryptAndSendToGroup');
238
+ return this.client.encryptAndSendMock(args);
239
+ }
240
+ uploadDeviceKeys() {
241
+ log('uploadDeviceKeys');
242
+ return Promise.resolve();
243
+ }
244
+ isUserInboxStreamUpToDate(_upToDateStreams) {
245
+ return true;
246
+ }
247
+ getPriorityForStream(_streamId, _highPriorityIds, _recentStreamIds) {
248
+ return 0;
249
+ }
250
+ markStreamUpToDate(streamId) {
251
+ this._upToDateStreams.add(streamId);
252
+ this.setStreamUpToDate(streamId);
253
+ }
254
+ statusChangedTick() {
255
+ this.seenStates.push(this.status);
256
+ Object.values(this.inProgress).forEach((t) => {
257
+ t.tick(this.status);
258
+ });
259
+ }
260
+ }
261
+ class MockGroupEncryptionClient extends EventEmitter {
262
+ clientDiscoveryService;
263
+ shareKeysResponses = {};
264
+ constructor(clientDiscoveryService) {
265
+ super();
266
+ this.clientDiscoveryService = clientDiscoveryService;
267
+ }
268
+ crypto;
269
+ decryptionExtensions;
270
+ get userDevice() {
271
+ return this.crypto ? this.crypto.getUserDevice() : undefined;
272
+ }
273
+ downloadUserDeviceInfo(_userIds, _forceDownload) {
274
+ return Promise.resolve({});
275
+ }
276
+ encryptAndShareGroupSessions(_streamId, _sessions, _devicesInRoom) {
277
+ return Promise.resolve();
278
+ }
279
+ getDevicesInStream(_streamId) {
280
+ return Promise.resolve({});
281
+ }
282
+ getMiniblockInfo(_streamId) {
283
+ return Promise.resolve({ miniblockNum: 0n, miniblockHash: new Uint8Array() });
284
+ }
285
+ sendKeySolicitation(args) {
286
+ // assume the request is sent
287
+ return new Promise((resolve) => {
288
+ // resolve when the response is received
289
+ this.shareKeysResponses[args.deviceKey] = resolve;
290
+ });
291
+ }
292
+ async encryptAndSendMock(args) {
293
+ const { sessions, streamId } = args;
294
+ if (!this.userDevice) {
295
+ throw new Error('no user device');
296
+ }
297
+ // prepare the common parts of the payload
298
+ const streamIdBytes = streamIdToBytes(streamId);
299
+ const sessionIds = sessions.map((s) => s.sessionId);
300
+ const payload = toJsonString(SessionKeysSchema, makeSessionKeys(sessions));
301
+ // encrypt and send the payload to each client
302
+ const otherClients = Object.values(this.clientDiscoveryService).filter((c) => c.userDevice?.deviceKey != this.userDevice?.deviceKey);
303
+ const promises = otherClients.map(async (c) => {
304
+ const cipertext = await this.crypto?.encryptWithDeviceKeys(payload, [c.userDevice]);
305
+ const groupSession = create(UserInboxPayload_GroupEncryptionSessionsSchema, {
306
+ streamId: streamIdBytes,
307
+ senderKey: this.userDevice?.deviceKey,
308
+ sessionIds: sessionIds,
309
+ ciphertexts: cipertext,
310
+ algorithm: args.algorithm,
311
+ });
312
+ // pretend sending the payload to the client
313
+ // ....
314
+ // pretend receiving the response
315
+ // trigger a new group session processing
316
+ await c.decryptionExtensions?.newGroupSessions(groupSession, this.userDevice.deviceKey);
317
+ await c.resolveGroupSessionResponse(args);
318
+ });
319
+ await Promise.all(promises);
320
+ }
321
+ resolveGroupSessionResponse(args) {
322
+ // fake receiving the response
323
+ const resolve = this.shareKeysResponses[args.item.solicitation.deviceKey];
324
+ if (resolve) {
325
+ resolve(args);
326
+ }
327
+ return Promise.resolve();
328
+ }
329
+ sendKeyFulfillment(_args) {
330
+ return Promise.resolve({});
331
+ }
332
+ uploadDeviceKeys() {
333
+ return Promise.resolve();
334
+ }
335
+ }
336
+ class MockEntitlementsDelegate {
337
+ isEntitled(_spaceId, _channelId, _user, _permission) {
338
+ return Promise.resolve(true);
339
+ }
340
+ }
341
+ function genUserId(name) {
342
+ return `0x${name}${Date.now()}`;
343
+ }
344
+ function genStreamId() {
345
+ const hexNanoId = customAlphabet('0123456789abcdef', 64);
346
+ return hexNanoId();
347
+ }
348
+ function stringToArray(fromString) {
349
+ const uint8Array = new TextEncoder().encode(fromString);
350
+ return uint8Array;
351
+ }
352
+ function streamIdToBytes(streamId) {
353
+ return bin_fromHexString(streamId);
354
+ }
355
+ //# sourceMappingURL=decryptionExtensions.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decryptionExtensions.test.js","sourceRoot":"","sources":["../../src/tests/decryptionExtensions.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=encryption-protocol.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encryption-protocol.test.d.ts","sourceRoot":"","sources":["../../src/tests/encryption-protocol.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,150 @@
1
+ /* eslint-disable @typescript-eslint/no-unsafe-member-access */
2
+ import { EncryptionDelegate } from '../encryptionDelegate';
3
+ import debug from 'debug';
4
+ const log = debug('test');
5
+ describe.concurrent('Encryption Protocol', () => {
6
+ let aliceAccount;
7
+ let bobAccount;
8
+ let aliceSession;
9
+ let bobSession;
10
+ beforeAll(async () => {
11
+ const delegate = new EncryptionDelegate();
12
+ await delegate.init();
13
+ aliceAccount = delegate.createAccount();
14
+ bobAccount = delegate.createAccount();
15
+ aliceSession = delegate.createSession();
16
+ bobSession = delegate.createSession();
17
+ });
18
+ afterAll(async () => {
19
+ if (aliceAccount !== undefined) {
20
+ aliceAccount.free();
21
+ aliceAccount = undefined;
22
+ }
23
+ if (bobAccount !== undefined) {
24
+ bobAccount.free();
25
+ bobAccount = undefined;
26
+ }
27
+ if (aliceSession !== undefined) {
28
+ aliceSession.free();
29
+ aliceSession = undefined;
30
+ }
31
+ if (bobSession !== undefined) {
32
+ bobSession.free();
33
+ bobSession = undefined;
34
+ }
35
+ });
36
+ it('shouldEncryptAndDecrypt', async () => {
37
+ if (aliceAccount === undefined ||
38
+ bobAccount === undefined ||
39
+ aliceSession === undefined ||
40
+ bobSession === undefined) {
41
+ throw new Error('Account and Session objects not initialized');
42
+ }
43
+ aliceAccount.create();
44
+ bobAccount.create();
45
+ // public one time key for pre-key message generation to establish the session
46
+ bobAccount.generate_one_time_keys(2);
47
+ const bobOneTimeKeys = JSON.parse(bobAccount.one_time_keys()).curve25519;
48
+ log('bobOneTimeKeys', bobOneTimeKeys);
49
+ bobAccount.mark_keys_as_published();
50
+ const bobIdKey = JSON.parse(bobAccount?.identity_keys()).curve25519;
51
+ const otkId = Object.keys(bobOneTimeKeys)[0];
52
+ // create outbound sessions using bob's one time key
53
+ aliceSession.create_outbound(aliceAccount, bobIdKey, bobOneTimeKeys[otkId]);
54
+ let TEST_TEXT = 'test message for bob';
55
+ let encrypted = aliceSession.encrypt(TEST_TEXT);
56
+ expect(encrypted.type).toEqual(0);
57
+ // create inbound sessions using own account and encrypted body from alice
58
+ bobSession.create_inbound(bobAccount, encrypted.body);
59
+ bobAccount.remove_one_time_keys(bobSession);
60
+ let decrypted = bobSession.decrypt(encrypted.type, encrypted.body);
61
+ log('bob decrypted ciphertext: ', decrypted);
62
+ expect(decrypted).toEqual(TEST_TEXT);
63
+ TEST_TEXT = 'test message for alice';
64
+ encrypted = bobSession.encrypt(TEST_TEXT);
65
+ expect(encrypted.type).toEqual(1);
66
+ decrypted = aliceSession.decrypt(encrypted.type, encrypted.body);
67
+ log('alice decrypted ciphertext: ', decrypted);
68
+ expect(decrypted).toEqual(TEST_TEXT);
69
+ });
70
+ it('shouldEncryptAndDecryptWithFallbackKey', async () => {
71
+ if (aliceAccount === undefined ||
72
+ bobAccount === undefined ||
73
+ aliceSession === undefined ||
74
+ bobSession === undefined) {
75
+ throw new Error('Account and session objects not initialized');
76
+ }
77
+ aliceAccount.create();
78
+ bobAccount.create();
79
+ // public fallback key for pre-key message generation to establish the session
80
+ bobAccount.generate_fallback_key();
81
+ const bobFallbackKey = JSON.parse(bobAccount.unpublished_fallback_key()).curve25519;
82
+ log('bobFallbackKeys', bobFallbackKey);
83
+ const bobIdKey = JSON.parse(bobAccount?.identity_keys()).curve25519;
84
+ const otkId = Object.keys(bobFallbackKey)[0];
85
+ // create outbound sessions using bob's fallback key
86
+ aliceSession.create_outbound(aliceAccount, bobIdKey, bobFallbackKey[otkId]);
87
+ let TEST_TEXT = 'test message for bob';
88
+ let encrypted = aliceSession.encrypt(TEST_TEXT);
89
+ expect(encrypted.type).toEqual(0);
90
+ log('aliceSession sessionId', aliceSession.session_id());
91
+ // create inbound sessions using own account and encrypted body from alice
92
+ bobSession.create_inbound(bobAccount, encrypted.body);
93
+ let decrypted = bobSession.decrypt(encrypted.type, encrypted.body);
94
+ log('bob decrypted ciphertext: ', decrypted);
95
+ expect(decrypted).toEqual(TEST_TEXT);
96
+ TEST_TEXT = 'test message for alice';
97
+ encrypted = bobSession.encrypt(TEST_TEXT);
98
+ expect(encrypted.type).toEqual(1);
99
+ decrypted = aliceSession.decrypt(encrypted.type, encrypted.body);
100
+ log('alice decrypted ciphertext: ', decrypted);
101
+ expect(decrypted).toEqual(TEST_TEXT);
102
+ // Sep 2: encrypt with same session as pre-key message
103
+ log('aliceSession sessionId', aliceSession.session_id());
104
+ const TEST_TEXT_2 = 'test message for bob 2';
105
+ aliceSession.create_outbound(aliceAccount, bobIdKey, bobFallbackKey[otkId]);
106
+ const encrypted_2 = aliceSession.encrypt(TEST_TEXT_2);
107
+ expect(encrypted_2.type).toEqual(0);
108
+ bobSession.create_inbound(bobAccount, encrypted_2.body);
109
+ const decrypted_2 = bobSession.decrypt(encrypted_2.type, encrypted_2.body);
110
+ log('bob decrypted ciphertext 2: ', decrypted_2);
111
+ expect(decrypted_2).toEqual(TEST_TEXT_2);
112
+ });
113
+ it('shouldNotEncryptAndDecryptWithBadFallbackKey', async () => {
114
+ if (aliceAccount === undefined ||
115
+ bobAccount === undefined ||
116
+ aliceSession === undefined ||
117
+ bobSession === undefined) {
118
+ throw new Error('Account and session objects not initialized');
119
+ }
120
+ aliceAccount.create();
121
+ bobAccount.create();
122
+ // public fallback key for pre-key message generation to establish the session
123
+ aliceAccount.generate_fallback_key();
124
+ const aliceFallbackKey = JSON.parse(aliceAccount.unpublished_fallback_key()).curve25519;
125
+ log('aliceFallbackKey', aliceFallbackKey);
126
+ const bobIdKey = JSON.parse(bobAccount?.identity_keys()).curve25519;
127
+ const aliceIdKey = JSON.parse(aliceAccount?.identity_keys()).curve25519;
128
+ const otkId = Object.keys(aliceFallbackKey)[0];
129
+ // create outbound sessions using alice's fallback key (should fail)
130
+ aliceSession.create_outbound(aliceAccount, bobIdKey, aliceFallbackKey[otkId]);
131
+ const TEST_TEXT = 'test message for bob';
132
+ const encrypted = aliceSession.encrypt(TEST_TEXT);
133
+ expect(encrypted.type).toEqual(0);
134
+ log('aliceSession sessionId', aliceSession.session_id());
135
+ // create inbound sessions using own account and encrypted body from alice
136
+ // this should fail as outbound session was not created using bob's fallback key
137
+ try {
138
+ bobSession.create_inbound_from(bobAccount, aliceIdKey, encrypted.body);
139
+ bobSession.decrypt(encrypted.type, encrypted.body);
140
+ }
141
+ catch (e) {
142
+ log('bobSession.create_inbound_from failed as expected', e);
143
+ expect(e.message).toContain('OLM.BAD_MESSAGE_KEY_ID');
144
+ return;
145
+ }
146
+ // we shouldn't get here
147
+ expect(true).toEqual(false);
148
+ });
149
+ });
150
+ //# sourceMappingURL=encryption-protocol.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encryption-protocol.test.js","sourceRoot":"","sources":["../../src/tests/encryption-protocol.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=encryptionDelegate.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encryptionDelegate.test.d.ts","sourceRoot":"","sources":["../../src/tests/encryptionDelegate.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,78 @@
1
+ import { EncryptionDelegate } from '../encryptionDelegate';
2
+ function getFallbackKey(account) {
3
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
4
+ return Object.values(
5
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
6
+ JSON.parse(account.unpublished_fallback_key())['curve25519'])[0];
7
+ }
8
+ function getIdentityKey(account) {
9
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-member-access
10
+ return JSON.parse(account.identity_keys()).curve25519;
11
+ }
12
+ describe.concurrent('EncrytionDelegate', () => {
13
+ const delegate = new EncryptionDelegate();
14
+ let bob;
15
+ let alice;
16
+ beforeEach(async () => {
17
+ await delegate.init();
18
+ bob = delegate.createAccount();
19
+ alice = delegate.createAccount();
20
+ bob.create();
21
+ alice.create();
22
+ });
23
+ it('encrypt decrypt', async () => {
24
+ alice.generate_fallback_key();
25
+ const aliceFallbackKey = getFallbackKey(alice);
26
+ const aliceIdentityKey = getIdentityKey(alice);
27
+ const bobToAlice = delegate.createSession();
28
+ bobToAlice.create_outbound(bob, aliceIdentityKey, aliceFallbackKey);
29
+ const encrypted = bobToAlice.encrypt('bob to alice 1');
30
+ const aliceToBob = delegate.createSession();
31
+ aliceToBob.create_inbound(alice, encrypted.body);
32
+ const decrypted = aliceToBob.decrypt(encrypted.type, encrypted.body);
33
+ expect(decrypted).toEqual('bob to alice 1');
34
+ const encrypted2 = aliceToBob.encrypt('alice to bob 1');
35
+ const decrypted2 = bobToAlice.decrypt(encrypted2.type, encrypted2.body);
36
+ expect(decrypted2).toEqual('alice to bob 1');
37
+ });
38
+ it('decrypt same message twice', async () => {
39
+ alice.generate_fallback_key();
40
+ const aliceFallbackKey = getFallbackKey(alice);
41
+ const aliceIdentityKey = getIdentityKey(alice);
42
+ const bobToAlice = delegate.createSession();
43
+ bobToAlice.create_outbound(bob, aliceIdentityKey, aliceFallbackKey);
44
+ const encrypted = bobToAlice.encrypt('bob to alice 1');
45
+ const aliceToBob = delegate.createSession();
46
+ aliceToBob.create_inbound(alice, encrypted.body);
47
+ expect(aliceToBob.decrypt(encrypted.type, encrypted.body)).toEqual('bob to alice 1');
48
+ const aliceToBob2 = delegate.createSession();
49
+ aliceToBob2.create_inbound(alice, encrypted.body);
50
+ expect(aliceToBob2.decrypt(encrypted.type, encrypted.body)).toEqual('bob to alice 1');
51
+ });
52
+ it('decrypt same message twice throws', async () => {
53
+ alice.generate_fallback_key();
54
+ const aliceFallbackKey = getFallbackKey(alice);
55
+ const aliceIdentityKey = getIdentityKey(alice);
56
+ const bobToAlice = delegate.createSession();
57
+ bobToAlice.create_outbound(bob, aliceIdentityKey, aliceFallbackKey);
58
+ const encrypted = bobToAlice.encrypt('bob to alice 1');
59
+ const aliceToBob = delegate.createSession();
60
+ aliceToBob.create_inbound(alice, encrypted.body);
61
+ expect(aliceToBob.decrypt(encrypted.type, encrypted.body)).toEqual('bob to alice 1');
62
+ expect(() => aliceToBob.decrypt(encrypted.type, encrypted.body)).toThrow();
63
+ });
64
+ it('decrypt same messages out of order', async () => {
65
+ alice.generate_fallback_key();
66
+ const aliceFallbackKey = getFallbackKey(alice);
67
+ const aliceIdentityKey = getIdentityKey(alice);
68
+ const bobToAlice = delegate.createSession();
69
+ bobToAlice.create_outbound(bob, aliceIdentityKey, aliceFallbackKey);
70
+ const encrypted1 = bobToAlice.encrypt('bob to alice 1');
71
+ const encrypted2 = bobToAlice.encrypt('bob to alice 2');
72
+ const aliceToBob = delegate.createSession();
73
+ aliceToBob.create_inbound(alice, encrypted2.body);
74
+ expect(aliceToBob.decrypt(encrypted2.type, encrypted2.body)).toEqual('bob to alice 2');
75
+ expect(aliceToBob.decrypt(encrypted1.type, encrypted1.body)).toEqual('bob to alice 1');
76
+ });
77
+ });
78
+ //# sourceMappingURL=encryptionDelegate.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encryptionDelegate.test.js","sourceRoot":"","sources":["../../src/tests/encryptionDelegate.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=group-encryption-protocol.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"group-encryption-protocol.test.d.ts","sourceRoot":"","sources":["../../src/tests/group-encryption-protocol.test.ts"],"names":[],"mappings":""}