Page MenuHomePhabricator

D9401.id31993.diff
No OneTemporary

D9401.id31993.diff

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
@@ -11,6 +11,7 @@
const static std::string keyserverHostedNotificationsID;
const static std::string initialEncryptedMessageContent;
+ static std::string getPicklingKey();
static void serializeAndFlushCryptoModule(
crypto::CryptoModule &cryptoModule,
const std::string &path,
@@ -49,5 +50,23 @@
const std::string &data,
const size_t messageType,
const std::string &callingProcessName);
+
+ class StatefulDecryptResult {
+ StatefulDecryptResult(
+ crypto::CryptoModule cryptoModule,
+ std::string decryptedData);
+ std::unique_ptr<crypto::CryptoModule> cryptoModuleState;
+ std::string decryptedData;
+ friend NotificationsCryptoModule;
+
+ public:
+ std::string getDecryptedData();
+ };
+
+ 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);
};
} // 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
@@ -132,9 +132,7 @@
remove(temporaryPath.c_str());
}
-void NotificationsCryptoModule::callCryptoModule(
- std::function<void(crypto::CryptoModule &cryptoModule)> caller,
- const std::string &callingProcessName) {
+std::string NotificationsCryptoModule::getPicklingKey() {
CommSecureStore secureStore{};
folly::Optional<std::string> picklingKey = secureStore.get(
NotificationsCryptoModule::secureStoreNotificationsAccountDataKey);
@@ -143,15 +141,20 @@
"Attempt to retrieve notifications crypto account before it was "
"correctly initialized.");
}
+ return picklingKey.value();
+}
+void NotificationsCryptoModule::callCryptoModule(
+ std::function<void(crypto::CryptoModule &cryptoModule)> caller,
+ const std::string &callingProcessName) {
+ const std::string picklingKey = NotificationsCryptoModule::getPicklingKey();
const std::string path =
PlatformSpecificTools::getNotificationsCryptoAccountPath();
crypto::CryptoModule cryptoModule =
- NotificationsCryptoModule::deserializeCryptoModule(
- path, picklingKey.value());
+ NotificationsCryptoModule::deserializeCryptoModule(path, picklingKey);
caller(cryptoModule);
NotificationsCryptoModule::serializeAndFlushCryptoModule(
- cryptoModule, path, picklingKey.value(), callingProcessName);
+ cryptoModule, path, picklingKey, callingProcessName);
}
void NotificationsCryptoModule::initializeNotificationsCryptoAccount(
@@ -283,4 +286,48 @@
NotificationsCryptoModule::callCryptoModule(caller, callingProcessName);
return decryptedData;
}
+
+NotificationsCryptoModule::StatefulDecryptResult::StatefulDecryptResult(
+ crypto::CryptoModule cryptoModule,
+ std::string decryptedData)
+ : cryptoModuleState(std::make_unique<crypto::CryptoModule>(cryptoModule)),
+ decryptedData(decryptedData) {
+}
+
+std::string
+NotificationsCryptoModule::StatefulDecryptResult::getDecryptedData() {
+ return this->decryptedData;
+}
+
+std::unique_ptr<NotificationsCryptoModule::StatefulDecryptResult>
+NotificationsCryptoModule::statefulDecrypt(
+ const std::string &data,
+ const size_t messageType) {
+ std::string path = PlatformSpecificTools::getNotificationsCryptoAccountPath();
+ std::string picklingKey = NotificationsCryptoModule::getPicklingKey();
+
+ 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(cryptoModule, 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();
+
+ crypto::CryptoModule cryptoModule = *statefulDecryptResult->cryptoModuleState;
+
+ NotificationsCryptoModule::serializeAndFlushCryptoModule(
+ cryptoModule, path, picklingKey, callingProcessName);
+}
} // namespace comm
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
@@ -63,6 +63,10 @@
UNNotificationContent *publicUserContent = content;
// Step 1: notification decryption.
+ std::unique_ptr<comm::NotificationsCryptoModule::StatefulDecryptResult>
+ statefulDecryptResultPtr;
+ BOOL decryptionExecuted = NO;
+
if ([self shouldBeDecrypted:content.userInfo]) {
std::optional<std::string> notifID;
NSString *objcNotifID = content.userInfo[@"id"];
@@ -73,7 +77,8 @@
std::string decryptErrorMessage;
try {
@try {
- [self decryptContentInPlace:content];
+ statefulDecryptResultPtr = [self decryptContentInPlace:content];
+ decryptionExecuted = YES;
} @catch (NSException *e) {
decryptErrorMessage = "NSE: Received Obj-C exception: " +
std::string([e.name UTF8String]) +
@@ -215,8 +220,14 @@
withPublicUserContent:publicUserContent];
return;
}
+
[self callContentHandlerForKey:contentHandlerKey
withContent:publicUserContent];
+
+ if (decryptionExecuted) {
+ comm::NotificationsCryptoModule::flushState(
+ std::move(statefulDecryptResultPtr), callingProcessName);
+ }
}
- (void)serviceExtensionTimeWillExpire {
@@ -456,20 +467,17 @@
[payload[encryptionFailureKey] isEqualToNumber:@(1)];
}
-- (NSString *)singleDecrypt:(NSString *)data {
- std::string encryptedData = std::string([data UTF8String]);
- return [NSString
- stringWithUTF8String:
- (comm::NotificationsCryptoModule::decrypt(
- encryptedData,
- comm::NotificationsCryptoModule::olmEncryptedTypeMessage,
- callingProcessName))
- .c_str()];
-}
+- (std::unique_ptr<comm::NotificationsCryptoModule::StatefulDecryptResult>)
+ decryptContentInPlace:(UNMutableNotificationContent *)content {
+ std::string encryptedData =
+ std::string([content.userInfo[encryptedPayloadKey] UTF8String]);
+
+ auto decryptResult = comm::NotificationsCryptoModule::statefulDecrypt(
+ encryptedData, comm::NotificationsCryptoModule::olmEncryptedTypeMessage);
-- (void)decryptContentInPlace:(UNMutableNotificationContent *)content {
NSString *decryptedSerializedPayload =
- [self singleDecrypt:content.userInfo[encryptedPayloadKey]];
+ [NSString stringWithUTF8String:decryptResult->getDecryptedData().c_str()];
+
NSDictionary *decryptedPayload = [NSJSONSerialization
JSONObjectWithData:[decryptedSerializedPayload
dataUsingEncoding:NSUTF8StringEncoding]
@@ -526,6 +534,8 @@
[mutableUserInfo removeObjectForKey:encryptedPayloadKey];
mutableUserInfo[@"successfullyDecrypted"] = @(YES);
content.userInfo = mutableUserInfo;
+
+ return decryptResult;
}
// Apple documentation for NSE does not explicitly state

File Metadata

Mime Type
text/plain
Expires
Fri, Nov 15, 10:29 PM (21 h, 34 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2495679
Default Alt Text
D9401.id31993.diff (8 KB)

Event Timeline