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 @@ -65,7 +65,7 @@ const OlmBuffer &idKeys, const OlmBuffer &preKeys, const OlmBuffer &preKeySignature, - const OlmBuffer &oneTimeKey); + const std::optional &oneTimeKey); bool hasSessionFor(const std::string &targetDeviceId); std::shared_ptr getSessionByDeviceId(const std::string &deviceId); void removeSessionByDeviceId(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 @@ -288,7 +288,7 @@ const OlmBuffer &idKeys, const OlmBuffer &preKeys, const OlmBuffer &preKeySignature, - const OlmBuffer &oneTimeKey) { + const std::optional &oneTimeKey) { int newSessionVersion = 1; if (this->hasSessionFor(targetDeviceId)) { std::shared_ptr existingSession = 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 @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include "Tools.h" @@ -21,7 +22,7 @@ const OlmBuffer &idKeys, const OlmBuffer &preKeys, const OlmBuffer &preKeySignature, - const OlmBuffer &oneTimeKey); + const std::optional &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 @@ -1,6 +1,7 @@ #include "Session.h" #include "PlatformSpecificTools.h" +#include #include namespace comm { @@ -16,7 +17,7 @@ const OlmBuffer &idKeys, const OlmBuffer &preKeys, const OlmBuffer &preKeySignature, - const OlmBuffer &oneTimeKey) { + const std::optional &oneTimeKey) { std::unique_ptr session(new Session()); session->olmSessionBuffer.resize(::olm_session_size()); @@ -27,8 +28,31 @@ randomBuffer, ::olm_create_outbound_session_random_length(session->getOlmSession())); + if (oneTimeKey) { + if (-1 == + ::olm_create_outbound_session( + session->getOlmSession(), + account, + idKeys.data() + ID_KEYS_PREFIX_OFFSET, + KEYSIZE, + idKeys.data() + SIGNING_KEYS_PREFIX_OFFSET, + KEYSIZE, + preKeys.data(), + KEYSIZE, + preKeySignature.data(), + SIGNATURESIZE, + oneTimeKey->data(), + KEYSIZE, + randomBuffer.data(), + randomBuffer.size())) { + throw std::runtime_error( + "error createOutbound => " + + std::string{::olm_session_last_error(session->getOlmSession())}); + } + return session; + } if (-1 == - ::olm_create_outbound_session( + ::olm_create_outbound_session_without_otk( session->getOlmSession(), account, idKeys.data() + ID_KEYS_PREFIX_OFFSET, @@ -39,8 +63,6 @@ KEYSIZE, preKeySignature.data(), SIGNATURESIZE, - oneTimeKey.data(), - KEYSIZE, randomBuffer.data(), randomBuffer.size())) { throw std::runtime_error( diff --git a/native/cpp/CommonCpp/NativeModules/CommCoreModule.h b/native/cpp/CommonCpp/NativeModules/CommCoreModule.h --- a/native/cpp/CommonCpp/NativeModules/CommCoreModule.h +++ b/native/cpp/CommonCpp/NativeModules/CommCoreModule.h @@ -96,7 +96,7 @@ jsi::String identityKeys, jsi::String prekey, jsi::String prekeySignature, - jsi::String oneTimeKeys, + std::optional oneTimeKey, jsi::String keyserverID) override; virtual jsi::Value isNotificationsSessionInitialized(jsi::Runtime &rt) override; @@ -114,7 +114,7 @@ jsi::String identityKeys, jsi::String prekey, jsi::String prekeySignature, - jsi::String oneTimeKeys, + std::optional oneTimeKey, jsi::String deviceID) override; virtual jsi::Value initializeContentInboundSession( jsi::Runtime &rt, 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 @@ -1026,19 +1026,30 @@ jsi::String identityKeys, jsi::String prekey, jsi::String prekeySignature, - jsi::String oneTimeKey, + std::optional oneTimeKey, jsi::String keyserverID) { auto identityKeysCpp{identityKeys.utf8(rt)}; auto prekeyCpp{prekey.utf8(rt)}; auto prekeySignatureCpp{prekeySignature.utf8(rt)}; - auto oneTimeKeyCpp{oneTimeKey.utf8(rt)}; auto keyserverIDCpp{keyserverID.utf8(rt)}; + + std::optional oneTimeKeyCpp; + if (oneTimeKey) { + oneTimeKeyCpp = oneTimeKey->utf8(rt); + } + return createPromiseAsJSIValue( rt, [=](jsi::Runtime &innerRt, std::shared_ptr promise) { taskType job = [=, &innerRt]() { std::string error; crypto::EncryptedData result; try { + std::optional oneTimeKeyBuffer; + if (oneTimeKeyCpp) { + oneTimeKeyBuffer = crypto::OlmBuffer( + oneTimeKeyCpp->begin(), oneTimeKeyCpp->end()); + } + this->notifsCryptoModule->initializeOutboundForSendingSession( keyserverIDCpp, std::vector( @@ -1046,8 +1057,7 @@ std::vector(prekeyCpp.begin(), prekeyCpp.end()), std::vector( prekeySignatureCpp.begin(), prekeySignatureCpp.end()), - std::vector( - oneTimeKeyCpp.begin(), oneTimeKeyCpp.end())); + oneTimeKeyBuffer); result = this->notifsCryptoModule->encrypt( keyserverIDCpp, @@ -1237,13 +1247,18 @@ jsi::String identityKeys, jsi::String prekey, jsi::String prekeySignature, - jsi::String oneTimeKey, + std::optional oneTimeKey, jsi::String deviceID) { auto identityKeysCpp{identityKeys.utf8(rt)}; auto prekeyCpp{prekey.utf8(rt)}; auto prekeySignatureCpp{prekeySignature.utf8(rt)}; - auto oneTimeKeyCpp{oneTimeKey.utf8(rt)}; auto deviceIDCpp{deviceID.utf8(rt)}; + + std::optional oneTimeKeyCpp; + if (oneTimeKey) { + oneTimeKeyCpp = oneTimeKey->utf8(rt); + } + return createPromiseAsJSIValue( rt, [=](jsi::Runtime &innerRt, std::shared_ptr promise) { taskType job = [=, &innerRt]() { @@ -1251,6 +1266,11 @@ crypto::EncryptedData initialEncryptedData; int sessionVersion; try { + std::optional oneTimeKeyBuffer; + if (oneTimeKeyCpp) { + oneTimeKeyBuffer = crypto::OlmBuffer( + oneTimeKeyCpp->begin(), oneTimeKeyCpp->end()); + } sessionVersion = this->contentCryptoModule->initializeOutboundForSendingSession( deviceIDCpp, @@ -1259,8 +1279,7 @@ std::vector(prekeyCpp.begin(), prekeyCpp.end()), std::vector( prekeySignatureCpp.begin(), prekeySignatureCpp.end()), - std::vector( - oneTimeKeyCpp.begin(), oneTimeKeyCpp.end())); + oneTimeKeyBuffer); const std::string initMessage = "{\"type\": \"init\"}"; initialEncryptedData = diff --git a/native/cpp/CommonCpp/_generated/commJSI-generated.cpp b/native/cpp/CommonCpp/_generated/commJSI-generated.cpp --- a/native/cpp/CommonCpp/_generated/commJSI-generated.cpp +++ b/native/cpp/CommonCpp/_generated/commJSI-generated.cpp @@ -64,7 +64,7 @@ return static_cast(&turboModule)->validateAndUploadPrekeys(rt, args[0].asString(rt), args[1].asString(rt), args[2].asString(rt)); } static jsi::Value __hostFunction_CommCoreModuleSchemaCxxSpecJSI_initializeNotificationsSession(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { - return static_cast(&turboModule)->initializeNotificationsSession(rt, args[0].asString(rt), args[1].asString(rt), args[2].asString(rt), args[3].asString(rt), args[4].asString(rt)); + return static_cast(&turboModule)->initializeNotificationsSession(rt, args[0].asString(rt), args[1].asString(rt), args[2].asString(rt), args[3].isNull() || args[3].isUndefined() ? std::nullopt : std::make_optional(args[3].asString(rt)), args[4].asString(rt)); } static jsi::Value __hostFunction_CommCoreModuleSchemaCxxSpecJSI_isNotificationsSessionInitialized(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { return static_cast(&turboModule)->isNotificationsSessionInitialized(rt); @@ -79,7 +79,7 @@ return static_cast(&turboModule)->getKeyserverDataFromNotifStorage(rt, args[0].asObject(rt).asArray(rt)); } static jsi::Value __hostFunction_CommCoreModuleSchemaCxxSpecJSI_initializeContentOutboundSession(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { - return static_cast(&turboModule)->initializeContentOutboundSession(rt, args[0].asString(rt), args[1].asString(rt), args[2].asString(rt), args[3].asString(rt), args[4].asString(rt)); + return static_cast(&turboModule)->initializeContentOutboundSession(rt, args[0].asString(rt), args[1].asString(rt), args[2].asString(rt), args[3].isNull() || args[3].isUndefined() ? std::nullopt : std::make_optional(args[3].asString(rt)), args[4].asString(rt)); } static jsi::Value __hostFunction_CommCoreModuleSchemaCxxSpecJSI_initializeContentInboundSession(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { return static_cast(&turboModule)->initializeContentInboundSession(rt, args[0].asString(rt), args[1].asObject(rt), args[2].asString(rt), args[3].asNumber(), args[4].asBool()); 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 @@ -36,12 +36,12 @@ 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 oneTimeKey, jsi::String keyserverID) = 0; + virtual jsi::Value initializeNotificationsSession(jsi::Runtime &rt, jsi::String identityKeys, jsi::String prekey, jsi::String prekeySignature, std::optional oneTimeKey, jsi::String keyserverID) = 0; virtual jsi::Value isNotificationsSessionInitialized(jsi::Runtime &rt) = 0; virtual jsi::Value updateKeyserverDataInNotifStorage(jsi::Runtime &rt, jsi::Array keyserversData) = 0; virtual jsi::Value removeKeyserverDataFromNotifStorage(jsi::Runtime &rt, jsi::Array keyserverIDsToDelete) = 0; virtual jsi::Value getKeyserverDataFromNotifStorage(jsi::Runtime &rt, jsi::Array keyserverIDs) = 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 initializeContentOutboundSession(jsi::Runtime &rt, jsi::String identityKeys, jsi::String prekey, jsi::String prekeySignature, std::optional oneTimeKey, jsi::String deviceID) = 0; virtual jsi::Value initializeContentInboundSession(jsi::Runtime &rt, jsi::String identityKeys, jsi::Object encryptedContent, jsi::String deviceID, double sessionVersion, bool overwrite) = 0; virtual jsi::Value encrypt(jsi::Runtime &rt, jsi::String message, jsi::String deviceID) = 0; virtual jsi::Value decrypt(jsi::Runtime &rt, jsi::Object encryptedData, jsi::String deviceID) = 0; @@ -225,7 +225,7 @@ 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 oneTimeKey, jsi::String keyserverID) override { + jsi::Value initializeNotificationsSession(jsi::Runtime &rt, jsi::String identityKeys, jsi::String prekey, jsi::String prekeySignature, std::optional oneTimeKey, jsi::String keyserverID) override { static_assert( bridging::getParameterCount(&T::initializeNotificationsSession) == 6, "Expected initializeNotificationsSession(...) to have 6 parameters"); @@ -265,7 +265,7 @@ return bridging::callFromJs( rt, &T::getKeyserverDataFromNotifStorage, jsInvoker_, instance_, std::move(keyserverIDs)); } - jsi::Value initializeContentOutboundSession(jsi::Runtime &rt, jsi::String identityKeys, jsi::String prekey, jsi::String prekeySignature, jsi::String oneTimeKey, jsi::String deviceID) override { + jsi::Value initializeContentOutboundSession(jsi::Runtime &rt, jsi::String identityKeys, jsi::String prekey, jsi::String prekeySignature, std::optional oneTimeKey, jsi::String deviceID) override { static_assert( bridging::getParameterCount(&T::initializeContentOutboundSession) == 6, "Expected initializeContentOutboundSession(...) to have 6 parameters"); diff --git a/native/schema/CommCoreModuleSchema.js b/native/schema/CommCoreModuleSchema.js --- a/native/schema/CommCoreModuleSchema.js +++ b/native/schema/CommCoreModuleSchema.js @@ -61,7 +61,7 @@ identityKeys: string, prekey: string, prekeySignature: string, - oneTimeKey: string, + oneTimeKey: ?string, keyserverID: string, ) => Promise; +isNotificationsSessionInitialized: () => Promise; @@ -78,7 +78,7 @@ identityKeys: string, prekey: string, prekeySignature: string, - oneTimeKey: string, + oneTimeKey: ?string, deviceID: string, ) => Promise; +initializeContentInboundSession: (