diff --git a/lib/types/crypto-types.js b/lib/types/crypto-types.js index 754fc4e7c..02aef80d9 100644 --- a/lib/types/crypto-types.js +++ b/lib/types/crypto-types.js @@ -1,129 +1,133 @@ // @flow import t, { type TInterface } from 'tcomb'; import { tShape } from '../utils/validation-utils.js'; export type OLMIdentityKeys = { +ed25519: string, +curve25519: string, }; const olmIdentityKeysValidator: TInterface = tShape({ ed25519: t.String, curve25519: t.String, }); export type OLMPrekey = { +curve25519: { +id: string, +key: string, }, }; export type SignedPrekeys = { +contentPrekey: string, +contentPrekeySignature: string, +notifPrekey: string, +notifPrekeySignature: string, }; export const signedPrekeysValidator: TInterface = tShape({ contentPrekey: t.String, contentPrekeySignature: t.String, notifPrekey: t.String, notifPrekeySignature: t.String, }); export type OLMOneTimeKeys = { +curve25519: { +[string]: string }, }; export type OneTimeKeysResult = { +contentOneTimeKeys: OLMOneTimeKeys, +notificationsOneTimeKeys: OLMOneTimeKeys, }; export type OneTimeKeysResultValues = { +contentOneTimeKeys: $ReadOnlyArray, +notificationsOneTimeKeys: $ReadOnlyArray, }; export type PickledOLMAccount = { +picklingKey: string, +pickledAccount: string, }; export type CryptoStore = { +primaryAccount: PickledOLMAccount, +primaryIdentityKeys: OLMIdentityKeys, +notificationAccount: PickledOLMAccount, +notificationIdentityKeys: OLMIdentityKeys, }; export type CryptoStoreContextType = { +getInitializedCryptoStore: () => Promise, }; export type NotificationsOlmDataType = { +mainSession: string, +picklingKey: string, +pendingSessionUpdate: string, +updateCreationTimestamp: number, }; export type IdentityKeysBlob = { +primaryIdentityPublicKeys: OLMIdentityKeys, +notificationIdentityPublicKeys: OLMIdentityKeys, }; export const identityKeysBlobValidator: TInterface = tShape({ primaryIdentityPublicKeys: olmIdentityKeysValidator, notificationIdentityPublicKeys: olmIdentityKeysValidator, }); export type SignedIdentityKeysBlob = { +payload: string, +signature: string, }; export const signedIdentityKeysBlobValidator: TInterface = tShape({ payload: t.String, signature: t.String, }); export type UserDetail = { +username: string, +userID: string, }; // This type should not be changed without making equivalent changes to // `Message` in Identity service's `reserved_users` module export type ReservedUsernameMessage = | { +statement: 'Add the following usernames to reserved list', +payload: $ReadOnlyArray, +issuedAt: string, } | { +statement: 'Remove the following username from reserved list', +payload: string, +issuedAt: string, } | { +statement: 'This user is the owner of the following username and user ID', +payload: UserDetail, +issuedAt: string, }; export const olmEncryptedMessageTypes = Object.freeze({ PREKEY: 0, TEXT: 1, }); export type OlmAPI = { +initializeCryptoAccount: () => Promise, +encrypt: (content: string, deviceID: string) => Promise, +decrypt: (encryptedContent: string, deviceID: string) => Promise, + +contentInboundSessionCreator: ( + contentIdentityKeys: OLMIdentityKeys, + initialEncryptedContent: string, + ) => Promise, }; diff --git a/native/crypto/olm-api.js b/native/crypto/olm-api.js index 69329ad5d..adc6afd31 100644 --- a/native/crypto/olm-api.js +++ b/native/crypto/olm-api.js @@ -1,15 +1,29 @@ // @flow -import type { OlmAPI } from 'lib/types/crypto-types'; +import type { OlmAPI, OLMIdentityKeys } from 'lib/types/crypto-types'; import { commCoreModule } from '../native-modules.js'; const olmAPI: OlmAPI = { async initializeCryptoAccount(): Promise { await commCoreModule.initializeCryptoAccount(); }, encrypt: commCoreModule.encrypt, decrypt: commCoreModule.decrypt, + async contentInboundSessionCreator( + contentIdentityKeys: OLMIdentityKeys, + initialEncryptedContent: string, + ): Promise { + const identityKeys = JSON.stringify({ + curve25519: contentIdentityKeys.curve25519, + ed25519: contentIdentityKeys.ed25519, + }); + return commCoreModule.initializeContentInboundSession( + identityKeys, + initialEncryptedContent, + contentIdentityKeys.ed25519, + ); + }, }; export { olmAPI }; diff --git a/web/crypto/olm-api.js b/web/crypto/olm-api.js index 1a5f6cb9b..03bd043a5 100644 --- a/web/crypto/olm-api.js +++ b/web/crypto/olm-api.js @@ -1,47 +1,69 @@ // @flow import olm from '@commapp/olm'; import type { Account, Session } from '@commapp/olm'; import { type OlmAPI, olmEncryptedMessageTypes, + type OLMIdentityKeys, } from 'lib/types/crypto-types.js'; // methods below are just mocks to SQLite API // implement proper methods tracked in ENG-6462 -// eslint-disable-next-line no-unused-vars + function getOlmAccount(): Account { return new olm.Account(); } // eslint-disable-next-line no-unused-vars function getOlmSession(deviceID: string): Session { return new olm.Session(); } // eslint-disable-next-line no-unused-vars function storeOlmAccount(account: Account): void {} // eslint-disable-next-line no-unused-vars function storeOlmSession(session: Session): void {} const olmAPI: OlmAPI = { async initializeCryptoAccount(): Promise { await olm.init(); }, async encrypt(content: string, deviceID: string): Promise { const session = getOlmSession(deviceID); const { body } = session.encrypt(content); storeOlmSession(session); return body; }, async decrypt(encryptedContent: string, deviceID: string): Promise { const session = getOlmSession(deviceID); const result = session.decrypt( olmEncryptedMessageTypes.TEXT, encryptedContent, ); storeOlmSession(session); return result; }, + async contentInboundSessionCreator( + contentIdentityKeys: OLMIdentityKeys, + initialEncryptedContent: string, + ): Promise { + const account = getOlmAccount(); + const session = new olm.Session(); + session.create_inbound_from( + account, + contentIdentityKeys.curve25519, + initialEncryptedContent, + ); + + account.remove_one_time_keys(session); + const initialEncryptedMessage = session.decrypt( + olmEncryptedMessageTypes.PREKEY, + initialEncryptedContent, + ); + storeOlmAccount(account); + storeOlmSession(session); + return initialEncryptedMessage; + }, }; export { olmAPI };