Commit 62f2ae2a authored by Johan Pascal's avatar Johan Pascal

Code cleaning

better and more coherent variable and fields names
parent 6b81d5b4
......@@ -43,19 +43,19 @@ namespace lime {
};
/** Used to manage recipient list for encrypt function input: give a recipient GRUU and get it back with the header which must be sent to recipient with the cipher text*/
struct recipientData {
const 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. */
struct RecipientData {
const std::string deviceId; /**< input: recipient deviceId (shall be GRUU) */
bool identityVerified; /**< output: after encrypt calls back, it will hold the status of this peer device: identity verified or not */
std::vector<uint8_t> DRmessage; /**< output: after encrypt calls back, it will hold the Double Ratchet message targeted to the specified recipient. */
/**
* recipient data are built giving a recipient id
* @param[in] deviceId the recipient device Id (its GRUU)
*/
recipientData(const std::string deviceId) : deviceId{deviceId}, identityVerified{false}, cipherHeader{} {};
RecipientData(const std::string &deviceId) : deviceId{deviceId}, identityVerified{false}, DRmessage{} {};
};
/** what a Lime callback could possibly say */
enum class callbackReturn : uint8_t {
enum class CallbackReturn : uint8_t {
success, /**< operation completed successfully */
fail /**< operation failed, we shall have an explanation string too */
};
......@@ -65,7 +65,7 @@ namespace lime {
* @param[in] status success or fail
* @param[in] message in case of failure, an explanation, it may be empty
*/
using limeCallback = std::function<void(const lime::callbackReturn status, const std::string message)>;
using limeCallback = std::function<void(const lime::CallbackReturn status, const std::string message)>;
/* X3DH server communication : these functions prototypes are used to post data and get response from/to the X3DH server */
/**
......@@ -159,9 +159,9 @@ namespace lime {
*
* @param[in] localDeviceId used to identify which local acount to use and also as the identified source of the message, shall be the GRUU
* @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,out] recipients a list of RecipientData holding: the recipient device Id(GRUU) and an empty buffer to store the DRmessage 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[out] cipherMessage points to the buffer to store the encrypted message which must be routed to all recipients(if one is produced, depends on encryption policy)
* @param[in] callback Performing encryption may involve the X3DH server and is thus asynchronous, when the operation is completed,
* 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
......@@ -169,7 +169,7 @@ namespace lime {
* @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, lime::EncryptionPolicy encryptionPolicy=lime::EncryptionPolicy::optimizeUploadSize);
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::optimizeUploadSize);
/**
* @brief Decrypt the given message
......@@ -179,13 +179,13 @@ namespace lime {
* @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
* it is not necessarily the sip:uri base of the GRUU as this could be a message from alice first device intended to bob being decrypted on alice second device
* @param[in] senderDeviceId Identify sender Device. This field shall be extracted from signaling data in transport protocol, is used to rebuild the authenticated data associated to the encrypted message
* @param[in] cipherHeader the part of cipher which is targeted to current device
* @param[in] cipherMessage part of cipher routed to all recipient devices
* @param[in] DRmessage Double Ratchet message targeted to current device
* @param[in] cipherMessage part of cipher routed to all recipient devices, may be empty
* @param[out] plainMessage the output buffer
*
* @return true if the decryption is successfull, false otherwise
*/
bool 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);
bool decrypt(const std::string &localDeviceId, const std::string &recipientUserId, const std::string &senderDeviceId, const std::vector<uint8_t> &DRmessage, const std::vector<uint8_t> &cipherMessage, std::vector<uint8_t> &plainMessage);
/**
* @brief Update: shall be called once a day at least, performs checks, updates and cleaning operations
......
......@@ -132,7 +132,7 @@ namespace lime {
x3dh_protocol::buildMessage_publishSPk(X3DHmessage, SPk, SPk_sig, SPk_id);
postToX3DHServer(userData, X3DHmessage);
} else { // nothing to do but caller expect a callback
if (callback) callback(lime::callbackReturn::success, "");
if (callback) callback(lime::CallbackReturn::success, "");
}
}
......@@ -153,13 +153,13 @@ 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, const lime::EncryptionPolicy encryptionPolicy, 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 */
/* Create the appropriate recipient infos and fill it with sessions found in cache */
std::vector<recipientInfos<Curve>> internal_recipients{};
std::vector<RecipientInfos<Curve>> internal_recipients{};
for (const auto &recipient : *recipients) {
auto sessionElem = m_DR_sessions_cache.find(recipient.deviceId);
if (sessionElem != m_DR_sessions_cache.end()) { // session is in cache
......@@ -194,12 +194,12 @@ namespace lime {
postToX3DHServer(userData, X3DHmessage);
} else { // got everyone, encrypt
encryptMessage(internal_recipients, *plainMessage, *recipientUserId, m_selfDeviceId, *cipherMessage, encryptionPolicy);
// move cipher headers to the input/output structure
// move DR messages to the input/output structure
for (size_t i=0; i<recipients->size(); i++) {
(*recipients)[i].cipherHeader = std::move(internal_recipients[i].cipherHeader);
(*recipients)[i].DRmessage = std::move(internal_recipients[i].DRmessage);
(*recipients)[i].identityVerified = internal_recipients[i].identityVerified;
}
if (callback) callback(lime::callbackReturn::success, "");
if (callback) callback(lime::CallbackReturn::success, "");
// is there no one in an asynchronous encryption process and do we have something in encryption queue to process
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();
......@@ -210,7 +210,7 @@ namespace lime {
}
template <typename Curve>
bool Lime<Curve>::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) {
bool Lime<Curve>::decrypt(const std::string &recipientUserId, const std::string &senderDeviceId, const std::vector<uint8_t> &DRmessage, const std::vector<uint8_t> &cipherMessage, std::vector<uint8_t> &plainMessage) {
LIME_LOGD<<"decrypt from "<<senderDeviceId<<" to "<<recipientUserId;
// do we have any session (loaded or not) matching that senderDeviceId ?
auto sessionElem = m_DR_sessions_cache.find(senderDeviceId);
......@@ -218,7 +218,7 @@ namespace lime {
if (sessionElem != m_DR_sessions_cache.end()) { // session is in cache, it is the active one, just give it a try
db_sessionIdInCache = sessionElem->second->dbSessionId();
std::vector<std::shared_ptr<DR<Curve>>> DRSessions{1, sessionElem->second}; // copy the session pointer into a vector as the decryot function ask for it
if (decryptMessage<Curve>(senderDeviceId, m_selfDeviceId, recipientUserId, DRSessions, cipherHeader, cipherMessage, plainMessage) != nullptr) {
if (decryptMessage<Curve>(senderDeviceId, m_selfDeviceId, recipientUserId, DRSessions, DRmessage, cipherMessage, plainMessage) != nullptr) {
return true; // we manage to decrypt the message with the current active session loaded in cache, nothing else to do
} else { // remove session from cache
// session in local storage is not modified, so it's still the active one, it will change status to stale when an other active session will be created
......@@ -230,7 +230,7 @@ namespace lime {
std::vector<std::shared_ptr<DR<Curve>>> DRSessions{};
// load in DRSessions all the session found in cache for this peer device, except the one with id db_sessionIdInCache(is ignored if 0) as we already tried it
get_DRSessions(senderDeviceId, db_sessionIdInCache, DRSessions);
auto usedDRSession = decryptMessage<Curve>(senderDeviceId, m_selfDeviceId, recipientUserId, DRSessions, cipherHeader, cipherMessage, plainMessage);
auto usedDRSession = decryptMessage<Curve>(senderDeviceId, m_selfDeviceId, recipientUserId, DRSessions, DRmessage, cipherMessage, plainMessage);
if (usedDRSession != nullptr) { // we manage to decrypt with a session
m_DR_sessions_cache[senderDeviceId] = std::move(usedDRSession);
return true;
......@@ -238,7 +238,7 @@ namespace lime {
// No luck yet, is this message holds a X3DH header - if no we must give up
std::vector<uint8_t> X3DH_initMessage{};
if (!double_ratchet_protocol::parseMessage_get_X3DHinit<Curve>(cipherHeader, X3DH_initMessage)) {
if (!double_ratchet_protocol::parseMessage_get_X3DHinit<Curve>(DRmessage, X3DH_initMessage)) {
return false;
}
......@@ -252,7 +252,7 @@ namespace lime {
return false;
}
if (decryptMessage<Curve>(senderDeviceId, m_selfDeviceId, recipientUserId, DRSessions, cipherHeader, cipherMessage, plainMessage) != 0) {
if (decryptMessage<Curve>(senderDeviceId, m_selfDeviceId, recipientUserId, DRSessions, DRmessage, cipherMessage, plainMessage) != 0) {
// we manage to decrypt the message with this session, set it in cache
m_DR_sessions_cache[senderDeviceId] = std::move(DRSessions.front());
return true;
......
......@@ -210,7 +210,7 @@ namespace lime {
}
// each call to this function is made with a different DHr
receiverKeyChain<Curve> newRChain{m_DHr};
ReceiverKeyChain<Curve> newRChain{m_DHr};
m_mkskipped.push_back(newRChain);
auto rChain = &m_mkskipped.back();
......@@ -404,7 +404,7 @@ namespace lime {
#endif
template <typename Curve>
void encryptMessage(std::vector<recipientInfos<Curve>>& recipients, const std::vector<uint8_t>& plaintext, const std::string& recipientUserId, const std::string& sourceDeviceId, std::vector<uint8_t>& cipherMessage, const lime::EncryptionPolicy encryptionPolicy) {
void encryptMessage(std::vector<RecipientInfos<Curve>>& recipients, const std::vector<uint8_t>& plaintext, const std::string& recipientUserId, const std::string& sourceDeviceId, std::vector<uint8_t>& cipherMessage, const lime::EncryptionPolicy encryptionPolicy) {
// Shall we set the payload in the DR message or in a separate cupher message buffer?
bool payloadDirectEncryption;
switch (encryptionPolicy) {
......@@ -501,15 +501,15 @@ namespace lime {
recipientAD.insert(recipientAD.end(), recipients[i].deviceId.cbegin(), recipients[i].deviceId.cend()); //insert recipient device id(gruu)
if (payloadDirectEncryption) {
recipients[i].DRSession->ratchetEncrypt(plaintext, std::move(recipientAD), recipients[i].cipherHeader, payloadDirectEncryption);
recipients[i].DRSession->ratchetEncrypt(plaintext, std::move(recipientAD), recipients[i].DRmessage, payloadDirectEncryption);
} else {
recipients[i].DRSession->ratchetEncrypt(randomSeed, std::move(recipientAD), recipients[i].cipherHeader, payloadDirectEncryption);
recipients[i].DRSession->ratchetEncrypt(randomSeed, std::move(recipientAD), recipients[i].DRmessage, payloadDirectEncryption);
}
}
}
template <typename Curve>
std::shared_ptr<DR<Curve>> decryptMessage(const std::string& sourceDeviceId, const std::string& recipientDeviceId, const std::string& recipientUserId, std::vector<std::shared_ptr<DR<Curve>>>& DRSessions, const std::vector<uint8_t>& cipherHeader, const std::vector<uint8_t>& cipherMessage, std::vector<uint8_t>& plaintext) {
std::shared_ptr<DR<Curve>> decryptMessage(const std::string& sourceDeviceId, const std::string& recipientDeviceId, const std::string& recipientUserId, std::vector<std::shared_ptr<DR<Curve>>>& DRSessions, const std::vector<uint8_t>& DRmessage, const std::vector<uint8_t>& cipherMessage, std::vector<uint8_t>& plaintext) {
bool payloadDirectEncryption = (cipherMessage.size() == 0); // if we do not have any cipher message, then we must be in payload direct encryption mode: the payload is in the DR message
std::vector<uint8_t> AD; // the Associated Data authenticated by the AEAD scheme used in DR encrypt/decrypt
......@@ -537,9 +537,9 @@ namespace lime {
try {
// if payload is in the message, got the output directly in the plaintext buffer
if (payloadDirectEncryption) {
decryptStatus = DRSession->ratchetDecrypt(cipherHeader, AD, plaintext, payloadDirectEncryption);
decryptStatus = DRSession->ratchetDecrypt(DRmessage, AD, plaintext, payloadDirectEncryption);
} else {
decryptStatus = DRSession->ratchetDecrypt(cipherHeader, AD, randomSeed, payloadDirectEncryption);
decryptStatus = DRSession->ratchetDecrypt(DRmessage, AD, randomSeed, payloadDirectEncryption);
}
} catch (BctbxException &e) { // any bctbx Exception is just considered as decryption failed (it shall occurs in case of maximum skipped keys reached or inconsistency ib the direct Encryption flag)
LIME_LOGW<<"Double Ratchet session failed to decrypt message and raised an exception saying : "<<e.what();
......@@ -582,11 +582,11 @@ namespace lime {
/* template instanciations for C25519 and C448 encryption/decryption functions */
#ifdef EC25519_ENABLED
template void encryptMessage<C255>(std::vector<recipientInfos<C255>>& recipients, const std::vector<uint8_t>& plaintext, const std::string& recipientUserId, const std::string& sourceDeviceId, std::vector<uint8_t>& cipherMessage, const lime::EncryptionPolicy encryptionPolicy);
template std::shared_ptr<DR<C255>> decryptMessage<C255>(const std::string& sourceId, const std::string& recipientDeviceId, const std::string& recipientUserId, std::vector<std::shared_ptr<DR<C255>>>& DRSessions, const std::vector<uint8_t>& cipherHeader, const std::vector<uint8_t>& cipherMessage, std::vector<uint8_t>& plaintext);
template void encryptMessage<C255>(std::vector<RecipientInfos<C255>>& recipients, const std::vector<uint8_t>& plaintext, const std::string& recipientUserId, const std::string& sourceDeviceId, std::vector<uint8_t>& cipherMessage, const lime::EncryptionPolicy encryptionPolicy);
template std::shared_ptr<DR<C255>> decryptMessage<C255>(const std::string& sourceId, const std::string& recipientDeviceId, const std::string& recipientUserId, std::vector<std::shared_ptr<DR<C255>>>& DRSessions, const std::vector<uint8_t>& DRmessage, const std::vector<uint8_t>& cipherMessage, std::vector<uint8_t>& plaintext);
#endif
#ifdef EC448_ENABLED
template void encryptMessage<C448>(std::vector<recipientInfos<C448>>& recipients, const std::vector<uint8_t>& plaintext, const std::string& recipientUserId, const std::string& sourceDeviceId, std::vector<uint8_t>& cipherMessage, const lime::EncryptionPolicy encryptionPolicy);
template std::shared_ptr<DR<C448>> decryptMessage<C448>(const std::string& sourceId, const std::string& recipientDeviceId, const std::string& recipientUserId, std::vector<std::shared_ptr<DR<C448>>>& DRSessions, const std::vector<uint8_t>& cipherHeader, const std::vector<uint8_t>& cipherMessage, std::vector<uint8_t>& plaintext);
template void encryptMessage<C448>(std::vector<RecipientInfos<C448>>& recipients, const std::vector<uint8_t>& plaintext, const std::string& recipientUserId, const std::string& sourceDeviceId, std::vector<uint8_t>& cipherMessage, const lime::EncryptionPolicy encryptionPolicy);
template std::shared_ptr<DR<C448>> decryptMessage<C448>(const std::string& sourceId, const std::string& recipientDeviceId, const std::string& recipientUserId, std::vector<std::shared_ptr<DR<C448>>>& DRSessions, const std::vector<uint8_t>& DRmessage, const std::vector<uint8_t>& cipherMessage, std::vector<uint8_t>& plaintext);
#endif
}
......@@ -50,7 +50,7 @@ namespace lime {
* Chain storing the DH and MKs associated with Nr(uint16_t map index)
*/
template <typename Curve>
struct receiverKeyChain {
struct ReceiverKeyChain {
/// peer public key identifying this chain
X<Curve, lime::Xtype::publicKey> DHr;
/// message keys indexed by Nr
......@@ -59,7 +59,7 @@ namespace lime {
* Start a new empty chain
* @param[in] key the peer DH public key used on this chain
*/
receiverKeyChain(X<Curve, lime::Xtype::publicKey> key) :DHr{std::move(key)}, messageKeys{} {};
ReceiverKeyChain(X<Curve, lime::Xtype::publicKey> key) :DHr{std::move(key)}, messageKeys{} {};
};
/**
......@@ -81,7 +81,7 @@ namespace lime {
std::uint16_t m_Ns,m_Nr; // Message index in sending and receiving chain
std::uint16_t m_PN; // Number of messages in previous sending chain
SharedADBuffer m_sharedAD; // Associated Data derived from self and peer device Identity key, set once at session creation, given by X3DH
std::vector<lime::receiverKeyChain<Curve>> m_mkskipped; // list of skipped message indexed by DH receiver public key and Nr, store MK generated during on-going decrypt, lookup is done directly in DB.
std::vector<lime::ReceiverKeyChain<Curve>> m_mkskipped; // list of skipped message indexed by DH receiver public key and Nr, store MK generated during on-going decrypt, lookup is done directly in DB.
/* helpers variables */
std::shared_ptr<RNG> m_RNG; // Random Number Generator context
......@@ -125,14 +125,13 @@ namespace lime {
* Used for internal management of recipientData, includes the Double Ratchet session shared with the recipient
*/
template <typename Curve>
struct recipientInfos {
struct RecipientInfos {
std::shared_ptr<DR<Curve>> DRSession; /**< DR Session to reach recipient */
std::string deviceId; /**< recipient deviceId (shall be GRUU) */
const 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. */
recipientInfos() : DRSession{nullptr}, deviceId{}, identityVerified{false}, cipherHeader{} {};
recipientInfos(std::string deviceId) : DRSession{nullptr}, deviceId{deviceId}, identityVerified{false}, cipherHeader{} {};
recipientInfos(std::string deviceId, std::shared_ptr<DR<Curve>> session) : DRSession{session}, deviceId{deviceId}, identityVerified{false}, cipherHeader{} {};
std::vector<uint8_t> DRmessage; /**< after encrypt calls back, it will hold the DR message targeted to the specified recipient. It may contain an X3DH init message. */
RecipientInfos(const std::string &deviceId) : DRSession{nullptr}, deviceId{deviceId}, identityVerified{false}, DRmessage{} {};
RecipientInfos(const std::string &deviceId, std::shared_ptr<DR<Curve>> session) : DRSession{session}, deviceId{deviceId}, identityVerified{false}, DRmessage{} {};
};
// helpers function wich are the one to be used to encrypt/decrypt messages
......@@ -142,16 +141,16 @@ namespace lime {
* The key and IV are then encrypted with DR Session specific to each device
*
* @param[in,out] recipients vector of recipients device id(gruu) and linked DR Session, DR Session are modified by the encryption
* The recipients struct also hold after encryption the encrypted message header targeted to that recipient only
* The recipients struct also hold after encryption the double ratchet message targeted to that particular recipient
* @param[in] plaintext data to be encrypted
* @param[in] recipientUserId the recipient ID, not specific to a device(could be a sip-uri) or a user(could be a group sip-uri)
* @param[in] sourceDeviceId the Id of sender device(gruu)
* @param[out] cipherMessage message encrypted with a random generated key(and IV)
* @param[out] cipherMessage message encrypted with a random generated key(and IV). May be an empty buffer depending on encryptionPolicy, recipients and plaintext characteristics
* @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.
*/
template <typename Curve>
void encryptMessage(std::vector<recipientInfos<Curve>>& recipients, const std::vector<uint8_t>& plaintext, const std::string& recipientUserId, const std::string& sourceDeviceId, std::vector<uint8_t>& cipherMessage, const lime::EncryptionPolicy encryptionPolicy);
void encryptMessage(std::vector<RecipientInfos<Curve>>& recipients, const std::vector<uint8_t>& plaintext, const std::string& recipientUserId, const std::string& sourceDeviceId, std::vector<uint8_t>& cipherMessage, const lime::EncryptionPolicy encryptionPolicy);
/**
* @brief Decrypt a message
......@@ -161,14 +160,14 @@ namespace lime {
* @param[in] recipientDeviceId the recipient ID, specific to current device(gruu)
* @param[in] recipientUserId the recipient ID, not specific to a device(could be a sip-uri) or a user(could be a group sip-uri)
* @param[int,out] DRSessions list of DR Sessions linked to sender device, first one shall be the one registered as active
* @param[out] cipherHeader message holding the random decryption key encrypted by the DR session
* @param[out] cipherMessage message encrypted with a random generated key(and IV)
* @param[out] DRmessage Double Ratcher message holding as payload either the encrypted plaintext or the random key used to encrypt it encrypted by the DR session
* @param[out] cipherMessage if not zero lenght, plain text encrypted with a random generated key(and IV)
* @param[out] plaintext decrypted message
*
* @return a shared pointer towards the session used to decrypt, nullptr if we couldn't find one to do it
*/
template <typename Curve>
std::shared_ptr<DR<Curve>> decryptMessage(const std::string& sourceDeviceId, const std::string& recipientDeviceId, const std::string& recipientUserId, std::vector<std::shared_ptr<DR<Curve>>>& DRSessions, const std::vector<uint8_t>& cipherHeader, const std::vector<uint8_t>& cipherMessage, std::vector<uint8_t>& plaintext);
std::shared_ptr<DR<Curve>> decryptMessage(const std::string& sourceDeviceId, const std::string& recipientDeviceId, const std::string& recipientUserId, std::vector<std::shared_ptr<DR<Curve>>>& DRSessions, const std::vector<uint8_t>& DRmessage, const std::vector<uint8_t>& cipherMessage, std::vector<uint8_t>& plaintext);
/**
* @brief check the message for presence of X3DH init in the header, parse it if there is one
......@@ -186,13 +185,13 @@ namespace lime {
/* this templates are instanciated once in the lime_double_ratchet.cpp file, explicitly tell anyone including this header that there is no need to re-instanciate them */
#ifdef EC25519_ENABLED
extern template class DR<C255>;
extern template void encryptMessage<C255>(std::vector<recipientInfos<C255>>& recipients, const std::vector<uint8_t>& plaintext, const std::string& recipientUserId, const std::string& sourceDeviceId, std::vector<uint8_t>& cipherMessage, const lime::EncryptionPolicy encryptionPolicy);
extern template std::shared_ptr<DR<C255>> decryptMessage<C255>(const std::string& sourceDeviceId, const std::string& recipientDeviceId, const std::string& recipientUserId, std::vector<std::shared_ptr<DR<C255>>>& DRSessions, const std::vector<uint8_t>& cipherHeader, const std::vector<uint8_t>& cipherMessage, std::vector<uint8_t>& plaintext);
extern template void encryptMessage<C255>(std::vector<RecipientInfos<C255>>& recipients, const std::vector<uint8_t>& plaintext, const std::string& recipientUserId, const std::string& sourceDeviceId, std::vector<uint8_t>& cipherMessage, const lime::EncryptionPolicy encryptionPolicy);
extern template std::shared_ptr<DR<C255>> decryptMessage<C255>(const std::string& sourceDeviceId, const std::string& recipientDeviceId, const std::string& recipientUserId, std::vector<std::shared_ptr<DR<C255>>>& DRSessions, const std::vector<uint8_t>& DRmessage, const std::vector<uint8_t>& cipherMessage, std::vector<uint8_t>& plaintext);
#endif
#ifdef EC448_ENABLED
extern template class DR<C448>;
extern template void encryptMessage<C448>(std::vector<recipientInfos<C448>>& recipients, const std::vector<uint8_t>& plaintext, const std::string& recipientUserId, const std::string& sourceDeviceId, std::vector<uint8_t>& cipherMessage, const lime::EncryptionPolicy encryptionPolicy);
extern template std::shared_ptr<DR<C448>> decryptMessage<C448>(const std::string& sourceDeviceId, const std::string& recipientDeviceId, const std::string& recipientUserId, std::vector<std::shared_ptr<DR<C448>>>& DRSessions, const std::vector<uint8_t>& cipherHeader, const std::vector<uint8_t>& cipherMessage, std::vector<uint8_t>& plaintext);
extern template void encryptMessage<C448>(std::vector<RecipientInfos<C448>>& recipients, const std::vector<uint8_t>& plaintext, const std::string& recipientUserId, const std::string& sourceDeviceId, std::vector<uint8_t>& cipherMessage, const lime::EncryptionPolicy encryptionPolicy);
extern template std::shared_ptr<DR<C448>> decryptMessage<C448>(const std::string& sourceDeviceId, const std::string& recipientDeviceId, const std::string& recipientUserId, std::vector<std::shared_ptr<DR<C448>>>& DRSessions, const std::vector<uint8_t>& DRmessage, const std::vector<uint8_t>& cipherMessage, std::vector<uint8_t>& plaintext);
#endif
}
......
......@@ -72,7 +72,7 @@ namespace lime {
bool create_user();
// user load from DB is implemented directly as a Db member function, output of it is passed to Lime<> ctor
void get_SelfIdentityKey(); // check our Identity key pair is loaded in Lime object, retrieve it from DB if it isn't
void cache_DR_sessions(std::vector<recipientInfos<Curve>> &internal_recipients, std::vector<std::string> &missing_devices); // loop on internal recipient an try to load in DR session cache the one which have no session attached
void cache_DR_sessions(std::vector<RecipientInfos<Curve>> &internal_recipients, std::vector<std::string> &missing_devices); // loop on internal recipient an try to load in DR session cache the one which have no session attached
void get_DRSessions(const std::string &senderDeviceId, const long int ignoreThisDRSessionId, std::vector<std::shared_ptr<DR<Curve>>> &DRSessions); // load from local storage in DRSessions all DR session matching the peerDeviceId, ignore the one picked by id in 2nd arg
long int store_peerDevice(const std::string &peerDeviceId, const DSA<Curve, lime::DSAtype::publicKey> &Ik); // store given peer Device Id and public identity key, return the Id used in table to store it
......@@ -133,8 +133,8 @@ 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, 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;
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> &DRmessage, const std::vector<uint8_t> &cipherMessage, std::vector<uint8_t> &plainMessage) override;
};
/**
......@@ -149,7 +149,7 @@ namespace lime {
/// Recipient username. Needed for encryption: get a shared ref to keep params alive
std::shared_ptr<const std::string> recipientUserId;
/// Recipient data vector. Needed for encryption: get a shared ref to keep params alive
std::shared_ptr<std::vector<recipientData>> recipients;
std::shared_ptr<std::vector<RecipientData>> recipients;
/// plaintext. Needed for encryption: get a shared ref to keep params alive
std::shared_ptr<const std::vector<uint8_t>> plainMessage;
/// ciphertext buffer. Needed for encryption: get a shared ref to keep params alive
......@@ -180,7 +180,7 @@ namespace lime {
/** 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::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,
lime::EncryptionPolicy policy)
: limeObj{thiz}, callback{callbackRef},
......
......@@ -53,29 +53,29 @@ 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,out] recipients a list of RecipientData holding: the recipient device Id(GRUU) and an empty buffer to store the DRmessage 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[out] cipherMessage points to the buffer to store the encrypted message which must be routed to all recipients(if one is produced, depends on encryption policy)
* @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, const lime::EncryptionPolicy encryptionPolicy, 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
*
* @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
* it is not necessarily the sip:uri base of the GRUU as this could be a message from alice first device intended to bob being decrypted on alice second device
* @param[in] cipherHeader the part of cipher which is targeted to current device
* @param[in] DRmessage the Double Ratchet message targeted to current device
* @param[in] cipherMessage part of cipher routed to all recipient devices
* @param[out] plainMessage the output buffer
*
* @return true if the decryption is successfull, false otherwise
*/
virtual 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) = 0;
virtual bool decrypt(const std::string &recipientUserId, const std::string &senderDeviceId, const std::vector<uint8_t> &DRmessage, const std::vector<uint8_t> &cipherMessage, std::vector<uint8_t> &plainMessage) = 0;
......
......@@ -728,7 +728,7 @@ void Lime<Curve>::X3DH_generate_OPks(std::vector<X<Curve, lime::Xtype::publicKey
}
template <typename Curve>
void Lime<Curve>::cache_DR_sessions(std::vector<recipientInfos<Curve>> &internal_recipients, std::vector<std::string> &missing_devices) {
void Lime<Curve>::cache_DR_sessions(std::vector<RecipientInfos<Curve>> &internal_recipients, std::vector<std::string> &missing_devices) {
// build a user list of missing ones : produce a list ready to be sent to SQL query: 'user','user','user',... also build a map to store shared_ptr to sessions
// build also a list of all peer devices used to fetch from DB the ones with identity not verified
std::string sqlString_requestedDevices{""};
......@@ -939,7 +939,7 @@ void Lime<Curve>::X3DH_updateOPkStatus(const std::vector<uint32_t> &OPkIds) {
template void Lime<C255>::get_SelfIdentityKey();
template void Lime<C255>::X3DH_generate_SPk(X<C255, lime::Xtype::publicKey> &publicSPk, DSA<C255, DSAtype::signature> &SPk_sig, uint32_t &SPk_id);
template void Lime<C255>::X3DH_generate_OPks(std::vector<X<C255, lime::Xtype::publicKey>> &publicOPks, std::vector<uint32_t> &OPk_ids, const uint16_t OPk_number);
template void Lime<C255>::cache_DR_sessions(std::vector<recipientInfos<C255>> &internal_recipients, std::vector<std::string> &missing_devices);
template void Lime<C255>::cache_DR_sessions(std::vector<RecipientInfos<C255>> &internal_recipients, std::vector<std::string> &missing_devices);
template long int Lime<C255>::store_peerDevice(const std::string &peerDeviceId, const DSA<C255, lime::DSAtype::publicKey> &Ik);
template void Lime<C255>::get_DRSessions(const std::string &senderDeviceId, const long int ignoreThisDBSessionId, std::vector<std::shared_ptr<DR<C255>>> &DRSessions);
template void Lime<C255>::X3DH_get_SPk(uint32_t SPk_id, Xpair<C255> &SPk);
......@@ -953,7 +953,7 @@ void Lime<Curve>::X3DH_updateOPkStatus(const std::vector<uint32_t> &OPkIds) {
template void Lime<C448>::get_SelfIdentityKey();
template void Lime<C448>::X3DH_generate_SPk(X<C448, lime::Xtype::publicKey> &publicSPk, DSA<C448, DSAtype::signature> &SPk_sig, uint32_t &SPk_id);
template void Lime<C448>::X3DH_generate_OPks(std::vector<X<C448, lime::Xtype::publicKey>> &publicOPks, std::vector<uint32_t> &OPk_ids, const uint16_t OPk_number);
template void Lime<C448>::cache_DR_sessions(std::vector<recipientInfos<C448>> &internal_recipients, std::vector<std::string> &missing_devices);
template void Lime<C448>::cache_DR_sessions(std::vector<RecipientInfos<C448>> &internal_recipients, std::vector<std::string> &missing_devices);
template long int Lime<C448>::store_peerDevice(const std::string &peerDeviceId, const DSA<C448, lime::DSAtype::publicKey> &Ik);
template void Lime<C448>::get_DRSessions(const std::string &senderDeviceId, const long int ignoreThisDBSessionId, std::vector<std::shared_ptr<DR<C448>>> &DRSessions);
template void Lime<C448>::X3DH_get_SPk(uint32_t SPk_id, Xpair<C448> &SPk);
......
......@@ -48,12 +48,12 @@ namespace lime {
}
void LimeManager::create_user(const std::string &localDeviceId, const std::string &x3dhServerUrl, const lime::CurveId curve, const uint16_t OPkInitialBatchSize, const limeCallback &callback) {
auto thiz = this;
limeCallback managerCreateCallback([thiz, localDeviceId, callback](lime::callbackReturn returnCode, std::string errorMessage) {
limeCallback managerCreateCallback([thiz, localDeviceId, callback](lime::CallbackReturn returnCode, std::string errorMessage) {
// first forward the callback
callback(returnCode, errorMessage);
// then check if it went well, if not delete the user from localDB
if (returnCode != lime::callbackReturn::success) {
if (returnCode != lime::CallbackReturn::success) {
auto localStorage = std::unique_ptr<lime::Db>(new lime::Db(thiz->m_db_access));
localStorage->delete_LimeUser(localDeviceId);
thiz->m_users_cache.erase(localDeviceId);
......@@ -65,7 +65,7 @@ namespace lime {
void LimeManager::delete_user(const std::string &localDeviceId, const limeCallback &callback) {
auto thiz = this;
limeCallback managerDeleteCallback([thiz, localDeviceId, callback](lime::callbackReturn returnCode, std::string errorMessage) {
limeCallback managerDeleteCallback([thiz, localDeviceId, callback](lime::CallbackReturn returnCode, std::string errorMessage) {
// first forward the callback
callback(returnCode, errorMessage);
......@@ -81,7 +81,7 @@ 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, const lime::EncryptionPolicy encryptionPolicy) {
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);
......@@ -90,13 +90,13 @@ namespace lime {
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) {
bool LimeManager::decrypt(const std::string &localDeviceId, const std::string &recipientUserId, const std::string &senderDeviceId, const std::vector<uint8_t> &DRmessage, const std::vector<uint8_t> &cipherMessage, std::vector<uint8_t> &plainMessage) {
// Load user object
std::shared_ptr<LimeGeneric> user;
LimeManager::load_user(user, localDeviceId);
// call the decryption function
return user->decrypt(recipientUserId, senderDeviceId, cipherHeader, cipherMessage, plainMessage);
return user->decrypt(recipientUserId, senderDeviceId, DRmessage, cipherMessage, plainMessage);
}
/* This version use default settings */
......@@ -118,13 +118,13 @@ namespace lime {
//This counter will trace number of callbacks, to trace how many operation did end.
// we expect two callback per local user account: one for update SPk, one for get OPk number on server
auto callbackCount = make_shared<size_t>(deviceIds.size()*2);
auto globalReturnCode = make_shared<lime::callbackReturn>(lime::callbackReturn::success);
auto globalReturnCode = make_shared<lime::CallbackReturn>(lime::CallbackReturn::success);
// this callback will get all callbacks from update OPk and SPk on all users, when everyone is done, call the callback given to LimeManager::update
limeCallback managerUpdateCallback([callbackCount, globalReturnCode, callback](lime::callbackReturn returnCode, std::string errorMessage) {
limeCallback managerUpdateCallback([callbackCount, globalReturnCode, callback](lime::CallbackReturn returnCode, std::string errorMessage) {
(*callbackCount)--;
if (returnCode == lime::callbackReturn::fail) {
*globalReturnCode = lime::callbackReturn::fail; // if one fail, return fail at the end of it
if (returnCode == lime::CallbackReturn::fail) {
*globalReturnCode = lime::CallbackReturn::fail; // if one fail, return fail at the end of it
}
if (*callbackCount == 0) {
......
......@@ -196,21 +196,21 @@ namespace lime {
// check message holds at leat a header before trying to read it
if (body.size()<X3DH_headerSize) {
LIME_LOGE<<"Got an invalid response from X3DH server";
if (callback) callback(lime::callbackReturn::fail, "Got an invalid response from X3DH server");
if (callback) callback(lime::CallbackReturn::fail, "Got an invalid response from X3DH server");
return false;
}
// check X3DH protocol version
if (body[0] != static_cast<uint8_t>(X3DH_protocolVersion)) {
LIME_LOGE<<"X3DH server runs an other version of X3DH protocol(server "<<int(body[0])<<" - local "<<static_cast<uint8_t>(X3DH_protocolVersion)<<")";
if (callback) callback(lime::callbackReturn::fail, "X3DH server and client protocol version mismatch");
if (callback) callback(lime::CallbackReturn::fail, "X3DH server and client protocol version mismatch");
return false;
}
// check curve id
if (body[2] != static_cast<uint8_t>(Curve::curveId())) {
LIME_LOGE<<"X3DH server runs curve Id "<<int(body[2])<<" while local is set to "<<static_cast<uint8_t>(Curve::curveId())<<" for this server)";
if (callback) callback(lime::callbackReturn::fail, "X3DH server and client curve Id mismatch");
if (callback) callback(lime::CallbackReturn::fail, "X3DH server and client curve Id mismatch");
return false;
}
......@@ -475,7 +475,7 @@ namespace lime {
case x3dh_protocol::x3dh_message_type::unset_type:
case x3dh_protocol::x3dh_message_type::getPeerBundle:
case x3dh_protocol::x3dh_message_type::getSelfOPks: {
if (callback) callback(lime::callbackReturn::fail, "X3DH unexpected message from server");
if (callback) callback(lime::CallbackReturn::fail, "X3DH unexpected message from server");
cleanUserData(userData);
}
return;
......@@ -493,7 +493,7 @@ namespace lime {
x3dh_protocol::buildMessage_publishSPk(X3DHmessage, SPk, SPk_sig, SPk_id);
postToX3DHServer(userData, X3DHmessage);
} else { // after registering a user, we must post SPk and OPks
if (callback) callback(lime::callbackReturn::fail, "Internal Error: we registered a new user on X3DH server but do not plan to post SPk or OPks");
if (callback) callback(lime::CallbackReturn::fail, "Internal Error: we registered a new user on X3DH server but do not plan to post SPk or OPks");
cleanUserData(userData);
}
}
......@@ -526,7 +526,7 @@ namespace lime {
std::vector<X3DH_peerBundle<Curve>> peersBundle;
if (!x3dh_protocol::parseMessage_getPeerBundles(responseBody, peersBundle)) { // parsing went wrong
LIME_LOGE<<"Got an invalid peerBundle packet from X3DH server";
if (callback) callback(lime::callbackReturn::fail, "Got an invalid peerBundle packet from X3DH server");
if (callback) callback(lime::CallbackReturn::fail, "Got an invalid peerBundle packet from X3DH server");
cleanUserData(userData);
return;
}
......@@ -538,7 +538,7 @@ namespace lime {
// when message stop crossing themselves on the network
X3DH_init_sender_session(peersBundle);
} catch (BctbxException &e) { // something went wrong, go for callback as this function may be called by code not supporting exceptions
if (callback) callback(lime::callbackReturn::fail, std::string{"Error during the peer Bundle processing : "}.append(e.what()));
if (callback) callback(lime::CallbackReturn::fail, std::string{"Error during the peer Bundle processing : "}.append(e.what()));
cleanUserData(userData);
return;
}
......@@ -556,7 +556,7 @@ namespace lime {
std::vector<uint32_t> selfOPkIds{};
if (!x3dh_protocol::parseMessage_selfOPks<Curve>(responseBody, selfOPkIds)) { // parsing went wrong
LIME_LOGE<<"Got an invalid selfOPKs packet from X3DH server";
if (callback) callback(lime::callbackReturn::fail, "Got an invalid selfOPKs packet from X3DH server");
if (callback) callback(lime::CallbackReturn::fail, "Got an invalid selfOPKs packet from X3DH server");
cleanUserData(userData);
return;
}
......@@ -574,7 +574,7 @@ namespace lime {
x3dh_protocol::buildMessage_publishOPks(X3DHmessage, OPks, OPk_ids);
postToX3DHServer(userData, X3DHmessage);
} else { /* nothing to do, just call the callback */
if (callback) callback(lime::callbackReturn::success, "");
if (callback) callback(lime::CallbackReturn::success, "");
cleanUserData(userData);
}
}
......@@ -582,19 +582,19 @@ namespace lime {
case x3dh_protocol::x3dh_message_type::error: {
// error messages are logged inside the parseMessage_getType function, just return failure to callback
if (callback) callback(lime::callbackReturn::fail, "X3DH server error");
if (callback) callback(lime::CallbackReturn::fail, "X3DH server error");
cleanUserData(userData);
}
return;
}
// we get here only if processing is over and response was the expected one
if (callback) callback(lime::callbackReturn::success, "");
if (callback) callback(lime::CallbackReturn::success, "");
cleanUserData(userData);
return;
} else { // response code is not 200Ok
if (callback) callback(lime::callbackReturn::fail, std::string("Got a non Ok response from server : ").append(std::to_string(responseCode)));
if (callback) callback(lime::CallbackReturn::fail, std::string("Got a non Ok response from server : ").append(std::to_string(responseCode)));
cleanUserData(userData);
return;
}
......
This diff is collapsed.
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