Commit 26022db5 authored by johan's avatar johan

Cache functionnal

- use libxml2 to manage cache
- add set/unset previously verified sas flag management interface
- clean debug code
parent 4e60d73a
......@@ -31,6 +31,14 @@ if test "$found_cunit" = "no" ; then
])
fi
dnl check libxml2
PKG_CHECK_MODULES(LIBXML2, [libxml-2.0] ,[libxml2_found=yes] ,foo=bar)
if test "$libxml2_found" != "yes" ; then
AC_MSG_WARN([libxml2 not found. Disabling cache.)])
else
AC_DEFINE(HAVE_LIBXML2,1,[defined when libxml2 is available]) ]
fi
if test "$found_cunit" = "no" ; then
AC_MSG_WARN([Could not find cunit framework, tests are not compiled.])
else
......
......@@ -195,4 +195,18 @@ __attribute__ ((visibility ("default"))) int bzrtp_isSecure(bzrtpContext_t *zrtp
*/
__attribute__ ((visibility ("default"))) int bzrtp_processMessage(bzrtpContext_t *zrtpContext, uint32_t selfSSRC, uint8_t *zrtpPacketString, uint16_t zrtpPacketStringLength);
/**
* @brief Called by user when the SAS has been verified
*
* @param[in/out] zrtpContext The ZRTP context we're dealing with
*/
__attribute__ ((visibility ("default"))) void bzrtp_SASVerified(bzrtpContext_t *zrtpContext);
/**
* @brief Called by user when the SAS has been set to unverified
*
* @param[in/out] zrtpContext The ZRTP context we're dealing with
*/
__attribute__ ((visibility ("default"))) void bzrtp_resetSASVerified(bzrtpContext_t *zrtpContext);
#endif /* ifndef BZRTP_H */
......@@ -39,7 +39,6 @@
#define RESPONDER 1
#include <stdint.h>
#include <stdio.h>
typedef struct bzrtpChannelContext_struct bzrtpChannelContext_t;
......@@ -71,7 +70,8 @@ typedef struct bzrtpTimer_struct {
uint8_t timerStep; /**< in ms. Step between next timer fire: used to reset firingTime for next timer fire */
} bzrtpTimer_t;
/* the rs1 and rs2 are 256 bits long - see rfc section 4.6.1 */
#define RETAINED_SECRET_LENGTH 32
/**
* @brief A set of cached secrets retrieved from the cache as defined
*/
......@@ -84,6 +84,7 @@ typedef struct cachedSecrets_struct {
uint8_t auxsecretLength; /**< auxiliary secret length in bytes */
uint8_t *pbxsecret; /**< PBX secret */
uint8_t pbxsecretLength; /**< PBX secret length in bytes */
uint8_t previouslyVerifiedSas; /* boolean, is a SAS has been previously verified with this user */
} cachedSecrets_t;
/**
......@@ -101,8 +102,8 @@ typedef struct cachedSecretsHash_struct {
*/
typedef struct zrtpCallbacks_struct {
/* cache related functions */
int (* bzrtp_loadCache)(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)(uint8_t *input, uint32_t size); /**< Cache related function : write size bytes to cache */
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 */
......
......@@ -30,7 +30,8 @@
#include "typedef.h"
#define ZRTP_ZIDCACHE_INVALID_CONTEXT 0x2001
#define ZRTP_ZIDCACHE_UNABLETOUPDATE 0x2002
#define ZRTP_ZIDCACHE_INVALID_CACHE 0x2002
#define ZRTP_ZIDCACHE_UNABLETOUPDATE 0x2003
/**
* @brief : retrieve ZID from cache
......@@ -55,4 +56,18 @@ int bzrtp_getSelfZID(bzrtpContext_t *context, uint8_t selfZID[12]);
*/
int bzrtp_getPeerAssociatedSecretsHash(bzrtpContext_t *context, uint8_t peerZID[12]);
/**
* @brief Write the given taf into peer Node, if the tag exists, content is replaced
* Cache file is locked(TODO), read and updated during this call
*
* @param[in/out] context the current context, used to get the negotiated Hash algorithm and cache access functions and store result
* @param[in] peerZID a byte array of the peer ZID
* @param[in] tagName the tagname of node to be written, it MUST be null terminated
* @param[in] tagNameLength the length of tagname (not including the null termination char)
* @param[in] tagContent the content of the node(a byte buffer which will be converted to hexa string)
* @param[in] tagContentLength the length of the content to be written
*
* return 0 on success, error code otherwise
*/
int bzrtp_writePeerNode(bzrtpContext_t *context, uint8_t peerZID[12], uint8_t *tagName, uint8_t tagNameLength, uint8_t *tagContent, uint32_t tagContentLength);
#endif /* ZIDCACHE_H */
lib_LTLIBRARIES = libbzrtp.la
libbzrtp_la_LIBADD= $(LIBXML2_LIBS)
libbzrtp_la_SOURCES= bzrtp.c cryptoPolarssl.c cryptoUtils.c packetParser.c zidCache.c stateMachine.c
libbzrtp_la_LDFLAGS=-fvisibility=hidden -no-undefined
AM_CPPFLAGS= -I$(top_srcdir)/include
AM_CFLAGS=$(LIBXML2_CFLAGS)
......@@ -109,15 +109,14 @@ bzrtpContext_t *bzrtp_createBzrtpContext(uint32_t selfSSRC)
/**
* @brief Perform some initialisation which can't be done without some callback functions:
* - get ZID
* This function is called once per session when the first channel is created.
* It must be called after the cache callback function have been set
* - load cache
* - get ZID from cache or generate it
*
* @param[in] context The context to initialise
* @param[in] context The context to initialise
*/
void bzrtp_initBzrtpContext(bzrtpContext_t *context) {
/* load the cache buffer */
if (context->zrtpCallbacks.bzrtp_loadCache != 0) {
context->zrtpCallbacks.bzrtp_loadCache(&context->cacheBuffer, &(context->cacheBufferLength));
}
/* initialise ZID. Randomly generated if no ZID is found in cache or no cache found */
bzrtp_getSelfZID(context, context->selfZID);
......@@ -192,10 +191,10 @@ void bzrtp_destroyBzrtpContext(bzrtpContext_t *context, uint32_t selfSSRC)
int bzrtp_setCallback(bzrtpContext_t *context, int (*functionPointer)(), uint16_t functionID) {
switch (functionID) {
case ZRTP_CALLBACK_LOADCACHE:
context->zrtpCallbacks.bzrtp_loadCache = (int (*)(uint8_t **, uint32_t *))functionPointer;
context->zrtpCallbacks.bzrtp_loadCache = (int (*)(void *, uint8_t **, uint32_t *))functionPointer;
break;
case ZRTP_CALLBACK_WRITECACHE:
context->zrtpCallbacks.bzrtp_writeCache = (int (*)(uint8_t *, uint32_t))functionPointer;
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;
......@@ -308,7 +307,6 @@ int bzrtp_startChannelEngine(bzrtpContext_t *zrtpContext, uint32_t selfSSRC) {
int bzrtp_iterate(bzrtpContext_t *zrtpContext, uint32_t selfSSRC, uint64_t timeReference) {
/* get channel context */
bzrtpChannelContext_t *zrtpChannelContext = getChannelContext(zrtpContext, selfSSRC);
fflush(NULL);
if (zrtpChannelContext == NULL) {
return BZRTP_ERROR_INVALIDCONTEXT;
......@@ -424,6 +422,32 @@ int bzrtp_isSecure(bzrtpContext_t *zrtpContext, uint32_t selfSSRC) {
}
/*
* @brief Called by user when the SAS has been verified
* update the cache(if any) to set the previously verified flag
*
* @param[in/out] zrtpContext The ZRTP context we're dealing with
*/
void bzrtp_SASVerified(bzrtpContext_t *zrtpContext) {
if (zrtpContext != NULL) {
uint8_t pvsFlag = 1;
bzrtp_writePeerNode(zrtpContext, zrtpContext->peerZID, (uint8_t *)"pvs", 3, &pvsFlag, 1);
}
}
/*
* @brief Called by user when the SAS has been set to unverified
* update the cache(if any) to unset the previously verified flag
*
* @param[in/out] zrtpContext The ZRTP context we're dealing with
*/
void bzrtp_resetSASVerified(bzrtpContext_t *zrtpContext) {
if (zrtpContext != NULL) {
uint8_t pvsFlag = 0;
bzrtp_writePeerNode(zrtpContext, zrtpContext->peerZID, (uint8_t *)"pvs", 3, &pvsFlag, 1);
}
}
/* Local functions implementation */
/**
......
......@@ -139,7 +139,6 @@ bzrtpPacket_t *bzrtp_packetCheck(const uint8_t * input, uint16_t inputLength, ui
* TODO: what if we got a Sequence Number overflowing the 16 bits ? */
uint16_t sequenceNumber = (((uint16_t)input[2])<<8) | ((uint16_t)input[3]);
if (sequenceNumber <= lastValidSequenceNumber) {
printf("Sequence number check last %d current %d", lastValidSequenceNumber, sequenceNumber);
*exitCode = BZRTP_PARSER_ERROR_OUTOFORDER;
return NULL;
}
......@@ -1219,7 +1218,7 @@ bzrtpPacket_t *bzrtp_createZrtpPacket(bzrtpContext_t *zrtpContext, bzrtpChannelC
zrtpConfirmMessage->sig_len = 0; /* signature is not supported */
zrtpConfirmMessage->cacheExpirationInterval = 0xFFFFFFFF; /* expiration interval is set to unlimited as recommended in rfc section 4.9 */
zrtpConfirmMessage->E = 0; /* we are not a PBX and then will never signal an enrollment - rfc section 7.3.1 */
zrtpConfirmMessage->V = 0; /* TODO: this one shall be read from the cache - rfc section 7.1 */
zrtpConfirmMessage->V = zrtpContext->cachedSecret.previouslyVerifiedSas;
zrtpConfirmMessage->A = 0; /* Go clear message is not supported - rfc section 4.7.2 */
zrtpConfirmMessage->D = 0; /* The is no backdoor in our implementation of ZRTP - rfc section 11 */
......
This diff is collapsed.
This diff is collapsed.
<selfZID>3e6adbe0a8e7755d30d18a24</selfZID><peer><ZID>005dbe0399643d953a2202dd</ZID><rs1>c6e2b22e272ae149461098077d4790b36798bebf800fd74b7c09958746115ed1</rs1><aux>f8324dd18ea905171ec2be89f879d01d5994132048d92ea020778cbdf31c605e</aux></peer>
<?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>
<selfZID>005dbe0399643d953a2202dd</selfZID><peer><ZID>3e6adbe0a8e7755d30d18a24</ZID><rs1>c6e2b22e272ae149461098077d4790b36798bebf800fd74b7c09958746115ed1</rs1><aux>f8324dd18ea905171ec2be89f879d01d5994132048d92ea020778cbdf31c605e</aux></peer>
<?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>
......@@ -211,9 +211,19 @@ void test_parser(void) {
}
/* context structure mainly used by statemachine test, but also needed by parserComplete to get the zid Filename */
typedef struct my_Context_struct {
unsigned char nom[30]; /* nom du contexte */
bzrtpContext_t *peerContext;
bzrtpChannelContext_t *peerChannelContext;
char zidFilename[80]; /* nom du fichier de cache */
} my_Context_t;
int floadAlice(uint8_t **output, uint32_t *size) {
FILE *ALICECACHE = fopen("test/ZIDAlice.txt", "r+");
int floadAlice(void *clientData, uint8_t **output, uint32_t *size) {
/* get filename from ClientData */
my_Context_t *clientContext = (my_Context_t *)clientData;
char *filename = clientContext->zidFilename;
FILE *ALICECACHE = fopen(filename, "r+");
fseek(ALICECACHE, 0L, SEEK_END); /* Position to end of file */
*size = ftell(ALICECACHE); /* Get file length */
rewind(ALICECACHE); /* Back to start of file */
......@@ -223,15 +233,23 @@ int floadAlice(uint8_t **output, uint32_t *size) {
return *size;
}
int fwriteAlice(uint8_t *input, uint32_t size) {
FILE *ALICECACHE = fopen("test/ZIDAlice.txt", "w+");
int fwriteAlice(void *clientData, uint8_t *input, uint32_t size) {
/* get filename from ClientData */
my_Context_t *clientContext = (my_Context_t *)clientData;
char *filename = clientContext->zidFilename;
FILE *ALICECACHE = fopen(filename, "w+");
int retval = fwrite(input, 1, size, ALICECACHE);
fclose(ALICECACHE);
return retval;
}
int floadBob(uint8_t **output, uint32_t *size) {
FILE *BOBCACHE = fopen("test/ZIDBob.txt", "r+");
int floadBob(void *clientData, uint8_t **output, uint32_t *size) {
/* get filename from ClientData */
my_Context_t *clientContext = (my_Context_t *)clientData;
char *filename = clientContext->zidFilename;
FILE *BOBCACHE = fopen(filename, "r+");
fseek(BOBCACHE, 0L, SEEK_END); /* Position to end of file */
*size = ftell(BOBCACHE); /* Get file length */
rewind(BOBCACHE); /* Back to start of file */
......@@ -242,8 +260,12 @@ int floadBob(uint8_t **output, uint32_t *size) {
}
int fwriteBob(uint8_t *input, uint32_t size) {
FILE *BOBCACHE = fopen("test/ZIDBob.txt", "w+");
int fwriteBob(void *clientData, uint8_t *input, uint32_t size) {
/* get filename from ClientData */
my_Context_t *clientContext = (my_Context_t *)clientData;
char *filename = clientContext->zidFilename;
FILE *BOBCACHE = fopen(filename, "w+");
int retval = fwrite(input, 1, size, BOBCACHE);
fclose(BOBCACHE);
return retval;
......@@ -260,6 +282,16 @@ void test_parserComplete() {
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 */
/* Create the client context, used for zidFilename only */
my_Context_t clientContextAlice;
my_Context_t clientContextBob;
memcpy(clientContextAlice.zidFilename, "test/ZIDAlice.txt", 18);
memcpy(clientContextBob.zidFilename, "test/ZIDBob.txt", 16);
/* attach the clientContext to the bzrtp Context */
retval = bzrtp_setClientData(contextAlice, 0x12345678, (void *)&clientContextAlice);
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);
......@@ -1416,12 +1448,6 @@ void test_parserComplete() {
}
typedef struct my_Context_struct {
unsigned char nom[30]; /* nom du contexte */
bzrtpContext_t *peerContext;
bzrtpChannelContext_t *peerChannelContext;
} my_Context_t;
typedef struct packetDatas_struct {
uint8_t packetString[1000];
uint16_t packetLength;
......@@ -1489,7 +1515,12 @@ void test_stateMachine() {
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 */
/* operate cache less: no cache access functions */
/* 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 */
int retval;
......@@ -1497,10 +1528,6 @@ void test_stateMachine() {
retval += bzrtp_setCallback(contextBob, (int (*)())bzrtp_sendData, ZRTP_CALLBACK_SENDDATA);
printf("Set callbacks return %x\n", retval);
/* run the init even if it useless as we are running cacheless and init just get the cache file */
bzrtp_initBzrtpContext(contextAlice);
bzrtp_initBzrtpContext(contextBob);
/* create the client Data and associate them to the channel contexts */
my_Context_t aliceClientData, bobClientData;
......@@ -1510,11 +1537,18 @@ void test_stateMachine() {
aliceClientData.peerChannelContext = contextBob->channelContext[0];
bobClientData.peerContext = contextAlice;
bobClientData.peerChannelContext = contextAlice->channelContext[0];
memcpy(aliceClientData.zidFilename, "test/ZIDAlice.txt", 18);
memcpy(bobClientData.zidFilename, "test/ZIDBob.txt", 16);
retval = bzrtp_setClientData(contextAlice, 0x12345678, (void *)&aliceClientData);
retval += bzrtp_setClientData(contextBob, 0x87654321, (void *)&bobClientData);
printf("Set client data return %x\n", retval);
/* run the init */
bzrtp_initBzrtpContext(contextAlice);
bzrtp_initBzrtpContext(contextBob);
/* now start the engine */
uint64_t initialTime = getCurrentTimeInMs();
retval = bzrtp_startChannelEngine(contextAlice, 0x12345678);
......@@ -1581,7 +1615,7 @@ void test_stateMachine() {
printf ("Bob starts return %x\n", retval);
/* now start infinite loop until we reach secure state */
while ((getCurrentTimeInMs()-initialTime<3000)){
while ((getCurrentTimeInMs()-initialTime<2000)){
int i;
/* first check the message queue */
for (i=0; i<aliceQueueIndex; i++) {
......
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