Page MenuHomePhabricator

D11342.diff
No OneTemporary

D11342.diff

diff --git a/lib/types/crypto-types.js b/lib/types/crypto-types.js
--- a/lib/types/crypto-types.js
+++ b/lib/types/crypto-types.js
@@ -149,6 +149,12 @@
contentIdentityKeys: OLMIdentityKeys,
contentInitializationInfo: OlmSessionInitializationInfo,
) => Promise<string>,
+ +notificationsSessionCreator: (
+ cookie: ?string,
+ notificationsIdentityKeys: OLMIdentityKeys,
+ notificationsInitializationInfo: OlmSessionInitializationInfo,
+ keyserverID: string,
+ ) => Promise<string>,
+getOneTimeKeys: (numberOfKeys: number) => Promise<OneTimeKeysResultValues>,
+validateAndUploadPrekeys: (authMetadata: AuthMetadata) => Promise<void>,
};
diff --git a/lib/utils/__mocks__/config.js b/lib/utils/__mocks__/config.js
--- a/lib/utils/__mocks__/config.js
+++ b/lib/utils/__mocks__/config.js
@@ -19,6 +19,7 @@
decrypt: jest.fn(),
contentInboundSessionCreator: jest.fn(),
contentOutboundSessionCreator: jest.fn(),
+ notificationsSessionCreator: jest.fn(),
getOneTimeKeys: jest.fn(),
validateAndUploadPrekeys: jest.fn(),
},
diff --git a/native/crypto/olm-api.js b/native/crypto/olm-api.js
--- a/native/crypto/olm-api.js
+++ b/native/crypto/olm-api.js
@@ -50,6 +50,22 @@
contentIdentityKeys.ed25519,
);
},
+ notificationsSessionCreator(
+ cookie: ?string,
+ notificationsIdentityKeys: OLMIdentityKeys,
+ notificationsInitializationInfo: OlmSessionInitializationInfo,
+ keyserverID: string,
+ ): Promise<string> {
+ const { prekey, prekeySignature, oneTimeKey } =
+ notificationsInitializationInfo;
+ return commCoreModule.initializeNotificationsSession(
+ JSON.stringify(notificationsIdentityKeys),
+ prekey,
+ prekeySignature,
+ oneTimeKey,
+ keyserverID,
+ );
+ },
async getOneTimeKeys(numberOfKeys: number): Promise<OneTimeKeysResultValues> {
const { contentOneTimeKeys, notificationsOneTimeKeys } =
await commCoreModule.getOneTimeKeys(numberOfKeys);
diff --git a/web/crypto/olm-api.js b/web/crypto/olm-api.js
--- a/web/crypto/olm-api.js
+++ b/web/crypto/olm-api.js
@@ -56,6 +56,7 @@
decrypt: proxyToWorker('decrypt'),
contentInboundSessionCreator: proxyToWorker('contentInboundSessionCreator'),
contentOutboundSessionCreator: proxyToWorker('contentOutboundSessionCreator'),
+ notificationsSessionCreator: proxyToWorker('notificationsSessionCreator'),
getOneTimeKeys: proxyToWorker('getOneTimeKeys'),
validateAndUploadPrekeys: proxyToWorker('validateAndUploadPrekeys'),
};
diff --git a/web/shared-worker/worker/worker-crypto.js b/web/shared-worker/worker/worker-crypto.js
--- a/web/shared-worker/worker/worker-crypto.js
+++ b/web/shared-worker/worker/worker-crypto.js
@@ -1,9 +1,14 @@
// @flow
import olm from '@commapp/olm';
+import localforage from 'localforage';
import uuid from 'uuid';
import { initialEncryptedMessageContent } from 'lib/shared/crypto-utils.js';
+import {
+ hasMinCodeVersion,
+ NEXT_CODE_VERSION,
+} from 'lib/shared/version-utils.js';
import {
olmEncryptedMessageTypes,
type OLMIdentityKeys,
@@ -14,6 +19,7 @@
type OlmAPI,
type OneTimeKeysResultValues,
type ClientPublicKeys,
+ type NotificationsOlmDataType,
} from 'lib/types/crypto-types.js';
import type {
IdentityNewDeviceKeyUpload,
@@ -32,7 +38,20 @@
import { getIdentityClient } from './identity-client.js';
import { getProcessingStoreOpsExceptionMessage } from './process-operations.js';
-import { getDBModule, getSQLiteQueryExecutor } from './worker-database.js';
+import {
+ getDBModule,
+ getSQLiteQueryExecutor,
+ getPlatformDetails,
+} from './worker-database.js';
+import {
+ encryptData,
+ exportKeyToJWK,
+ generateCryptoKey,
+} from '../../crypto/aes-gcm-crypto-utils.js';
+import {
+ getOlmDataContentKeyForCookie,
+ getOlmEncryptionKeyDBLabelForCookie,
+} from '../../push-notif/notif-crypto-utils.js';
import {
type WorkerRequestMessage,
type WorkerResponseMessage,
@@ -40,6 +59,7 @@
workerResponseMessageTypes,
} from '../../types/worker-types.js';
import type { OlmPersistSession } from '../types/sqlite-query-executor.js';
+import { isDesktopSafari } from '../utils/db-utils.js';
type WorkerCryptoStore = {
+contentAccountPickleKey: string,
@@ -435,6 +455,95 @@
return initialContentEncryptedMessage;
},
+ async notificationsSessionCreator(
+ cookie: ?string,
+ notificationsIdentityKeys: OLMIdentityKeys,
+ notificationsInitializationInfo: OlmSessionInitializationInfo,
+ keyserverID: string,
+ ): Promise<string> {
+ const platformDetails = getPlatformDetails();
+ if (!platformDetails) {
+ throw new Error('Worker not initialized');
+ }
+
+ if (!cryptoStore) {
+ throw new Error('Crypto account not initialized');
+ }
+
+ const { notificationAccountPickleKey, notificationAccount } = cryptoStore;
+ const encryptionKey = await generateCryptoKey({
+ extractable: isDesktopSafari,
+ });
+
+ const notificationsPrekey = notificationsInitializationInfo.prekey;
+ const session = new olm.Session();
+ session.create_outbound(
+ notificationAccount,
+ notificationsIdentityKeys.curve25519,
+ notificationsIdentityKeys.ed25519,
+ notificationsPrekey,
+ notificationsInitializationInfo.prekeySignature,
+ notificationsInitializationInfo.oneTimeKey,
+ );
+ const { body: initialNotificationsEncryptedMessage } = session.encrypt(
+ JSON.stringify(initialEncryptedMessageContent),
+ );
+
+ const mainSession = session.pickle(notificationAccountPickleKey);
+ const notificationsOlmData: NotificationsOlmDataType = {
+ mainSession,
+ pendingSessionUpdate: mainSession,
+ updateCreationTimestamp: Date.now(),
+ picklingKey: notificationAccountPickleKey,
+ };
+ const encryptedOlmData = await encryptData(
+ new TextEncoder().encode(JSON.stringify(notificationsOlmData)),
+ encryptionKey,
+ );
+
+ let notifsOlmDataContentKey;
+ let notifsOlmDataEncryptionKeyDBLabel;
+
+ if (
+ hasMinCodeVersion(platformDetails, { majorDesktop: NEXT_CODE_VERSION })
+ ) {
+ notifsOlmDataEncryptionKeyDBLabel = getOlmEncryptionKeyDBLabelForCookie(
+ cookie,
+ keyserverID,
+ );
+ notifsOlmDataContentKey = getOlmDataContentKeyForCookie(
+ cookie,
+ keyserverID,
+ );
+ } else {
+ notifsOlmDataEncryptionKeyDBLabel =
+ getOlmEncryptionKeyDBLabelForCookie(cookie);
+ notifsOlmDataContentKey = getOlmDataContentKeyForCookie(cookie);
+ }
+
+ const persistEncryptionKeyPromise = (async () => {
+ let cryptoKeyPersistentForm;
+ if (isDesktopSafari) {
+ // Safari doesn't support structured clone algorithm in service
+ // worker context so we have to store CryptoKey as JSON
+ cryptoKeyPersistentForm = await exportKeyToJWK(encryptionKey);
+ } else {
+ cryptoKeyPersistentForm = encryptionKey;
+ }
+
+ await localforage.setItem(
+ notifsOlmDataEncryptionKeyDBLabel,
+ cryptoKeyPersistentForm,
+ );
+ })();
+
+ await Promise.all([
+ localforage.setItem(notifsOlmDataContentKey, encryptedOlmData),
+ persistEncryptionKeyPromise,
+ ]);
+
+ return initialNotificationsEncryptedMessage;
+ },
async getOneTimeKeys(numberOfKeys: number): Promise<OneTimeKeysResultValues> {
if (!cryptoStore) {
throw new Error('Crypto account not initialized');

File Metadata

Mime Type
text/plain
Expires
Tue, Nov 26, 2:23 AM (21 h, 51 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2582047
Default Alt Text
D11342.diff (7 KB)

Event Timeline