lime
Lime is a C++ library implementing Open Whisper System Signal protocol
lime_impl.hpp
Go to the documentation of this file.
1 /*
2  lime_impl.hpp
3  @author Johan Pascal
4  @copyright Copyright (C) 2017 Belledonne Communications SARL
5 
6  This program is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19 #ifndef lime_impl_hpp
20 #define lime_impl_hpp
21 
22 #include <memory>
23 #include <vector>
24 #include <unordered_map>
25 #include <queue>
26 #include <mutex>
27 
28 #include "lime/lime.hpp"
29 #include "lime_lime.hpp"
31 #include "lime_localStorage.hpp"
32 #include "lime_double_ratchet.hpp"
33 #include "lime_x3dh.hpp"
34 #include "lime_x3dh_protocol.hpp"
35 
36 namespace lime {
37  // an enum used by network state engine to manage sequence packet sending(at user creation)
38  enum class network_state : uint8_t {done=0x00, sendSPk=0x01, sendOPk=0x02};
39 
40  struct callbackUserData;
41 
45  template <typename Curve>
46  class Lime : public LimeGeneric, public std::enable_shared_from_this<Lime<Curve>> {
47  private:
48  /*** data members ***/
49  /* general purpose */
50  std::shared_ptr<RNG> m_RNG; // Random Number Generator context
51  std::string m_selfDeviceId; // self device Id, shall be the GRUU
52  std::mutex m_mutex; // a mutex to lock own thread sensitive ressources (m_DR_sessions_cache, encryption_queue)
53 
54  /* X3DH engine */
55  std::shared_ptr<X3DH> m_X3DH; // manage X3DH operations
56 
57  /* local storage related */
58  std::shared_ptr<lime::Db> m_localStorage; // shared pointer would be used/stored in Double Ratchet Sessions
59  long int m_db_Uid; // the Uid in database, retrieved at creation/load, used for faster access
60 
61  /* Double ratchet related */
62  std::unordered_map<std::string, std::shared_ptr<DR>> m_DR_sessions_cache; // store already loaded DR session
63 
64  /* encryption queue: encryption requesting asynchronous operation(connection to X3DH server) are queued to avoid repeating a request to server */
65  std::shared_ptr<callbackUserData> m_ongoing_encryption;
66  std::queue<std::shared_ptr<callbackUserData>> m_encryption_queue;
67 
68  /*** Private functions ***/
69  void cache_DR_sessions(std::vector<RecipientInfos> &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
70  void get_DRSessions(const std::string &senderDeviceId, const long int ignoreThisDRSessionId, std::vector<std::shared_ptr<DR>> &DRSessions); // load from local storage in DRSessions all DR session matching the peerDeviceId, ignore the one picked by id in 2nd arg
71 
72  public: /* Implement API defined in lime_lime.hpp in LimeGeneric abstract class */
73  Lime(std::shared_ptr<lime::Db> localStorage, const std::string &deviceId, const std::string &url, const limeX3DHServerPostData &X3DH_post_data, const long int Uid = 0);
74  ~Lime();
75  Lime(Lime<Curve> &a) = delete; // can't copy a session, force usage of shared pointers
76  Lime<Curve> &operator=(Lime<Curve> &a) = delete; // can't copy a session
77 
78  void publish_user(const std::shared_ptr<limeCallback> callback, const uint16_t OPkInitialBatchSize) override;
79  void delete_user(const std::shared_ptr<limeCallback> callback) override;
80  void delete_peerDevice(const std::string &peerDeviceId) override;
81  void update_SPk(const std::shared_ptr<limeCallback> callback) override;
82  void update_OPk(const std::shared_ptr<limeCallback> callback, uint16_t OPkServerLowLimit, uint16_t OPkBatchSize) override;
83  void get_Ik(std::vector<uint8_t> &Ik) override;
84  void encrypt(std::shared_ptr<lime::EncryptionContext> encryptionContext, const std::shared_ptr<limeCallback> callback, const std::shared_ptr<limeRandomSeedCallback> randomSeedCallback) override;
85  lime::PeerDeviceStatus decrypt(const std::vector<uint8_t> &recipientUserId, const std::string &senderDeviceId, const std::vector<uint8_t> &DRmessage, const std::vector<uint8_t> &cipherMessage, std::vector<uint8_t> &plainMessage) override;
86  void set_x3dhServerUrl(const std::string &x3dhServerUrl) override;
87  std::string get_x3dhServerUrl() override;
88  void stale_sessions(const std::string &peerDeviceId) override;
89  void processEncryptionQueue(void) override;
90  void DRcache_delete(const std::string &deviceId) override;
91  void DRcache_insert(const std::string &deviceId, std::shared_ptr<DR> DRsession) override;
92  std::shared_ptr<X3DH> get_X3DH(void) override {return m_X3DH;}
93  std::unique_lock<std::mutex> lock(void) override {return std::unique_lock<std::mutex>(m_mutex);}
94  };
95 
101  std::weak_ptr<LimeGeneric> limeObj;
103  const std::shared_ptr<limeCallback> callback;
105  const std::shared_ptr<limeRandomSeedCallback> randomSeedCallback;
107  std::shared_ptr<lime::EncryptionContext> encryptionContext;
111  uint16_t OPkBatchSize;
112 
114  callbackUserData(std::weak_ptr<LimeGeneric> thiz, const std::shared_ptr<limeCallback> callback, uint16_t OPkInitialBatchSize=lime::settings::OPk_initialBatchSize)
115  : limeObj{thiz}, callback{callback}, randomSeedCallback{nullptr},
116  encryptionContext{nullptr}, OPkServerLowLimit(0), OPkBatchSize(OPkInitialBatchSize) {};
117 
119  callbackUserData(std::weak_ptr<LimeGeneric> thiz, const std::shared_ptr<limeCallback> callback, uint16_t OPkServerLowLimit, uint16_t OPkBatchSize)
120  : limeObj{thiz}, callback{callback}, randomSeedCallback{nullptr},
121  encryptionContext{nullptr}, OPkServerLowLimit{OPkServerLowLimit}, OPkBatchSize{OPkBatchSize} {};
122 
124  callbackUserData(std::weak_ptr<LimeGeneric> thiz, const std::shared_ptr<limeCallback> callback, const std::shared_ptr<limeRandomSeedCallback> randomSeedCallback,
125  std::shared_ptr<lime::EncryptionContext> encryptionContext)
126  : limeObj{thiz}, callback{callback}, randomSeedCallback{randomSeedCallback},
127  encryptionContext{encryptionContext}, OPkServerLowLimit(0), OPkBatchSize(0) {};
128 
130  callbackUserData(callbackUserData &a) = delete;
133  };
134 
135 
136 /* this template is intanciated in lime.cpp, do not re-instanciate it anywhere else */
137 #ifdef EC25519_ENABLED
138  extern template class Lime<C255>;
139 #endif
140 
141 #ifdef EC448_ENABLED
142  extern template class Lime<C448>;
143 #endif
144 #ifdef HAVE_BCTBXPQ
145 #ifdef EC25519_ENABLED
146  extern template class Lime<C255K512>;
147  extern template class Lime<C255MLK512>;
148 #endif
149 #ifdef EC448_ENABLED
150  extern template class Lime<C448MLK1024>;
151 #endif
152 #endif
153 
154 }
155 #endif /* lime_impl_hpp */
constexpr uint16_t OPk_initialBatchSize
default batch size when creating a new user
Definition: lime_settings.hpp:90
void set_x3dhServerUrl(const std::string &x3dhServerUrl) override
Set the X3DH key server URL for this identified user.
Definition: lime.cpp:375
structure holding user data while waiting for callback from X3DH server response processing ...
Definition: lime_impl.hpp:99
callbackUserData(std::weak_ptr< LimeGeneric > thiz, const std::shared_ptr< limeCallback > callback, const std::shared_ptr< limeRandomSeedCallback > randomSeedCallback, std::shared_ptr< lime::EncryptionContext > encryptionContext)
created at encrypt(getPeerBundle)
Definition: lime_impl.hpp:124
~Lime()
Definition: lime.cpp:162
std::weak_ptr< LimeGeneric > limeObj
limeObj is owned by the LimeManager, it shall no be destructed, do not own this with a shared_ptr as ...
Definition: lime_impl.hpp:101
void processEncryptionQueue(void) override
Check if we have queued encryption to process, if yes, do it.
Definition: lime.cpp:396
uint16_t OPkBatchSize
Used when fetching from server self OPk : how many will we upload if needed.
Definition: lime_impl.hpp:111
lime::PeerDeviceStatus decrypt(const std::vector< uint8_t > &recipientUserId, const std::string &senderDeviceId, const std::vector< uint8_t > &DRmessage, const std::vector< uint8_t > &cipherMessage, std::vector< uint8_t > &plainMessage) override
Decrypt the given message.
Definition: lime.cpp:307
std::shared_ptr< X3DH > get_X3DH(void) override
accessor to the internal X3DH engine
Definition: lime_impl.hpp:92
void delete_user(const std::shared_ptr< limeCallback > callback) override
Delete user from local Storage and from X3DH server.
Definition: lime.cpp:178
std::function< void(const std::string &url, const std::string &from, std::vector< uint8_t > &&message, const limeX3DHServerResponseProcess &reponseProcess)> limeX3DHServerPostData
Post a message to the X3DH server.
Definition: lime.hpp:123
Implement the abstract class LimeGeneric.
Definition: lime_impl.hpp:46
uint16_t OPkServerLowLimit
Used when fetching from server self OPk to check if we shall upload more.
Definition: lime_impl.hpp:109
void stale_sessions(const std::string &peerDeviceId) override
Stale all sessions between localDeviceId and peerDevice. If peerDevice keep using this session to enc...
Definition: lime.cpp:380
PeerDeviceStatus
Definition: lime.hpp:59
void get_Ik(std::vector< uint8_t > &Ik) override
Retrieve self public Identity key.
Definition: lime.cpp:215
void publish_user(const std::shared_ptr< limeCallback > callback, const uint16_t OPkInitialBatchSize) override
Publish on X3DH server the user, it is performed just after creation in local storage this will...
Definition: lime.cpp:171
network_state
Definition: lime_impl.hpp:38
void update_OPk(const std::shared_ptr< limeCallback > callback, uint16_t OPkServerLowLimit, uint16_t OPkBatchSize) override
check if we shall upload more OPks on X3DH server
Definition: lime.cpp:206
Lime(std::shared_ptr< lime::Db > localStorage, const std::string &deviceId, const std::string &url, const limeX3DHServerPostData &X3DH_post_data, const long int Uid=0)
Load or Create user constructor.
Definition: lime.cpp:154
callbackUserData(std::weak_ptr< LimeGeneric > thiz, const std::shared_ptr< limeCallback > callback, uint16_t OPkServerLowLimit, uint16_t OPkBatchSize)
created at update: getSelfOPks. EncryptionPolicy is not used, set it to the default value anyway ...
Definition: lime_impl.hpp:119
Definition: lime.cpp:33
void delete_peerDevice(const std::string &peerDeviceId) override
Purge cached sessions for a given peer Device (used when a peer device is being deleted) ...
Definition: lime.cpp:188
callbackUserData(std::weak_ptr< LimeGeneric > thiz, const std::shared_ptr< limeCallback > callback, uint16_t OPkInitialBatchSize=lime::settings::OPk_initialBatchSize)
created at user create/delete and keys Post. EncryptionPolicy is not used, set it to the default valu...
Definition: lime_impl.hpp:114
callbackUserData operator=(callbackUserData &a)=delete
do not copy callback data, force passing the pointer around after creation
std::shared_ptr< lime::EncryptionContext > encryptionContext
Encryption context :AD, plain and cipher text, encryption policy and recipients.
Definition: lime_impl.hpp:107
const std::shared_ptr< limeRandomSeedCallback > randomSeedCallback
this is a ptr to a lambda, we may use it several time so we can manage precisely its timelife ...
Definition: lime_impl.hpp:105
std::unique_lock< std::mutex > lock(void) override
Definition: lime_impl.hpp:93
Lime< Curve > & operator=(Lime< Curve > &a)=delete
std::string get_x3dhServerUrl() override
Get the X3DH key server URL for this identified user.
Definition: lime.cpp:370
void DRcache_delete(const std::string &deviceId) override
delete an entry (if found) from the DR session cache
Definition: lime.cpp:407
void encrypt(std::shared_ptr< lime::EncryptionContext > encryptionContext, const std::shared_ptr< limeCallback > callback, const std::shared_ptr< limeRandomSeedCallback > randomSeedCallback) override
Encrypt a buffer (text or file) for a given list of recipient devices.
Definition: lime.cpp:220
const std::shared_ptr< limeCallback > callback
this is a ptr to a lambda, we may use it several time so we can manage precisely its timelife ...
Definition: lime_impl.hpp:103
A pure abstract class defining the API to encrypt/decrypt/manage user and its keys.
Definition: lime_lime.hpp:42
void DRcache_insert(const std::string &deviceId, std::shared_ptr< DR > DRsession) override
insert an entry in the DR session cache if an entry with the same key already exists, do nothing
Definition: lime.cpp:412
void update_SPk(const std::shared_ptr< limeCallback > callback) override
Check if the current SPk needs to be updated, if yes, generate a new one and publish it on server...
Definition: lime.cpp:193