diff --git a/native/cpp/CommonCpp/CryptoTools/CryptoModule.cpp b/native/cpp/CommonCpp/CryptoTools/CryptoModule.cpp index ea8201e17..b9ea51c57 100644 --- a/native/cpp/CommonCpp/CryptoTools/CryptoModule.cpp +++ b/native/cpp/CommonCpp/CryptoTools/CryptoModule.cpp @@ -1,415 +1,382 @@ #include "CryptoModule.h" #include "Logger.h" #include "PlatformSpecificTools.h" #include "olm/account.hh" #include "olm/session.hh" #include namespace comm { namespace crypto { CryptoModule::CryptoModule(std::string id) : id{id} { this->createAccount(); } CryptoModule::CryptoModule( std::string id, std::string secretKey, Persist persist) : id{id} { if (persist.isEmpty()) { this->createAccount(); } else { this->restoreFromB64(secretKey, persist); } } void CryptoModule::createAccount() { this->accountBuffer.resize(::olm_account_size()); this->account = ::olm_account(this->accountBuffer.data()); size_t randomSize = ::olm_create_account_random_length(this->account); OlmBuffer randomBuffer; PlatformSpecificTools::generateSecureRandomBytes(randomBuffer, randomSize); if (-1 == ::olm_create_account(this->account, randomBuffer.data(), randomSize)) { throw std::runtime_error{"error createAccount => ::olm_create_account"}; }; } void CryptoModule::exposePublicIdentityKeys() { size_t identityKeysSize = ::olm_account_identity_keys_length(this->account); if (this->keys.identityKeys.size() == identityKeysSize) { return; } this->keys.identityKeys.resize( ::olm_account_identity_keys_length(this->account)); if (-1 == ::olm_account_identity_keys( this->account, this->keys.identityKeys.data(), this->keys.identityKeys.size())) { throw std::runtime_error{ "error generateIdentityKeys => ::olm_account_identity_keys"}; } } void CryptoModule::generateOneTimeKeys(size_t oneTimeKeysAmount) { size_t oneTimeKeysSize = ::olm_account_generate_one_time_keys_random_length( this->account, oneTimeKeysAmount); if (this->keys.oneTimeKeys.size() == oneTimeKeysSize) { return; } OlmBuffer random; PlatformSpecificTools::generateSecureRandomBytes(random, oneTimeKeysSize); if (-1 == ::olm_account_generate_one_time_keys( this->account, oneTimeKeysAmount, random.data(), random.size())) { throw std::runtime_error{ "error generateOneTimeKeys => ::olm_account_generate_one_time_keys"}; } } // returns number of published keys size_t CryptoModule::publishOneTimeKeys() { this->keys.oneTimeKeys.resize( ::olm_account_one_time_keys_length(this->account)); if (-1 == ::olm_account_one_time_keys( this->account, this->keys.oneTimeKeys.data(), this->keys.oneTimeKeys.size())) { throw std::runtime_error{ "error publishOneTimeKeys => ::olm_account_one_time_keys"}; } return ::olm_account_mark_keys_as_published(this->account); } Keys CryptoModule::keysFromStrings( const std::string &identityKeys, const std::string &oneTimeKeys) { return { OlmBuffer(identityKeys.begin(), identityKeys.end()), OlmBuffer(oneTimeKeys.begin(), oneTimeKeys.end())}; } std::string CryptoModule::getIdentityKeys() { this->exposePublicIdentityKeys(); return std::string{ this->keys.identityKeys.begin(), this->keys.identityKeys.end()}; } std::string CryptoModule::getOneTimeKeys(size_t oneTimeKeysAmount) { this->generateOneTimeKeys(oneTimeKeysAmount); size_t publishedOneTimeKeys = this->publishOneTimeKeys(); if (publishedOneTimeKeys != oneTimeKeysAmount) { throw std::runtime_error{ "error generateKeys => invalid amount of one-time keys published. " "Expected " + std::to_string(oneTimeKeysAmount) + ", got " + std::to_string(publishedOneTimeKeys)}; } return std::string{ this->keys.oneTimeKeys.begin(), this->keys.oneTimeKeys.end()}; } std::uint8_t CryptoModule::getNumPrekeys() { return reinterpret_cast(this->account)->num_prekeys; } std::string CryptoModule::getPrekey() { OlmBuffer prekey; prekey.resize(::olm_account_prekey_length(this->account)); if (-1 == ::olm_account_prekey(this->account, prekey.data(), prekey.size())) { throw std::runtime_error{ "error getPrekey => " + std::string{::olm_account_last_error(this->account)}}; } return std::string{std::string{prekey.begin(), prekey.end()}}; } folly::Optional CryptoModule::getUnpublishedPrekey() { OlmBuffer prekey; prekey.resize(::olm_account_prekey_length(this->account)); std::size_t retval = ::olm_account_unpublished_prekey( this->account, prekey.data(), prekey.size()); if (0 == retval) { return folly::none; } else if (-1 == retval) { throw std::runtime_error{ "error getUnpublishedPrekey => " + std::string{::olm_account_last_error(this->account)}}; } return std::string{prekey.begin(), prekey.end()}; } std::string CryptoModule::generateAndGetPrekey() { size_t prekeySize = ::olm_account_generate_prekey_random_length(this->account); OlmBuffer random; PlatformSpecificTools::generateSecureRandomBytes(random, prekeySize); if (-1 == ::olm_account_generate_prekey( this->account, random.data(), random.size())) { throw std::runtime_error{ "error generateAndGetPrekey => " + std::string{::olm_account_last_error(this->account)}}; } OlmBuffer prekey; prekey.resize(::olm_account_prekey_length(this->account)); if (-1 == ::olm_account_prekey(this->account, prekey.data(), prekey.size())) { throw std::runtime_error{ "error generateAndGetPrekey => " + std::string{::olm_account_last_error(this->account)}}; } return std::string{prekey.begin(), prekey.end()}; } void CryptoModule::markPrekeyAsPublished() { ::olm_account_mark_prekey_as_published(this->account); } void CryptoModule::forgetOldPrekey() { ::olm_account_forget_old_prekey(this->account); } void CryptoModule::initializeInboundForReceivingSession( const std::string &targetUserId, const OlmBuffer &encryptedMessage, const OlmBuffer &idKeys, const bool overwrite) { if (this->hasSessionFor(targetUserId)) { if (overwrite) { this->sessions.erase(this->sessions.find(targetUserId)); } else { throw std::runtime_error{ "error initializeInboundForReceivingSession => session already " "initialized"}; } } std::unique_ptr newSession = Session::createSessionAsResponder( this->account, this->keys.identityKeys.data(), encryptedMessage, idKeys); this->sessions.insert(make_pair(targetUserId, std::move(newSession))); } void CryptoModule::initializeOutboundForSendingSession( const std::string &targetUserId, const OlmBuffer &idKeys, const OlmBuffer &preKeys, const OlmBuffer &preKeySignature, const OlmBuffer &oneTimeKeys, size_t keyIndex) { if (this->hasSessionFor(targetUserId)) { Logger::log( "olm session overwritten for the user with id: " + targetUserId); this->sessions.erase(this->sessions.find(targetUserId)); } std::unique_ptr newSession = Session::createSessionAsInitializer( this->account, this->keys.identityKeys.data(), idKeys, preKeys, preKeySignature, oneTimeKeys, keyIndex); this->sessions.insert(make_pair(targetUserId, std::move(newSession))); } bool CryptoModule::hasSessionFor(const std::string &targetUserId) { return (this->sessions.find(targetUserId) != this->sessions.end()); } std::shared_ptr CryptoModule::getSessionByUserId(const std::string &userId) { return this->sessions.at(userId); } -bool CryptoModule::matchesInboundSession( - const std::string &targetUserId, - EncryptedData encryptedData, - const OlmBuffer &theirIdentityKey) const { - OlmSession *session = this->sessions.at(targetUserId)->getOlmSession(); - // Check that the inbound session matches the message it was created from. - OlmBuffer tmpEncryptedMessage(encryptedData.message); - if (1 != - ::olm_matches_inbound_session( - session, tmpEncryptedMessage.data(), tmpEncryptedMessage.size())) { - return false; - } - - // Check that the inbound session matches the key this message is supposed - // to be from. - tmpEncryptedMessage = OlmBuffer(encryptedData.message); - return 1 == - ::olm_matches_inbound_session_from( - session, - theirIdentityKey.data() + ID_KEYS_PREFIX_OFFSET, - KEYSIZE, - tmpEncryptedMessage.data(), - tmpEncryptedMessage.size()); -} - Persist CryptoModule::storeAsB64(const std::string &secretKey) { Persist persist; size_t accountPickleLength = ::olm_pickle_account_length(this->account); OlmBuffer accountPickleBuffer(accountPickleLength); if (accountPickleLength != ::olm_pickle_account( this->account, secretKey.data(), secretKey.size(), accountPickleBuffer.data(), accountPickleLength)) { throw std::runtime_error{"error storeAsB64 => ::olm_pickle_account"}; } persist.account = accountPickleBuffer; std::unordered_map>::iterator it; for (it = this->sessions.begin(); it != this->sessions.end(); ++it) { OlmBuffer buffer = it->second->storeAsB64(secretKey); persist.sessions.insert(make_pair(it->first, buffer)); } return persist; } void CryptoModule::restoreFromB64( const std::string &secretKey, Persist persist) { this->accountBuffer.resize(::olm_account_size()); this->account = ::olm_account(this->accountBuffer.data()); if (-1 == ::olm_unpickle_account( this->account, secretKey.data(), secretKey.size(), persist.account.data(), persist.account.size())) { throw std::runtime_error{"error restoreFromB64 => ::olm_unpickle_account"}; } std::unordered_map::iterator it; for (it = persist.sessions.begin(); it != persist.sessions.end(); ++it) { std::unique_ptr session = session->restoreFromB64( this->account, this->keys.identityKeys.data(), secretKey, it->second); this->sessions.insert(make_pair(it->first, move(session))); } } EncryptedData CryptoModule::encrypt( const std::string &targetUserId, const std::string &content) { if (!this->hasSessionFor(targetUserId)) { throw std::runtime_error{"error encrypt => uninitialized session"}; } OlmSession *session = this->sessions.at(targetUserId)->getOlmSession(); OlmBuffer encryptedMessage( ::olm_encrypt_message_length(session, content.size())); OlmBuffer messageRandom; PlatformSpecificTools::generateSecureRandomBytes( messageRandom, ::olm_encrypt_random_length(session)); size_t messageType = ::olm_encrypt_message_type(session); if (-1 == ::olm_encrypt( session, (uint8_t *)content.data(), content.size(), messageRandom.data(), messageRandom.size(), encryptedMessage.data(), encryptedMessage.size())) { throw std::runtime_error{"error encrypt => ::olm_encrypt"}; } return {encryptedMessage, messageType}; } std::string CryptoModule::decrypt( const std::string &targetUserId, - EncryptedData encryptedData, - const OlmBuffer &theirIdentityKey) { + EncryptedData encryptedData) { if (!this->hasSessionFor(targetUserId)) { throw std::runtime_error{"error decrypt => uninitialized session"}; } OlmSession *session = this->sessions.at(targetUserId)->getOlmSession(); OlmBuffer tmpEncryptedMessage(encryptedData.message); - if (encryptedData.messageType == (size_t)olm::MessageType::PRE_KEY) { - if (!this->matchesInboundSession( - targetUserId, encryptedData, theirIdentityKey)) { - throw std::runtime_error{"error decrypt => matchesInboundSession"}; - } - } - size_t maxSize = ::olm_decrypt_max_plaintext_length( session, encryptedData.messageType, tmpEncryptedMessage.data(), tmpEncryptedMessage.size()); OlmBuffer decryptedMessage(maxSize); size_t decryptedSize = ::olm_decrypt( session, encryptedData.messageType, encryptedData.message.data(), encryptedData.message.size(), decryptedMessage.data(), decryptedMessage.size()); if (decryptedSize == -1) { throw std::runtime_error{"error ::olm_decrypt"}; } return std::string{(char *)decryptedMessage.data(), decryptedSize}; } std::string CryptoModule::signMessage(const std::string &message) { OlmBuffer signature; signature.resize(::olm_account_signature_length(this->account)); size_t signatureLength = ::olm_account_sign( this->account, (uint8_t *)message.data(), message.length(), signature.data(), signature.size()); if (signatureLength == -1) { throw std::runtime_error{ "olm error: " + std::string{::olm_account_last_error(this->account)}}; } return std::string{(char *)signature.data(), signatureLength}; } void CryptoModule::verifySignature( const std::string &publicKey, const std::string &message, const std::string &signature) { OlmBuffer utilityBuffer; utilityBuffer.resize(::olm_utility_size()); OlmUtility *olmUtility = ::olm_utility(utilityBuffer.data()); ssize_t verificationResult = ::olm_ed25519_verify( olmUtility, (uint8_t *)publicKey.data(), publicKey.length(), (uint8_t *)message.data(), message.length(), (uint8_t *)signature.data(), signature.length()); if (verificationResult == -1) { throw std::runtime_error{ "olm error: " + std::string{::olm_utility_last_error(olmUtility)}}; } } } // namespace crypto } // namespace comm diff --git a/native/cpp/CommonCpp/CryptoTools/CryptoModule.h b/native/cpp/CommonCpp/CryptoTools/CryptoModule.h index be80d9c63..5251eab83 100644 --- a/native/cpp/CommonCpp/CryptoTools/CryptoModule.h +++ b/native/cpp/CommonCpp/CryptoTools/CryptoModule.h @@ -1,89 +1,83 @@ #pragma once #include #include #include #include "folly/Optional.h" #include "olm/olm.h" #include "Persist.h" #include "Session.h" #include "Tools.h" namespace comm { namespace crypto { class CryptoModule { OlmAccount *account = nullptr; OlmBuffer accountBuffer; std::unordered_map> sessions = {}; Keys keys; void createAccount(); void exposePublicIdentityKeys(); void generateOneTimeKeys(size_t oneTimeKeysAmount); // returns number of published keys size_t publishOneTimeKeys(); public: const std::string id; CryptoModule(std::string id); CryptoModule(std::string id, std::string secretKey, Persist persist); static Keys keysFromStrings( const std::string &identityKeys, const std::string &oneTimeKeys); std::string getIdentityKeys(); std::string getOneTimeKeys(size_t oneTimeKeysAmount = 50); // Prekey rotation methods for X3DH std::uint8_t getNumPrekeys(); std::string getPrekey(); folly::Optional getUnpublishedPrekey(); std::string generateAndGetPrekey(); void markPrekeyAsPublished(); void forgetOldPrekey(); void initializeInboundForReceivingSession( const std::string &targetUserId, const OlmBuffer &encryptedMessage, const OlmBuffer &idKeys, const bool overwrite = false); void initializeOutboundForSendingSession( const std::string &targetUserId, const OlmBuffer &idKeys, const OlmBuffer &preKeys, const OlmBuffer &preKeySignature, const OlmBuffer &oneTimeKeys, size_t keyIndex = 0); bool hasSessionFor(const std::string &targetUserId); std::shared_ptr getSessionByUserId(const std::string &userId); - bool matchesInboundSession( - const std::string &targetUserId, - EncryptedData encryptedData, - const OlmBuffer &theirIdentityKey) const; Persist storeAsB64(const std::string &secretKey); void restoreFromB64(const std::string &secretKey, Persist persist); EncryptedData encrypt(const std::string &targetUserId, const std::string &content); - std::string decrypt( - const std::string &targetUserId, - EncryptedData encryptedData, - const OlmBuffer &theirIdentityKey); + std::string + decrypt(const std::string &targetUserId, EncryptedData encryptedData); std::string signMessage(const std::string &message); static void verifySignature( const std::string &publicKey, const std::string &message, const std::string &signature); }; } // namespace crypto } // namespace comm diff --git a/native/cpp/CommonCpp/Notifications/BackgroundDataStorage/NotificationsCryptoModule.cpp b/native/cpp/CommonCpp/Notifications/BackgroundDataStorage/NotificationsCryptoModule.cpp index 27de88b02..f5e5d30e8 100644 --- a/native/cpp/CommonCpp/Notifications/BackgroundDataStorage/NotificationsCryptoModule.cpp +++ b/native/cpp/CommonCpp/Notifications/BackgroundDataStorage/NotificationsCryptoModule.cpp @@ -1,236 +1,250 @@ #include "NotificationsCryptoModule.h" #include "../../CryptoTools/Persist.h" #include "../../CryptoTools/Tools.h" #include "../../Tools/CommSecureStore.h" #include "../../Tools/PlatformSpecificTools.h" #include #include #include #include #include #include #include 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\"}"; crypto::CryptoModule NotificationsCryptoModule::deserializeCryptoModule( const std::string &path, const std::string &picklingKey) { std::ifstream pickledPersistStream(path, std::ifstream::in); if (!pickledPersistStream.good()) { throw std::runtime_error( "Attempt to deserialize non-existing notifications crypto account"); } std::stringstream pickledPersistStringStream; pickledPersistStringStream << pickledPersistStream.rdbuf(); pickledPersistStream.close(); std::string pickledPersist = pickledPersistStringStream.str(); folly::dynamic persistJSON; try { persistJSON = folly::parseJson(pickledPersist); } catch (const folly::json::parse_error &e) { throw std::runtime_error( "Notifications crypto account JSON deserialization failed with " "reason: " + std::string(e.what())); } std::string accountString = persistJSON["account"].asString(); crypto::OlmBuffer account = std::vector(accountString.begin(), accountString.end()); std::unordered_map sessions; if (persistJSON["sessions"].isNull()) { return crypto::CryptoModule{ notificationsCryptoAccountID, picklingKey, {account, sessions}}; } for (auto &sessionKeyValuePair : persistJSON["sessions"].items()) { std::string targetUserID = sessionKeyValuePair.first.asString(); std::string sessionData = sessionKeyValuePair.second.asString(); sessions[targetUserID] = std::vector(sessionData.begin(), sessionData.end()); } return crypto::CryptoModule{ notificationsCryptoAccountID, picklingKey, {account, sessions}}; } void NotificationsCryptoModule::serializeAndFlushCryptoModule( crypto::CryptoModule &cryptoModule, const std::string &path, const std::string &picklingKey, const std::string &callingProcessName) { crypto::Persist persist = cryptoModule.storeAsB64(picklingKey); 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()); } 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 temporaryPath = path + callingProcessName; // This is for the case if any of the steps below failed/app was killed // in a previous call to this method leaving temporary file unremoved. // We supply `callingProcessName` as function argument in order to name // temporary file in a deterministic way. Otherwise we would need to use // directory search API to retrieve unremoved files paths. remove(temporaryPath.c_str()); 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()); 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))); } } void NotificationsCryptoModule::callCryptoModule( std::function caller, const std::string &callingProcessName) { CommSecureStore secureStore{}; folly::Optional picklingKey = secureStore.get( NotificationsCryptoModule::secureStoreNotificationsAccountDataKey); if (!picklingKey.hasValue()) { throw std::runtime_error( "Attempt to retrieve notifications crypto account before it was " "correctly initialized."); } const std::string path = PlatformSpecificTools::getNotificationsCryptoAccountPath(); crypto::CryptoModule cryptoModule = NotificationsCryptoModule::deserializeCryptoModule( path, picklingKey.value()); caller(cryptoModule); NotificationsCryptoModule::serializeAndFlushCryptoModule( cryptoModule, path, picklingKey.value(), callingProcessName); } void NotificationsCryptoModule::initializeNotificationsCryptoAccount( const std::string &callingProcessName) { 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 notificationCryptoAccountCheck.close(); return; } // 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 CommSecureStore secureStore{}; std::string picklingKey = crypto::Tools::generateRandomString(64); secureStore.set( NotificationsCryptoModule::secureStoreNotificationsAccountDataKey, picklingKey); crypto::CryptoModule cryptoModule{ NotificationsCryptoModule::notificationsCryptoAccountID}; NotificationsCryptoModule::serializeAndFlushCryptoModule( cryptoModule, notificationsCryptoAccountPath, picklingKey, callingProcessName); } std::string NotificationsCryptoModule::getNotificationsIdentityKeys( const std::string &callingProcessName) { std::string identityKeys; auto caller = [&identityKeys](crypto::CryptoModule cryptoModule) { identityKeys = cryptoModule.getIdentityKeys(); }; NotificationsCryptoModule::callCryptoModule(caller, callingProcessName); return identityKeys; } crypto::EncryptedData NotificationsCryptoModule::initializeNotificationsSession( const std::string &identityKeys, const std::string &prekey, const std::string &prekeySignature, const std::string &oneTimeKeys, const std::string &callingProcessName) { crypto::EncryptedData initialEncryptedMessage; auto caller = [&](crypto::CryptoModule &cryptoModule) { cryptoModule.initializeOutboundForSendingSession( NotificationsCryptoModule::keyserverHostedNotificationsID, std::vector(identityKeys.begin(), identityKeys.end()), std::vector(prekey.begin(), prekey.end()), std::vector(prekeySignature.begin(), prekeySignature.end()), std::vector(oneTimeKeys.begin(), oneTimeKeys.end())); initialEncryptedMessage = cryptoModule.encrypt( NotificationsCryptoModule::keyserverHostedNotificationsID, NotificationsCryptoModule::initialEncryptedMessageContent); }; NotificationsCryptoModule::callCryptoModule(caller, callingProcessName); return initialEncryptedMessage; } bool NotificationsCryptoModule::isNotificationsSessionInitialized( const std::string &callingProcessName) { bool sessionInitialized; auto caller = [&sessionInitialized](crypto::CryptoModule &cryptoModule) { sessionInitialized = cryptoModule.hasSessionFor( NotificationsCryptoModule::keyserverHostedNotificationsID); }; NotificationsCryptoModule::callCryptoModule(caller, callingProcessName); return sessionInitialized; } void NotificationsCryptoModule::clearSensitiveData() { std::string notificationsCryptoAccountPath = PlatformSpecificTools::getNotificationsCryptoAccountPath(); if (remove(notificationsCryptoAccountPath.c_str()) == -1 && errno != ENOENT) { throw std::runtime_error( "Unable to remove notifications crypto account. Security requirements " "might be violated."); } } + +std::string NotificationsCryptoModule::decrypt( + const std::string &data, + const size_t messageType, + const std::string &callingProcessName) { + std::string decryptedData; + auto caller = [&](crypto::CryptoModule &cryptoModule) { + decryptedData = cryptoModule.decrypt( + NotificationsCryptoModule::keyserverHostedNotificationsID, + {std::vector(data.begin(), data.end()), messageType}); + }; + NotificationsCryptoModule::callCryptoModule(caller, callingProcessName); + return decryptedData; +} } // namespace comm diff --git a/native/cpp/CommonCpp/Notifications/BackgroundDataStorage/NotificationsCryptoModule.h b/native/cpp/CommonCpp/Notifications/BackgroundDataStorage/NotificationsCryptoModule.h index 33e3947cd..423b330ce 100644 --- a/native/cpp/CommonCpp/Notifications/BackgroundDataStorage/NotificationsCryptoModule.h +++ b/native/cpp/CommonCpp/Notifications/BackgroundDataStorage/NotificationsCryptoModule.h @@ -1,41 +1,45 @@ #pragma once #include "../../CryptoTools/CryptoModule.h" #include 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 void serializeAndFlushCryptoModule( crypto::CryptoModule &cryptoModule, const std::string &path, const std::string &picklingKey, const std::string &callingProcessName); static crypto::CryptoModule deserializeCryptoModule( const std::string &path, const std::string &picklingKey); static void callCryptoModule( std::function caller, const std::string &callingProcessName); public: static void initializeNotificationsCryptoAccount(const std::string &callingProcessName); static void clearSensitiveData(); static std::string getNotificationsIdentityKeys(const std::string &callingProcessName); 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 std::string decrypt( + const std::string &data, + const size_t messageType, + const std::string &callingProcessName); }; } // namespace comm