Commit c63e302e authored by Johan Pascal's avatar Johan Pascal

LimeManager encrypt gets the encryption policy argument

parent 1d61f556
......@@ -42,7 +42,7 @@ namespace lime {
std::string deviceId; // recipient deviceId (shall be GRUU)
bool identityVerified; // after encrypt calls back, it will hold the status of this peer device: identity verified or not
std::vector<uint8_t> cipherHeader; // after encrypt calls back, it will hold the header targeted to the specified recipient. This header may contain an X3DH init message.
recipientData(std::string deviceId) : deviceId{deviceId}, identityVerified{false}, cipherHeader{} {};
recipientData(const std::string deviceId) : deviceId{deviceId}, identityVerified{false}, cipherHeader{} {};
};
/* Enum of what a Lime callback could possibly say */
......@@ -143,8 +143,10 @@ namespace lime {
* this callback will be called giving the exit status and an error message in case of failure.
* It is advised to capture a copy of cipherMessage and recipients shared_ptr in this callback so they can access
* the output of encryption as it won't be part of the callback parameters.
* @param[in] encryptionPolicy select how to manage the encryption: direct use of Double Ratchet message or encrypt in the cipher message and use the DR message to share the cipher message key
* default is optimized output size mode.
*/
void encrypt(const std::string &localDeviceId, std::shared_ptr<const std::string> recipientUserId, std::shared_ptr<std::vector<recipientData>> recipients, std::shared_ptr<const std::vector<uint8_t>> plainMessage, std::shared_ptr<std::vector<uint8_t>> cipherMessage, const limeCallback &callback);
void encrypt(const std::string &localDeviceId, std::shared_ptr<const std::string> recipientUserId, std::shared_ptr<std::vector<recipientData>> recipients, std::shared_ptr<const std::vector<uint8_t>> plainMessage, std::shared_ptr<std::vector<uint8_t>> cipherMessage, const limeCallback &callback, lime::EncryptionPolicy encryptionPolicy=lime::EncryptionPolicy::optimizeSize);
/**
* @brief Decrypt the given message
......
......@@ -153,7 +153,7 @@ namespace lime {
}
template <typename Curve>
void Lime<Curve>::encrypt(std::shared_ptr<const std::string> recipientUserId, std::shared_ptr<std::vector<recipientData>> recipients, std::shared_ptr<const std::vector<uint8_t>> plainMessage, std::shared_ptr<std::vector<uint8_t>> cipherMessage, const limeCallback &callback) {
void Lime<Curve>::encrypt(std::shared_ptr<const std::string> recipientUserId, std::shared_ptr<std::vector<recipientData>> recipients, std::shared_ptr<const std::vector<uint8_t>> plainMessage, const lime::EncryptionPolicy encryptionPolicy, std::shared_ptr<std::vector<uint8_t>> cipherMessage, const limeCallback &callback) {
LIME_LOGD<<"encrypt from "<<m_selfDeviceId<<" to "<<recipients->size()<<" recipients";
/* Check if we have all the Double Ratchet sessions ready or shall we go for an X3DH */
std::vector<std::string> missingPeers; /* vector of deviceId(GRUU) which are requested to perform X3DH before the encryption can occurs */
......@@ -181,7 +181,7 @@ namespace lime {
/* If we are still missing session we must ask the X3DH server for key bundles */
if (missing_devices.size()>0) {
// create a new callbackUserData, it shall be then deleted in callback, store in all shared_ptr to input/output values needed to call this encrypt function
auto userData = make_shared<callbackUserData<Curve>>(this->shared_from_this(), callback, recipientUserId, recipients, plainMessage, cipherMessage);
auto userData = make_shared<callbackUserData<Curve>>(this->shared_from_this(), callback, recipientUserId, recipients, plainMessage, cipherMessage, encryptionPolicy);
if (m_ongoing_encryption == nullptr) { // no ongoing asynchronous encryption process it
m_ongoing_encryption = userData;
} else { // some one else is expecting X3DH server response, enqueue this request
......@@ -193,7 +193,7 @@ namespace lime {
x3dh_protocol::buildMessage_getPeerBundles<Curve>(X3DHmessage, missing_devices);
postToX3DHServer(userData, X3DHmessage);
} else { // got everyone, encrypt
encryptMessage(internal_recipients, *plainMessage, *recipientUserId, m_selfDeviceId, *cipherMessage);
encryptMessage(internal_recipients, *plainMessage, *recipientUserId, m_selfDeviceId, *cipherMessage, encryptionPolicy);
// move cipher headers to the input/output structure
for (size_t i=0; i<recipients->size(); i++) {
(*recipients)[i].cipherHeader = std::move(internal_recipients[i].cipherHeader);
......@@ -204,7 +204,7 @@ namespace lime {
if (m_ongoing_encryption == nullptr && !m_encryption_queue.empty()) { // may happend when an encryption was queued but session was created by a previously queued encryption request
auto userData = m_encryption_queue.front();
m_encryption_queue.pop(); // remove it from queue and do it
encrypt(userData->recipientUserId, userData->recipients, userData->plainMessage, userData->cipherMessage, userData->callback);
encrypt(userData->recipientUserId, userData->recipients, userData->plainMessage, userData->encryptionPolicy, userData->cipherMessage, userData->callback);
}
}
}
......
......@@ -133,7 +133,7 @@ namespace lime {
*/
virtual void get_Ik(std::vector<uint8_t> &Ik) override;
void encrypt(std::shared_ptr<const std::string> recipientUserId, std::shared_ptr<std::vector<recipientData>> recipients, std::shared_ptr<const std::vector<uint8_t>> plainMessage, std::shared_ptr<std::vector<uint8_t>> cipherMessage, const limeCallback &callback) override;
void encrypt(std::shared_ptr<const std::string> recipientUserId, std::shared_ptr<std::vector<recipientData>> recipients, std::shared_ptr<const std::vector<uint8_t>> plainMessage, const lime::EncryptionPolicy encryptionPolicy, std::shared_ptr<std::vector<uint8_t>> cipherMessage, const limeCallback &callback) override;
bool decrypt(const std::string &recipientUserId, const std::string &senderDeviceId, const std::vector<uint8_t> &cipherHeader, const std::vector<uint8_t> &cipherMessage, std::vector<uint8_t> &plainMessage) override;
};
......@@ -149,27 +149,30 @@ namespace lime {
std::shared_ptr<const std::vector<uint8_t>> plainMessage;
std::shared_ptr<std::vector<uint8_t>> cipherMessage;
lime::network_state network_state_machine; /* used to run a simple state machine at user creation to perform sequence of packet sending: registerUser, postSPk, postOPks */
lime::EncryptionPolicy encryptionPolicy; /* the encryption policy from the original encryption request(if running an encryption request) */
uint16_t OPkServerLowLimit; /* Used when fetching from server self OPk to check if we shall upload more */
uint16_t OPkBatchSize;
// created at user create/delete and keys Post
// created at user create/delete and keys Post. EncryptionPolicy is not used, set it to the default value anyway
callbackUserData(std::weak_ptr<Lime<Curve>> thiz, const limeCallback &callbackRef, uint16_t OPkInitialBatchSize=lime::settings::OPk_initialBatchSize, bool startRegisterUserSequence=false)
: limeObj{thiz}, callback{callbackRef},
recipientUserId{nullptr}, recipients{nullptr}, plainMessage{nullptr}, cipherMessage{nullptr}, network_state_machine{startRegisterUserSequence?lime::network_state::sendSPk:lime::network_state::done},
OPkServerLowLimit(0), OPkBatchSize(OPkInitialBatchSize) {};
encryptionPolicy(lime::EncryptionPolicy::optimizeSize), OPkServerLowLimit(0), OPkBatchSize(OPkInitialBatchSize) {};
// created at update: getSelfOPks
// created at update: getSelfOPks. EncryptionPolicy is not used, set it to the default value anyway
callbackUserData(std::weak_ptr<Lime<Curve>> thiz, const limeCallback &callbackRef, uint16_t OPkServerLowLimit, uint16_t OPkBatchSize)
: limeObj{thiz}, callback{callbackRef},
recipientUserId{nullptr}, recipients{nullptr}, plainMessage{nullptr}, cipherMessage{nullptr}, network_state_machine{lime::network_state::done},
OPkServerLowLimit{OPkServerLowLimit}, OPkBatchSize{OPkBatchSize} {};
encryptionPolicy(lime::EncryptionPolicy::optimizeSize), OPkServerLowLimit{OPkServerLowLimit}, OPkBatchSize{OPkBatchSize} {};
// created at encrypt(getPeerBundle)
callbackUserData(std::weak_ptr<Lime<Curve>> thiz, const limeCallback &callbackRef,
std::shared_ptr<const std::string> recipientUserId, std::shared_ptr<std::vector<recipientData>> recipients,
std::shared_ptr<const std::vector<uint8_t>> plainMessage, std::shared_ptr<std::vector<uint8_t>> cipherMessage)
std::shared_ptr<const std::vector<uint8_t>> plainMessage, std::shared_ptr<std::vector<uint8_t>> cipherMessage,
lime::EncryptionPolicy policy)
: limeObj{thiz}, callback{callbackRef},
recipientUserId{recipientUserId}, recipients{recipients}, plainMessage{plainMessage}, cipherMessage{cipherMessage}, network_state_machine {lime::network_state::done}, // copy construct all shared_ptr
OPkServerLowLimit(0), OPkBatchSize(0) {};
encryptionPolicy(policy), OPkServerLowLimit(0), OPkBatchSize(0) {};
// do not copy callback data, force passing the pointer around after creation
callbackUserData(callbackUserData &a) = delete;
callbackUserData operator=(callbackUserData &a) = delete;
......
......@@ -52,16 +52,17 @@ namespace lime {
*
* Note: all parameters are shared pointers as the process being asynchronous, the ownership will be taken internally exempting caller to manage the buffers.
*
* @param[in] recipientUserId the Id of intended recipient, shall be a sip:uri of user or conference, is used as associated data to ensure no-one can mess with intended recipient
* @param[in/out] recipients a list of recipientData holding: the recipient device Id(GRUU) and an empty buffer to store the cipherHeader which must then be routed to that recipient
* @param[in] plainMessage a buffer holding the message to encrypt, can be text or data.
* @param[out] cipherMessage points to the buffer to store the encrypted message which must be routed to all recipients
* @param[in] callback This operation contact the X3DH server and is thus asynchronous, when server responds,
* @param[in] recipientUserId the Id of intended recipient, shall be a sip:uri of user or conference, is used as associated data to ensure no-one can mess with intended recipient
* @param[in/out] recipients a list of recipientData holding: the recipient device Id(GRUU) and an empty buffer to store the cipherHeader which must then be routed to that recipient
* @param[in] plainMessage a buffer holding the message to encrypt, can be text or data.
* @param[in] encryptionPolicy select how to manage the encryption: direct use of Double Ratchet message or encrypt in the cipher message and use the DR message to share the cipher message key
* @param[out] cipherMessage points to the buffer to store the encrypted message which must be routed to all recipients
* @param[in] callback This operation contact the X3DH server and is thus asynchronous, when server responds,
* this callback will be called giving the exit status and an error message in case of failure.
* It is advised to capture a copy of cipherMessage and recipients shared_ptr in this callback so they can access
* the output of encryption as it won't be part of the callback parameters.
*/
virtual void encrypt(std::shared_ptr<const std::string> recipientUserId, std::shared_ptr<std::vector<recipientData>> recipients, std::shared_ptr<const std::vector<uint8_t>> plainMessage, std::shared_ptr<std::vector<uint8_t>> cipherMessage, const limeCallback &callback) = 0;
virtual void encrypt(std::shared_ptr<const std::string> recipientUserId, std::shared_ptr<std::vector<recipientData>> recipients, std::shared_ptr<const std::vector<uint8_t>> plainMessage, const lime::EncryptionPolicy encryptionPolicy, std::shared_ptr<std::vector<uint8_t>> cipherMessage, const limeCallback &callback) = 0;
/**
* @brief Decrypt the given message
......
......@@ -81,13 +81,13 @@ namespace lime {
user->delete_user(managerDeleteCallback);
}
void LimeManager::encrypt(const std::string &localDeviceId, std::shared_ptr<const std::string> recipientUserId, std::shared_ptr<std::vector<recipientData>> recipients, std::shared_ptr<const std::vector<uint8_t>> plainMessage, std::shared_ptr<std::vector<uint8_t>> cipherMessage, const limeCallback &callback) {
void LimeManager::encrypt(const std::string &localDeviceId, std::shared_ptr<const std::string> recipientUserId, std::shared_ptr<std::vector<recipientData>> recipients, std::shared_ptr<const std::vector<uint8_t>> plainMessage, std::shared_ptr<std::vector<uint8_t>> cipherMessage, const limeCallback &callback, const lime::EncryptionPolicy encryptionPolicy) {
// Load user object
std::shared_ptr<LimeGeneric> user;
LimeManager::load_user(user, localDeviceId);
// call the encryption function
user->encrypt(recipientUserId, recipients, plainMessage, cipherMessage, callback);
user->encrypt(recipientUserId, recipients, plainMessage, encryptionPolicy, cipherMessage, callback);
}
bool LimeManager::decrypt(const std::string &localDeviceId, const std::string &recipientUserId, const std::string &senderDeviceId, const std::vector<uint8_t> &cipherHeader, const std::vector<uint8_t> &cipherMessage, std::vector<uint8_t> &plainMessage) {
......
......@@ -448,7 +448,7 @@ namespace lime {
if (!m_encryption_queue.empty()) {
auto userData = m_encryption_queue.front();
m_encryption_queue.pop(); // remove it from queue and do it, as there is no more ongoing it shall be processed even if the queue still holds elements
encrypt(userData->recipientUserId, userData->recipients, userData->plainMessage, userData->cipherMessage, userData->callback);
encrypt(userData->recipientUserId, userData->recipients, userData->plainMessage, userData->encryptionPolicy, userData->cipherMessage, userData->callback);
}
} else { // its not an encryption, just set userData to null it shall destroy it
userData = nullptr;
......@@ -544,7 +544,7 @@ namespace lime {
}
// call the encrypt function again, it will call the callback when done, encryption queue won't be processed as still locked by the m_ongoing_encryption member
encrypt(userData->recipientUserId, userData->recipients, userData->plainMessage, userData->cipherMessage, callback);
encrypt(userData->recipientUserId, userData->recipients, userData->plainMessage, userData->encryptionPolicy, userData->cipherMessage, callback);
// now we can safely delete the user data, note that this may trigger an other encryption if there is one in queue
cleanUserData(userData);
......
......@@ -41,6 +41,9 @@ int wait_for_timeout=4000;
// default value for initial OPk batch size, keep it small so not too many OPks generated
uint16_t OPkInitialBatchSize=3;
std::string shortMessage{"Short Message"};
std::string longMessage{"This message is long enough to automatically switch to cipher Message mode when at least two recipients are involved. This message is long enough to automatically switch to cipher Message mode when at least two recipients are involved."};
std::vector<std::string> messages_pattern = {
{"Frankly, my dear, I don't give a damn."},
{"I'm gonna make him an offer he can't refuse."},
......
......@@ -32,6 +32,9 @@ using namespace::lime;
namespace lime_tester {
extern std::string shortMessage;
extern std::string longMessage;
extern std::vector<std::string> messages_pattern;
// default value for the timeout
......
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment