Commit fa20bae3 authored by Simon Morlat's avatar Simon Morlat

clean API

- loadCache should not assume the buffer is allocated with malloc. Instead, a function to call for freeing the buffer is to be passed.
- replace setCallback() by setCallbacks() so that strong type checking is performed on the supplied callbacks.
parent 6f723936
bzrtp-1.0.0 - Thursday, March 5th 2015
* first official release of bzrtp
......@@ -3,7 +3,7 @@
AC_INIT([bzrtp],[0.1])
AC_INIT([bzrtp],[1.0.0])
AC_PREREQ(2.63)
AC_CONFIG_SRCDIR([src/bzrtp.c])
AC_CONFIG_AUX_DIR([build-aux])
......
......@@ -103,6 +103,29 @@ typedef struct bzrtpSrtpSecrets_struct {
uint8_t sasLength; /**< The length of sas, including the termination character */
} bzrtpSrtpSecrets_t;
/**
* Function pointer used by bzrtp to free memory allocated by callbacks.
**/
typedef void (*zrtpFreeBuffer_callback)(void *);
/**
* @brief All the callback functions provided by the client needed by the ZRTP engine
*/
typedef struct bzrtpCallbacks_struct {
/* cache related functions */
int (* bzrtp_loadCache)(void *clientData, uint8_t **cacheBuffer, uint32_t *cacheBufferSize, zrtpFreeBuffer_callback *callback); /**< Cache related function : load the whole cache file in a buffer allocated by the function, return the buffer and its size in bytes */
int (* bzrtp_writeCache)(void *clientData, const uint8_t *input, uint32_t size); /**< Cache related function : write size bytes to cache */
/* sending packets */
int (* bzrtp_sendData)(void *clientData, const uint8_t *packetString, uint16_t packetLength); /**< Send a ZRTP packet to peer. Shall return 0 on success */
/* dealing with SRTP session */
int (* bzrtp_srtpSecretsAvailable)(void *clientData, bzrtpSrtpSecrets_t *srtpSecrets, uint8_t part); /**< Send the srtp secrets to the client, for either sender, receiver or both according to the part parameter value. Client may wait for the end of ZRTP process before using it */
int (* bzrtp_startSrtpSession)(void *clientData, const char* sas, int32_t verified); /**< ZRTP process ended well, client is given the SAS and may start his SRTP session if not done when calling srtpSecretsAvailable */
/* ready for exported keys */
int (* bzrtp_contextReadyForExportedKeys)(void *clientData, uint8_t peerZID[12], uint8_t role); /**< Tell the client that this is the time to create and store in cache any exported keys, client is given the peerZID to adress the correct node in cache and current role which is needed to set a pair of keys for IM encryption */
} bzrtpCallbacks_t;
#define ZRTP_MAGIC_COOKIE 0x5a525450
#define ZRTP_VERSION "1.10"
/*#define ZRTP_CLIENT_IDENTIFIER "LINPHONEZRTP0.01"*/
......@@ -148,22 +171,15 @@ BZRTP_EXPORT void bzrtp_initBzrtpContext(bzrtpContext_t *context);
*/
BZRTP_EXPORT void bzrtp_destroyBzrtpContext(bzrtpContext_t *context, uint32_t selfSSRC);
#define ZRTP_CALLBACK_LOADCACHE 0x0101
#define ZRTP_CALLBACK_WRITECACHE 0x0102
#define ZRTP_CALLBACK_SENDDATA 0x0110
#define ZRTP_CALLBACK_SRTPSECRETSAVAILABLE 0x0120
#define ZRTP_CALLBACK_STARTSRTPSESSION 0x0140
#define ZRTP_CALLBACK_CONTEXTREADYFOREXPORTEDKEYS 0x0180
/**
* @brief Allocate a function pointer to the callback function identified by his id
* @param[in/out] context The zrtp context to set the callback function
* @param[in] functionPointer The pointer to the function to bind as callback.
* @param[in] functionID The ID as defined above to identify which callback to be set.
* @param[in] cbs A structure containing all the callbacks to supply.
*
* @return 0 on success
*
*/
BZRTP_EXPORT int bzrtp_setCallback(bzrtpContext_t *context, int (*functionPointer)(), uint16_t functionID);
BZRTP_EXPORT int bzrtp_setCallbacks(bzrtpContext_t *context, const bzrtpCallbacks_t *cbs);
/**
* @brief Set the client data pointer in a channel context
......
......@@ -103,24 +103,6 @@ typedef struct cachedSecretsHash_struct {
uint8_t pbxsecretID[8]; /**< pbx secret Hash */
} cachedSecretsHash_t;
/**
* @brief All the callback functions provided by the client needed by the ZRTP engine
*/
typedef struct zrtpCallbacks_struct {
/* cache related functions */
int (* bzrtp_loadCache)(void *clientData, uint8_t **cacheBuffer, uint32_t *cacheBufferSize); /**< Cache related function : load the whole cache file in a buffer allocated by the function, return the buffer and its size in bytes */
int (* bzrtp_writeCache)(void *clientData, uint8_t *input, uint32_t size); /**< Cache related function : write size bytes to cache */
/* sending packets */
int (* bzrtp_sendData)(void *clientData, uint8_t *packetString, uint16_t packetLength); /**< Send a ZRTP packet to peer. Shall return 0 on success */
/* dealing with SRTP session */
int (* bzrtp_srtpSecretsAvailable)(void *clientData, bzrtpSrtpSecrets_t *srtpSecrets, uint8_t part); /**< Send the srtp secrets to the client, for either sender, receiver or both according to the part parameter value. Client may wait for the end of ZRTP process before using it */
int (* bzrtp_startSrtpSession)(void *clientData, char* sas, int32_t verified); /**< ZRTP process ended well, client is given the SAS and may start his SRTP session if not done when calling srtpSecretsAvailable */
/* ready for exported keys */
int (* bzrtp_contextReadyForExportedKeys)(void *clientData, uint8_t peerZID[12], uint8_t role); /**< Tell the client that this is the time to create and store in cache any exported keys, client is given the peerZID to adress the correct node in cache and current role which is needed to set a pair of keys for IM encryption */
} zrtpCallbacks_t;
/**
* @brief The zrtp context of a channel
......@@ -204,7 +186,7 @@ struct bzrtpContext_struct {
uint64_t timeReference; /**< in ms. This field will set at each channel State Machine start and updated at each tick after creation of the context, it is used to set the firing time of a channel timer */
/* callbacks */
zrtpCallbacks_t zrtpCallbacks; /**< structure holding all the pointers to callbacks functions needed by the ZRTP engine. Functions are set by client using the bzrtp_setCallback function */
bzrtpCallbacks_t zrtpCallbacks; /**< structure holding all the pointers to callbacks functions needed by the ZRTP engine. Functions are set by client using the bzrtp_setCallback function */
/* channel contexts */
bzrtpChannelContext_t *channelContext[ZRTP_MAX_CHANNEL_NUMBER]; /**< All the context data needed for a channel are stored in a dedicated structure */
......
......@@ -186,37 +186,9 @@ void bzrtp_destroyBzrtpContext(bzrtpContext_t *context, uint32_t selfSSRC) {
return;
}
/**
* @brief Allocate a function pointer to the callback function identified by his id
* @param[in] functionPointer The pointer to the function to bind as callback.
* @param[in] functionID The ID as defined above to identify which callback to be set.
*
* @return 0 on success
*
*/
int bzrtp_setCallback(bzrtpContext_t *context, int (*functionPointer)(), uint16_t functionID) {
switch (functionID) {
case ZRTP_CALLBACK_LOADCACHE:
context->zrtpCallbacks.bzrtp_loadCache = (int (*)(void *, uint8_t **, uint32_t *))functionPointer;
break;
case ZRTP_CALLBACK_WRITECACHE:
context->zrtpCallbacks.bzrtp_writeCache = (int (*)(void *, uint8_t *, uint32_t))functionPointer;
break;
case ZRTP_CALLBACK_SENDDATA:
context->zrtpCallbacks.bzrtp_sendData = (int (*)(void *, uint8_t *, uint16_t))functionPointer;
break;
case ZRTP_CALLBACK_SRTPSECRETSAVAILABLE:
context->zrtpCallbacks.bzrtp_srtpSecretsAvailable = (int (*)(void *, bzrtpSrtpSecrets_t *, uint8_t))functionPointer;
break;
case ZRTP_CALLBACK_STARTSRTPSESSION:
context->zrtpCallbacks.bzrtp_startSrtpSession = (int (*)(void *, char*, int32_t))functionPointer;
break;
case ZRTP_CALLBACK_CONTEXTREADYFOREXPORTEDKEYS:
context->zrtpCallbacks.bzrtp_contextReadyForExportedKeys = (int (*)(void *, uint8_t *, uint8_t))functionPointer;
default:
return BZRTP_ERROR_INVALIDCALLBACKID;
break;
}
int bzrtp_setCallbacks(bzrtpContext_t *context, const bzrtpCallbacks_t *cbs) {
context->zrtpCallbacks=*cbs;
return 0;
}
......
......@@ -55,9 +55,10 @@ int bzrtp_getSelfZID(bzrtpContext_t *context, uint8_t selfZID[12]) {
if (context->zrtpCallbacks.bzrtp_loadCache != NULL) {
uint8_t *cacheStringBuffer;
uint32_t cacheStringLength;
context->zrtpCallbacks.bzrtp_loadCache(context->channelContext[0]->clientData, &cacheStringBuffer, &cacheStringLength);
zrtpFreeBuffer_callback cb=NULL;
context->zrtpCallbacks.bzrtp_loadCache(context->channelContext[0]->clientData, &cacheStringBuffer, &cacheStringLength, &cb);
context->cacheBuffer = xmlParseDoc(cacheStringBuffer);
free(cacheStringBuffer);
if (cb!=NULL) cb(cacheStringBuffer);
} else {
/* we are running cacheless, return a random number */
bzrtpCrypto_getRandom(context->RNGContext, selfZID, 12);
......@@ -245,13 +246,14 @@ int bzrtp_writePeerNode(bzrtpContext_t *context, uint8_t peerZID[12], uint8_t *t
if ((fileFlag&BZRTP_CACHE_LOADFILEBIT) == BZRTP_CACHE_LOADFILE) { /* we must reload the cache from file */
uint8_t *cacheStringBuffer;
uint32_t cacheStringLength;
zrtpFreeBuffer_callback cb=NULL;
/* reload cache from file locking it (TODO: lock) */
xmlFreeDoc(context->cacheBuffer);
context->cacheBuffer = NULL;
context->zrtpCallbacks.bzrtp_loadCache(context->channelContext[0]->clientData, &cacheStringBuffer, &cacheStringLength);
context->zrtpCallbacks.bzrtp_loadCache(context->channelContext[0]->clientData, &cacheStringBuffer, &cacheStringLength,&cb);
context->cacheBuffer = xmlParseDoc(cacheStringBuffer);
free(cacheStringBuffer);
if (cb) cb(cacheStringBuffer);
}
/* parse the cache to find the peer element matching the given ZID */
......
<?xml version="1.0" encoding="UTF-8"?>
<cache><selfZID>ef7692d0792a67491ae2d44e</selfZID><peer><ZID>005dbe0399643d953a2202dd</ZID><rs1>7d4fa5bcebbfa03ca2141036ba2c060f6ef76c62cfb6d1857f377a5f55c4182c</rs1><aux>f8324dd18ea905171ec2be89f879d01d5994132048d92ea020778cbdf31c605e</aux><rs2>99423ca64fd139a5352a571f31ecc65b3f15fd0c3bc39b710526752acb82819e</rs2></peer></cache>
<cache><selfZID>ef7692d0792a67491ae2d44e</selfZID><peer><ZID>005dbe0399643d953a2202dd</ZID><rs1>daacd1c76efa71c29a3630fc1e984ab2406e04aad1bfc042f98510d6558a68ff</rs1><aux>f8324dd18ea905171ec2be89f879d01d5994132048d92ea020778cbdf31c605e</aux><rs2>7d4fa5bcebbfa03ca2141036ba2c060f6ef76c62cfb6d1857f377a5f55c4182c</rs2><pvs>01</pvs></peer></cache>
<?xml version="1.0" encoding="UTF-8"?>
<cache><selfZID>005dbe0399643d953a2202dd</selfZID><peer><ZID>ef7692d0792a67491ae2d44e</ZID><rs1>7d4fa5bcebbfa03ca2141036ba2c060f6ef76c62cfb6d1857f377a5f55c4182c</rs1><aux>f8324dd18ea905171ec2be89f879d01d5994132048d92ea020778cbdf31c605e</aux><rs2>99423ca64fd139a5352a571f31ecc65b3f15fd0c3bc39b710526752acb82819e</rs2></peer></cache>
<cache><selfZID>005dbe0399643d953a2202dd</selfZID><peer><ZID>ef7692d0792a67491ae2d44e</ZID><rs1>daacd1c76efa71c29a3630fc1e984ab2406e04aad1bfc042f98510d6558a68ff</rs1><aux>f8324dd18ea905171ec2be89f879d01d5994132048d92ea020778cbdf31c605e</aux><rs2>7d4fa5bcebbfa03ca2141036ba2c060f6ef76c62cfb6d1857f377a5f55c4182c</rs2><pvs>01</pvs></peer></cache>
......@@ -220,7 +220,11 @@ typedef struct my_Context_struct {
char zidFilename[80]; /* nom du fichier de cache */
} my_Context_t;
int floadAlice(void *clientData, uint8_t **output, uint32_t *size) {
static void freeBuf(void* p){
free(p);
}
int floadAlice(void *clientData, uint8_t **output, uint32_t *size, zrtpFreeBuffer_callback *cb) {
/* get filename from ClientData */
my_Context_t *clientContext = (my_Context_t *)clientData;
char *filename = clientContext->zidFilename;
......@@ -235,10 +239,11 @@ int floadAlice(void *clientData, uint8_t **output, uint32_t *size) {
*(*output+*size) = '\0';
*size += 1;
fclose(ALICECACHE);
*cb=freeBuf;
return *size;
}
int fwriteAlice(void *clientData, uint8_t *input, uint32_t size) {
int fwriteAlice(void *clientData, const uint8_t *input, uint32_t size) {
/* get filename from ClientData */
my_Context_t *clientContext = (my_Context_t *)clientData;
char *filename = clientContext->zidFilename;
......@@ -249,7 +254,7 @@ int fwriteAlice(void *clientData, uint8_t *input, uint32_t size) {
return retval;
}
int floadBob(void *clientData, uint8_t **output, uint32_t *size) {
int floadBob(void *clientData, uint8_t **output, uint32_t *size, zrtpFreeBuffer_callback *cb) {
/* get filename from ClientData */
my_Context_t *clientContext = (my_Context_t *)clientData;
char *filename = clientContext->zidFilename;
......@@ -266,11 +271,12 @@ int floadBob(void *clientData, uint8_t **output, uint32_t *size) {
*(*output+*size) = '\0';
*size += 1;
fclose(BOBCACHE);
*cb=freeBuf;
return *size;
}
int fwriteBob(void *clientData, uint8_t *input, uint32_t size) {
int fwriteBob(void *clientData, const uint8_t *input, uint32_t size) {
/* get filename from ClientData */
my_Context_t *clientContext = (my_Context_t *)clientData;
char *filename = clientContext->zidFilename;
......@@ -338,6 +344,7 @@ void test_parserComplete() {
bzrtpConfirmMessage_t *alice_Confirm2FromBob_message=NULL;
bzrtpPacket_t *alice_Conf2ACK;
bzrtpPacket_t *bob_Conf2ACKFromAlice;
bzrtpCallbacks_t cbs={0};
/* Create the client context, used for zidFilename only */
my_Context_t clientContextAlice;
......@@ -350,11 +357,14 @@ void test_parserComplete() {
retval += bzrtp_setClientData(contextBob, 0x87654321, (void *)&clientContextBob);
/* set the cache related callback functions */
bzrtp_setCallback(contextAlice, (int (*)())floadAlice, ZRTP_CALLBACK_LOADCACHE);
bzrtp_setCallback(contextAlice, (int (*)())fwriteAlice, ZRTP_CALLBACK_WRITECACHE);
cbs.bzrtp_loadCache=floadAlice;
cbs.bzrtp_writeCache=fwriteAlice;
bzrtp_setCallbacks(contextAlice, &cbs);
bzrtp_setCallback(contextBob, (int (*)())floadBob, ZRTP_CALLBACK_LOADCACHE);
bzrtp_setCallback(contextBob, (int (*)())fwriteBob, ZRTP_CALLBACK_WRITECACHE);
cbs.bzrtp_loadCache=floadBob;
cbs.bzrtp_writeCache=fwriteBob;
bzrtp_setCallbacks(contextBob, &cbs);
printf ("Init the contexts\n");
/* end the context init */
......@@ -1539,7 +1549,7 @@ uint8_t block_Hello = 0;
/* this is a callback function for send data, just dump the packet */
/* client Data is a my_Context_t structure */
int bzrtp_sendData(void *clientData, uint8_t *packetString, uint16_t packetLength) {
int bzrtp_sendData(void *clientData, const uint8_t *packetString, uint16_t packetLength) {
/* get the client Data */
my_Context_t *contexts = (my_Context_t *)clientData;
......@@ -1605,23 +1615,23 @@ void test_stateMachine() {
uint32_t CRC;
uint8_t *CRCbuffer;
my_Context_t aliceSecondChannelClientData, bobSecondChannelClientData;
bzrtpCallbacks_t cbs={0} ;
/* Create zrtp Context */
bzrtpContext_t *contextAlice = bzrtp_createBzrtpContext(0x12345678); /* Alice's SSRC of main channel is 12345678 */
bzrtpContext_t *contextBob = bzrtp_createBzrtpContext(0x87654321); /* Bob's SSRC of main channel is 87654321 */
/* set the cache related callback functions */
bzrtp_setCallback(contextAlice, (int (*)())floadAlice, ZRTP_CALLBACK_LOADCACHE);
bzrtp_setCallback(contextAlice, (int (*)())fwriteAlice, ZRTP_CALLBACK_WRITECACHE);
bzrtp_setCallback(contextBob, (int (*)())floadBob, ZRTP_CALLBACK_LOADCACHE);
bzrtp_setCallback(contextBob, (int (*)())fwriteBob, ZRTP_CALLBACK_WRITECACHE);
/* define the sendData function */
retval = bzrtp_setCallback(contextAlice, (int (*)())bzrtp_sendData, ZRTP_CALLBACK_SENDDATA);
retval += bzrtp_setCallback(contextBob, (int (*)())bzrtp_sendData, ZRTP_CALLBACK_SENDDATA);
printf("Set callbacks return %x\n", retval);
cbs.bzrtp_loadCache=floadAlice;
cbs.bzrtp_writeCache=fwriteAlice;
cbs.bzrtp_sendData=bzrtp_sendData;
bzrtp_setCallbacks(contextAlice, &cbs);
cbs.bzrtp_loadCache=floadBob;
cbs.bzrtp_writeCache=fwriteBob;
cbs.bzrtp_sendData=bzrtp_sendData;
bzrtp_setCallbacks(contextBob, &cbs);
/* create the client Data and associate them to the channel contexts */
memcpy(aliceClientData.nom, "Alice", 6);
memcpy(bobClientData.nom, "Bob", 4);
......
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