lime.h 9.76 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
/*
linphone
Copyright (C) 2015  Belledonne Communications SARL

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
17
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18 19
*/

20 21 22 23 24 25 26
#ifndef LIME_H
#define LIME_H

#define LIME_INVALID_CACHE	0x1001
#define LIME_UNABLE_TO_DERIVE_KEY 0x1002
#define LIME_UNABLE_TO_ENCRYPT_MESSAGE 0x1004
#define LIME_UNABLE_TO_DECRYPT_MESSAGE 0x1008
27
#define LIME_NO_VALID_KEY_FOUND_FOR_PEER	0x1010
28
#define LIME_INVALID_ENCRYPTED_MESSAGE 0x1020
johan's avatar
johan committed
29
#define LIME_PEER_KEY_HAS_EXPIRED	0x1040
30
#define LIME_NOT_ENABLED 0x1100
31 32 33

/* this define the maximum key derivation number allowed to get the caches back in sync in case of missed messages */
#define MAX_DERIVATION_NUMBER 100
34 35 36 37 38 39 40 41

#define LIME_SENDER	0x01
#define LIME_RECEIVER 0x02
#include <stdint.h>
#include <libxml/tree.h>
#include <libxml/parser.h>
#include <libxml/xmlwriter.h>

42
#include "linphone/core.h"
43 44
#include <mediastreamer2/mscommon.h>

45 46 47
/**
 * @brief Structure holding all needed material to encrypt/decrypt Messages */
typedef struct limeKey_struct  {
48
	int zuid; /**< the internal cache id for this key, zuid is a binding on local uri and zid <-> peer uri and zid */
49 50 51 52 53 54 55 56 57 58 59
	uint8_t key[32]; /**< a 256 bit key used to encrypt/decrypt message */
	uint8_t sessionId[32]; /**< a session id used to derive key */
	uint32_t sessionIndex; /**< an index to count number of derivation */
	uint8_t peerZID[12]; /**< the ZID associated to this key */
} limeKey_t;

/**
 * @brief Store the differents keys associated to a sipURI */
typedef struct limeURIKeys_struct {
	limeKey_t 	**peerKeys; /**< an array of all the key material associated to each ZID matching the specified URI */
	uint16_t	associatedZIDNumber; /**< previous array length */
60 61
	char 		*peerURI; /**< the peer sip URI associated to all the keys, must be a null terminated string */
	char  		*selfURI; /**< the local sip URI used to send messages, must be a null terminated string */
62 63
} limeURIKeys_t;

64 65 66 67
#ifdef __cplusplus
extern "C" {
#endif

68 69 70 71 72
/**
 * @brief Get from cache all the senders keys associated to the given URI
 * peerKeys field from associatedKeys param must be NULL when calling this function.
 * Structure content must then be freed using lime_freeKeys function
 *
73 74
 * @param[in]		cachedb		Pointer to the sqlite3 DB
 * @param[in,out]	associatedKeys	Structure containing the self and peer URI. After this call contains all key material associated to the given URI. Must be then freed through lime_freeKeys function
75
 *
johan's avatar
johan committed
76
 * @return 0 on success(at least one valid key found), error code otherwise
77
 */
78
LINPHONE_PUBLIC int lime_getCachedSndKeysByURI(void *cachedb, limeURIKeys_t *associatedKeys);
79 80 81 82

/**
 * @brief Get the receiver key associated to the ZID given in the associatedKey parameter
 *
83 84 85 86
 * @param[in]		cachedb			Pointer to the sqlite3 DB
 * @param[in,out]	associatedKey		Structure containing the peerZID and will store the retrieved key
 * @param[in]		selfURI			The source URI
 * @param[in]		peerURI			The destination URI
87 88 89
 *
 * @return 0 on success, error code otherwise
 */
90
LINPHONE_PUBLIC int lime_getCachedRcvKeyByZid(void *cachedb, limeKey_t *associatedKey, const char *selfURI, const char *peerURI);
91 92 93 94

/**
 * @brief Set in cache the given key material, association is made by ZID contained in the associatedKey parameter
 *
95
 * @param[in/out]	cachedb		Pointer to the sqlite3 DB
johan's avatar
johan committed
96
 * @param[in,out]	associatedKey		Structure containing the key and ZID to identify the peer node to be updated
97
 * @param[in]		role			Can be LIME_SENDER or LIME_RECEIVER, specify which key we want to update
johan's avatar
johan committed
98
 * @param[in]		validityTimeSpan	If not 0, set the <valid> tag to now+validityTimeSpan (in seconds)
99 100 101
 *
 * @return 0 on success, error code otherwise
 */
102
LINPHONE_PUBLIC int lime_setCachedKey(void *cachedb, limeKey_t *associatedKey, uint8_t role, uint64_t validityTimeSpan);
103 104 105 106

/**
 * @brief Free all allocated data in the associated keys structure
 * Note, this will also free the peerURI string which then must have been allocated
107
 * This does not free the memory area pointed by associatedKeys.
108
 *
109
 * @param[in,out]	associatedKeys	The structure to be cleaned
110 111
 *
 */
112
LINPHONE_PUBLIC void lime_freeKeys(limeURIKeys_t *associatedKeys);
113 114 115

/**
 * @brief encrypt a message with the given key
116
 *
117
 * @param[in]	key					Key to use: first 192 bits are used as key, last 64 bits as init vector
118
 * @param[in]	plainMessage		The string to be encrypted
119 120 121 122 123 124
 * @param[in]	messageLength		The length in bytes of the message to be encrypted
 * @param[in]	selfZID				The self ZID is use in authentication tag computation
 * @param[out]	encryptedMessage	A buffer to hold the output, ouput length is input's one + 16 for the authentication tag
 * 									Authentication tag is set at the begining of the encrypted Message
 *
 * @return 0 on success, error code otherwise
125
 *
126
 */
Ghislain MARY's avatar
Ghislain MARY committed
127
LINPHONE_PUBLIC int lime_encryptMessage(limeKey_t *key, const uint8_t *plainMessage, uint32_t messageLength, uint8_t selfZID[12], uint8_t *encryptedMessage);
128 129 130

/**
 * @brief decrypt and authentify a message with the given key
131
 *
132
 * @param[in]	key					Key to use: first 192 bits are used as key, last 64 bits as init vector
133
 * @param[in]	encryptedMessage	The string to be decrypted
134 135 136 137 138 139
 * @param[in]	messageLength		The length in bytes of the message to be decrypted (this include the 16 bytes tag at the begining of the message)
 * @param[in]	selfZID				The self ZID is use in authentication tag computation
 * @param[out]	plainMessage		A buffer to hold the output, ouput length is input's one - 16 for the authentication tag + 1 for null termination char
 * 									Authentication tag is retrieved at the begining of the encrypted Message
 *
 * @return 0 on success, error code otherwise
140
 *
141 142
 */

143
LINPHONE_PUBLIC int lime_decryptMessage(limeKey_t *key, uint8_t *encryptedMessage, uint32_t messageLength, uint8_t selfZID[12], uint8_t *plainMessage);
144 145 146 147 148

/**
 * @brief create the encrypted multipart xml message from plain text and destination URI
 * Retrieve in cache the needed keys which are then updated. Output buffer is allocated and must be freed by caller
 *
149 150
 * @param[in,out]	cachedb			Pointer to the sqlite DB holding zrtp/lime cache, get the keys and selfZID from it, updated by this function with derivated keys
 * @param[in]		content_type		The content type of the message to encrypt
Ghislain MARY's avatar
Ghislain MARY committed
151
 * @param[in]		message			The message content to be encrypted
152
 * @param[in]		selfURI			The source URI
153 154 155 156 157
 * @param[in]		peerURI			The destination URI, associated keys will be found in cache
 * @param[out]		output			The output buffer, allocated and set with the encrypted message xml body(null terminated string). Must be freed by caller
 *
 * @return 	0 on success, error code otherwise
 */
158
LINPHONE_PUBLIC int lime_createMultipartMessage(void *cachedb, const char *contentType, uint8_t *message, const char *selfURI, const char *peerURI, uint8_t **output);
159 160 161 162 163

/**
 * @brief decrypt a multipart xml message
 * Retrieve in cache the needed key which is then updated. Output buffer is allocated and must be freed by caller
 *
164
 * @param[in,out]	cachedb			Pointer to the sqlite DB holding zrtp/lime cache, get the keys and selfZID from it, updated by this function with derivated keys
165
 * @param[in]		message			The multipart message, contain one or several part identified by destination ZID, one shall match the self ZID retrieved from cache
166 167
 * @param[in]		selfURI			The source URI
 * @param[in]		peerURI			The destination URI, associated keys will be found in cache
168
 * @param[out]		output			The output buffer, allocated and set with the decrypted message(null terminated string). Must be freed by caller
Ghislain MARY's avatar
Ghislain MARY committed
169
 * @param[out]		content_type	The content type of the decrypted message
johan's avatar
johan committed
170
 * @param[in]		validityTimeSpan	If not 0, update the <valid> tag associated to sender to now+validityTimeSpan (in seconds)
171 172
 * @return 	0 on success, error code otherwise
 */
173
LINPHONE_PUBLIC int lime_decryptMultipartMessage(void *cachedb, uint8_t *message, const char *selfURI, const char *peerURI, uint8_t **output, char **content_type, uint64_t validityTimeSpan);
174 175 176 177 178 179

/**
 * @brief given a readable version of error code generated by Lime functions
 * @param[in]	errorCode	The error code
 * @return a string containing the error description
 */
180
LINPHONE_PUBLIC const char *lime_error_code_to_string(int errorCode);
181

182 183 184 185 186
/**
 * @brief Check if Lime was enabled at build time
 *
 * @return TRUE if Lime is available, FALSE if not
 */
187
LINPHONE_PUBLIC bool_t lime_is_available(void);
188

189
int lime_im_encryption_engine_process_incoming_message_cb(LinphoneImEncryptionEngine *engine, LinphoneChatRoom *room, LinphoneChatMessage *msg);
190

191
int lime_im_encryption_engine_process_outgoing_message_cb(LinphoneImEncryptionEngine *engine, LinphoneChatRoom *room, LinphoneChatMessage *msg);
192

193
int lime_im_encryption_engine_process_downloading_file_cb(LinphoneImEncryptionEngine *engine, LinphoneChatMessage *msg, size_t offset, const uint8_t *buffer, size_t size, uint8_t *decrypted_buffer);
194

195
int lime_im_encryption_engine_process_uploading_file_cb(LinphoneImEncryptionEngine *engine, LinphoneChatMessage *msg, size_t offset, const uint8_t *buffer, size_t *size, uint8_t *encrypted_buffer);
196

197
bool_t lime_im_encryption_engine_is_file_encryption_enabled_cb(LinphoneImEncryptionEngine *engine, LinphoneChatRoom *room);
198

199
void lime_im_encryption_engine_generate_file_transfer_key_cb(LinphoneImEncryptionEngine *engine, LinphoneChatRoom *room, LinphoneChatMessage *msg);
200

201 202 203 204
#ifdef __cplusplus
}
#endif

205
#endif /* LIME_H */
206