Commit b3a890ed authored by johan's avatar johan

Improve code documentation

parent 081b8d91
......@@ -180,13 +180,17 @@ namespace lime {
* 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
* @param[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
* @param[in] DRmessage Double Ratchet message targeted to current device
* @param[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.
* @param[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.
* @param[out] plainMessage the output buffer
*
* @return true if the decryption is successfull, false otherwise
*/
bool decrypt(const std::string &localDeviceId, const std::string &recipientUserId, const std::string &senderDeviceId, const std::vector<uint8_t> &DRmessage, std::vector<uint8_t> &plainMessage);
bool 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);
/**
* @overload decrypt(const std::string &localDeviceId, const std::string &recipientUserId, const std::string &senderDeviceId, const std::vector<uint8_t> &DRmessage, std::vector<uint8_t> &plainMessage)
* convenience form to be called when no cipher message is received
*/
bool decrypt(const std::string &localDeviceId, const std::string &recipientUserId, const std::string &senderDeviceId, const std::vector<uint8_t> &DRmessage, std::vector<uint8_t> &plainMessage);
/**
* @brief Update: shall be called once a day at least, performs checks, updates and cleaning operations
......
......@@ -94,7 +94,7 @@ namespace lime {
* this will, on success, trigger generation and sending of SPk and OPks for our new user
*
* @param[in] callback call when completed
* @param[in] initialOPkBatchSize Number of OPks in the first batch uploaded to X3DH server
* @param[in] OPkInitialBatchSize Number of OPks in the first batch uploaded to X3DH server
*/
template <typename Curve>
void Lime<Curve>::publish_user(const limeCallback &callback, const uint16_t OPkInitialBatchSize) {
......
......@@ -57,13 +57,31 @@ class bctbx_RNG : public RNG {
public:
/* accessor */
/**
* @brief access internal RNG context
* Used internally by the bctoolbox wrapper, is not exposed to the lime_crypto_primitive API.
*
* @return a pointer to the RNG context
*/
bctbx_rng_context_t *get_context(void) {
return m_context;
}
/**
* @brief fill given buffer with Random bytes
*
* @param[out] buffer point to the beginning of the buffer to be filled with random bytes
* @param[in] size size of the buffer to be filled
*/
void randomize(uint8_t *buffer, const size_t size) override {
bctbx_rng_get(m_context, buffer, size);
};
/**
* @brief fill given buffer with Random bytes
*
* @param[out] buffer vector to be filled with random bytes(based on original vector size)
*/
void randomize(std::vector<uint8_t> buffer) override {
randomize(buffer.data(), buffer.size());
};
......@@ -168,13 +186,16 @@ class bctbx_EDDSA : public Signature<Curve> {
* @brief Sign a message using the key pair previously set in the object
*
* @param[in] message The message to be signed
* @param[in] associatedData A context for this signature, up to 255 bytes
* @param[out] signature The signature produced from the message with a key pair previously introduced in the object
*/
void sign(const std::vector<uint8_t> &message, DSA<Curve, lime::DSAtype::signature> &signature) override {
auto sigSize = signature.size();
bctbx_EDDSA_sign(m_context, message.data(), message.size(), nullptr, 0, signature.data(), &sigSize);
}
/**
* @overload void bctbx_EDDSA::sign(const X<Curve, lime::Xtype::publicKey> &message, DSA<Curve, lime::DSAtype::signature> &signature)
* a convenience function to directly verify a key exchange public key
*/
void sign(const X<Curve, lime::Xtype::publicKey> &message, DSA<Curve, lime::DSAtype::signature> &signature) override {
auto sigSize = signature.size();
bctbx_EDDSA_sign(m_context, message.data(), message.ssize(), nullptr, 0, signature.data(), &sigSize);
......@@ -191,6 +212,10 @@ class bctbx_EDDSA : public Signature<Curve> {
bool verify(const std::vector<uint8_t> &message, const DSA<Curve, lime::DSAtype::signature> &signature) override {
return (bctbx_EDDSA_verify(m_context, message.data(), message.size(), nullptr, 0, signature.data(), signature.size()) == BCTBX_VERIFY_SUCCESS);
}
/**
* @overload bool bctbx_EDDSA::verify(const X<Curve, lime::Xtype::publicKey> &message, const DSA<Curve, lime::DSAtype::signature> &signature)
* a convenience function to directly verify a key exchange public key
*/
bool verify(const X<Curve, lime::Xtype::publicKey> &message, const DSA<Curve, lime::DSAtype::signature> &signature) override {
return (bctbx_EDDSA_verify(m_context, message.data(), message.ssize(), nullptr, 0, signature.data(), signature.ssize()) == BCTBX_VERIFY_SUCCESS);
}
......
......@@ -74,10 +74,14 @@ namespace lime {
X<Base, lime::Xtype::publicKey> m_pubKey;
X<Base, lime::Xtype::privateKey> m_privKey;
public:
/// access the private key
X<Base, lime::Xtype::privateKey> &privateKey(void) {return m_privKey;};
/// access the public key
X<Base, lime::Xtype::publicKey> &publicKey(void) {return m_pubKey;};
/// copy construct a key pair from public and private keys (no verification on validity of keys is performed)
Xpair(X<Base, lime::Xtype::publicKey> &pub, X<Base, lime::Xtype::privateKey> &priv):m_pubKey(pub),m_privKey(priv) {};
Xpair() :m_pubKey{},m_privKey{}{};
/// == operator assert that public and private keys are the same
bool operator==(Xpair<Base> b) const {return (m_privKey==b.privateKey() && m_pubKey==b.publicKey());};
};
......@@ -109,10 +113,14 @@ namespace lime {
DSA<Base, lime::DSAtype::publicKey> m_pubKey;
DSA<Base, lime::DSAtype::privateKey> m_privKey;
public:
/// access the private key
DSA<Base, lime::DSAtype::privateKey> &privateKey(void) {return m_privKey;};
/// access the public key
DSA<Base, lime::DSAtype::publicKey> &publicKey(void) {return m_pubKey;};
/// copy construct a key pair from public and private keys (no verification on validity of keys is performed)
DSApair(DSA<Base, lime::DSAtype::publicKey> &pub, DSA<Base, lime::DSAtype::privateKey> &priv):m_pubKey(pub),m_privKey(priv) {};
DSApair() :m_pubKey{},m_privKey{}{};
/// == operator assert that public and private keys are the same
bool operator==(DSApair<Base> b) const {return (m_privKey==b.privateKey() && m_pubKey==b.publicKey());};
};
......@@ -132,8 +140,8 @@ class RNG {
* @param[out] buffer point to the beginning of the buffer to be filled with random bytes
* @param[in] size size of the buffer to be filled
*/
virtual void randomize(uint8_t *buffer, const size_t size) = 0;
/**
* @brief fill given buffer with Random bytes
*
......@@ -218,7 +226,7 @@ class Signature {
* @param[out] signature The signature produced from the message with a key pair previously introduced in the object
*/
virtual void sign(const std::vector<uint8_t> &message, DSA<Base, lime::DSAtype::signature> &signature) = 0;
/*
/**
* @overload virtual void sign(const X<Base, lime::Xtype::publicKey> &message, DSA<Base, lime::DSAtype::signature> &signature)
* a convenience function to directly verify a key exchange public key
*/
......@@ -233,7 +241,7 @@ class Signature {
* @return true if the signature is valid, false otherwise
*/
virtual bool verify(const std::vector<uint8_t> &message, const DSA<Base, lime::DSAtype::signature> &signature) = 0;
/*
/**
* @overload virtual bool verify(const X<Base, lime::Xtype::publicKey> &message, const DSA<Base, lime::DSAtype::signature> &signature)
* a convenience function to directly verify a key exchange public key
*/
......
......@@ -126,10 +126,12 @@ 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] 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
* @param[in] RNG_context A Random Number Generator context used for any rndom generation needed by this session
*/
template <typename Curve>
DR<Curve>::DR(lime::Db *localStorage, const DRChainKey &SK, const SharedADBuffer &AD, const X<Curve, lime::Xtype::publicKey> &peerPublicKey, long int peerDid, long int selfDid, const std::vector<uint8_t> &X3DH_initMessage, std::shared_ptr<RNG> RNG_context)
......@@ -160,9 +162,11 @@ 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] 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] 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(lime::Db *localStorage, const DRChainKey &SK, const SharedADBuffer &AD, const Xpair<Curve> &selfKeyPair, long int peerDid, long int selfDid, std::shared_ptr<RNG> RNG_context)
......@@ -178,6 +182,7 @@ namespace lime {
*
* @param[in] localStorage Local storage accessor to save DR session and perform mkskipped lookup
* @param[in] sessionId row id in the database identifying the session to be loaded
* @param[in] RNG_context A Random Number Generator context used for any rndom generation needed by this session
*/
template <typename Curve>
DR<Curve>::DR(lime::Db *localStorage, long sessionId, std::shared_ptr<RNG> RNG_context)
......
......@@ -116,8 +116,10 @@ namespace lime {
void ratchetEncrypt(const inputContainer &plaintext, std::vector<uint8_t> &&AD, std::vector<uint8_t> &ciphertext, const bool payloadDirectEncryption);
template<typename outputContainer>
bool ratchetDecrypt(const std::vector<uint8_t> &cipherText, const std::vector<uint8_t> &AD, outputContainer &plaintext, const bool payloadDirectEncryption);
long int dbSessionId(void) const {return m_dbSessionId;}; // retrieve the session's local storage id
bool isActive(void) const {return m_active_status;} // return the current status of session
/// return the session's local storage id
long int dbSessionId(void) const {return m_dbSessionId;};
/// return the current status of session
bool isActive(void) const {return m_active_status;}
};
......@@ -130,8 +132,17 @@ namespace lime {
const std::string deviceId; /**< recipient deviceId (shall be GRUU) */
bool identityVerified; /**< after encrypt calls back, it will hold the status of this peer device: identity verified or not */
std::vector<uint8_t> DRmessage; /**< after encrypt calls back, it will hold the DR message targeted to the specified recipient. It may contain an X3DH init message. */
RecipientInfos(const std::string &deviceId) : DRSession{nullptr}, deviceId{deviceId}, identityVerified{false}, DRmessage{} {};
/**
* Constructor: the deviceId is a constant and must be provided to the constructor
*
* @param[in] deviceId The device Id (GRUU) of this recipient
* @param[in] session The double ratchet session linking current device with this recipient.
*/
RecipientInfos(const std::string &deviceId, std::shared_ptr<DR<Curve>> session) : DRSession{session}, deviceId{deviceId}, identityVerified{false}, DRmessage{} {};
/**
* @overload RecipientInfos(const std::string &deviceId)
*/
RecipientInfos(const std::string &deviceId) : DRSession{nullptr}, deviceId{deviceId}, identityVerified{false}, DRmessage{} {};
};
// helpers function wich are the one to be used to encrypt/decrypt messages
......
......@@ -95,12 +95,17 @@ namespace lime {
bool m_payload_direct_encryption; // flag to store the message encryption mode: in the double ratchet packet or using a random key to encrypt it separately and encrypt the key in the DR packet
public:
/* data member accessors (read only) */
/// read-only accessor to Sender Chain index (Ns)
uint16_t Ns(void) const {return m_Ns;}
/// read-only accessor to Previous Sender Chain index (PN)
uint16_t PN(void) const {return m_PN;}
/// read-only accessor to peer Double Ratchet public key
const X<Curve, lime::Xtype::publicKey> &DHs(void) const {return m_DHs;}
/// is this header valid? (property is set by constructor/parser)
bool valid(void) const {return m_valid;}
/// what encryption mode is advertised in this header
bool payloadDirectEncryption(void) const {return m_payload_direct_encryption;}
/// read-only accessor to the size of parsed header
size_t size(void) {return m_size;}
/* ctor/dtor */
......
......@@ -142,7 +142,7 @@ namespace lime {
*/
template <typename Curve>
struct callbackUserData {
// limeObj is owned by the LimeManager, it shall no be destructed, do not own this with a shared_ptr as Lime obj may own the callbackUserData obj thus creating circular reference
/// limeObj is owned by the LimeManager, it shall no be destructed, do not own this with a shared_ptr as Lime obj may own the callbackUserData obj thus creating circular reference
std::weak_ptr<Lime<Curve>> limeObj;
/// is a lambda closure, not real idea of what is its lifetime but it seems ok to hold it this way
const limeCallback callback;
......@@ -163,22 +163,19 @@ namespace lime {
/// Used when fetching from server self OPk : how many will we upload if needed
uint16_t OPkBatchSize;
/** created at user create/delete and keys Post. EncryptionPolicy is not used, set it to the default value anyway
*/
/// created at user create/delete and keys Post. EncryptionPolicy is not used, set it to the default value anyway
callbackUserData(std::weak_ptr<Lime<Curve>> thiz, const limeCallback &callbackRef, uint16_t OPkInitialBatchSize=lime::settings::OPk_initialBatchSize, bool startRegisterUserSequence=false)
: limeObj{thiz}, callback{callbackRef},
recipientUserId{nullptr}, recipients{nullptr}, plainMessage{nullptr}, cipherMessage{nullptr}, network_state_machine{startRegisterUserSequence?lime::network_state::sendSPk:lime::network_state::done},
encryptionPolicy(lime::EncryptionPolicy::optimizeUploadSize), OPkServerLowLimit(0), OPkBatchSize(OPkInitialBatchSize) {};
/** created at update: getSelfOPks. EncryptionPolicy is not used, set it to the default value anyway
*/
/// created at update: getSelfOPks. EncryptionPolicy is not used, set it to the default value anyway
callbackUserData(std::weak_ptr<Lime<Curve>> thiz, const limeCallback &callbackRef, uint16_t OPkServerLowLimit, uint16_t OPkBatchSize)
: limeObj{thiz}, callback{callbackRef},
recipientUserId{nullptr}, recipients{nullptr}, plainMessage{nullptr}, cipherMessage{nullptr}, network_state_machine{lime::network_state::done},
encryptionPolicy(lime::EncryptionPolicy::optimizeUploadSize), OPkServerLowLimit{OPkServerLowLimit}, OPkBatchSize{OPkBatchSize} {};
/** created at encrypt(getPeerBundle)
*/
/// created at encrypt(getPeerBundle)
callbackUserData(std::weak_ptr<Lime<Curve>> thiz, const limeCallback &callbackRef,
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,
......@@ -186,6 +183,7 @@ namespace lime {
: limeObj{thiz}, callback{callbackRef},
recipientUserId{recipientUserId}, recipients{recipients}, plainMessage{plainMessage}, cipherMessage{cipherMessage}, network_state_machine {lime::network_state::done}, // copy construct all shared_ptr
encryptionPolicy(policy), OPkServerLowLimit(0), OPkBatchSize(0) {};
// do not copy callback data, force passing the pointer around after creation
callbackUserData(callbackUserData &a) = delete;
callbackUserData operator=(callbackUserData &a) = delete;
......
......@@ -37,6 +37,7 @@ namespace lime {
* curve 25519 key size definition, use a 4 chars(C255) to identify it to improve code readability
*/
struct C255 {
/// the C25519 curve id using the CurveId enumeration
static constexpr lime::CurveId curveId() {return lime::CurveId::c25519;};
/// for X25519, public, private and shared secret have the same length: 32 bytes
static constexpr size_t Xsize(lime::Xtype dataType) {return 32;};
......@@ -48,6 +49,7 @@ namespace lime {
* curve 448-goldilocks key sizes definition
*/
struct C448 {
///the C448 curve id using the CurveId enumeration
static constexpr lime::CurveId curveId() {return lime::CurveId::c448;};
/// for X448, public, private and shared secret have the same length 56 bytes
static constexpr size_t Xsize(lime::Xtype dataType) {return 56;};
......
......@@ -67,11 +67,12 @@ namespace lime {
/**
* @brief Decrypt the given message
*
* @param[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
* @param[in] DRmessage the Double Ratchet message targeted to current device
* @param[in] cipherMessage part of cipher routed to all recipient devices
* @param[out] plainMessage the output buffer
* @param[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
* @param[in] senderDeviceId the device Id (GRUU) of the message sender
* @param[in] DRmessage the Double Ratchet message targeted to current device
* @param[in] cipherMessage part of cipher routed to all recipient devices(it may be actually empty depending on sender encryption policy and message characteristics)
* @param[out] plainMessage the output buffer
*
* @return true if the decryption is successfull, false otherwise
*/
......@@ -85,7 +86,7 @@ namespace lime {
* this will, on success, trigger generation and sending of SPk and OPks for our new user
*
* @param[in] callback call when completed
* @param[in] initialOPkBatchSize Number of OPks in the first batch uploaded to X3DH server
* @param[in] OPkInitialBatchSize Number of OPks in the first batch uploaded to X3DH server
*/
virtual void publish_user(const limeCallback &callback, const uint16_t OPkInitialBatchSize) = 0;
......
......@@ -30,7 +30,7 @@ namespace lime {
*/
class Db {
public:
// soci connexion to DB
/// soci connexion to DB
soci::session sql;
Db()=delete; // we can't create a new DB holder without DB filename
......@@ -57,7 +57,7 @@ namespace lime {
/**
* @brief if exists, delete user
*
* @param[in] userId a string holding the user to look for in DB, shall be its GRUU
* @param[in] deviceId a string holding the user to look for in DB, shall be its GRUU
*
*/
void delete_LimeUser(const std::string &deviceId);
......
......@@ -38,11 +38,25 @@ namespace lime {
X<Curve, lime::Xtype::publicKey> OPk; /**< peer device One Time preKey */
uint32_t OPk_id; /**< id of the peer device current public pre-signed key */
X3DH_peerBundle(std::string &&deviceId, std::vector<uint8_t>::const_iterator Ik, std::vector<uint8_t>::const_iterator SPk, uint32_t SPk_id, std::vector<uint8_t>::const_iterator SPk_sig) :
deviceId{deviceId}, Ik{Ik}, SPk{SPk}, SPk_id{SPk_id}, SPk_sig{SPk_sig}, haveOPk{false}, OPk{}, OPk_id{0} {};
/**
* Constructor gets vector<uint8_t> iterators to all needed data and copy them into correct data types
*
* @param[in] deviceId peer Device Id providing this key bundle
* @param[in] Ik peer public identity key (DSA format)
* @param[in] SPk peer public Signed-Pre-key (X format)
* @param[in] SPk_id id of the public Signed-Pre-key
* @param[in] SPk_sig Signature of the public Signed-Pre-key(signed with peer Identity key)
* @param[in] OPk One-time Pre-key (X format) - this parameter is optionnal
* @param[in] OPk_id id of the One-time Pre-key - this parameter is optionnal
*/
X3DH_peerBundle(std::string &&deviceId, std::vector<uint8_t>::const_iterator Ik, std::vector<uint8_t>::const_iterator SPk, uint32_t SPk_id, std::vector<uint8_t>::const_iterator SPk_sig, std::vector<uint8_t>::const_iterator OPk, uint32_t OPk_id) :
deviceId{deviceId}, Ik{Ik}, SPk{SPk}, SPk_id{SPk_id}, SPk_sig{SPk_sig}, haveOPk{true}, OPk{OPk}, OPk_id{OPk_id} {};
/**
* @overload
* construct without OPk when not present in the parsed bundle
*/
X3DH_peerBundle(std::string &&deviceId, std::vector<uint8_t>::const_iterator Ik, std::vector<uint8_t>::const_iterator SPk, uint32_t SPk_id, std::vector<uint8_t>::const_iterator SPk_sig) :
deviceId{deviceId}, Ik{Ik}, SPk{SPk}, SPk_id{SPk_id}, SPk_sig{SPk_sig}, haveOPk{false}, OPk{}, OPk_id{0} {};
};
......
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