lime
Lime is a C++ library implementing Open Whisper System Signal protocol
Enumerations | Functions | Variables
lime::x3dh_protocol Namespace Reference

Group in this namespace all the functions related to building or parsing x3dh packets. More...

Enumerations

enum  x3dh_message_type : uint8_t {
  x3dh_message_type::deprecated_registerUser =0x01, x3dh_message_type::deleteUser =0x02, x3dh_message_type::postSPk =0x03, x3dh_message_type::postOPks =0x04,
  x3dh_message_type::getPeerBundle =0x05, x3dh_message_type::peerBundle =0x06, x3dh_message_type::getSelfOPks =0x07, x3dh_message_type::selfOPks =0x08,
  x3dh_message_type::registerUser =0x09, x3dh_message_type::error =0xff
}
 the x3dh message type exchanged with the X3DH server More...
 
enum  x3dh_error_code : uint8_t {
  x3dh_error_code::bad_content_type =0x00, x3dh_error_code::bad_curve =0x01, x3dh_error_code::missing_senderId =0x02, x3dh_error_code::bad_x3dh_protocol_version =0x03,
  x3dh_error_code::bad_size =0x04, x3dh_error_code::user_already_in =0x05, x3dh_error_code::user_not_found =0x06, x3dh_error_code::db_error =0x07,
  x3dh_error_code::bad_request =0x08, x3dh_error_code::server_failure =0x09, x3dh_error_code::resource_limit_reached =0x0a, x3dh_error_code::unknown_error_code =0xfe,
  x3dh_error_code::unset_error_code =0xff
}
 the error codes included in the x3dh error message received from the X3DH server More...
 

Functions

static std::string x3dh_messageTypeString (const x3dh_message_type message_type)
 Helper function to get human readable trace of x3dh messages types. More...
 
static std::vector< uint8_t > X3DH_makeHeader (const x3dh_message_type message_type, const lime::CurveId curve) noexcept
 Build X3DH message header using current protocol Version byte. More...
 
template<typename Curve >
void buildMessage_registerUser (std::vector< uint8_t > &message, const DSA< Curve, lime::DSAtype::publicKey > &Ik, const X< Curve, lime::Xtype::publicKey > &SPk, const DSA< Curve, lime::DSAtype::signature > &Sig, const uint32_t SPk_id, const std::vector< X< Curve, lime::Xtype::publicKey >> &OPks, const std::vector< uint32_t > &OPk_ids) noexcept
 build a registerUser message : Identity Key<EDDSA Public Key length> More...
 
template<typename Curve >
void buildMessage_deleteUser (std::vector< uint8_t > &message) noexcept
 build a deleteUser message More...
 
template<typename Curve >
void buildMessage_publishSPk (std::vector< uint8_t > &message, const X< Curve, lime::Xtype::publicKey > &SPk, const DSA< Curve, lime::DSAtype::signature > &Sig, const uint32_t SPk_id) noexcept
 build a postSPk message More...
 
template<typename Curve >
void buildMessage_publishOPks (std::vector< uint8_t > &message, const std::vector< X< Curve, lime::Xtype::publicKey >> &OPks, const std::vector< uint32_t > &OPk_ids) noexcept
 build a postOPks message More...
 
template<typename Curve >
void buildMessage_getPeerBundles (std::vector< uint8_t > &message, std::vector< std::string > &peer_device_ids) noexcept
 build a getPeerBundle message More...
 
template<typename Curve >
void buildMessage_getSelfOPks (std::vector< uint8_t > &message) noexcept
 build a getSelfOPks message More...
 
template<typename Curve >
bool parseMessage_getType (const std::vector< uint8_t > &body, x3dh_message_type &message_type, x3dh_error_code &error_code, const limeCallback callback) noexcept
 
template<typename Curve >
bool parseMessage_getPeerBundles (const std::vector< uint8_t > &body, std::vector< X3DH_peerBundle< Curve >> &peersBundle) noexcept
 Parse a peerBundles message and populate a vector of peerBundles. More...
 
template<typename Curve >
bool parseMessage_selfOPks (const std::vector< uint8_t > &body, std::vector< uint32_t > &selfOPkIds) noexcept
 Parse a selfOPk message and populate a self OPk ids. More...
 

Variables

constexpr uint8_t X3DH_protocolVersion = 0x01
 
constexpr size_t X3DH_headerSize = 3
 

Detailed Description

Group in this namespace all the functions related to building or parsing x3dh packets.

Protocol Version 0x01:
Header is : Protccol Version Number<1 byte> || Message type<1 byte> || Curve id<1 byte> Messages are : header<3 bytes> || Message content

If not an error the server responds with a message holding just a header of the same message type except for getPeerBundle which shall be answered with a peerBundle message

Message types description :

Enumeration Type Documentation

◆ x3dh_error_code

enum lime::x3dh_protocol::x3dh_error_code : uint8_t
strong

the error codes included in the x3dh error message received from the X3DH server

Note
Do not change the mapped values as they must be synced with X3DH server definition
Enumerator
bad_content_type 
bad_curve 
missing_senderId 
bad_x3dh_protocol_version 
bad_size 
user_already_in 
user_not_found 
db_error 
bad_request 
server_failure 
resource_limit_reached 
unknown_error_code 
unset_error_code 

◆ x3dh_message_type

the x3dh message type exchanged with the X3DH server

Note
Do not change the mapped values as they must be synced with X3DH server definition
Enumerator
deprecated_registerUser 
deleteUser 
postSPk 
postOPks 
getPeerBundle 
peerBundle 
getSelfOPks 
selfOPks 
registerUser 
error 

Function Documentation

◆ buildMessage_deleteUser()

template<typename Curve >
void lime::x3dh_protocol::buildMessage_deleteUser ( std::vector< uint8_t > &  message)
noexcept

build a deleteUser message

empty message, server retrieves deviceId to delete from authentication header, you cannot delete someone else!

Parameters
[in,out]messagean empty buffer to store the message

◆ buildMessage_getPeerBundles()

template<typename Curve >
void lime::x3dh_protocol::buildMessage_getPeerBundles ( std::vector< uint8_t > &  message,
std::vector< std::string > &  peer_device_ids 
)
noexcept

build a getPeerBundle message

request Count < 2 bytes unsigned Big Endian> ||
(userId Size <2 bytes unsigned Big Endian> || UserId <...> (the GRUU of user we wan't to send a message)) {request Count}

Parameters
[in,out]messagean empty buffer to store the message
[in]peer_device_idsa vector of all devices id for wich we request a key bundle

◆ buildMessage_getSelfOPks()

template<typename Curve >
void lime::x3dh_protocol::buildMessage_getSelfOPks ( std::vector< uint8_t > &  message)
noexcept

build a getSelfOPks message

empty message, ask server for the OPk Id it still holds for us

Parameters
[in,out]messagean empty buffer to store the message

◆ buildMessage_publishOPks()

template<typename Curve >
void lime::x3dh_protocol::buildMessage_publishOPks ( std::vector< uint8_t > &  message,
const std::vector< X< Curve, lime::Xtype::publicKey >> &  OPks,
const std::vector< uint32_t > &  OPk_ids 
)
noexcept

build a postOPks message

Keys Count<2 bytes unsigned integer Big endian> ||
( OPk< ECDH Public key length > || OPk Id <4 bytes>){Keys Count}

Parameters
[in,out]messagean empty buffer to store the message
[in]OPksa vector of OPks to be published
[in]OPk_idsId vector matching the order of the OPks vector

◆ buildMessage_publishSPk()

template<typename Curve >
void lime::x3dh_protocol::buildMessage_publishSPk ( std::vector< uint8_t > &  message,
const X< Curve, lime::Xtype::publicKey > &  SPk,
const DSA< Curve, lime::DSAtype::signature > &  Sig,
const uint32_t  SPk_id 
)
noexcept

build a postSPk message

SPk< ECDH Public key length > || SPk Signature< Signature Length > || SPk Id < 4 bytes>

Parameters
[in,out]messagean empty buffer to store the message
[in]SPkPublic Signed Pre-Key
[in]SigSignature of Public Signed Pre-Key (signed using self Identity key)
[in]SPk_idSPk id used to retrieve the SPk from local storage

◆ buildMessage_registerUser()

template<typename Curve >
void lime::x3dh_protocol::buildMessage_registerUser ( std::vector< uint8_t > &  message,
const DSA< Curve, lime::DSAtype::publicKey > &  Ik,
const X< Curve, lime::Xtype::publicKey > &  SPk,
const DSA< Curve, lime::DSAtype::signature > &  Sig,
const uint32_t  SPk_id,
const std::vector< X< Curve, lime::Xtype::publicKey >> &  OPks,
const std::vector< uint32_t > &  OPk_ids 
)
noexcept

build a registerUser message : Identity Key<EDDSA Public Key length>

Parameters
[in,out]messagean empty buffer to store the message
[in]IkSelf public identity key (formatted for signature algorithm)
[in]SPkpublic signed pre-key (ECDH format)
[in]SigSPk signed using Ik
[in]SPk_idSPk Id in local storage
[in]OPksVector of one time pre-keys
[in]OPk_idsIds of the OPk hold by previous vector(in matching indexes)

◆ parseMessage_getPeerBundles()

template<typename Curve >
bool lime::x3dh_protocol::parseMessage_getPeerBundles ( const std::vector< uint8_t > &  body,
std::vector< X3DH_peerBundle< Curve >> &  peersBundle 
)
noexcept

Parse a peerBundles message and populate a vector of peerBundles.

Warning: no checks are done on message type, they are performed before calling this function

peerBundle : bundle Count < 2 bytes unsigned Big Endian> ||
( deviceId Size < 2 bytes unsigned Big Endian > || deviceId Flag<1 byte: 0 if no OPK in bundle, 1 if present, 2 no key bundle found on server> || Ik < EDDSA Public Key Length > || SPk < ECDH Public Key Length > || SPK id <4 bytes> SPk_sig < Signature Length > || (OPk < ECDH Public Key Length > || OPk id <4 bytes>){0,1 in accordance to flag} ) { bundle Count}

Parameters
[in]bodya buffer holding the message
[out]peersBundlea vector to be populated from message content, is empty if none found
Returns
true if all went ok, false and empty peersBundle otherwise

◆ parseMessage_getType()

template<typename Curve >
bool lime::x3dh_protocol::parseMessage_getType ( const std::vector< uint8_t > &  body,
x3dh_message_type message_type,
x3dh_error_code error_code,
const limeCallback  callback 
)
noexcept

◆ parseMessage_selfOPks()

template<typename Curve >
bool lime::x3dh_protocol::parseMessage_selfOPks ( const std::vector< uint8_t > &  body,
std::vector< uint32_t > &  selfOPkIds 
)
noexcept

Parse a selfOPk message and populate a self OPk ids.

Warning: no checks are done on message type, they are performed before calling this function
selfOPks : OPk Count <2 bytes unsigned integer Big Endian> ||
(OPk id <4 bytes uint32_t big endian>){OPk Count}

Parameters
[in]bodya buffer holding the message
[out]selfOPkIdsa vector to be populated from message content, is empty if no OPk returned
Returns
true if all went ok, false otherwise

◆ X3DH_makeHeader()

static std::vector<uint8_t> lime::x3dh_protocol::X3DH_makeHeader ( const x3dh_message_type  message_type,
const lime::CurveId  curve 
)
staticnoexcept

Build X3DH message header using current protocol Version byte.

Parameters
[in]message_typeThe message type we are creating
[in]curveThe curve Id we're working with
Returns
a vector holding the well formed header ready to be expanded to include the message body

◆ x3dh_messageTypeString()

static std::string lime::x3dh_protocol::x3dh_messageTypeString ( const x3dh_message_type  message_type)
static

Helper function to get human readable trace of x3dh messages types.

Parameters
[in]message_typeThe message type in enum class format
Returns
the message type as a human readable string

Variable Documentation

◆ X3DH_headerSize

constexpr size_t lime::x3dh_protocol::X3DH_headerSize = 3

◆ X3DH_protocolVersion

constexpr uint8_t lime::x3dh_protocol::X3DH_protocolVersion = 0x01