Added process outgoing message for im encryption engine

This commit is contained in:
Sylvain Berfini 2016-11-04 15:35:59 +01:00
parent 2c905e4cde
commit 47c08783af
6 changed files with 89 additions and 54 deletions

View file

@ -100,7 +100,7 @@ void sal_process_incoming_message(SalOp *op,const belle_sip_request_event_t *eve
bool_t cipher_xml=FALSE;
bool_t rcs_filetransfer=FALSE;
uint8_t *decryptedMessage = NULL;
LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op));
LinphoneCore *lc = (LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op));
int retval = -1;
from_header=belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(req),belle_sip_header_from_t);
@ -206,7 +206,9 @@ int sal_message_send(SalOp *op, const char *from, const char *to, const char* co
time_t curtime = ms_time(NULL);
uint8_t *multipartEncryptedMessage = NULL;
const char *body;
int retval;
int retval = -1;
LinphoneCore *lc = (LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op));
LinphoneImEncryptionEngine *imee = linphone_core_get_im_encryption_engine(lc);
if (op->dialog){
/*for SIP MESSAGE that are sent in call's dialog*/
@ -228,59 +230,19 @@ int sal_message_send(SalOp *op, const char *from, const char *to, const char* co
}
}
/* shall we try to encrypt the message?*/
if ((strcmp(content_type, "xml/cipher") == 0) || ((strcmp(content_type, "application/cipher.vnd.gsma.rcs-ft-http+xml") == 0))) {
/* access the zrtp cache to get keys needed to cipher the message */
LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op));
FILE *CACHEFD = fopen(lc->zrtp_secrets_cache, "rb+");
if (CACHEFD == NULL) {
ms_warning("Unable to access ZRTP ZID cache to encrypt message");
/*probably not a good idea to do this:*/
sal_error_info_set(&op->error_info, SalReasonNotAcceptable, 488, "Unable to encrypt IM", NULL);
op->base.root->callbacks.text_delivery_update(op,SalTextDeliveryFailed);
return -1;
} else {
size_t cacheSize;
char *cacheString;
xmlDocPtr cacheXml;
int retval;
cacheString=ms_load_file_content(CACHEFD, &cacheSize);
if (!cacheString){
ms_warning("Unable to load content of ZRTP ZID cache to encrypt message");
return -1;
}
cacheString[cacheSize] = '\0';
cacheSize += 1;
fclose(CACHEFD);
cacheXml = xmlParseDoc((xmlChar*)cacheString);
ms_free(cacheString);
retval = lime_createMultipartMessage(cacheXml, (uint8_t *)msg, (uint8_t *)peer_uri, &multipartEncryptedMessage);
if (retval != 0) {
ms_warning("Unable to encrypt message for %s : %s - op [%p]", peer_uri, lime_error_code_to_string(retval), op);
xmlFreeDoc(cacheXml);
free(multipartEncryptedMessage);
/*probably not a good idea to do this:*/
sal_error_info_set(&op->error_info, SalReasonNotAcceptable, 488, "Unable to encrypt IM", NULL);
op->base.root->callbacks.text_delivery_update(op,SalTextDeliveryFailed);
return -1;
} else {
/* dump updated cache to a string */
xmlChar *xmlStringOutput;
int xmlStringLength;
xmlDocDumpFormatMemoryEnc(cacheXml, &xmlStringOutput, &xmlStringLength, "UTF-8", 0);
/* write it to the cache file */
CACHEFD = fopen(lc->zrtp_secrets_cache, "wb+");
if (fwrite(xmlStringOutput, 1, xmlStringLength, CACHEFD)<=0){
ms_warning("Unable to write zid cache");
}
xmlFree(xmlStringOutput);
fclose(CACHEFD);
content_length = strlen((const char *)multipartEncryptedMessage);
}
xmlFreeDoc(cacheXml);
if (imee) {
LinphoneImEncryptionEngineCbs *imee_cbs = linphone_im_encryption_engine_get_callbacks(imee);
LinphoneImEncryptionEngineOutgoingMessageCb cb_process_outgoing_message = linphone_im_encryption_engine_cbs_get_process_outgoing_message(imee_cbs);
if (cb_process_outgoing_message) {
retval = cb_process_outgoing_message(lc, peer_uri, content_type, msg, (char **)&multipartEncryptedMessage, &content_length);
}
}
if (retval > 0) {
/*probably not a good idea to do this:*/
sal_error_info_set(&op->error_info, SalReasonNotAcceptable, retval, "Unable to encrypt IM", NULL);
op->base.root->callbacks.text_delivery_update(op, SalTextDeliveryFailed);
return -1;
}
snprintf(content_type_raw,sizeof(content_type_raw),BELLE_SIP_CONTENT_TYPE ": %s",content_type);
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(belle_sip_header_content_type_parse(content_type_raw)));

View file

@ -23,6 +23,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
struct _LinphoneImEncryptionEngineCbs {
void *user_data;
LinphoneImEncryptionEngineIncomingMessageCb process_incoming_message;
LinphoneImEncryptionEngineOutgoingMessageCb process_outgoing_message;
};
struct _LinphoneImEncryptionEngine {
@ -68,4 +69,12 @@ LinphoneImEncryptionEngineIncomingMessageCb linphone_im_encryption_engine_cbs_ge
void linphone_im_encryption_engine_cbs_set_process_incoming_message(LinphoneImEncryptionEngineCbs *cbs, LinphoneImEncryptionEngineIncomingMessageCb cb) {
cbs->process_incoming_message = cb;
}
LinphoneImEncryptionEngineOutgoingMessageCb linphone_im_encryption_engine_cbs_get_process_outgoing_message(LinphoneImEncryptionEngineCbs *cbs) {
return cbs->process_outgoing_message;
}
void linphone_im_encryption_engine_cbs_set_process_outgoing_message(LinphoneImEncryptionEngineCbs *cbs, LinphoneImEncryptionEngineOutgoingMessageCb cb) {
cbs->process_outgoing_message = cb;
}

View file

@ -28,6 +28,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
typedef int (*LinphoneImEncryptionEngineIncomingMessageCb)(LinphoneCore* lc, const char* content_type, const char* content_subtype, const char* body, char** decrypted_body);
typedef int (*LinphoneImEncryptionEngineOutgoingMessageCb)(LinphoneCore* lc, const char *peer_uri, const char* content_type, const char* body, char** crypted_body, size_t* content_length);
typedef struct _LinphoneImEncryptionEngineCbs LinphoneImEncryptionEngineCbs;
typedef struct _LinphoneImEncryptionEngine LinphoneImEncryptionEngine;
@ -50,4 +52,8 @@ LINPHONE_PUBLIC LinphoneImEncryptionEngineIncomingMessageCb linphone_im_encrypti
LINPHONE_PUBLIC void linphone_im_encryption_engine_cbs_set_process_incoming_message(LinphoneImEncryptionEngineCbs *cbs, LinphoneImEncryptionEngineIncomingMessageCb cb);
LINPHONE_PUBLIC LinphoneImEncryptionEngineOutgoingMessageCb linphone_im_encryption_engine_cbs_get_process_outgoing_message(LinphoneImEncryptionEngineCbs *cbs);
LINPHONE_PUBLIC void linphone_im_encryption_engine_cbs_set_process_outgoing_message(LinphoneImEncryptionEngineCbs *cbs, LinphoneImEncryptionEngineOutgoingMessageCb cb);
#endif /* IM_ENCRYPTION_ENGINE_H */

View file

@ -851,7 +851,7 @@ int lime_im_encryption_engine_process_incoming_message_cb(LinphoneCore* lc, cons
retval = lime_decryptMultipartMessage(cacheXml, (uint8_t *)body, (uint8_t **)decrypted_body);
if (retval != 0) {
ms_warning("Unable to decrypt message, reason : %s", lime_error_code_to_string(retval));
free(decrypted_body);
if (*decrypted_body) free(*decrypted_body);
xmlFreeDoc(cacheXml);
errcode = 488;
return errcode;
@ -875,6 +875,58 @@ int lime_im_encryption_engine_process_incoming_message_cb(LinphoneCore* lc, cons
return errcode;
}
int lime_im_encryption_engine_process_outgoing_message_cb(LinphoneCore* lc, const char *peer_uri, const char* content_type, const char* body, char** crypted_body, size_t* content_length) {
int errcode = -1;
/* shall we try to encrypt the message?*/
if ((strcmp(content_type, "xml/cipher") == 0) || ((strcmp(content_type, "application/cipher.vnd.gsma.rcs-ft-http+xml") == 0))) {
/* access the zrtp cache to get keys needed to cipher the message */
const char *zrtp_secrets_cache = linphone_core_get_zrtp_secrets_file(lc);
FILE *CACHEFD = fopen(zrtp_secrets_cache, "rb+");
errcode = 0;
if (CACHEFD == NULL) {
ms_warning("Unable to access ZRTP ZID cache to encrypt message");
errcode = 488;
} else {
size_t cacheSize;
char *cacheString;
xmlDocPtr cacheXml;
int retval;
cacheString=ms_load_file_content(CACHEFD, &cacheSize);
if (!cacheString){
ms_warning("Unable to load content of ZRTP ZID cache to encrypt message");
errcode = 500;
return errcode;
}
cacheString[cacheSize] = '\0';
cacheSize += 1;
fclose(CACHEFD);
cacheXml = xmlParseDoc((xmlChar*)cacheString);
ms_free(cacheString);
retval = lime_createMultipartMessage(cacheXml, (uint8_t *)body, (uint8_t *)peer_uri, (uint8_t **)crypted_body);
if (retval != 0) {
ms_warning("Unable to encrypt message for %s : %s", peer_uri, lime_error_code_to_string(retval));
if (*crypted_body) free(*crypted_body);
errcode = 488;
} else {
/* dump updated cache to a string */
xmlChar *xmlStringOutput;
int xmlStringLength;
xmlDocDumpFormatMemoryEnc(cacheXml, &xmlStringOutput, &xmlStringLength, "UTF-8", 0);
/* write it to the cache file */
CACHEFD = fopen(zrtp_secrets_cache, "wb+");
if (fwrite(xmlStringOutput, 1, xmlStringLength, CACHEFD)<=0){
ms_warning("Unable to write zid cache");
}
xmlFree(xmlStringOutput);
fclose(CACHEFD);
*content_length = strlen((const char *)*crypted_body);
}
xmlFreeDoc(cacheXml);
}
}
return errcode;
}
#else /* HAVE_LIME */
@ -903,6 +955,9 @@ int lime_decryptMessage(limeKey_t *key, uint8_t *encryptedMessage, uint32_t mess
int lime_im_encryption_engine_process_incoming_message_cb(LinphoneCore* lc, const char* content_type, const char* content_subtype, const char* body, char** decrypted_body) {
return 500;
}
int lime_im_encryption_engine_process_outgoing_message_cb(LinphoneCore* lc, const char *peer_uri, const char* content_type, const char* body, char** crypted_body, size_t* content_length) {
return 500;
}
#endif /* HAVE_LIME */
char *lime_error_code_to_string(int errorCode) {

View file

@ -207,4 +207,6 @@ LINPHONE_PUBLIC bool_t lime_is_available(void);
int lime_im_encryption_engine_process_incoming_message_cb(LinphoneCore* lc, const char* content_type, const char* content_subtype, const char* body, char** decrypted_body);
int lime_im_encryption_engine_process_outgoing_message_cb(LinphoneCore* lc, const char *peer_uri, const char* content_type, const char* body, char** crypted_body, size_t* content_length);
#endif /* LIME_H */

View file

@ -1955,6 +1955,7 @@ void linphone_core_enable_lime(LinphoneCore *lc, LinphoneLimeState val){
LinphoneImEncryptionEngine *imee = linphone_im_encryption_engine_new();
LinphoneImEncryptionEngineCbs *cbs = linphone_im_encryption_engine_get_callbacks(imee);
linphone_im_encryption_engine_cbs_set_process_incoming_message(cbs, lime_im_encryption_engine_process_incoming_message_cb);
linphone_im_encryption_engine_cbs_set_process_outgoing_message(cbs, lime_im_encryption_engine_process_outgoing_message_cb);
lc->im_encryption_engine = imee;
} else {
if (lc->im_encryption_engine) {