diff --git a/lib/actions/user-actions.js b/lib/actions/user-actions.js --- a/lib/actions/user-actions.js +++ b/lib/actions/user-actions.js @@ -10,6 +10,7 @@ } from '../keyserver-conn/keyserver-call-utils.js'; import type { CallKeyserverEndpoint } from '../keyserver-conn/keyserver-conn-types.js'; import { preRequestUserStateSelector } from '../selectors/account-selectors.js'; +import { getOneTimeKeyValuesFromBlob } from '../shared/crypto-utils.js'; import { IdentityClientContext } from '../shared/identity-client-context.js'; import threadWatcher from '../shared/thread-watcher.js'; import type { @@ -757,11 +758,26 @@ options?: ?CallSingleKeyserverEndpointOptions, ) => Promise) => async options => { - return await callSingleKeyserverEndpoint( + const olmInitData = await callSingleKeyserverEndpoint( 'get_olm_session_initialization_data', {}, options, ); + return { + signedIdentityKeysBlob: olmInitData.signedIdentityKeysBlob, + contentInitializationInfo: { + ...olmInitData.contentInitializationInfo, + oneTimeKey: getOneTimeKeyValuesFromBlob( + olmInitData.contentInitializationInfo.oneTimeKey, + )[0], + }, + notifInitializationInfo: { + ...olmInitData.notifInitializationInfo, + oneTimeKey: getOneTimeKeyValuesFromBlob( + olmInitData.notifInitializationInfo.oneTimeKey, + )[0], + }, + }; }; const policyAcknowledgmentActionTypes = Object.freeze({ diff --git a/lib/shared/crypto-utils.js b/lib/shared/crypto-utils.js --- a/lib/shared/crypto-utils.js +++ b/lib/shared/crypto-utils.js @@ -17,7 +17,7 @@ CallSingleKeyserverEndpointOptions, CallSingleKeyserverEndpoint, } from '../utils/call-single-keyserver-endpoint.js'; -import { values, entries } from '../utils/objects.js'; +import { values } from '../utils/objects.js'; import { useDispatchActionPromise } from '../utils/redux-promise-utils.js'; export type InitialNotifMessageOptions = { @@ -104,14 +104,6 @@ return getPrekeyValue(prekey); } -function getOneTimeKeyArray( - oneTimeKeys: OLMOneTimeKeys, -): $ReadOnlyArray { - return entries(oneTimeKeys.curve25519).map(([key, value]: [string, string]) => - JSON.stringify({ curve25519: { [key]: value } }), - ); -} - export { getOneTimeKeyValues, getPrekeyValue, @@ -119,5 +111,4 @@ getPrekeyValueFromBlob, initialEncryptedMessageContent, useInitialNotificationsEncryptedMessage, - getOneTimeKeyArray, }; diff --git a/native/cpp/CommonCpp/CryptoTools/CryptoModule.h b/native/cpp/CommonCpp/CryptoTools/CryptoModule.h --- a/native/cpp/CommonCpp/CryptoTools/CryptoModule.h +++ b/native/cpp/CommonCpp/CryptoTools/CryptoModule.h @@ -64,8 +64,7 @@ const OlmBuffer &idKeys, const OlmBuffer &preKeys, const OlmBuffer &preKeySignature, - const OlmBuffer &oneTimeKeys, - size_t keyIndex = 0); + const OlmBuffer &oneTimeKey); bool hasSessionFor(const std::string &targetDeviceId); std::shared_ptr getSessionByDeviceId(const std::string &deviceId); diff --git a/native/cpp/CommonCpp/CryptoTools/CryptoModule.cpp b/native/cpp/CommonCpp/CryptoTools/CryptoModule.cpp --- a/native/cpp/CommonCpp/CryptoTools/CryptoModule.cpp +++ b/native/cpp/CommonCpp/CryptoTools/CryptoModule.cpp @@ -284,8 +284,7 @@ const OlmBuffer &idKeys, const OlmBuffer &preKeys, const OlmBuffer &preKeySignature, - const OlmBuffer &oneTimeKeys, - size_t keyIndex) { + const OlmBuffer &oneTimeKey) { if (this->hasSessionFor(targetDeviceId)) { Logger::log( "olm session overwritten for the device with id: " + targetDeviceId); @@ -297,8 +296,7 @@ idKeys, preKeys, preKeySignature, - oneTimeKeys, - keyIndex); + oneTimeKey); this->sessions.insert(make_pair(targetDeviceId, std::move(newSession))); } diff --git a/native/cpp/CommonCpp/CryptoTools/Session.h b/native/cpp/CommonCpp/CryptoTools/Session.h --- a/native/cpp/CommonCpp/CryptoTools/Session.h +++ b/native/cpp/CommonCpp/CryptoTools/Session.h @@ -27,8 +27,7 @@ const OlmBuffer &idKeys, const OlmBuffer &preKeys, const OlmBuffer &preKeySignature, - const OlmBuffer &oneTimeKeys, - size_t keyIndex = 0); + const OlmBuffer &oneTimeKey); static std::unique_ptr createSessionAsResponder( OlmAccount *account, std::uint8_t *ownerIdentityKeys, diff --git a/native/cpp/CommonCpp/CryptoTools/Session.cpp b/native/cpp/CommonCpp/CryptoTools/Session.cpp --- a/native/cpp/CommonCpp/CryptoTools/Session.cpp +++ b/native/cpp/CommonCpp/CryptoTools/Session.cpp @@ -16,8 +16,7 @@ const OlmBuffer &idKeys, const OlmBuffer &preKeys, const OlmBuffer &preKeySignature, - const OlmBuffer &oneTimeKeys, - size_t keyIndex) { + const OlmBuffer &oneTimeKey) { std::unique_ptr session(new Session(account, ownerIdentityKeys)); session->olmSessionBuffer.resize(::olm_session_size()); @@ -40,8 +39,7 @@ KEYSIZE, preKeySignature.data(), SIGNATURESIZE, - oneTimeKeys.data() + ONE_TIME_KEYS_PREFIX_OFFSET + - (KEYSIZE + ONE_TIME_KEYS_MIDDLE_OFFSET) * keyIndex, + oneTimeKey.data(), KEYSIZE, randomBuffer.data(), randomBuffer.size())) { @@ -75,7 +73,7 @@ if (-1 == ::olm_remove_one_time_keys(account, session->getOlmSession())) { throw std::runtime_error( - "error createInbound (remove oneTimeKeys) => " + + "error createInbound (remove oneTimeKey) => " + std::string{::olm_session_last_error(session->getOlmSession())}); } return session; diff --git a/native/cpp/CommonCpp/CryptoTools/Tools.h b/native/cpp/CommonCpp/CryptoTools/Tools.h --- a/native/cpp/CommonCpp/CryptoTools/Tools.h +++ b/native/cpp/CommonCpp/CryptoTools/Tools.h @@ -11,8 +11,6 @@ #define ID_KEYS_PREFIX_OFFSET 15 #define SIGNING_KEYS_PREFIX_OFFSET 71 #define PRE_KEY_PREFIX_OFFSET 25 -#define ONE_TIME_KEYS_PREFIX_OFFSET 25 -#define ONE_TIME_KEYS_MIDDLE_OFFSET 12 #define ENCRYPTED_MESSAGE_TYPE 1 diff --git a/native/cpp/CommonCpp/NativeModules/CommCoreModule.cpp b/native/cpp/CommonCpp/NativeModules/CommCoreModule.cpp --- a/native/cpp/CommonCpp/NativeModules/CommCoreModule.cpp +++ b/native/cpp/CommonCpp/NativeModules/CommCoreModule.cpp @@ -796,12 +796,12 @@ jsi::String identityKeys, jsi::String prekey, jsi::String prekeySignature, - jsi::String oneTimeKeys, + jsi::String oneTimeKey, jsi::String keyserverID) { auto identityKeysCpp{identityKeys.utf8(rt)}; auto prekeyCpp{prekey.utf8(rt)}; auto prekeySignatureCpp{prekeySignature.utf8(rt)}; - auto oneTimeKeysCpp{oneTimeKeys.utf8(rt)}; + auto oneTimeKeyCpp{oneTimeKey.utf8(rt)}; return createPromiseAsJSIValue( rt, [=](jsi::Runtime &innerRt, std::shared_ptr promise) { taskType job = [=, &innerRt]() { @@ -812,7 +812,7 @@ identityKeysCpp, prekeyCpp, prekeySignatureCpp, - oneTimeKeysCpp, + oneTimeKeyCpp, "Comm"); } catch (const std::exception &e) { error = e.what(); @@ -861,12 +861,12 @@ jsi::String identityKeys, jsi::String prekey, jsi::String prekeySignature, - jsi::String oneTimeKeys, + jsi::String oneTimeKey, jsi::String deviceID) { auto identityKeysCpp{identityKeys.utf8(rt)}; auto prekeyCpp{prekey.utf8(rt)}; auto prekeySignatureCpp{prekeySignature.utf8(rt)}; - auto oneTimeKeysCpp{oneTimeKeys.utf8(rt)}; + auto oneTimeKeyCpp{oneTimeKey.utf8(rt)}; auto deviceIDCpp{deviceID.utf8(rt)}; return createPromiseAsJSIValue( rt, [=](jsi::Runtime &innerRt, std::shared_ptr promise) { @@ -882,7 +882,7 @@ std::vector( prekeySignatureCpp.begin(), prekeySignatureCpp.end()), std::vector( - oneTimeKeysCpp.begin(), oneTimeKeysCpp.end())); + oneTimeKeyCpp.begin(), oneTimeKeyCpp.end())); const std::string initMessage = "{\"type\": \"init\"}"; initialEncryptedMessage = diff --git a/native/cpp/CommonCpp/Notifications/BackgroundDataStorage/NotificationsCryptoModule.cpp b/native/cpp/CommonCpp/Notifications/BackgroundDataStorage/NotificationsCryptoModule.cpp --- a/native/cpp/CommonCpp/Notifications/BackgroundDataStorage/NotificationsCryptoModule.cpp +++ b/native/cpp/CommonCpp/Notifications/BackgroundDataStorage/NotificationsCryptoModule.cpp @@ -241,7 +241,7 @@ const std::string &identityKeys, const std::string &prekey, const std::string &prekeySignature, - const std::string &oneTimeKeys, + const std::string &oneTimeKey, const std::string &callingProcessName) { crypto::EncryptedData initialEncryptedMessage; auto caller = [&](const std::unique_ptr &cryptoModule) { @@ -250,7 +250,7 @@ std::vector(identityKeys.begin(), identityKeys.end()), std::vector(prekey.begin(), prekey.end()), std::vector(prekeySignature.begin(), prekeySignature.end()), - std::vector(oneTimeKeys.begin(), oneTimeKeys.end())); + std::vector(oneTimeKey.begin(), oneTimeKey.end())); initialEncryptedMessage = cryptoModule->encrypt( NotificationsCryptoModule::keyserverHostedNotificationsID, NotificationsCryptoModule::initialEncryptedMessageContent); diff --git a/native/cpp/CommonCpp/_generated/commJSI.h b/native/cpp/CommonCpp/_generated/commJSI.h --- a/native/cpp/CommonCpp/_generated/commJSI.h +++ b/native/cpp/CommonCpp/_generated/commJSI.h @@ -41,9 +41,9 @@ virtual jsi::Value getOneTimeKeys(jsi::Runtime &rt, double oneTimeKeysAmount) = 0; virtual jsi::Value validateAndGetPrekeys(jsi::Runtime &rt) = 0; virtual jsi::Value validateAndUploadPrekeys(jsi::Runtime &rt, jsi::String authUserID, jsi::String authDeviceID, jsi::String authAccessToken) = 0; - virtual jsi::Value initializeNotificationsSession(jsi::Runtime &rt, jsi::String identityKeys, jsi::String prekey, jsi::String prekeySignature, jsi::String oneTimeKeys, jsi::String keyserverID) = 0; + virtual jsi::Value initializeNotificationsSession(jsi::Runtime &rt, jsi::String identityKeys, jsi::String prekey, jsi::String prekeySignature, jsi::String oneTimeKey, jsi::String keyserverID) = 0; virtual jsi::Value isNotificationsSessionInitialized(jsi::Runtime &rt) = 0; - virtual jsi::Value initializeContentOutboundSession(jsi::Runtime &rt, jsi::String identityKeys, jsi::String prekey, jsi::String prekeySignature, jsi::String oneTimeKeys, jsi::String deviceID) = 0; + virtual jsi::Value initializeContentOutboundSession(jsi::Runtime &rt, jsi::String identityKeys, jsi::String prekey, jsi::String prekeySignature, jsi::String oneTimeKey, jsi::String deviceID) = 0; virtual jsi::Value initializeContentInboundSession(jsi::Runtime &rt, jsi::String identityKeys, jsi::String encryptedMessage, jsi::String deviceID) = 0; virtual jsi::Value encrypt(jsi::Runtime &rt, jsi::String message, jsi::String deviceID) = 0; virtual jsi::Value decrypt(jsi::Runtime &rt, jsi::String message, jsi::String deviceID) = 0; @@ -255,13 +255,13 @@ return bridging::callFromJs( rt, &T::validateAndUploadPrekeys, jsInvoker_, instance_, std::move(authUserID), std::move(authDeviceID), std::move(authAccessToken)); } - jsi::Value initializeNotificationsSession(jsi::Runtime &rt, jsi::String identityKeys, jsi::String prekey, jsi::String prekeySignature, jsi::String oneTimeKeys, jsi::String keyserverID) override { + jsi::Value initializeNotificationsSession(jsi::Runtime &rt, jsi::String identityKeys, jsi::String prekey, jsi::String prekeySignature, jsi::String oneTimeKey, jsi::String keyserverID) override { static_assert( bridging::getParameterCount(&T::initializeNotificationsSession) == 6, "Expected initializeNotificationsSession(...) to have 6 parameters"); return bridging::callFromJs( - rt, &T::initializeNotificationsSession, jsInvoker_, instance_, std::move(identityKeys), std::move(prekey), std::move(prekeySignature), std::move(oneTimeKeys), std::move(keyserverID)); + rt, &T::initializeNotificationsSession, jsInvoker_, instance_, std::move(identityKeys), std::move(prekey), std::move(prekeySignature), std::move(oneTimeKey), std::move(keyserverID)); } jsi::Value isNotificationsSessionInitialized(jsi::Runtime &rt) override { static_assert( @@ -271,13 +271,13 @@ return bridging::callFromJs( rt, &T::isNotificationsSessionInitialized, jsInvoker_, instance_); } - jsi::Value initializeContentOutboundSession(jsi::Runtime &rt, jsi::String identityKeys, jsi::String prekey, jsi::String prekeySignature, jsi::String oneTimeKeys, jsi::String deviceID) override { + jsi::Value initializeContentOutboundSession(jsi::Runtime &rt, jsi::String identityKeys, jsi::String prekey, jsi::String prekeySignature, jsi::String oneTimeKey, jsi::String deviceID) override { static_assert( bridging::getParameterCount(&T::initializeContentOutboundSession) == 6, "Expected initializeContentOutboundSession(...) to have 6 parameters"); return bridging::callFromJs( - rt, &T::initializeContentOutboundSession, jsInvoker_, instance_, std::move(identityKeys), std::move(prekey), std::move(prekeySignature), std::move(oneTimeKeys), std::move(deviceID)); + rt, &T::initializeContentOutboundSession, jsInvoker_, instance_, std::move(identityKeys), std::move(prekey), std::move(prekeySignature), std::move(oneTimeKey), std::move(deviceID)); } jsi::Value initializeContentInboundSession(jsi::Runtime &rt, jsi::String identityKeys, jsi::String encryptedMessage, jsi::String deviceID) override { static_assert( diff --git a/native/handlers/peer-to-peer-message-handler.js b/native/handlers/peer-to-peer-message-handler.js --- a/native/handlers/peer-to-peer-message-handler.js +++ b/native/handlers/peer-to-peer-message-handler.js @@ -1,6 +1,6 @@ // @flow -import { getOneTimeKeyArray } from 'lib/shared/crypto-utils.js'; +import { getOneTimeKeyValues } from 'lib/shared/crypto-utils.js'; import { type PeerToPeerMessage, peerToPeerMessageTypes, @@ -64,8 +64,8 @@ userID, deviceID, accessToken, - getOneTimeKeyArray(contentOneTimeKeys), - getOneTimeKeyArray(notificationsOneTimeKeys), + getOneTimeKeyValues(contentOneTimeKeys), + getOneTimeKeyValues(notificationsOneTimeKeys), ); } catch (e) { console.log(`Error uploading one-time keys: ${e.message}`); diff --git a/native/schema/CommCoreModuleSchema.js b/native/schema/CommCoreModuleSchema.js --- a/native/schema/CommCoreModuleSchema.js +++ b/native/schema/CommCoreModuleSchema.js @@ -95,7 +95,7 @@ identityKeys: string, prekey: string, prekeySignature: string, - oneTimeKeys: string, + oneTimeKey: string, keyserverID: string, ) => Promise; +isNotificationsSessionInitialized: () => Promise; @@ -103,7 +103,7 @@ identityKeys: string, prekey: string, prekeySignature: string, - oneTimeKeys: string, + oneTimeKey: string, deviceID: string, ) => Promise; +initializeContentInboundSession: ( diff --git a/web/account/account-hooks.js b/web/account/account-hooks.js --- a/web/account/account-hooks.js +++ b/web/account/account-hooks.js @@ -8,7 +8,6 @@ import { initialEncryptedMessageContent, - getOneTimeKeyValuesFromBlob, getPrekeyValueFromBlob, } from 'lib/shared/crypto-utils.js'; import { OlmSessionCreatorContext } from 'lib/shared/olm-session-creator-context.js'; @@ -262,9 +261,6 @@ const notificationsPrekey = getPrekeyValueFromBlob( notificationsInitializationInfo.prekey, ); - const [notificationsOneTimeKey] = getOneTimeKeyValuesFromBlob( - notificationsInitializationInfo.oneTimeKey, - ); const session = new olm.Session(); session.create_outbound( @@ -273,7 +269,7 @@ notificationsIdentityKeys.ed25519, notificationsPrekey, notificationsInitializationInfo.prekeySignature, - notificationsOneTimeKey, + notificationsInitializationInfo.oneTimeKey, ); const { body: initialNotificationsEncryptedMessage } = session.encrypt( JSON.stringify(initialEncryptedMessageContent), @@ -341,9 +337,6 @@ const contentPrekey = getPrekeyValueFromBlob( contentInitializationInfo.prekey, ); - const [contentOneTimeKey] = getOneTimeKeyValuesFromBlob( - contentInitializationInfo.oneTimeKey, - ); const session = new olm.Session(); session.create_outbound( @@ -352,7 +345,7 @@ contentIdentityKeys.ed25519, contentPrekey, contentInitializationInfo.prekeySignature, - contentOneTimeKey, + contentInitializationInfo.oneTimeKey, ); const { body: initialContentEncryptedMessage } = session.encrypt( JSON.stringify(initialEncryptedMessageContent),