Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F3153274
D10600.id35611.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
11 KB
Referenced Files
None
Subscribers
None
D10600.id35611.diff
View Options
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
@@ -28,6 +28,7 @@
void generateOneTimeKeys(size_t oneTimeKeysAmount);
// returns number of published keys
size_t publishOneTimeKeys();
+ bool verifyPrekeyPublishTime(uint64_t threshold);
public:
const std::string id;
@@ -82,6 +83,7 @@
const std::string &publicKey,
const std::string &message,
const std::string &signature);
+ std::optional<std::string> validateAndPublishPrekey();
};
} // namespace crypto
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
@@ -4,6 +4,7 @@
#include "olm/account.hh"
#include "olm/session.hh"
+#include <ctime>
#include <stdexcept>
namespace comm {
@@ -102,6 +103,18 @@
return ::olm_account_mark_keys_as_published(this->getOlmAccount());
}
+bool CryptoModule::verifyPrekeyPublishTime(uint64_t threshold) {
+ if (this->getUnpublishedPrekey().hasValue()) {
+ return false;
+ }
+
+ uint64_t currentTime = std::time(nullptr);
+ uint64_t lastPrekeyPublishTime =
+ ::olm_account_get_last_prekey_publish_time(this->getOlmAccount());
+
+ return currentTime - lastPrekeyPublishTime >= threshold;
+}
+
Keys CryptoModule::keysFromStrings(
const std::string &identityKeys,
const std::string &oneTimeKeys) {
@@ -447,5 +460,24 @@
}
}
+std::optional<std::string> CryptoModule::validateAndPublishPrekey() {
+ static const uint64_t maxPrekeyPublishTime = 10 * 60;
+ static const uint64_t maxOldPrekeyAge = 2 * 60;
+ std::optional<std::string> maybeNewPrekey;
+
+ bool shouldRotatePrekey = this->verifyPrekeyPublishTime(maxPrekeyPublishTime);
+ if (shouldRotatePrekey) {
+ maybeNewPrekey = this->generateAndGetPrekey();
+ this->markPrekeyAsPublished();
+ }
+
+ bool shouldForgetPrekey = this->verifyPrekeyPublishTime(maxOldPrekeyAge);
+ if (shouldForgetPrekey) {
+ this->forgetOldPrekey();
+ }
+
+ return maybeNewPrekey;
+}
+
} // namespace crypto
} // namespace comm
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
@@ -72,6 +72,7 @@
jsi::Runtime &rt,
double oneTimeKeysAmount) override;
virtual jsi::Value generateAndGetPrekeys(jsi::Runtime &rt) override;
+ virtual jsi::Value validateAndUploadPrekeys(jsi::Runtime &rt) override;
virtual jsi::Value initializeNotificationsSession(
jsi::Runtime &rt,
jsi::String identityKeys,
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
@@ -654,6 +654,81 @@
});
}
+jsi::Value CommCoreModule::validateAndUploadPrekeys(jsi::Runtime &rt) {
+ return createPromiseAsJSIValue(
+ rt, [=](jsi::Runtime &innerRt, std::shared_ptr<Promise> promise) {
+ taskType job = [=, &innerRt]() {
+ std::string error;
+ std::string copyPickleKey;
+ crypto::Persist cryptoModuleCopy;
+ std::optional<std::string> maybeNewPrekey;
+
+ try {
+ copyPickleKey = crypto::Tools::generateRandomString(64);
+ cryptoModuleCopy = this->cryptoModule->storeAsB64(copyPickleKey);
+ maybeNewPrekey = this->cryptoModule->validateAndPublishPrekey();
+ if (!maybeNewPrekey.has_value()) {
+ this->persistCryptoModule();
+ }
+ } catch (const std::exception &e) {
+ error = e.what();
+ }
+
+ if (error.size()) {
+ this->jsInvoker_->invokeAsync(
+ [=, &innerRt]() { promise->reject(error); });
+ return;
+ } else if (!maybeNewPrekey.has_value()) {
+ this->jsInvoker_->invokeAsync(
+ [=]() { promise->resolve(jsi::Value::undefined()); });
+ return;
+ }
+
+ std::string newPrekey = maybeNewPrekey.value();
+ std::string prekeyUploadError;
+
+ try {
+ std::string prekeySignature =
+ this->cryptoModule->getPrekeySignature();
+ // TODO: Implement notifs prekey rotation.
+ // Notifications prekey is not rotated at this moment. It
+ // is fetched with signatireto match identity service API.
+ std::string notificationsPrekey =
+ NotificationsCryptoModule::getNotificationsPrekey("Comm");
+ std::string notificationsPrekeySignature =
+ NotificationsCryptoModule::getNotificationsPrekeySignature(
+ "Comm");
+ try {
+ // TODO: upload prekey to identity service
+ } catch (const std::exception &e) {
+ prekeyUploadError = e.what();
+ }
+ if (prekeyUploadError.size()) {
+ this->cryptoModule->restoreFromB64(
+ copyPickleKey, cryptoModuleCopy);
+ } else {
+ this->persistCryptoModule();
+ }
+ } catch (std::exception &e) {
+ error = e.what();
+ }
+
+ this->jsInvoker_->invokeAsync([=]() {
+ if (error.size()) {
+ promise->reject(error);
+ return;
+ }
+ if (prekeyUploadError.size()) {
+ promise->reject(prekeyUploadError);
+ return;
+ }
+ promise->resolve(jsi::Value::undefined());
+ });
+ };
+ this->cryptoThread->scheduleTask(job);
+ });
+}
+
jsi::Value CommCoreModule::initializeNotificationsSession(
jsi::Runtime &rt,
jsi::String identityKeys,
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
@@ -33,6 +33,8 @@
static std::string
getNotificationsIdentityKeys(const std::string &callingProcessName);
static std::string
+ getNotificationsPrekey(const std::string &callingProcessName);
+ static std::string
generateAndGetNotificationsPrekey(const std::string &callingProcessName);
static std::string
getNotificationsPrekeySignature(const std::string &callingProcessName);
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
@@ -203,6 +203,17 @@
return identityKeys;
}
+std::string NotificationsCryptoModule::getNotificationsPrekey(
+ const std::string &callingProcessName) {
+ std::string prekey;
+ auto caller =
+ [&prekey](const std::unique_ptr<crypto::CryptoModule> &cryptoModule) {
+ prekey = cryptoModule->getPrekey();
+ };
+ NotificationsCryptoModule::callCryptoModule(caller, callingProcessName);
+ return prekey;
+}
+
std::string NotificationsCryptoModule::generateAndGetNotificationsPrekey(
const std::string &callingProcessName) {
std::string prekey;
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
@@ -75,6 +75,9 @@
static jsi::Value __hostFunction_CommCoreModuleSchemaCxxSpecJSI_generateAndGetPrekeys(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
return static_cast<CommCoreModuleSchemaCxxSpecJSI *>(&turboModule)->generateAndGetPrekeys(rt);
}
+static jsi::Value __hostFunction_CommCoreModuleSchemaCxxSpecJSI_validateAndUploadPrekeys(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
+ return static_cast<CommCoreModuleSchemaCxxSpecJSI *>(&turboModule)->validateAndUploadPrekeys(rt);
+}
static jsi::Value __hostFunction_CommCoreModuleSchemaCxxSpecJSI_initializeNotificationsSession(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
return static_cast<CommCoreModuleSchemaCxxSpecJSI *>(&turboModule)->initializeNotificationsSession(rt, args[0].asString(rt), args[1].asString(rt), args[2].asString(rt), args[3].asString(rt));
}
@@ -169,6 +172,7 @@
methodMap_["getPrimaryOneTimeKeys"] = MethodMetadata {1, __hostFunction_CommCoreModuleSchemaCxxSpecJSI_getPrimaryOneTimeKeys};
methodMap_["getNotificationsOneTimeKeys"] = MethodMetadata {1, __hostFunction_CommCoreModuleSchemaCxxSpecJSI_getNotificationsOneTimeKeys};
methodMap_["generateAndGetPrekeys"] = MethodMetadata {0, __hostFunction_CommCoreModuleSchemaCxxSpecJSI_generateAndGetPrekeys};
+ methodMap_["validateAndUploadPrekeys"] = MethodMetadata {0, __hostFunction_CommCoreModuleSchemaCxxSpecJSI_validateAndUploadPrekeys};
methodMap_["initializeNotificationsSession"] = MethodMetadata {4, __hostFunction_CommCoreModuleSchemaCxxSpecJSI_initializeNotificationsSession};
methodMap_["isNotificationsSessionInitialized"] = MethodMetadata {0, __hostFunction_CommCoreModuleSchemaCxxSpecJSI_isNotificationsSessionInitialized};
methodMap_["initializeContentOutboundSession"] = MethodMetadata {5, __hostFunction_CommCoreModuleSchemaCxxSpecJSI_initializeContentOutboundSession};
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
@@ -40,6 +40,7 @@
virtual jsi::Value getPrimaryOneTimeKeys(jsi::Runtime &rt, double oneTimeKeysAmount) = 0;
virtual jsi::Value getNotificationsOneTimeKeys(jsi::Runtime &rt, double oneTimeKeysAmount) = 0;
virtual jsi::Value generateAndGetPrekeys(jsi::Runtime &rt) = 0;
+ virtual jsi::Value validateAndUploadPrekeys(jsi::Runtime &rt) = 0;
virtual jsi::Value initializeNotificationsSession(jsi::Runtime &rt, jsi::String identityKeys, jsi::String prekey, jsi::String prekeySignature, jsi::String oneTimeKeys) = 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;
@@ -244,6 +245,14 @@
return bridging::callFromJs<jsi::Value>(
rt, &T::generateAndGetPrekeys, jsInvoker_, instance_);
}
+ jsi::Value validateAndUploadPrekeys(jsi::Runtime &rt) override {
+ static_assert(
+ bridging::getParameterCount(&T::validateAndUploadPrekeys) == 1,
+ "Expected validateAndUploadPrekeys(...) to have 1 parameters");
+
+ return bridging::callFromJs<jsi::Value>(
+ rt, &T::validateAndUploadPrekeys, jsInvoker_, instance_);
+ }
jsi::Value initializeNotificationsSession(jsi::Runtime &rt, jsi::String identityKeys, jsi::String prekey, jsi::String prekeySignature, jsi::String oneTimeKeys) override {
static_assert(
bridging::getParameterCount(&T::initializeNotificationsSession) == 5,
diff --git a/native/schema/CommCoreModuleSchema.js b/native/schema/CommCoreModuleSchema.js
--- a/native/schema/CommCoreModuleSchema.js
+++ b/native/schema/CommCoreModuleSchema.js
@@ -82,6 +82,7 @@
oneTimeKeysAmount: number,
) => Promise<OLMOneTimeKeys>;
+generateAndGetPrekeys: () => Promise<SignedPrekeys>;
+ +validateAndUploadPrekeys: () => Promise<void>;
+initializeNotificationsSession: (
identityKeys: string,
prekey: string,
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Nov 6, 6:02 AM (21 h, 29 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2428909
Default Alt Text
D10600.id35611.diff (11 KB)
Attached To
Mode
D10600: Implement prekey rotation on native
Attached
Detach File
Event Timeline
Log In to Comment