Commit 436cad78 authored by Johan Pascal's avatar Johan Pascal

Peer device information(Ik and status) is shared between local users in DB

parent 52db2da2
......@@ -157,12 +157,13 @@ namespace lime {
* @param[in] SK a 32 bytes shared secret established prior the session init (likely done using X3DH)
* @param[in] peerPublicKey the public key of message recipient (also obtained through X3DH, shall be peer SPk)
* @param[in] peerDid Id used in local storage for this peer Device this session shall be attached to
* @param[in] selfDid Id used in local storage for local user this session shall be attached to
* @param[in] X3DH_initMessage at session creation as sender we shall also store the X3DHInit message to be able to include it in all message until we got a response from peer
*/
template <typename Curve>
DR<Curve>::DR(lime::Db *localStorage, const DRChainKey &SK, const SharedADBuffer &AD, const X<Curve> &peerPublicKey, long int peerDid, const std::vector<uint8_t> &X3DH_initMessage)
DR<Curve>::DR(lime::Db *localStorage, const DRChainKey &SK, const SharedADBuffer &AD, const X<Curve> &peerPublicKey, long int peerDid, long int selfDid, const std::vector<uint8_t> &X3DH_initMessage)
:m_DHr{peerPublicKey},m_DHr_valid{true}, m_DHs{},m_RK(SK),m_CKs{},m_CKr{},m_Ns(0),m_Nr(0),m_PN(0),m_sharedAD(AD),m_mkskipped{},
m_RNG{bctbx_rng_context_new()},m_dbSessionId{0},m_usedNr{0},m_usedDHid{0},m_localStorage{localStorage},m_dirty{DRSessionDbStatus::dirty},m_peerDid{peerDid},
m_RNG{bctbx_rng_context_new()},m_dbSessionId{0},m_usedNr{0},m_usedDHid{0},m_localStorage{localStorage},m_dirty{DRSessionDbStatus::dirty},m_peerDid{peerDid}, m_db_Uid{selfDid},
m_active_status{true}, m_X3DH_initMessage{X3DH_initMessage}
{
// generate a new self key pair
......@@ -192,11 +193,12 @@ namespace lime {
* @param[in] SK a 32 bytes shared secret established prior the session init (likely done using X3DH)
* @param[in] selfKeyPair the key pair used by sender to establish this DR session
* @param[in] peerDid Id used in local storage for this peer Device this session shall be attached to
* @param[in] selfDid Id used in local storage for local user this session shall be attached to
*/
template <typename Curve>
DR<Curve>::DR(lime::Db *localStorage, const DRChainKey &SK, const SharedADBuffer &AD, const KeyPair<X<Curve>> &selfKeyPair, long int peerDid)
DR<Curve>::DR(lime::Db *localStorage, const DRChainKey &SK, const SharedADBuffer &AD, const KeyPair<X<Curve>> &selfKeyPair, long int peerDid, long int selfDid)
:m_DHr{},m_DHr_valid{false},m_DHs{selfKeyPair},m_RK(SK),m_CKs{},m_CKr{},m_Ns(0),m_Nr(0),m_PN(0),m_sharedAD(AD),m_mkskipped{},
m_RNG{bctbx_rng_context_new()},m_dbSessionId{0},m_usedNr{0},m_usedDHid{0},m_localStorage{localStorage},m_dirty{DRSessionDbStatus::dirty},m_peerDid{peerDid},
m_RNG{bctbx_rng_context_new()},m_dbSessionId{0},m_usedNr{0},m_usedDHid{0},m_localStorage{localStorage},m_dirty{DRSessionDbStatus::dirty},m_peerDid{peerDid}, m_db_Uid{selfDid},
m_active_status{true}, m_X3DH_initMessage{}
{ }
......@@ -211,7 +213,7 @@ namespace lime {
template <typename Curve>
DR<Curve>::DR(lime::Db *localStorage, long sessionId)
:m_DHr{},m_DHr_valid{true},m_DHs{},m_RK{},m_CKs{},m_CKr{},m_Ns(0),m_Nr(0),m_PN(0),m_sharedAD{},m_mkskipped{},
m_RNG{bctbx_rng_context_new()},m_dbSessionId{sessionId},m_usedNr{0},m_usedDHid{0},m_localStorage{localStorage},m_dirty{DRSessionDbStatus::clean},m_peerDid{0},
m_RNG{bctbx_rng_context_new()},m_dbSessionId{sessionId},m_usedNr{0},m_usedDHid{0},m_localStorage{localStorage},m_dirty{DRSessionDbStatus::clean},m_peerDid{0}, m_db_Uid{0},
m_active_status{false}, m_X3DH_initMessage{}
{
session_load();
......
......@@ -81,6 +81,7 @@ namespace lime {
lime::Db *m_localStorage; // enable access to the database holding sessions and skipped message keys, no need to use smart pointers here, Db is not owned by DRsession, it must persist even if no session exists
DRSessionDbStatus m_dirty; // status of the object regarding its instance in local storage, could be: clean, dirty_encrypt, dirty_decrypt or dirty
long int m_peerDid; // used during session creation only to hold the peer device id in DB as we need it to insert the session in local Storage
long int m_db_Uid; // used to link session to a local device Id
bool m_active_status; // current status of this session, true if it is the active one, false if it is stale
std::vector<uint8_t> m_X3DH_initMessage; // store the X3DH init message to be able to prepend it to any message until we got a first response from peer so we're sure he was able to init the session on his side
......@@ -94,8 +95,8 @@ namespace lime {
public:
DR() = delete; // make sure the Double Ratchet is not initialised without parameters
DR(lime::Db *localStorage, const DRChainKey &SK, const SharedADBuffer &AD, const X<Curve> &peerPublicKey, long int peerDeviceId, const std::vector<uint8_t> &X3DH_initMessage); // call to initialise a session for sender: we have Shared Key and peer Public key
DR(lime::Db *localStorage, const DRChainKey &SK, const SharedADBuffer &AD, const KeyPair<X<Curve>> &selfKeyPair, long int peerDeviceId); // call at initialisation of a session for receiver: we have Share Key and self key pair
DR(lime::Db *localStorage, const DRChainKey &SK, const SharedADBuffer &AD, const X<Curve> &peerPublicKey, long int peerDeviceId, long int selfDeviceId, const std::vector<uint8_t> &X3DH_initMessage); // call to initialise a session for sender: we have Shared Key and peer Public key
DR(lime::Db *localStorage, const DRChainKey &SK, const SharedADBuffer &AD, const KeyPair<X<Curve>> &selfKeyPair, long int peerDeviceId, long int selfDeviceId); // call at initialisation of a session for receiver: we have Share Key and self key pair
DR(lime::Db *localStorage, long sessionId); // load session from DB
DR(DR<Curve> &a) = delete; // can't copy a session, force usage of shared pointers
DR<Curve> &operator=(DR<Curve> &a) = delete; // can't copy a session
......
This diff is collapsed.
......@@ -156,7 +156,7 @@ namespace lime {
if (peerBundle.haveOPk) {
m_DR_sessions_cache.erase(peerBundle.deviceId); // will just do nothing if this peerDeviceId is not in cache
}
m_DR_sessions_cache.emplace(peerBundle.deviceId, make_shared<DR<Curve>>(m_localStorage.get(), SK, AD, peerBundle.SPk, peerDid, X3DH_initMessage)); // will just do nothing if this peerDeviceId is already in cache
m_DR_sessions_cache.emplace(peerBundle.deviceId, make_shared<DR<Curve>>(m_localStorage.get(), SK, AD, peerBundle.SPk, peerDid, m_db_Uid, X3DH_initMessage)); // will just do nothing if this peerDeviceId is already in cache
BCTBX_SLOGI<<"X3DH created session with device "<<peerBundle.deviceId;
}
......@@ -249,7 +249,7 @@ namespace lime {
long int peerDid=0;
peerDid = store_peerDevice(senderDeviceId, peerIk);
auto DRSession = make_shared<DR<Curve>>(m_localStorage.get(), SK, AD, SPk, peerDid);
auto DRSession = make_shared<DR<Curve>>(m_localStorage.get(), SK, AD, SPk, peerDid, m_db_Uid);
bctbx_clean(SPk.privateKey().data(), SPk.privateKey().size());
return DRSession;
......
......@@ -183,18 +183,18 @@ void dr_sessionsInit(std::shared_ptr<DR<Curve>> &alice, std::shared_ptr<DR<Curve
long int aliceUid,bobUid,bobDid,aliceDid;
localStorageAlice->sql<<"INSERT INTO lime_LocalUsers(UserId, Ik, server) VALUES ('dummy', 1, 'dummy')";
localStorageAlice->sql<<"select last_insert_rowid()",soci::into(aliceUid);
localStorageAlice->sql<<"INSERT INTO lime_PeerDevices(DeviceId, Uid, Ik) VALUES ('dummy', :Uid, 1)", soci::use(aliceUid);
localStorageAlice->sql<<"INSERT INTO lime_PeerDevices(DeviceId, Ik) VALUES ('dummy', 1)";
localStorageAlice->sql<<"select last_insert_rowid()",soci::into(aliceDid);
localStorageBob->sql<<"INSERT INTO lime_LocalUsers(UserId, Ik, server) VALUES ('dummy', 1, 'dummy')";
localStorageBob->sql<<"select last_insert_rowid()",soci::into(bobUid);
localStorageBob->sql<<"INSERT INTO lime_PeerDevices(DeviceId, Uid, Ik) VALUES ('dummy', :Uid, 1)", soci::use(bobUid);
localStorageBob->sql<<"INSERT INTO lime_PeerDevices(DeviceId, Ik) VALUES ('dummy', 1)";
localStorageBob->sql<<"select last_insert_rowid()",soci::into(bobDid);
// create DR sessions
std::vector<uint8_t> X3DH_initMessage{};
alice = std::make_shared<DR<Curve>>(localStorageAlice.get(), SK, AD, bobKeyPair.publicKey(), aliceDid, X3DH_initMessage);
bob = std::make_shared<DR<Curve>>(localStorageBob.get(), SK, AD, bobKeyPair, bobDid);
alice = std::make_shared<DR<Curve>>(localStorageAlice.get(), SK, AD, bobKeyPair.publicKey(), aliceDid, aliceUid, X3DH_initMessage);
bob = std::make_shared<DR<Curve>>(localStorageBob.get(), SK, AD, bobKeyPair, bobDid, bobUid);
}
......@@ -349,7 +349,7 @@ long int get_DRsessionsId(const std::string &dbFilename, const std::string &self
std::vector<int> status(25);
try {
soci::session sql(sqlite3, dbFilename); // open the DB
soci::statement st = (sql.prepare << "SELECT s.sessionId, s.Status FROM DR_sessions as s INNER JOIN lime_PeerDevices as d on s.Did = d.Did INNER JOIN lime_LocalUsers as u on u.Uid = d.Uid WHERE u.UserId = :selfId AND d.DeviceId = :peerId ORDER BY s.Status DESC, s.Did;", into(sessionsId), into(status), use(selfDeviceId), use(peerDeviceId));
soci::statement st = (sql.prepare << "SELECT s.sessionId, s.Status FROM DR_sessions as s INNER JOIN lime_PeerDevices as d on s.Did = d.Did INNER JOIN lime_LocalUsers as u on u.Uid = s.Uid WHERE u.UserId = :selfId AND d.DeviceId = :peerId ORDER BY s.Status DESC, s.Did;", into(sessionsId), into(status), use(selfDeviceId), use(peerDeviceId));
st.execute();
if (st.fetch()) { // all retrieved session shall fit in the arrays no need to go on several fetch
// check we don't have more than one active session
......@@ -379,7 +379,7 @@ unsigned int get_StoredMessageKeyCount(const std::string &dbFilename, const std:
try {
soci::session sql(sqlite3, dbFilename); // open the DB
unsigned int mkCount=0;
sql<< "SELECT count(m.MK) FROM DR_sessions as s INNER JOIN lime_PeerDevices as d on s.Did = d.Did INNER JOIN lime_LocalUsers as u on u.Uid = d.Uid INNER JOIN DR_MSk_DHr as c on c.sessionId = s.sessionId INNER JOIN DR_MSk_Mk as m ON m.DHid=c.DHid WHERE u.UserId = :selfId AND d.DeviceId = :peerId ORDER BY s.Status DESC, s.Did;", into(mkCount), use(selfDeviceId), use(peerDeviceId);
sql<< "SELECT count(m.MK) FROM DR_sessions as s INNER JOIN lime_PeerDevices as d on s.Did = d.Did INNER JOIN lime_LocalUsers as u on u.Uid = s.Uid INNER JOIN DR_MSk_DHr as c on c.sessionId = s.sessionId INNER JOIN DR_MSk_Mk as m ON m.DHid=c.DHid WHERE u.UserId = :selfId AND d.DeviceId = :peerId ORDER BY s.Status DESC, s.Did;", into(mkCount), use(selfDeviceId), use(peerDeviceId);
if (sql.got_data()) {
return mkCount;
} else {
......
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