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 @@ -2,6 +2,7 @@ import t, { type TInterface } from 'tcomb'; +import type { OlmSessionInitializationInfo } from './request-types.js'; import { type AuthMetadata } from '../shared/identity-client-context.js'; import { tShape } from '../utils/validation-utils.js'; @@ -130,6 +131,10 @@ contentIdentityKeys: OLMIdentityKeys, initialEncryptedContent: string, ) => Promise, + +contentOutboundSessionCreator: ( + contentIdentityKeys: OLMIdentityKeys, + contentInitializationInfo: OlmSessionInitializationInfo, + ) => Promise, +getOneTimeKeys: (numberOfKeys: number) => Promise, +validateAndUploadPrekeys: (authMetadata: AuthMetadata) => Promise, }; 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 @@ -17,6 +17,7 @@ encrypt: jest.fn(), decrypt: jest.fn(), contentInboundSessionCreator: jest.fn(), + contentOutboundSessionCreator: 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 @@ -7,6 +7,7 @@ OlmAPI, OLMIdentityKeys, } from 'lib/types/crypto-types'; +import type { OlmSessionInitializationInfo } from 'lib/types/request-types.js'; import { commCoreModule } from '../native-modules.js'; @@ -30,6 +31,24 @@ contentIdentityKeys.ed25519, ); }, + async contentOutboundSessionCreator( + contentIdentityKeys: OLMIdentityKeys, + contentInitializationInfo: OlmSessionInitializationInfo, + ): Promise { + const { prekey, prekeySignature, oneTimeKey } = contentInitializationInfo; + const identityKeys = JSON.stringify({ + curve25519: contentIdentityKeys.curve25519, + ed25519: contentIdentityKeys.ed25519, + }); + + return commCoreModule.initializeContentOutboundSession( + identityKeys, + prekey, + prekeySignature, + oneTimeKey, + contentIdentityKeys.ed25519, + ); + }, async getOneTimeKeys(numberOfKeys: number): Promise { 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 @@ -54,6 +54,7 @@ encrypt: proxyToWorker('encrypt'), decrypt: proxyToWorker('decrypt'), contentInboundSessionCreator: proxyToWorker('contentInboundSessionCreator'), + contentOutboundSessionCreator: proxyToWorker('contentOutboundSessionCreator'), 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 @@ -3,6 +3,7 @@ import olm from '@commapp/olm'; import uuid from 'uuid'; +import { initialEncryptedMessageContent } from 'lib/shared/crypto-utils.js'; import { olmEncryptedMessageTypes, type OLMIdentityKeys, @@ -17,6 +18,7 @@ IdentityNewDeviceKeyUpload, IdentityExistingDeviceKeyUpload, } from 'lib/types/identity-service-types.js'; +import type { OlmSessionInitializationInfo } from 'lib/types/request-types.js'; import { entries } from 'lib/utils/objects.js'; import { retrieveAccountKeysSet, @@ -389,6 +391,33 @@ return initialEncryptedMessage; }, + async contentOutboundSessionCreator( + contentIdentityKeys: OLMIdentityKeys, + contentInitializationInfo: OlmSessionInitializationInfo, + ): Promise { + if (!cryptoStore) { + throw new Error('Crypto account not initialized'); + } + const { contentAccount, contentSessions } = cryptoStore; + + const session = new olm.Session(); + session.create_outbound( + contentAccount, + contentIdentityKeys.curve25519, + contentIdentityKeys.ed25519, + contentInitializationInfo.prekey, + contentInitializationInfo.prekeySignature, + contentInitializationInfo.oneTimeKey, + ); + const { body: initialContentEncryptedMessage } = session.encrypt( + JSON.stringify(initialEncryptedMessageContent), + ); + + contentSessions[contentIdentityKeys.ed25519] = session; + persistCryptoStore(); + + return initialContentEncryptedMessage; + }, async getOneTimeKeys(numberOfKeys: number): Promise { if (!cryptoStore) { throw new Error('Crypto account not initialized');