lime
Lime is a C++ library implementing Open Whisper System Signal protocol
|
Manage several Lime objects(one is needed for each local user). More...
Public Member Functions | |
void | create_user (const std::string &localDeviceId, const std::string &x3dhServerUrl, const lime::CurveId curve, const uint16_t OPkInitialBatchSize, const limeCallback &callback) |
Create a user in local database and publish it on the given X3DH server. More... | |
void | create_user (const std::string &localDeviceId, const std::string &x3dhServerUrl, const lime::CurveId curve, const limeCallback &callback) |
void | delete_user (const std::string &localDeviceId, const limeCallback &callback) |
Delete a user from local database and from the X3DH server. More... | |
bool | is_user (const std::string &localDeviceId) |
Check if a user is present and active in local storage. More... | |
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) |
Encrypt a buffer (text or file) for a given list of recipient devices. More... | |
lime::PeerDeviceStatus | 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) |
Decrypt the given message. More... | |
lime::PeerDeviceStatus | decrypt (const std::string &localDeviceId, const std::string &recipientUserId, const std::string &senderDeviceId, const std::vector< uint8_t > &DRmessage, std::vector< uint8_t > &plainMessage) |
void | update (const limeCallback &callback, uint16_t OPkServerLowLimit, uint16_t OPkBatchSize) |
Update: shall be called once a day at least, performs checks, updates and cleaning operations. More... | |
void | update (const limeCallback &callback) |
void | get_selfIdentityKey (const std::string &localDeviceId, std::vector< uint8_t > &Ik) |
retrieve self Identity Key, an EdDSA formatted public key More... | |
void | set_peerDeviceStatus (const std::string &peerDeviceId, const std::vector< uint8_t > &Ik, lime::PeerDeviceStatus status) |
set the peer device status flag in local storage: unsafe, trusted or untrusted. More... | |
void | set_peerDeviceStatus (const std::string &peerDeviceId, lime::PeerDeviceStatus status) |
set the peer device status flag in local storage: unsafe or untrusted. More... | |
lime::PeerDeviceStatus | get_peerDeviceStatus (const std::string &peerDeviceId) |
get the status of a peer device: unknown, untrusted, trusted, unsafe More... | |
bool | is_localUser (const std::string &deviceId) |
checks if a device iD exists in the local users More... | |
void | delete_peerDevice (const std::string &peerDeviceId) |
delete a peerDevice from local storage More... | |
void | stale_sessions (const std::string &localDeviceId, const std::string &peerDeviceId) |
Stale all sessions between localDeviceId and peerDevice. If peerDevice keep using this session to encrypt and we decrypt with success, the session will be reactivated but to encrypt a message to this peerDevice, a new session will be created. If no session is active between the given device, this call has no effect. More... | |
void | set_x3dhServerUrl (const std::string &localDeviceId, const std::string &x3dhServerUrl) |
Set the X3DH key server URL for this identified user. More... | |
std::string | get_x3dhServerUrl (const std::string &localDeviceId) |
Get the X3DH key server URL for this identified user. More... | |
LimeManager ()=delete | |
LimeManager (const LimeManager &)=delete | |
LimeManager | operator= (const LimeManager &)=delete |
LimeManager (const std::string &db_access, const limeX3DHServerPostData &X3DH_post_data, std::shared_ptr< std::recursive_mutex > db_mutex) | |
Lime Manager constructor. More... | |
LimeManager (const std::string &db_access, const limeX3DHServerPostData &X3DH_post_data) | |
~LimeManager ()=default | |
Manage several Lime objects(one is needed for each local user).
LimeManager is mostly a cache of Lime users, any command get as first parameter the device Id (Lime manage devices only, the link user(sip:uri)<->device(GRUU) is provided by upper level) All interactions should take place through the LimeManager object, any endpoint shall have only one LimeManager object instanciated
|
delete |
|
delete |
lime::LimeManager::LimeManager | ( | const std::string & | db_access, |
const limeX3DHServerPostData & | X3DH_post_data, | ||
std::shared_ptr< std::recursive_mutex > | db_mutex | ||
) |
Lime Manager constructor.
[in] | db_access | string used to access DB: can be filename for sqlite3 or access params for mysql, directly forwarded to SOCI session opening |
[in] | X3DH_post_data | A function to send data to the X3DH server, parameters includes a callback to transfer back the server response |
[in] | db_mutex | a mutex used to lock database access. Is optionnal: if not given, the manager will produce one internally |
lime::LimeManager::LimeManager | ( | const std::string & | db_access, |
const limeX3DHServerPostData & | X3DH_post_data | ||
) |
This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.
|
default |
void lime::LimeManager::create_user | ( | const std::string & | localDeviceId, |
const std::string & | x3dhServerUrl, | ||
const lime::CurveId | curve, | ||
const uint16_t | OPkInitialBatchSize, | ||
const limeCallback & | callback | ||
) |
Create a user in local database and publish it on the given X3DH server.
The Lime user shall be created at the same time the account is created on the device, this function shall not be called again, attempt to re-create an already existing user will fail. A user is identified by its deviceId (shall be the GRUU) and must at creation select a base Elliptic curve to use, this setting cannot be changed later A user is published on an X3DH key server who must run using the same elliptic curve selected for this user (creation will fail otherwise), the server url cannot be changed later
[in] | localDeviceId | Identify the local user account, it must be unique and is also be used as Id on the X3DH key server, it shall be the GRUU |
[in] | x3dhServerUrl | The complete url(including port) of the X3DH key server. It must connect using HTTPS. Example: https://sip5.linphone.org:25519 |
[in] | curve | Choice of elliptic curve used as base for ECDH and EdDSA operation involved. Can be CurveId::c25519 or CurveId::c448. |
[in] | OPkInitialBatchSize | Number of OPks in the first batch uploaded to X3DH server |
[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 |
void lime::LimeManager::create_user | ( | const std::string & | localDeviceId, |
const std::string & | x3dhServerUrl, | ||
const lime::CurveId | curve, | ||
const limeCallback & | callback | ||
) |
This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.
lime::PeerDeviceStatus lime::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 | ||
) |
Decrypt the given message.
if specified localDeviceId is not found in local Storage, throw an exception
[in] | localDeviceId | used to identify which local acount to use and also as the recipient device ID of the message, shall be the GRUU |
[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 |
[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 |
[in] | DRmessage | Double Ratchet message targeted to current device |
[in] | cipherMessage | when present (depends on encryption policy) holds a common part of the encrypted message. Can be ignored or set to empty vector if not present in the incoming message. |
[out] | plainMessage | the output buffer |
lime::LimeManager::decrypt | ( | const std::string & | localDeviceId, |
const std::string & | recipientUserId, | ||
const std::string & | senderDeviceId, | ||
const std::vector< uint8_t > & | DRmessage, | ||
std::vector< uint8_t > & | plainMessage | ||
) |
This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.
convenience form to be called when no cipher message is received
void lime::LimeManager::delete_peerDevice | ( | const std::string & | peerDeviceId | ) |
delete a peerDevice from local storage
[in] | peerDeviceId | The device Id to be removed from local storage, shall be its GRUU |
Call is silently ignored if the device is not found in local storage
void lime::LimeManager::delete_user | ( | const std::string & | localDeviceId, |
const limeCallback & | callback | ||
) |
Delete a user from local database and from the X3DH server.
if specified localDeviceId is not found in local Storage, throw an exception
[in] | localDeviceId | Identify the local user acount to use, it must be unique and is also be used as Id on the X3DH key server, it shall be the GRUU |
[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 |
void lime::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, | ||
lime::EncryptionPolicy | encryptionPolicy = lime::EncryptionPolicy::optimizeUploadSize |
||
) |
Encrypt a buffer (text or file) for a given list of recipient devices.
if specified localDeviceId is not found in local Storage, throw an exception
Clarification on recipients: recipients information needed are a list of the device Id and one userId. The device Id shall be their GRUU while the userId is a sip:uri. recipient User Id is used to identify the actual intended recipient. Example: alice have two devices and is signed up on a conference having bob and claire as other members. The recipientUserId will be the conference sip:uri and device list will include: - alice other device - bob devices - claire devices If Alice write to Bob only, the recipientUserId will be bob sip:uri and recipient devices list : - alice other device - bob devices In all cases, the identified source of the message will be the localDeviceId If the X3DH server can't provide keys for a peer device, its status is set to fail and its DRmessage is empty. Other devices get their encrypted message If no peer device could get encrypted for all of them are missing keys on the X3DH server, the callback will be called with fail exit status
[in] | localDeviceId | used to identify which local acount to use and also as the identified source of the message, shall be the GRUU |
[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 |
[in,out] | recipients | a list of RecipientData holding:
|
[in] | plainMessage | a buffer holding the message to encrypt, can be text or data. |
[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) |
[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 the output of encryption as it won't be part of the callback parameters. |
[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 upload size mode. |
lime::PeerDeviceStatus lime::LimeManager::get_peerDeviceStatus | ( | const std::string & | peerDeviceId | ) |
get the status of a peer device: unknown, untrusted, trusted, unsafe
[in] | peerDeviceId | The device Id of peer, shall be its GRUU |
void lime::LimeManager::get_selfIdentityKey | ( | const std::string & | localDeviceId, |
std::vector< uint8_t > & | Ik | ||
) |
retrieve self Identity Key, an EdDSA formatted public key
if specified localDeviceId is not found in local Storage, throw an exception
[in] | localDeviceId | used to identify which local account we're dealing with, shall be the GRUU |
[out] | Ik | the EdDSA public identity key, formatted as in RFC8032 |
std::string lime::LimeManager::get_x3dhServerUrl | ( | const std::string & | localDeviceId | ) |
Get the X3DH key server URL for this identified user.
[in] | localDeviceId | Identify the local user account, it must be unique and is also be used as Id on the X3DH key server, it shall be the GRUU |
Throw an exception if the user is unknow or inactive
bool lime::LimeManager::is_localUser | ( | const std::string & | deviceId | ) |
checks if a device iD exists in the local users
[in] | deviceId | The device Id to check |
bool lime::LimeManager::is_user | ( | const std::string & | localDeviceId | ) |
Check if a user is present and active in local storage.
[in] | localDeviceId | used to identify which local account looking up, shall be the GRUU |
|
delete |
void lime::LimeManager::set_peerDeviceStatus | ( | const std::string & | peerDeviceId, |
const std::vector< uint8_t > & | Ik, | ||
lime::PeerDeviceStatus | status | ||
) |
set the peer device status flag in local storage: unsafe, trusted or untrusted.
[in] | peerDeviceId | The device Id of peer, shall be its GRUU |
[in] | Ik | the EdDSA peer public identity key, formatted as in RFC8032 |
[in] | status | value of flag to set: accepted values are trusted, untrusted, unsafe |
throw an exception if given key doesn't match the one present in local storage if the status flag value is unexpected (not one of trusted, untrusted, unsafe), ignore the call if the status flag is unsafe or untrusted, ignore the value of Ik and call the version of this function without it
if peer Device is not present in local storage and status is trusted or unsafe, it is added, if status is untrusted, it is just ignored
General algorithm followed by the set_peerDeviceStatus functions
void lime::LimeManager::set_peerDeviceStatus | ( | const std::string & | peerDeviceId, |
lime::PeerDeviceStatus | status | ||
) |
set the peer device status flag in local storage: unsafe or untrusted.
This variation allows to set a peer Device status to unsafe or untrusted only whithout providing its identity key Ik
[in] | peerDeviceId | The device Id of peer, shall be its GRUU |
[in] | status | value of flag to set: accepted values are untrusted or unsafe |
if the status flag value is unexpected (not one of untrusted, unsafe), ignore the call
if peer Device is not present in local storage, it is inserted if status is unsafe and call is ignored if status is untrusted if the status is untrusted but the current status in local storage is unsafe, ignore the call Any call to the other form of the function with a status to unsafe or untrusted is rerouted to this function
void lime::LimeManager::set_x3dhServerUrl | ( | const std::string & | localDeviceId, |
const std::string & | x3dhServerUrl | ||
) |
Set the X3DH key server URL for this identified user.
[in] | localDeviceId | Identify the local user account, it must be unique and is also be used as Id on the X3DH key server, it shall be the GRUU |
[in] | x3dhServerUrl | The complete url(including port) of the X3DH key server. It must connect using HTTPS. Example: https://sip5.linphone.org:25519 |
Throw an exception if the user is unknow or inactive
void lime::LimeManager::stale_sessions | ( | const std::string & | localDeviceId, |
const std::string & | peerDeviceId | ||
) |
Stale all sessions between localDeviceId and peerDevice. If peerDevice keep using this session to encrypt and we decrypt with success, the session will be reactivated but to encrypt a message to this peerDevice, a new session will be created. If no session is active between the given device, this call has no effect.
[in] | localDeviceId | Identify the local user account, it must be unique and is also be used as Id on the X3DH key server, it shall be the GRUU |
[in] | peerDeviceId | The device Id of peer, shall be its GRUU |
void lime::LimeManager::update | ( | const limeCallback & | callback, |
uint16_t | OPkServerLowLimit, | ||
uint16_t | OPkBatchSize | ||
) |
Update: shall be called once a day at least, performs checks, updates and cleaning operations.
Is performed for all users founds in local storage
[in] | callback | This operation may 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. |
[in] | OPkServerLowLimit | If server holds less OPk than this limit, generate and upload a batch of OPks |
[in] | OPkBatchSize | Number of OPks in a batch uploaded to server |
void lime::LimeManager::update | ( | const limeCallback & | callback | ) |
This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.