Page MenuHomePhorge

D11234.1765269981.diff
No OneTemporary

Size
30 KB
Referenced Files
None
Subscribers
None

D11234.1765269981.diff

diff --git a/native/android/app/src/cpp/NotificationsCryptoModuleJNIHelper.cpp b/native/android/app/src/cpp/NotificationsCryptoModuleJNIHelper.cpp
--- a/native/android/app/src/cpp/NotificationsCryptoModuleJNIHelper.cpp
+++ b/native/android/app/src/cpp/NotificationsCryptoModuleJNIHelper.cpp
@@ -9,11 +9,11 @@
std::string NotificationsCryptoModuleJNIHelper::decrypt(
facebook::jni::alias_ref<NotificationsCryptoModuleJNIHelper> jThis,
+ std::string keyserverID,
std::string data,
- int messageType,
- std::string callingProcessName) {
+ int messageType) {
std::string decryptedData =
- NotificationsCryptoModule::decrypt(data, messageType, callingProcessName);
+ NotificationsCryptoModule::decrypt(keyserverID, data, messageType);
return decryptedData;
}
diff --git a/native/android/app/src/main/java/app/comm/android/fbjni/NotificationsCryptoModule.java b/native/android/app/src/main/java/app/comm/android/fbjni/NotificationsCryptoModule.java
--- a/native/android/app/src/main/java/app/comm/android/fbjni/NotificationsCryptoModule.java
+++ b/native/android/app/src/main/java/app/comm/android/fbjni/NotificationsCryptoModule.java
@@ -3,5 +3,5 @@
public class NotificationsCryptoModule {
public static native int olmEncryptedTypeMessage();
public static native String
- decrypt(String data, int messageType, String callingProcessName);
+ decrypt(String keyserverID, String data, int messageType);
}
diff --git a/native/android/app/src/main/java/app/comm/android/notifications/CommNotificationsHandler.java b/native/android/app/src/main/java/app/comm/android/notifications/CommNotificationsHandler.java
--- a/native/android/app/src/main/java/app/comm/android/notifications/CommNotificationsHandler.java
+++ b/native/android/app/src/main/java/app/comm/android/notifications/CommNotificationsHandler.java
@@ -89,9 +89,14 @@
@Override
public void onMessageReceived(RemoteMessage message) {
+ String senderKeyserverID = message.getData().get(KEYSERVER_ID_KEY);
+ if (senderKeyserverID == null) {
+ senderKeyserverID = ASHOAT_KEYSERVER_ID;
+ }
+
if (message.getData().get(ENCRYPTED_PAYLOAD_KEY) != null) {
try {
- message = this.decryptRemoteMessage(message);
+ message = this.decryptRemoteMessage(message, senderKeyserverID);
} catch (JSONException e) {
Log.w("COMM", "Malformed notification JSON payload.", e);
return;
@@ -375,14 +380,15 @@
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE);
}
- private RemoteMessage decryptRemoteMessage(RemoteMessage message)
+ private RemoteMessage
+ decryptRemoteMessage(RemoteMessage message, String senderKeyserverID)
throws JSONException, IllegalStateException {
String encryptedSerializedPayload =
message.getData().get(ENCRYPTED_PAYLOAD_KEY);
String decryptedSerializedPayload = NotificationsCryptoModule.decrypt(
+ senderKeyserverID,
encryptedSerializedPayload,
- NotificationsCryptoModule.olmEncryptedTypeMessage(),
- "CommNotificationsHandler");
+ NotificationsCryptoModule.olmEncryptedTypeMessage());
JSONObject decryptedPayload = new JSONObject(decryptedSerializedPayload);
diff --git a/native/cpp/CommonCpp/DatabaseManagers/SQLiteQueryExecutor.cpp b/native/cpp/CommonCpp/DatabaseManagers/SQLiteQueryExecutor.cpp
--- a/native/cpp/CommonCpp/DatabaseManagers/SQLiteQueryExecutor.cpp
+++ b/native/cpp/CommonCpp/DatabaseManagers/SQLiteQueryExecutor.cpp
@@ -11,6 +11,8 @@
#include <thread>
#ifndef EMSCRIPTEN
+#include "../CryptoTools/CryptoModule.h"
+#include "../Notifications/BackgroundDataStorage/NotificationsCryptoModule.h"
#include "CommSecureStore.h"
#include "PlatformSpecificTools.h"
#include "StaffUtils.h"
@@ -513,6 +515,41 @@
return create_table(db, query, "communities");
}
+bool migrate_notifs_crypto_account(sqlite3 *db) {
+#ifndef EMSCRIPTEN
+ std::string legacyCryptoAccountDataKey = "cryptoAccountDataKey";
+ folly::Optional<std::string> secretKey =
+ CommSecureStore::get(legacyCryptoAccountDataKey);
+
+ if (!secretKey.hasValue()) {
+ return false;
+ }
+
+ std::unique_ptr<crypto::CryptoModule> legacyNotifsAccount =
+ NotificationsCryptoModule::migrateLegacyNotificationsCryptoModule();
+
+ if (!legacyNotifsAccount) {
+ return true;
+ }
+
+ std::string insert_notifs_account_query =
+ "REPLACE INTO olm_persist_account (id, account_data) "
+ "VALUES (?, ?);";
+
+ crypto::Persist legacyNotifsPersist =
+ legacyNotifsAccount->storeAsB64(secretKey.value());
+ std::string notifsAccountData = std::string(
+ legacyNotifsPersist.account.begin(), legacyNotifsPersist.account.end());
+
+ replaceEntity<OlmPersistAccount>(
+ db, insert_notifs_account_query, {NOTIFS_ACCOUNT_ID, notifsAccountData});
+
+ return true;
+#else
+ return true;
+#endif
+}
+
bool create_schema(sqlite3 *db) {
char *error;
sqlite3_exec(
@@ -846,7 +883,8 @@
{32, {create_users_table, true}},
{33, {create_keyservers_table, true}},
{34, {enable_rollback_journal_mode, false}},
- {35, {create_communities_table, true}}}};
+ {35, {create_communities_table, true}},
+ {36, {migrate_notifs_crypto_account, true}}}};
enum class MigrationResult { SUCCESS, FAILURE, NOT_APPLIED };
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
@@ -841,21 +841,35 @@
auto prekeyCpp{prekey.utf8(rt)};
auto prekeySignatureCpp{prekeySignature.utf8(rt)};
auto oneTimeKeyCpp{oneTimeKey.utf8(rt)};
+ auto keyserverIDCpp{keyserverID.utf8(rt)};
return createPromiseAsJSIValue(
rt, [=](jsi::Runtime &innerRt, std::shared_ptr<Promise> promise) {
taskType job = [=, &innerRt]() {
std::string error;
crypto::EncryptedData result;
try {
- // Introduced temporarily to make this diff non-breaking change
- NotificationsCryptoModule::initializeNotificationsCryptoAccount(
- "Comm");
- result = NotificationsCryptoModule::initializeNotificationsSession(
- identityKeysCpp,
- prekeyCpp,
- prekeySignatureCpp,
- oneTimeKeyCpp,
- "Comm");
+ this->notifsCryptoModule->initializeOutboundForSendingSession(
+ keyserverIDCpp,
+ std::vector<uint8_t>(
+ identityKeysCpp.begin(), identityKeysCpp.end()),
+ std::vector<uint8_t>(prekeyCpp.begin(), prekeyCpp.end()),
+ std::vector<uint8_t>(
+ prekeySignatureCpp.begin(), prekeySignatureCpp.end()),
+ std::vector<uint8_t>(
+ oneTimeKeyCpp.begin(), oneTimeKeyCpp.end()));
+
+ result = this->notifsCryptoModule->encrypt(
+ keyserverIDCpp,
+ NotificationsCryptoModule::initialEncryptedMessageContent);
+
+ std::shared_ptr<crypto::Session> keyserverNotificationsSession =
+ this->notifsCryptoModule->getSessionByDeviceId(keyserverIDCpp);
+
+ NotificationsCryptoModule::persistNotificationsSession(
+ keyserverIDCpp, keyserverNotificationsSession);
+
+ this->notifsCryptoModule->removeSessionByDeviceId(keyserverIDCpp);
+ this->persistCryptoModules(false, true);
} catch (const std::exception &e) {
error = e.what();
}
diff --git a/native/cpp/CommonCpp/Notifications/BackgroundDataStorage/NotificationsCryptoModule.h b/native/cpp/CommonCpp/Notifications/BackgroundDataStorage/NotificationsCryptoModule.h
--- a/native/cpp/CommonCpp/Notifications/BackgroundDataStorage/NotificationsCryptoModule.h
+++ b/native/cpp/CommonCpp/Notifications/BackgroundDataStorage/NotificationsCryptoModule.h
@@ -6,59 +6,58 @@
namespace comm {
class NotificationsCryptoModule {
- const static std::string secureStoreNotificationsAccountDataKey;
const static std::string notificationsCryptoAccountID;
- const static std::string keyserverHostedNotificationsID;
- const static std::string initialEncryptedMessageContent;
- static std::string getPicklingKey();
- static void serializeAndFlushCryptoModule(
- std::unique_ptr<crypto::CryptoModule> cryptoModule,
- const std::string &path,
- const std::string &picklingKey,
- const std::string &callingProcessName);
+ static std::string getPicklingKey(bool generateIfNotExists);
static std::unique_ptr<crypto::CryptoModule> deserializeCryptoModule(
const std::string &path,
const std::string &picklingKey);
- static void callCryptoModule(
- std::function<void(
- const std::unique_ptr<crypto::CryptoModule> &cryptoModule)> caller,
- const std::string &callingProcessName);
+ static std::string
+ getKeyserverNotificationsSessionKey(const std::string &keyserverID);
+ static void persistNotificationsSessionInternal(
+ const std::string &keyserverID,
+ const std::string &picklingKey,
+ std::shared_ptr<crypto::Session> session);
+ static std::unique_ptr<crypto::Session> fetchNotificationsSession(
+ const std::string &keyserverID,
+ const std::string &picklingKey);
public:
+ const static std::string initialEncryptedMessageContent;
const static int olmEncryptedTypeMessage;
- static void
- initializeNotificationsCryptoAccount(const std::string &callingProcessName);
+
+ static std::unique_ptr<crypto::CryptoModule>
+ migrateLegacyNotificationsCryptoModule();
static void clearSensitiveData();
- static crypto::EncryptedData initializeNotificationsSession(
- const std::string &identityKeys,
- const std::string &prekey,
- const std::string &prekeySignature,
- const std::string &oneTimeKeys,
- const std::string &callingProcessName);
- static bool
- isNotificationsSessionInitialized(const std::string &callingProcessName);
+ static void persistNotificationsSession(
+ const std::string &keyserverID,
+ std::shared_ptr<crypto::Session> keyserverNotificationsSession);
+ static bool isNotificationsSessionInitialized(const std::string &keyserverID);
static std::string decrypt(
+ const std::string &keyserverID,
const std::string &data,
- const size_t messageType,
- const std::string &callingProcessName);
+ const size_t messageType);
class StatefulDecryptResult {
StatefulDecryptResult(
- std::unique_ptr<crypto::CryptoModule> cryptoModule,
+ std::unique_ptr<crypto::Session> session,
+ std::string keyserverID,
std::string decryptedData);
- std::unique_ptr<crypto::CryptoModule> cryptoModuleState;
+ std::unique_ptr<crypto::Session> sessionState;
+ std::string keyserverID;
std::string decryptedData;
friend NotificationsCryptoModule;
public:
std::string getDecryptedData();
+ std::string getKeyserverID();
};
- static std::unique_ptr<StatefulDecryptResult>
- statefulDecrypt(const std::string &data, const size_t messageType);
- static void flushState(
- std::unique_ptr<StatefulDecryptResult> statefulDecryptResult,
- const std::string &callingProcessName);
+ static std::unique_ptr<StatefulDecryptResult> statefulDecrypt(
+ const std::string &keyserverID,
+ const std::string &data,
+ const size_t messageType);
+ static void
+ flushState(std::unique_ptr<StatefulDecryptResult> statefulDecryptResult);
};
} // namespace comm
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
@@ -1,6 +1,7 @@
#include "NotificationsCryptoModule.h"
#include "../../CryptoTools/Persist.h"
#include "../../CryptoTools/Tools.h"
+#include "../../Tools/CommMMKV.h"
#include "../../Tools/CommSecureStore.h"
#include "../../Tools/PlatformSpecificTools.h"
@@ -15,17 +16,14 @@
namespace comm {
-const std::string
- NotificationsCryptoModule::secureStoreNotificationsAccountDataKey =
- "notificationsCryptoAccountDataKey";
const std::string NotificationsCryptoModule::notificationsCryptoAccountID =
"notificationsCryptoAccountDataID";
-const std::string NotificationsCryptoModule::keyserverHostedNotificationsID =
- "keyserverHostedNotificationsID";
const std::string NotificationsCryptoModule::initialEncryptedMessageContent =
"{\"type\": \"init\"}";
const int NotificationsCryptoModule::olmEncryptedTypeMessage = 1;
-const int temporaryFilePathRandomSuffixLength = 32;
+
+// Introduced temporarily
+const std::string ashoatKeyserverID = "256";
std::unique_ptr<crypto::CryptoModule>
NotificationsCryptoModule::deserializeCryptoModule(
@@ -74,156 +72,92 @@
crypto::Persist({account, sessions}));
}
-void NotificationsCryptoModule::serializeAndFlushCryptoModule(
- std::unique_ptr<crypto::CryptoModule> cryptoModule,
- const std::string &path,
- const std::string &picklingKey,
- const std::string &callingProcessName) {
- crypto::Persist persist = cryptoModule->storeAsB64(picklingKey);
+std::string
+NotificationsCryptoModule::getPicklingKey(bool generateIfNotExists) {
+ static std::string notifsPicklingKeyID = "NOTIFS.PICKLING_KEY";
+ std::optional<std::string> picklingKey =
+ CommMMKV::getString(notifsPicklingKeyID);
- folly::dynamic sessions = folly::dynamic::object;
- for (auto &sessionKeyValuePair : persist.sessions) {
- std::string targetUserID = sessionKeyValuePair.first;
- crypto::OlmBuffer sessionData = sessionKeyValuePair.second;
- sessions[targetUserID] =
- std::string(sessionData.begin(), sessionData.end());
+ if (picklingKey.has_value()) {
+ return picklingKey.value();
}
- std::string account =
- std::string(persist.account.begin(), persist.account.end());
- folly::dynamic persistJSON =
- folly::dynamic::object("account", account)("sessions", sessions);
- std::string pickledPersist = folly::toJson(persistJSON);
-
- std::string temporaryFilePathRandomSuffix =
- crypto::Tools::generateRandomHexString(
- temporaryFilePathRandomSuffixLength);
- std::string temporaryPath =
- path + callingProcessName + temporaryFilePathRandomSuffix;
-
- mode_t readWritePermissionsMode = 0666;
- int temporaryFD =
- open(temporaryPath.c_str(), O_CREAT | O_WRONLY, readWritePermissionsMode);
- if (temporaryFD == -1) {
- throw std::runtime_error(
- "Failed to create temporary file. Unable to atomically update "
- "notifications crypto account. Details: " +
- std::string(strerror(errno)));
- }
- ssize_t bytesWritten =
- write(temporaryFD, pickledPersist.c_str(), pickledPersist.length());
- if (bytesWritten == -1 || bytesWritten != pickledPersist.length()) {
- remove(temporaryPath.c_str());
- throw std::runtime_error(
- "Failed to write all data to temporary file. Unable to atomically "
- "update notifications crypto account. Details: " +
- std::string(strerror(errno)));
- }
- if (fsync(temporaryFD) == -1) {
- remove(temporaryPath.c_str());
+ if (!generateIfNotExists) {
throw std::runtime_error(
- "Failed to synchronize temporary file data with hardware storage. "
- "Unable to atomically update notifications crypto account. Details: " +
- std::string(strerror(errno)));
- };
- close(temporaryFD);
- if (rename(temporaryPath.c_str(), path.c_str()) == -1) {
- remove(temporaryPath.c_str());
- throw std::runtime_error(
- "Failed to replace temporary file content with notifications crypto "
- "account. Unable to atomically update notifications crypto account. "
- "Details: " +
- std::string(strerror(errno)));
+ "Attempt to retrieve notifications sessions before it was "
+ "correctly initialized.");
}
- remove(temporaryPath.c_str());
-}
-std::string NotificationsCryptoModule::getPicklingKey() {
- folly::Optional<std::string> picklingKey = CommSecureStore::get(
- NotificationsCryptoModule::secureStoreNotificationsAccountDataKey);
- if (!picklingKey.hasValue()) {
- throw std::runtime_error(
- "Attempt to retrieve notifications crypto account before it was "
- "correctly initialized.");
+ std::string newPicklingKey = crypto::Tools::generateRandomString(64);
+ bool picklingKeySet =
+ CommMMKV::setString(notifsPicklingKeyID, newPicklingKey);
+
+ if (!picklingKeySet) {
+ throw std::runtime_error("Failed to set notifications pickling key.");
}
- return picklingKey.value();
+
+ return newPicklingKey;
}
-void NotificationsCryptoModule::callCryptoModule(
- std::function<
- void(const std::unique_ptr<crypto::CryptoModule> &cryptoModule)> caller,
- const std::string &callingProcessName) {
- const std::string picklingKey = NotificationsCryptoModule::getPicklingKey();
- const std::string path =
- PlatformSpecificTools::getNotificationsCryptoAccountPath();
- std::unique_ptr<crypto::CryptoModule> cryptoModule =
- NotificationsCryptoModule::deserializeCryptoModule(path, picklingKey);
- caller(cryptoModule);
- NotificationsCryptoModule::serializeAndFlushCryptoModule(
- std::move(cryptoModule), path, picklingKey, callingProcessName);
+std::string NotificationsCryptoModule::getKeyserverNotificationsSessionKey(
+ const std::string &keyserverID) {
+ return "KEYSERVER." + keyserverID + ".NOTIFS_SESSION";
}
-void NotificationsCryptoModule::initializeNotificationsCryptoAccount(
- const std::string &callingProcessName) {
+std::unique_ptr<crypto::CryptoModule>
+NotificationsCryptoModule::migrateLegacyNotificationsCryptoModule() {
const std::string notificationsCryptoAccountPath =
PlatformSpecificTools::getNotificationsCryptoAccountPath();
std::ifstream notificationCryptoAccountCheck(notificationsCryptoAccountPath);
- if (notificationCryptoAccountCheck.good()) {
- // Implemented in CommmCoreModule semantics regarding public olm account
- // initialization is idempotent. We should follow the same approach when it
- // comes to notifications
+
+ if (!notificationCryptoAccountCheck.good()) {
notificationCryptoAccountCheck.close();
- return;
+ return nullptr;
}
- // There is no reason to check if the key is already present since if we are
- // in this place in the code we are about to create new account
- std::string picklingKey = crypto::Tools::generateRandomString(64);
- CommSecureStore::set(
- NotificationsCryptoModule::secureStoreNotificationsAccountDataKey,
- picklingKey);
-
- std::unique_ptr<crypto::CryptoModule> cryptoModule =
- std::make_unique<crypto::CryptoModule>(
- NotificationsCryptoModule::notificationsCryptoAccountID);
- NotificationsCryptoModule::serializeAndFlushCryptoModule(
- std::move(cryptoModule),
- notificationsCryptoAccountPath,
- picklingKey,
- callingProcessName);
-}
+ notificationCryptoAccountCheck.close();
-crypto::EncryptedData NotificationsCryptoModule::initializeNotificationsSession(
- const std::string &identityKeys,
- const std::string &prekey,
- const std::string &prekeySignature,
- const std::string &oneTimeKey,
- const std::string &callingProcessName) {
- crypto::EncryptedData initialEncryptedMessage;
- auto caller = [&](const std::unique_ptr<crypto::CryptoModule> &cryptoModule) {
- cryptoModule->initializeOutboundForSendingSession(
- NotificationsCryptoModule::keyserverHostedNotificationsID,
- std::vector<uint8_t>(identityKeys.begin(), identityKeys.end()),
- std::vector<uint8_t>(prekey.begin(), prekey.end()),
- std::vector<uint8_t>(prekeySignature.begin(), prekeySignature.end()),
- std::vector<uint8_t>(oneTimeKey.begin(), oneTimeKey.end()));
- initialEncryptedMessage = cryptoModule->encrypt(
- NotificationsCryptoModule::keyserverHostedNotificationsID,
- NotificationsCryptoModule::initialEncryptedMessageContent);
- };
- NotificationsCryptoModule::callCryptoModule(caller, callingProcessName);
- return initialEncryptedMessage;
-}
+ std::string legacySecureStoreNotifsAccountKey =
+ "notificationsCryptoAccountDataKey";
+ folly::Optional<std::string> legacyPicklingKey =
+ CommSecureStore::get(legacySecureStoreNotifsAccountKey);
+ if (!legacyPicklingKey.hasValue()) {
+ throw std::runtime_error(
+ "Attempt to migrate legacy notifications account but pickling key "
+ "missing.");
+ }
-bool NotificationsCryptoModule::isNotificationsSessionInitialized(
- const std::string &callingProcessName) {
- bool sessionInitialized;
- auto caller = [&sessionInitialized](
- const std::unique_ptr<crypto::CryptoModule> &cryptoModule) {
- sessionInitialized = cryptoModule->hasSessionFor(
- NotificationsCryptoModule::keyserverHostedNotificationsID);
- };
- NotificationsCryptoModule::callCryptoModule(caller, callingProcessName);
- return sessionInitialized;
+ std::unique_ptr<crypto::CryptoModule> legacyCryptoModule =
+ NotificationsCryptoModule::deserializeCryptoModule(
+ notificationsCryptoAccountPath, legacyPicklingKey.value());
+
+ std::string newPicklingKey = NotificationsCryptoModule::getPicklingKey(true);
+ crypto::Persist persist = legacyCryptoModule->storeAsB64(newPicklingKey);
+
+ std::string legacyNotificationsSessionID = "keyserverHostedNotificationsID";
+ if (persist.sessions.find(legacyNotificationsSessionID) ==
+ persist.sessions.end()) {
+ return legacyCryptoModule;
+ }
+
+ crypto::OlmBuffer autoritativeKeyserverSession =
+ persist.sessions.at(legacyNotificationsSessionID);
+
+ std::string autoritativeKeyserverSessionKey =
+ NotificationsCryptoModule::getKeyserverNotificationsSessionKey(
+ ashoatKeyserverID);
+
+ bool storedSession = CommMMKV::setString(
+ autoritativeKeyserverSessionKey,
+ std::string(
+ autoritativeKeyserverSession.begin(),
+ autoritativeKeyserverSession.end()));
+
+ if (!storedSession) {
+ throw std::runtime_error(
+ "Failed to migrate autoritative keyserver session to MMKV.");
+ }
+
+ return legacyCryptoModule;
}
void NotificationsCryptoModule::clearSensitiveData() {
@@ -236,26 +170,88 @@
}
}
+void NotificationsCryptoModule::persistNotificationsSessionInternal(
+ const std::string &keyserverID,
+ const std::string &picklingKey,
+ std::shared_ptr<crypto::Session> session) {
+ auto sessionBytes = session->storeAsB64(picklingKey);
+ std::string serializedSession =
+ std::string(sessionBytes.begin(), sessionBytes.end());
+
+ std::string keyserverNotificationsSessionKey =
+ NotificationsCryptoModule::getKeyserverNotificationsSessionKey(
+ keyserverID);
+
+ bool sessionStored =
+ CommMMKV::setString(keyserverNotificationsSessionKey, serializedSession);
+
+ if (!sessionStored) {
+ throw std::runtime_error(
+ "Failed to persist to MMKV notifications session for keyserver: " +
+ keyserverID);
+ }
+}
+
+std::unique_ptr<crypto::Session>
+NotificationsCryptoModule::fetchNotificationsSession(
+ const std::string &keyserverID,
+ const std::string &picklingKey) {
+ std::string keyserverNotificationsSessionKey =
+ NotificationsCryptoModule::getKeyserverNotificationsSessionKey(
+ keyserverID);
+ std::optional<std::string> serializedSession =
+ CommMMKV::getString(keyserverNotificationsSessionKey);
+
+ if (!serializedSession.has_value()) {
+ throw std::runtime_error(
+ "Missing notifications session for keyserver: " + keyserverID);
+ }
+
+ crypto::OlmBuffer sessionBytes = crypto::OlmBuffer{
+ serializedSession.value().begin(), serializedSession.value().end()};
+ std::unique_ptr<crypto::Session> session =
+ crypto::Session::restoreFromB64(picklingKey, sessionBytes);
+ return session;
+}
+
+void NotificationsCryptoModule::persistNotificationsSession(
+ const std::string &keyserverID,
+ std::shared_ptr<crypto::Session> keyserverNotificationsSession) {
+ std::string picklingKey = NotificationsCryptoModule::getPicklingKey(true);
+ NotificationsCryptoModule::persistNotificationsSessionInternal(
+ keyserverID, picklingKey, keyserverNotificationsSession);
+}
+
+bool NotificationsCryptoModule::isNotificationsSessionInitialized(
+ const std::string &keyserverID) {
+ std::string keyserverNotificationsSessionKey =
+ "KEYSERVER." + keyserverID + ".NOTIFS_SESSION";
+ return CommMMKV::getString(keyserverNotificationsSessionKey).has_value();
+}
+
std::string NotificationsCryptoModule::decrypt(
+ const std::string &keyserverID,
const std::string &data,
- const size_t messageType,
- const std::string &callingProcessName) {
- std::string decryptedData;
- auto caller = [&](const std::unique_ptr<crypto::CryptoModule> &cryptoModule) {
- crypto::EncryptedData encryptedData{
- std::vector<uint8_t>(data.begin(), data.end()), messageType};
- decryptedData = cryptoModule->decrypt(
- NotificationsCryptoModule::keyserverHostedNotificationsID,
- encryptedData);
- };
- NotificationsCryptoModule::callCryptoModule(caller, callingProcessName);
+ const size_t messageType) {
+ std::string picklingKey = NotificationsCryptoModule::getPicklingKey(false);
+ std::unique_ptr<crypto::Session> session =
+ NotificationsCryptoModule::fetchNotificationsSession(
+ keyserverID, picklingKey);
+ crypto::EncryptedData encryptedData{
+ std::vector<uint8_t>(data.begin(), data.end()), messageType};
+ std::string decryptedData = session->decrypt(encryptedData);
+ NotificationsCryptoModule::persistNotificationsSessionInternal(
+ keyserverID, picklingKey, std::move(session));
return decryptedData;
}
NotificationsCryptoModule::StatefulDecryptResult::StatefulDecryptResult(
- std::unique_ptr<crypto::CryptoModule> cryptoModule,
+ std::unique_ptr<crypto::Session> session,
+ std::string keyserverID,
std::string decryptedData)
- : cryptoModuleState(std::move(cryptoModule)), decryptedData(decryptedData) {
+ : sessionState(std::move(session)),
+ keyserverID(keyserverID),
+ decryptedData(decryptedData) {
}
std::string
@@ -263,37 +259,37 @@
return this->decryptedData;
}
+std::string NotificationsCryptoModule::StatefulDecryptResult::getKeyserverID() {
+ return this->keyserverID;
+}
+
std::unique_ptr<NotificationsCryptoModule::StatefulDecryptResult>
NotificationsCryptoModule::statefulDecrypt(
+ const std::string &keyserverID,
const std::string &data,
const size_t messageType) {
- std::string path = PlatformSpecificTools::getNotificationsCryptoAccountPath();
- std::string picklingKey = NotificationsCryptoModule::getPicklingKey();
+ std::string picklingKey = NotificationsCryptoModule::getPicklingKey(false);
+
+ std::unique_ptr<crypto::Session> session =
+ NotificationsCryptoModule::fetchNotificationsSession(
+ keyserverID, picklingKey);
- std::unique_ptr<crypto::CryptoModule> cryptoModule =
- NotificationsCryptoModule::deserializeCryptoModule(path, picklingKey);
crypto::EncryptedData encryptedData{
std::vector<uint8_t>(data.begin(), data.end()), messageType};
- std::string decryptedData = cryptoModule->decrypt(
- NotificationsCryptoModule::keyserverHostedNotificationsID, encryptedData);
- StatefulDecryptResult statefulDecryptResult(
- std::move(cryptoModule), decryptedData);
+ std::string decryptedData = session->decrypt(encryptedData);
+ StatefulDecryptResult statefulDecryptResult(
+ std::move(session), keyserverID, decryptedData);
return std::make_unique<StatefulDecryptResult>(
std::move(statefulDecryptResult));
}
void NotificationsCryptoModule::flushState(
- std::unique_ptr<StatefulDecryptResult> statefulDecryptResult,
- const std::string &callingProcessName) {
-
- std::string path = PlatformSpecificTools::getNotificationsCryptoAccountPath();
- std::string picklingKey = NotificationsCryptoModule::getPicklingKey();
-
- NotificationsCryptoModule::serializeAndFlushCryptoModule(
- std::move(statefulDecryptResult->cryptoModuleState),
- path,
+ std::unique_ptr<StatefulDecryptResult> statefulDecryptResult) {
+ std::string picklingKey = NotificationsCryptoModule::getPicklingKey(false);
+ NotificationsCryptoModule::persistNotificationsSessionInternal(
+ statefulDecryptResult->getKeyserverID(),
picklingKey,
- callingProcessName);
+ std::move(statefulDecryptResult->sessionState));
}
} // namespace comm
diff --git a/native/cpp/CommonCpp/Notifications/BackgroundDataStorage/NotificationsCryptoModuleJNIHelper.h b/native/cpp/CommonCpp/Notifications/BackgroundDataStorage/NotificationsCryptoModuleJNIHelper.h
--- a/native/cpp/CommonCpp/Notifications/BackgroundDataStorage/NotificationsCryptoModuleJNIHelper.h
+++ b/native/cpp/CommonCpp/Notifications/BackgroundDataStorage/NotificationsCryptoModuleJNIHelper.h
@@ -14,10 +14,10 @@
static std::string decrypt(
facebook::jni::alias_ref<NotificationsCryptoModuleJNIHelper> jThis,
+ std::string keyserverID,
std::string data,
- int messageType,
- std::string callingProcessName);
+ int messageType);
static void registerNatives();
};
} // namespace comm
\ No newline at end of file
diff --git a/native/ios/NotificationService/NotificationService.mm b/native/ios/NotificationService/NotificationService.mm
--- a/native/ios/NotificationService/NotificationService.mm
+++ b/native/ios/NotificationService/NotificationService.mm
@@ -261,7 +261,7 @@
if (decryptionExecuted) {
comm::NotificationsCryptoModule::flushState(
- std::move(statefulDecryptResultPtr), callingProcessName);
+ std::move(statefulDecryptResultPtr));
}
}
@@ -534,9 +534,15 @@
decryptContentInPlace:(UNMutableNotificationContent *)content {
std::string encryptedData =
std::string([content.userInfo[encryptedPayloadKey] UTF8String]);
-
+ std::string senderKeyserverID = ashoatKeyserverID;
+ if (content.userInfo[keyserverIDKey]) {
+ senderKeyserverID =
+ std::string([content.userInfo[keyserverIDKey] UTF8String]);
+ }
auto decryptResult = comm::NotificationsCryptoModule::statefulDecrypt(
- encryptedData, comm::NotificationsCryptoModule::olmEncryptedTypeMessage);
+ senderKeyserverID,
+ encryptedData,
+ comm::NotificationsCryptoModule::olmEncryptedTypeMessage);
NSString *decryptedSerializedPayload =
[NSString stringWithUTF8String:decryptResult->getDecryptedData().c_str()];

File Metadata

Mime Type
text/plain
Expires
Tue, Dec 9, 8:46 AM (15 h, 35 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5853579
Default Alt Text
D11234.1765269981.diff (30 KB)

Event Timeline