Commit 26022db5 authored by johan's avatar johan
Browse files

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
*/
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 */
......
......@@ -25,7 +25,7 @@
*/
#include <stdlib.h>
#include "string.h"
#include <string.h>
#include "typedef.h"
#include "packetParser.h"
#include "cryptoUtils.h"
......@@ -35,11 +35,12 @@
/* Local functions prototypes */
int bzrtp_turnIntoResponder(bzrtpContext_t *zrtpContext, bzrtpChannelContext_t *zrtpChannelContext, bzrtpPacket_t *zrtpPacket, bzrtpCommitMessage_t *commitMessage);
int bzrtp_responseToHelloMessage(bzrtpContext_t *zrtpContext, bzrtpChannelContext_t *zrtpChannelContext, bzrtpPacket_t *zrtpPacket, bzrtpStateMachine_t nextState);
int bzrtp_responseToHelloMessage(bzrtpContext_t *zrtpContext, bzrtpChannelContext_t *zrtpChannelContext, bzrtpPacket_t *zrtpPacket);
int bzrtp_computeS0DHMMode(bzrtpContext_t *zrtpContext, bzrtpChannelContext_t *zrtpChannelContext);
int bzrtp_computeS0MultiStreamMode(bzrtpContext_t *zrtpContext, bzrtpChannelContext_t *zrtpChannelContext);
int bzrtp_deriveKeysFromS0(bzrtpContext_t *zrtpContext, bzrtpChannelContext_t *zrtpChannelContext);
int bzrtp_deriveSrtpKeysFromS0(bzrtpContext_t *zrtpContext, bzrtpChannelContext_t *zrtpChannelContext);
int bzrtp_updateCachedSecrets(bzrtpContext_t *zrtpContext, bzrtpChannelContext_t *zrtpChannelContext);
/*
* @brief This is the initial state
......@@ -108,11 +109,16 @@ int state_discovery_init(bzrtpEvent_t event) {
/* if we have an Hello packet, we must use it to determine which algo we will agree on */
if (zrtpPacket->messageType == MSGTYPE_HELLO) {
retval = bzrtp_responseToHelloMessage(zrtpContext, zrtpChannelContext, zrtpPacket, state_discovery_waitingForHelloAck);
retval = bzrtp_responseToHelloMessage(zrtpContext, zrtpChannelContext, zrtpPacket);
if (retval != 0) {
return retval;
}
/* reset the sending Hello timer as peer may have started slowly and lost all our Hello packets */
zrtpChannelContext->timer.status = BZRTP_TIMER_ON;
zrtpChannelContext->timer.firingTime = 0;
zrtpChannelContext->timer.firingCount = 0;
zrtpChannelContext->timer.timerStep = HELLO_BASE_RETRANSMISSION_STEP;
/* set next state (do not call it as we will just be waiting for a HelloACK packet from peer, nothing to do) */
zrtpChannelContext->stateMachine = state_discovery_waitingForHelloAck;
......@@ -204,7 +210,7 @@ int state_discovery_waitingForHello(bzrtpEvent_t event) {
/* packet is valid, set the sequence Number in channel context */
zrtpChannelContext->peerSequenceNumber = zrtpPacket->sequenceNumber;
retval = bzrtp_responseToHelloMessage(zrtpContext, zrtpChannelContext, zrtpPacket, state_discovery_waitingForHelloAck);
retval = bzrtp_responseToHelloMessage(zrtpContext, zrtpChannelContext, zrtpPacket);
if (retval != 0) {
return retval;
}
......@@ -480,28 +486,41 @@ int state_keyAgreement_sendingCommit(bzrtpEvent_t event) {
/* Check shared secret hash found in the DHPart1 message */
/* if we do not have the secret, don't check it as we do not expect the other part to have it neither */
/* TODO: in case of cache mismatch, warn the user and erase secret as it must not be used to compute s0 */
if (zrtpContext->cachedSecret.rs1!=NULL) {
if (memcmp(zrtpContext->initiatorCachedSecretHash.rs1ID, dhPart1Message->rs1ID,8) != 0) {
bzrtp_freeZrtpPacket(zrtpPacket);
return BZRTP_ERROR_CACHEMISMATCH;
if (memcmp(zrtpContext->responderCachedSecretHash.rs1ID, dhPart1Message->rs1ID,8) != 0) {
free(zrtpContext->cachedSecret.rs1);
zrtpContext->cachedSecret.rs1= NULL;
zrtpContext->cachedSecret.rs1Length = 0;
/*bzrtp_freeZrtpPacket(zrtpPacket);
return BZRTP_ERROR_CACHEMISMATCH;*/
}
}
if (zrtpContext->cachedSecret.rs2!=NULL) {
if (memcmp(zrtpContext->initiatorCachedSecretHash.rs2ID, dhPart1Message->rs2ID,8) != 0) {
bzrtp_freeZrtpPacket(zrtpPacket);
return BZRTP_ERROR_CACHEMISMATCH;
if (memcmp(zrtpContext->responderCachedSecretHash.rs2ID, dhPart1Message->rs2ID,8) != 0) {
free(zrtpContext->cachedSecret.rs2);
zrtpContext->cachedSecret.rs2= NULL;
zrtpContext->cachedSecret.rs2Length = 0;
/*bzrtp_freeZrtpPacket(zrtpPacket);
return BZRTP_ERROR_CACHEMISMATCH;*/
}
}
if (zrtpContext->cachedSecret.auxsecret!=NULL) {
if (memcmp(zrtpChannelContext->initiatorAuxsecretID, dhPart1Message->auxsecretID,8) != 0) {
bzrtp_freeZrtpPacket(zrtpPacket);
return BZRTP_ERROR_CACHEMISMATCH;
if (memcmp(zrtpChannelContext->responderAuxsecretID, dhPart1Message->auxsecretID,8) != 0) {
free(zrtpContext->cachedSecret.auxsecret);
zrtpContext->cachedSecret.auxsecret= NULL;
zrtpContext->cachedSecret.auxsecretLength = 0;
/*bzrtp_freeZrtpPacket(zrtpPacket);
return BZRTP_ERROR_CACHEMISMATCH;*/
}
}
if (zrtpContext->cachedSecret.pbxsecret!=NULL) {
if (memcmp(zrtpContext->initiatorCachedSecretHash.pbxsecretID, dhPart1Message->pbxsecretID,8) != 0) {
bzrtp_freeZrtpPacket(zrtpPacket);
return BZRTP_ERROR_CACHEMISMATCH;
if (memcmp(zrtpContext->responderCachedSecretHash.pbxsecretID, dhPart1Message->pbxsecretID,8) != 0) {
free(zrtpContext->cachedSecret.pbxsecret);
zrtpContext->cachedSecret.pbxsecret= NULL;
zrtpContext->cachedSecret.pbxsecretLength = 0;
/*bzrtp_freeZrtpPacket(zrtpPacket);
return BZRTP_ERROR_CACHEMISMATCH;*/
}
}
......@@ -711,26 +730,38 @@ int state_keyAgreement_responderSendingDHPart1(bzrtpEvent_t event) {
/* if we do not have the secret, don't check it as we do not expect the other part to have it neither */
if (zrtpContext->cachedSecret.rs1!=NULL) {
if (memcmp(zrtpContext->initiatorCachedSecretHash.rs1ID, dhPart2Message->rs1ID,8) != 0) {
bzrtp_freeZrtpPacket(zrtpPacket);
return BZRTP_ERROR_CACHEMISMATCH;
free(zrtpContext->cachedSecret.rs1);
zrtpContext->cachedSecret.rs1= NULL;
zrtpContext->cachedSecret.rs1Length = 0;
/*bzrtp_freeZrtpPacket(zrtpPacket);
return BZRTP_ERROR_CACHEMISMATCH;*/
}
}
if (zrtpContext->cachedSecret.rs2!=NULL) {
if (memcmp(zrtpContext->initiatorCachedSecretHash.rs2ID, dhPart2Message->rs2ID,8) != 0) {
bzrtp_freeZrtpPacket(zrtpPacket);
return BZRTP_ERROR_CACHEMISMATCH;
free(zrtpContext->cachedSecret.rs2);
zrtpContext->cachedSecret.rs2= NULL;
zrtpContext->cachedSecret.rs2Length = 0;
/*bzrtp_freeZrtpPacket(zrtpPacket);
return BZRTP_ERROR_CACHEMISMATCH;*/
}
}
if (zrtpContext->cachedSecret.auxsecret!=NULL) {
if (memcmp(zrtpChannelContext->initiatorAuxsecretID, dhPart2Message->auxsecretID,8) != 0) {
bzrtp_freeZrtpPacket(zrtpPacket);
return BZRTP_ERROR_CACHEMISMATCH;
free(zrtpContext->cachedSecret.auxsecret);
zrtpContext->cachedSecret.auxsecret= NULL;
zrtpContext->cachedSecret.auxsecretLength = 0;
/*bzrtp_freeZrtpPacket(zrtpPacket);
return BZRTP_ERROR_CACHEMISMATCH;*/
}
}
if (zrtpContext->cachedSecret.pbxsecret!=NULL) {
if (memcmp(zrtpContext->initiatorCachedSecretHash.pbxsecretID, dhPart2Message->pbxsecretID,8) != 0) {
bzrtp_freeZrtpPacket(zrtpPacket);
return BZRTP_ERROR_CACHEMISMATCH;
free(zrtpContext->cachedSecret.pbxsecret);
zrtpContext->cachedSecret.pbxsecret= NULL;
zrtpContext->cachedSecret.pbxsecretLength = 0;
/*bzrtp_freeZrtpPacket(zrtpPacket);
return BZRTP_ERROR_CACHEMISMATCH;*/
}
}
......@@ -1078,6 +1109,9 @@ int state_confirmation_responderSendingConfirm1(bzrtpEvent_t event) {
return retval;
}
/* compute and update in cache the retained shared secret */
bzrtp_updateCachedSecrets(zrtpContext, zrtpChannelContext);
/* send them to the environment for receiver as we may receive a srtp packet in response to our conf2ACK */
if (zrtpContext->zrtpCallbacks.bzrtp_srtpSecretsAvailable != NULL) {
zrtpContext->zrtpCallbacks.bzrtp_srtpSecretsAvailable(zrtpChannelContext->clientData, &zrtpChannelContext->srtpSecrets, ZRTP_SRTP_SECRETS_FOR_RECEIVER);
......@@ -1244,6 +1278,9 @@ int state_confirmation_initiatorSendingConfirm2(bzrtpEvent_t event) {
/* stop the retransmission timer */
zrtpChannelContext->timer.status = BZRTP_TIMER_OFF;
/* compute and update in cache the retained shared secret */
bzrtp_updateCachedSecrets(zrtpContext, zrtpChannelContext);
/* send the sender srtp keys to the client(we sent receiver only when the first confirm1 packet arrived) */
if (zrtpContext->zrtpCallbacks.bzrtp_srtpSecretsAvailable != NULL) {
zrtpContext->zrtpCallbacks.bzrtp_srtpSecretsAvailable(zrtpChannelContext->clientData, &zrtpChannelContext->srtpSecrets, ZRTP_SRTP_SECRETS_FOR_SENDER);
......@@ -1324,7 +1361,7 @@ int state_secure(bzrtpEvent_t event) {
/* call the environment to signal we're ready to operate */
if (zrtpContext->zrtpCallbacks.bzrtp_startSrtpSession!= NULL) {
zrtpContext->zrtpCallbacks.bzrtp_startSrtpSession(zrtpChannelContext->clientData, zrtpChannelContext->srtpSecrets.sas, 0); /* TODO: last param is the verified flag but we are cacheless for now so always 0*/
zrtpContext->zrtpCallbacks.bzrtp_startSrtpSession(zrtpChannelContext->clientData, zrtpChannelContext->srtpSecrets.sas, zrtpContext->cachedSecret.previouslyVerifiedSas);
}
return 0;
}
......@@ -1480,7 +1517,7 @@ int bzrtp_turnIntoResponder(bzrtpContext_t *zrtpContext, bzrtpChannelContext_t *
*
* @return 0 on succes, error code otherwise
*/
int bzrtp_responseToHelloMessage(bzrtpContext_t *zrtpContext, bzrtpChannelContext_t *zrtpChannelContext, bzrtpPacket_t *zrtpPacket, bzrtpStateMachine_t nextState) {
int bzrtp_responseToHelloMessage(bzrtpContext_t *zrtpContext, bzrtpChannelContext_t *zrtpChannelContext, bzrtpPacket_t *zrtpPacket) {
int retval;
bzrtpHelloMessage_t *helloMessage = (bzrtpHelloMessage_t *)zrtpPacket->messageData;
......@@ -1559,6 +1596,7 @@ int bzrtp_responseToHelloMessage(bzrtpContext_t *zrtpContext, bzrtpChannelContex
/* When in PreShared mode Derive ZRTPSess, s0 from the retained secret and then all the other keys */
if ((zrtpChannelContext->keyAgreementAlgo == ZRTP_KEYAGREEMENT_Prsh)) {
/*TODO*/
} else if (zrtpChannelContext->keyAgreementAlgo == ZRTP_KEYAGREEMENT_Mult) { /* when in Multistream mode, do nothing, will derive s0 from ZRTPSess when we know who is initiator */
......@@ -1980,3 +2018,45 @@ int bzrtp_deriveSrtpKeysFromS0(bzrtpContext_t *zrtpContext, bzrtpChannelContext_
return 0;
}
/*
* @brief Compute the new rs1 and update the cached secrets according to rfc section 4.6.1
*
* param[in] zrtpContext The context we are operation on
* param[in/out] zrtpChannelContext The channel context we are operation on(contains s0)
*
* return 0 on success, error code otherwise
*/
int bzrtp_updateCachedSecrets(bzrtpContext_t *zrtpContext, bzrtpChannelContext_t *zrtpChannelContext) {
/* if this channel context is in multistream mode, do nothing */
if (zrtpChannelContext->keyAgreementAlgo == ZRTP_KEYAGREEMENT_Mult) {
/* destroy s0 */
bzrtp_DestroyKey(zrtpChannelContext->s0, zrtpChannelContext->hashLength, zrtpContext->RNGContext);
free(zrtpChannelContext->s0);
zrtpChannelContext->s0 = NULL;
return 0;
}
/* if this channel context is not in DHM mode, backup rs1 in rs2 if it exists */
if (zrtpChannelContext->keyAgreementAlgo != ZRTP_KEYAGREEMENT_Prsh) {
if (zrtpContext->cachedSecret.rs1 != NULL) {
bzrtp_writePeerNode(zrtpContext, zrtpContext->peerZID, (uint8_t *)"rs2", 3, zrtpContext->cachedSecret.rs1, zrtpContext->cachedSecret.rs1Length);
}
}
/* compute rs1 = KDF(s0, "retained secret", KDF_Context, 256) */
if (zrtpContext->cachedSecret.rs1 == NULL) {
zrtpContext->cachedSecret.rs1 = (uint8_t *)malloc(RETAINED_SECRET_LENGTH);
zrtpContext->cachedSecret.rs1Length = RETAINED_SECRET_LENGTH;
}
bzrtp_keyDerivationFunction(zrtpChannelContext->s0, zrtpChannelContext->hashLength, (uint8_t *)"retained secret", 15, zrtpChannelContext->KDFContext, zrtpChannelContext->KDFContextLength, 32, (void (*)(uint8_t *, uint8_t, uint8_t *, uint32_t, uint8_t, uint8_t *))zrtpChannelContext->hmacFunction, zrtpContext->cachedSecret.rs1);
bzrtp_writePeerNode(zrtpContext, zrtpContext->peerZID, (uint8_t *)"rs1", 3, zrtpContext->cachedSecret.rs1, zrtpContext->cachedSecret.rs1Length);
/* destroy s0 */
bzrtp_DestroyKey(zrtpChannelContext->s0, zrtpChannelContext->hashLength, zrtpContext->RNGContext);
free(zrtpChannelContext->s0);
zrtpChannelContext->s0 = NULL;
return 0;
}
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