1 /* 2 linphone 3 Copyright (C) 2015 Belledonne Communications SARL 4 5 This program is free software; you can redistribute it and/or 6 modify it under the terms of the GNU General Public License 7 as published by the Free Software Foundation; either version 2 8 of the License, or (at your option) any later version. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 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 #ifndef LIME_H 21 #define LIME_H 22 23 #define LIME_INVALID_CACHE 0x1001 24 #define LIME_UNABLE_TO_DERIVE_KEY 0x1002 25 #define LIME_UNABLE_TO_ENCRYPT_MESSAGE 0x1004 26 #define LIME_UNABLE_TO_DECRYPT_MESSAGE 0x1008 27 #define LIME_NO_VALID_KEY_FOUND_FOR_PEER 0x1010 28 #define LIME_INVALID_ENCRYPTED_MESSAGE 0x1020 29 #define LIME_PEER_KEY_HAS_EXPIRED 0x1040 30 #define LIME_NOT_ENABLED 0x1100 31 32 /* this define the maximum key derivation number allowed to get the caches back in sync in case of missed messages */ 33 #define MAX_DERIVATION_NUMBER 100 34 35 #define LIME_SENDER 0x01 36 #define LIME_RECEIVER 0x02 37 #include <stdint.h> 38 #include <libxml/tree.h> 39 #include <libxml/parser.h> 40 #include <libxml/xmlwriter.h> 41 42 #include "linphone/core.h" 43 #include <mediastreamer2/mscommon.h> 44 45 /** 46 * @brief Structure holding all needed material to encrypt/decrypt Messages */ 47 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 uint8_t key[32]; /**< a 256 bit key used to encrypt/decrypt message */ 50 uint8_t sessionId[32]; /**< a session id used to derive key */ 51 uint32_t sessionIndex; /**< an index to count number of derivation */ 52 uint8_t peerZID[12]; /**< the ZID associated to this key */ 53 } limeKey_t; 54 55 /** 56 * @brief Store the differents keys associated to a sipURI */ 57 typedef struct limeURIKeys_struct { 58 limeKey_t **peerKeys; /**< an array of all the key material associated to each ZID matching the specified URI */ 59 uint16_t associatedZIDNumber; /**< previous array length */ 60 char *peerURI; /**< the peer sip URI associated to all the keys, must be a null terminated string */ 61 char *selfURI; /**< the local sip URI used to send messages, must be a null terminated string */ 62 } limeURIKeys_t; 63 64 /** 65 * @brief Get from cache all the senders keys associated to the given URI 66 * peerKeys field from associatedKeys param must be NULL when calling this function. 67 * Structure content must then be freed using lime_freeKeys function 68 * 69 * @param[in] cachedb Pointer to the sqlite3 DB 70 * @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 71 * 72 * @return 0 on success(at least one valid key found), error code otherwise 73 */ 74 LINPHONE_PUBLIC int lime_getCachedSndKeysByURI(void *cachedb, limeURIKeys_t *associatedKeys); 75 76 /** 77 * @brief Get the receiver key associated to the ZID given in the associatedKey parameter 78 * 79 * @param[in] cachedb Pointer to the sqlite3 DB 80 * @param[in,out] associatedKey Structure containing the peerZID and will store the retrieved key 81 * @param[in] selfURI The source URI 82 * @param[in] peerURI The destination URI 83 * 84 * @return 0 on success, error code otherwise 85 */ 86 LINPHONE_PUBLIC int lime_getCachedRcvKeyByZid(void *cachedb, limeKey_t *associatedKey, const char *selfURI, const char *peerURI); 87 88 /** 89 * @brief Set in cache the given key material, association is made by ZID contained in the associatedKey parameter 90 * 91 * @param[in/out] cachedb Pointer to the sqlite3 DB 92 * @param[in,out] associatedKey Structure containing the key and ZID to identify the peer node to be updated 93 * @param[in] role Can be LIME_SENDER or LIME_RECEIVER, specify which key we want to update 94 * @param[in] validityTimeSpan If not 0, set the <valid> tag to now+validityTimeSpan (in seconds) 95 * 96 * @return 0 on success, error code otherwise 97 */ 98 LINPHONE_PUBLIC int lime_setCachedKey(void *cachedb, limeKey_t *associatedKey, uint8_t role, uint64_t validityTimeSpan); 99 100 /** 101 * @brief Free all allocated data in the associated keys structure 102 * Note, this will also free the peerURI string which then must have been allocated 103 * This does not free the memory area pointed by associatedKeys. 104 * 105 * @param[in,out] associatedKeys The structure to be cleaned 106 * 107 */ 108 LINPHONE_PUBLIC void lime_freeKeys(limeURIKeys_t *associatedKeys); 109 110 /** 111 * @brief encrypt a message with the given key 112 * 113 * @param[in] key Key to use: first 192 bits are used as key, last 64 bits as init vector 114 * @param[in] plainMessage The string to be encrypted 115 * @param[in] messageLength The length in bytes of the message to be encrypted 116 * @param[in] selfZID The self ZID is use in authentication tag computation 117 * @param[out] encryptedMessage A buffer to hold the output, ouput length is input's one + 16 for the authentication tag 118 * Authentication tag is set at the begining of the encrypted Message 119 * 120 * @return 0 on success, error code otherwise 121 * 122 */ 123 LINPHONE_PUBLIC int lime_encryptMessage(limeKey_t *key, const uint8_t *plainMessage, uint32_t messageLength, uint8_t selfZID[12], uint8_t *encryptedMessage); 124 125 /** 126 * @brief Encrypt a file before transfering it to the server, encryption is done in several call, first one will be done with cryptoContext null, last one with length = 0 127 * 128 * @param[in,out] cryptoContext The context used to encrypt the file using AES-GCM. Is created at first call(if null) 129 * @param[in] key 256 bits : 192 bits of key || 64 bits of Initial Vector 130 * @param[in] length Length of data to be encrypted, if 0 it will conclude the encryption 131 * @param[in] plain Plain data to be encrypted (length bytes) 132 * @param[out] cipher Output to a buffer allocated by caller, at least length bytes available 133 * 134 * @return 0 on success, error code otherwise 135 * 136 */ 137 LINPHONE_PUBLIC int lime_encryptFile(void **cryptoContext, unsigned char *key, size_t length, char *plain, char *cipher); 138 139 /** 140 * @brief Decrypt a file retrieved from server, decryption is done in several call, first one will be done with cryptoContext null, last one with length = 0 141 * 142 * @param[in,out] cryptoContext The context used to decrypt the file using AES-GCM. Is created at first call(if null) 143 * @param[in] key 256 bits : 192 bits of key || 64 bits of Initial Vector 144 * @param[in] length Length of data to be decrypted, if 0 it will conclude the decryption 145 * @param[out] plain Output to a buffer allocated by caller, at least length bytes available 146 * @param[in] cipher Cipher text to be decrypted(length bytes) 147 * 148 * @return 0 on success, error code otherwise 149 * 150 */ 151 LINPHONE_PUBLIC int lime_decryptFile(void **cryptoContext, unsigned char *key, size_t length, char *plain, char *cipher); 152 153 /** 154 * @brief decrypt and authentify a message with the given key 155 * 156 * @param[in] key Key to use: first 192 bits are used as key, last 64 bits as init vector 157 * @param[in] encryptedMessage The string to be decrypted 158 * @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) 159 * @param[in] selfZID The self ZID is use in authentication tag computation 160 * @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 161 * Authentication tag is retrieved at the begining of the encrypted Message 162 * 163 * @return 0 on success, error code otherwise 164 * 165 */ 166 167 LINPHONE_PUBLIC int lime_decryptMessage(limeKey_t *key, uint8_t *encryptedMessage, uint32_t messageLength, uint8_t selfZID[12], uint8_t *plainMessage); 168 169 /** 170 * @brief create the encrypted multipart xml message from plain text and destination URI 171 * Retrieve in cache the needed keys which are then updated. Output buffer is allocated and must be freed by caller 172 * 173 * @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 174 * @param[in] content_type The content type of the message to encrypt 175 * @param[in] message The message content to be encrypted 176 * @param[in] selfURI The source URI 177 * @param[in] peerURI The destination URI, associated keys will be found in cache 178 * @param[out] output The output buffer, allocated and set with the encrypted message xml body(null terminated string). Must be freed by caller 179 * 180 * @return 0 on success, error code otherwise 181 */ 182 LINPHONE_PUBLIC int lime_createMultipartMessage(void *cachedb, const char *contentType, uint8_t *message, const char *selfURI, const char *peerURI, uint8_t **output); 183 184 /** 185 * @brief decrypt a multipart xml message 186 * Retrieve in cache the needed key which is then updated. Output buffer is allocated and must be freed by caller 187 * 188 * @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 189 * @param[in] message The multipart message, contain one or several part identified by destination ZID, one shall match the self ZID retrieved from cache 190 * @param[in] selfURI The source URI 191 * @param[in] peerURI The destination URI, associated keys will be found in cache 192 * @param[out] output The output buffer, allocated and set with the decrypted message(null terminated string). Must be freed by caller 193 * @param[out] content_type The content type of the decrypted message 194 * @param[in] validityTimeSpan If not 0, update the <valid> tag associated to sender to now+validityTimeSpan (in seconds) 195 * @return 0 on success, error code otherwise 196 */ 197 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); 198 199 /** 200 * @brief given a readable version of error code generated by Lime functions 201 * @param[in] errorCode The error code 202 * @return a string containing the error description 203 */ 204 LINPHONE_PUBLIC char *lime_error_code_to_string(int errorCode); 205 206 /** 207 * @brief Check if Lime was enabled at build time 208 * 209 * @return TRUE if Lime is available, FALSE if not 210 */ 211 LINPHONE_PUBLIC bool_t lime_is_available(void); 212 213 int lime_im_encryption_engine_process_incoming_message_cb(LinphoneImEncryptionEngine *engine, LinphoneChatRoom *room, LinphoneChatMessage *msg); 214 215 int lime_im_encryption_engine_process_outgoing_message_cb(LinphoneImEncryptionEngine *engine, LinphoneChatRoom *room, LinphoneChatMessage *msg); 216 217 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); 218 219 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); 220 221 bool_t lime_im_encryption_engine_is_file_encryption_enabled_cb(LinphoneImEncryptionEngine *engine, LinphoneChatRoom *room); 222 223 void lime_im_encryption_engine_generate_file_transfer_key_cb(LinphoneImEncryptionEngine *engine, LinphoneChatRoom *room, LinphoneChatMessage *msg); 224 225 #endif /* LIME_H */ 226