Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F3246277
D9401.id31993.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
8 KB
Referenced Files
None
Subscribers
None
D9401.id31993.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D9401: Implement stateful and deferrable notification decryption and use it on iOS in NSE
Attached
Detach File
Event Timeline
Log In to Comment