Commit 046fd0db authored by johan's avatar johan
Browse files

Delay OPk delete until DR session is actually saved in local storage

parent 7b43ba8f
......@@ -148,8 +148,8 @@ namespace lime {
template <typename Curve>
DR<Curve>::DR(std::shared_ptr<lime::Db> localStorage, const DRChainKey &SK, const SharedADBuffer &AD, const X<Curve, lime::Xtype::publicKey> &peerPublicKey, long int peerDid, const std::string &peerDeviceId, const DSA<Curve, lime::DSAtype::publicKey> &peerIk, long int selfDid, const std::vector<uint8_t> &X3DH_initMessage, std::shared_ptr<RNG> RNG_context)
: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{RNG_context},m_dbSessionId{0},m_usedNr{0},m_usedDHid{0},m_localStorage{localStorage},m_dirty{DRSessionDbStatus::dirty},m_peerDid{peerDid},m_peerDeviceId{},m_peerIk{},m_db_Uid{selfDid},
m_active_status{true}, m_X3DH_initMessage{X3DH_initMessage}
m_RNG{RNG_context},m_dbSessionId{0},m_usedNr{0},m_usedDHid{0}, m_usedOPkId{0}, m_localStorage{localStorage},m_dirty{DRSessionDbStatus::dirty},m_peerDid{peerDid},m_peerDeviceId{},
m_peerIk{},m_db_Uid{selfDid}, m_active_status{true}, m_X3DH_initMessage{X3DH_initMessage}
{
// generate a new self key pair
auto DH = make_keyExchange<Curve>();
......@@ -181,18 +181,19 @@ namespace lime {
* @param[in] localStorage Local storage accessor to save DR session and perform mkskipped lookup
* @param[in] SK a 32 bytes shared secret established prior the session init (likely done using X3DH)
* @param[in] AD The associated data generated by X3DH protocol and permanently part of the DR session(see X3DH spec section 3.3 and lime doc section 5.4.3)
* @param[in] selfKeyPair the key pair used by sender to establish this DR session
* @param[in] selfKeyPair the key pair used by sender to establish this DR session (DR spec section 5.1: it shall be our SPk)
* @param[in] peerDid Id used in local storage for this peer Device this session shall be attached to
* @param[in] peerDeviceId The peer Device Id this session is connected to. Ignored if peerDid is not 0
* @param[in] OPk_id Id of the self OPk used to create this session: we must remove it from local storage when saving the session in it. (ignored if 0)
* @param[in] peerIk The Identity Key of the peer device this session is connected to. Ignored if peerDid is not 0
* @param[in] selfDid Id used in local storage for local user this session shall be attached to
* @param[in] RNG_context A Random Number Generator context used for any rndom generation needed by this session
*/
template <typename Curve>
DR<Curve>::DR(std::shared_ptr<lime::Db> localStorage, const DRChainKey &SK, const SharedADBuffer &AD, const Xpair<Curve> &selfKeyPair, long int peerDid, const std::string &peerDeviceId, const DSA<Curve, lime::DSAtype::publicKey> &peerIk, long int selfDid, std::shared_ptr<RNG> RNG_context)
DR<Curve>::DR(std::shared_ptr<lime::Db> localStorage, const DRChainKey &SK, const SharedADBuffer &AD, const Xpair<Curve> &selfKeyPair, long int peerDid, const std::string &peerDeviceId, const uint32_t OPk_id, const DSA<Curve, lime::DSAtype::publicKey> &peerIk, long int selfDid, std::shared_ptr<RNG> RNG_context)
: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{RNG_context},m_dbSessionId{0},m_usedNr{0},m_usedDHid{0},m_localStorage{localStorage},m_dirty{DRSessionDbStatus::dirty},m_peerDid{peerDid},m_peerDeviceId{},m_peerIk{},m_db_Uid{selfDid},
m_active_status{true}, m_X3DH_initMessage{}
m_RNG{RNG_context},m_dbSessionId{0},m_usedNr{0},m_usedDHid{0}, m_usedOPkId{OPk_id}, m_localStorage{localStorage},m_dirty{DRSessionDbStatus::dirty},m_peerDid{peerDid},m_peerDeviceId{},
m_peerIk{},m_db_Uid{selfDid}, m_active_status{true}, m_X3DH_initMessage{}
{
// If we have no peerDid, copy peer DeviceId and Ik in the session so we can use them to create the peer device in local storage when first saving the session
if (peerDid == 0) {
......@@ -214,8 +215,8 @@ namespace lime {
template <typename Curve>
DR<Curve>::DR(std::shared_ptr<lime::Db> localStorage, long sessionId, std::shared_ptr<RNG> RNG_context)
: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{RNG_context},m_dbSessionId{sessionId},m_usedNr{0},m_usedDHid{0},m_localStorage{localStorage},m_dirty{DRSessionDbStatus::clean},m_peerDid{0},m_peerDeviceId{},m_peerIk{},m_db_Uid{0},
m_active_status{false}, m_X3DH_initMessage{}
m_RNG{RNG_context},m_dbSessionId{sessionId},m_usedNr{0},m_usedDHid{0}, m_usedOPkId{0}, m_localStorage{localStorage},m_dirty{DRSessionDbStatus::clean},m_peerDid{0},m_peerDeviceId{},
m_peerIk{},m_db_Uid{0}, m_active_status{false}, m_X3DH_initMessage{}
{
session_load();
}
......
......@@ -98,6 +98,7 @@ namespace lime {
long int m_dbSessionId; // used to store row id from Database Storage
uint16_t m_usedNr; // store the index of message key used for decryption if it came from mkskipped db
long m_usedDHid; // store the index of DHr message key used for decryption if it came from mkskipped db(not zero only if used)
uint32_t m_usedOPkId; // when the session is created on receiver side, store the OPk id used so we can remove it from local storage when saving session for the first time.
std::shared_ptr<lime::Db> m_localStorage; // enable access to the database holding sessions and skipped message keys
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
......@@ -118,7 +119,7 @@ namespace lime {
public:
DR() = delete; // make sure the Double Ratchet is not initialised without parameters
DR(std::shared_ptr<lime::Db> localStorage, const DRChainKey &SK, const SharedADBuffer &AD, const X<Curve, lime::Xtype::publicKey> &peerPublicKey, const long int peerDid, const std::string &peerDeviceId, const DSA<Curve, lime::DSAtype::publicKey> &peerIk, long int selfDeviceId, const std::vector<uint8_t> &X3DH_initMessage, std::shared_ptr<RNG> RNG_context); // call to initialise a session for sender: we have Shared Key and peer Public key
DR(std::shared_ptr<lime::Db> localStorage, const DRChainKey &SK, const SharedADBuffer &AD, const Xpair<Curve> &selfKeyPair, long int peerDid, const std::string &peerDeviceId, const DSA<Curve, lime::DSAtype::publicKey> &peerIk, long int selfDeviceId, std::shared_ptr<RNG> RNG_context); // call at initialisation of a session for receiver: we have Share Key and self key pair
DR(std::shared_ptr<lime::Db> localStorage, const DRChainKey &SK, const SharedADBuffer &AD, const Xpair<Curve> &selfKeyPair, long int peerDid, const std::string &peerDeviceId, const uint32_t OPk_id, const DSA<Curve, lime::DSAtype::publicKey> &peerIk, long int selfDeviceId, std::shared_ptr<RNG> RNG_context); // call at initialisation of a session for receiver: we have Share Key and self key pair
DR(std::shared_ptr<lime::Db> localStorage, long sessionId, std::shared_ptr<RNG> RNG_context); // 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
......
......@@ -616,6 +616,12 @@ bool DR<Curve>::session_save() {
/*if (!(sql.get_last_insert_id("DR_sessions", m_dbSessionId))) {
throw;
} */
// At session creation, we may have to delete an OPk from storage
if (m_usedOPkId != 0) {
m_localStorage->sql<<"DELETE FROM X3DH_OPK WHERE Uid = :Uid AND OPKid = :OPk_id;", use(m_db_Uid), use(m_usedOPkId);
m_usedOPkId = 0;
}
} else { // we have an id, it shall already be in the db
// Try to update an existing row
try{ //TODO: make sure the update was a success, or we shall signal it
......@@ -1250,7 +1256,6 @@ void Lime<Curve>::X3DH_get_OPk(uint32_t OPk_id, Xpair<Curve> &OPk) {
if (m_localStorage->sql.got_data()) { // Found it, it is stored in one buffer Public || Private
OPk_blob.read(0, (char *)(OPk.publicKey().data()), OPk.publicKey().size()); // Read the public key
OPk_blob.read(OPk.publicKey().size(), (char *)(OPk.privateKey().data()), OPk.privateKey().size()); // Read the private key
m_localStorage->sql<<"DELETE FROM X3DH_OPK WHERE Uid = :Uid AND OPKid = :OPk_id;", use(m_db_Uid), use(OPk_id); // And remove it from local Storage
} else {
throw BCTBX_EXCEPTION << "X3DH "<<m_selfDeviceId<<"look up for OPk id "<<OPk_id<<" failed";
}
......
......@@ -211,7 +211,7 @@ namespace lime {
// check the new peer device Id in Storage, if it is not found, the DR session will add it when it saves itself after successful decryption
auto peerDid = m_localStorage->check_peerDevice(senderDeviceId, peerIk);
auto DRSession = make_shared<DR<Curve>>(m_localStorage, SK, AD, SPk, peerDid, senderDeviceId, peerIk, m_db_Uid, m_RNG);
auto DRSession = make_shared<DR<Curve>>(m_localStorage, SK, AD, SPk, peerDid, senderDeviceId, OPk_flag?OPk_id:0, peerIk, m_db_Uid, m_RNG);
return DRSession;
}
......
......@@ -215,7 +215,7 @@ void dr_sessionsInit(std::shared_ptr<DR<Curve>> &alice, std::shared_ptr<DR<Curve
std::vector<uint8_t> X3DH_initMessage{};
DSA<Curve, lime::DSAtype::publicKey> dummyPeerIk{}; // DR session creation gets the peerDeviceId and peerIk but uses it only if peerDid is 0, give dummy, we're focusing on DR here
alice = std::make_shared<DR<Curve>>(localStorageAlice, SK, AD, bobKeyPair.publicKey(), aliceDid, "dummyPeerDevice", dummyPeerIk, aliceUid, X3DH_initMessage, RNG_context);
bob = std::make_shared<DR<Curve>>(localStorageBob, SK, AD, bobKeyPair, bobDid, "dummyPeerDevice", dummyPeerIk, bobUid, RNG_context);
bob = std::make_shared<DR<Curve>>(localStorageBob, SK, AD, bobKeyPair, bobDid, "dummyPeerDevice", 0, dummyPeerIk, bobUid, RNG_context);
}
......
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