Commit 11a03694 authored by johan's avatar johan

Rework init and start to be able to create and initialise multichannel

before DHM on first one complete.
parent 6700df00
...@@ -112,8 +112,8 @@ typedef void (*zrtpFreeBuffer_callback)(void *); ...@@ -112,8 +112,8 @@ typedef void (*zrtpFreeBuffer_callback)(void *);
*/ */
typedef struct bzrtpCallbacks_struct { typedef struct bzrtpCallbacks_struct {
/* cache related functions */ /* 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_loadCache)(void *ZIDCacheData, 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 */ int (* bzrtp_writeCache)(void *ZIDCacheData, const uint8_t *input, uint32_t size); /**< Cache related function : write size bytes to cache */
/* sending packets */ /* 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 */ int (* bzrtp_sendData)(void *clientData, const uint8_t *packetString, uint16_t packetLength); /**< Send a ZRTP packet to peer. Shall return 0 on success */
...@@ -123,7 +123,7 @@ typedef struct bzrtpCallbacks_struct { ...@@ -123,7 +123,7 @@ typedef struct bzrtpCallbacks_struct {
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 */ 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 */ /* 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 */ int (* bzrtp_contextReadyForExportedKeys)(void *ZIDCacheData, 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; } bzrtpCallbacks_t;
#define ZRTP_MAGIC_COOKIE 0x5a525450 #define ZRTP_MAGIC_COOKIE 0x5a525450
...@@ -149,22 +149,20 @@ typedef struct bzrtpContext_struct bzrtpContext_t; ...@@ -149,22 +149,20 @@ typedef struct bzrtpContext_struct bzrtpContext_t;
/** /**
* Create context structure and initialise it * Create context structure and initialise it
* A channel context is created when creating the zrtp context.
*
* @param[in] selfSSRC The SSRC given to the channel context created within the zrtpContext
* *
* @return The ZRTP engine context data * @return The ZRTP engine context data
* *
*/ */
BZRTP_EXPORT bzrtpContext_t *bzrtp_createBzrtpContext(uint32_t selfSSRC); BZRTP_EXPORT bzrtpContext_t *bzrtp_createBzrtpContext(void);
/** /**
* @brief Perform some initialisation which can't be done without some callback functions: * @brief Perform some initialisation which can't be done without some callback functions:
* - get ZID * - get ZID and create the first channel context
* *
* @param[in] context The context to initialise * @param[in] context The context to initialise
* @param[in] selfSSRC The SSRC given to the first channel context created within the zrtpContext
*/ */
BZRTP_EXPORT void bzrtp_initBzrtpContext(bzrtpContext_t *context); BZRTP_EXPORT void bzrtp_initBzrtpContext(bzrtpContext_t *context, uint32_t selfSSRC);
/** /**
* Free memory of context structure to a channel, if all channels are freed, free the global zrtp context * Free memory of context structure to a channel, if all channels are freed, free the global zrtp context
...@@ -184,6 +182,17 @@ BZRTP_EXPORT void bzrtp_destroyBzrtpContext(bzrtpContext_t *context, uint32_t se ...@@ -184,6 +182,17 @@ BZRTP_EXPORT void bzrtp_destroyBzrtpContext(bzrtpContext_t *context, uint32_t se
*/ */
BZRTP_EXPORT int bzrtp_setCallbacks(bzrtpContext_t *context, const bzrtpCallbacks_t *cbs); BZRTP_EXPORT int bzrtp_setCallbacks(bzrtpContext_t *context, const bzrtpCallbacks_t *cbs);
/*
* @brief Set the ZID cache data pointer in the global zrtp context
* This pointer is returned to the client by the callbacks function linked to cache: bzrtp_loadCache, bzrtp_writeCache and bzrtp_contextReadyForExportedKeys
* @param[in/out] zrtpContext The ZRTP context we're dealing with
* @param[in] selfSSRC The SSRC identifying the channel to be linked to the client Data
* @param[in] ZIDCacheData The ZIDCacheData pointer, casted to a (void *)
*
* @return 0 on success
*
*/
BZRTP_EXPORT int bzrtp_setZIDCacheData(bzrtpContext_t *zrtpContext, void *ZIDCacheData);
/** /**
* @brief Set the client data pointer in a channel context * @brief Set the client data pointer in a channel context
* This pointer is returned to the client by the callbacks function, used to store associated contexts (RTP session) * This pointer is returned to the client by the callbacks function, used to store associated contexts (RTP session)
...@@ -197,9 +206,9 @@ BZRTP_EXPORT int bzrtp_setCallbacks(bzrtpContext_t *context, const bzrtpCallback ...@@ -197,9 +206,9 @@ BZRTP_EXPORT int bzrtp_setCallbacks(bzrtpContext_t *context, const bzrtpCallback
BZRTP_EXPORT int bzrtp_setClientData(bzrtpContext_t *zrtpContext, uint32_t selfSSRC, void *clientData); BZRTP_EXPORT int bzrtp_setClientData(bzrtpContext_t *zrtpContext, uint32_t selfSSRC, void *clientData);
/** /**
* @brief Add a channel to an existing context, this can be done only if the first channel has concluded a DH key agreement * @brief Add a channel to an existing context
* *
* @param[in/out] zrtpContext The zrtp context who will get the additionnal channel. Must be in secure state. * @param[in/out] zrtpContext The zrtp context who will get the additionnal channel
* @param[in] selfSSRC The SSRC given to the channel context * @param[in] selfSSRC The SSRC given to the channel context
* *
* @return 0 on succes, error code otherwise * @return 0 on succes, error code otherwise
...@@ -209,6 +218,7 @@ BZRTP_EXPORT int bzrtp_addChannel(bzrtpContext_t *zrtpContext, uint32_t selfSSRC ...@@ -209,6 +218,7 @@ BZRTP_EXPORT int bzrtp_addChannel(bzrtpContext_t *zrtpContext, uint32_t selfSSRC
/** /**
* @brief Start the state machine of the specified channel * @brief Start the state machine of the specified channel
* To be able to start an addional channel, we must be in secure state
* *
* @param[in/out] zrtpContext The ZRTP context hosting the channel to be started * @param[in/out] zrtpContext The ZRTP context hosting the channel to be started
* @param[in] selfSSRC The SSRC identifying the channel to be started(will start sending Hello packets and listening for some) * @param[in] selfSSRC The SSRC identifying the channel to be started(will start sending Hello packets and listening for some)
......
...@@ -128,6 +128,7 @@ struct bzrtpChannelContext_struct { ...@@ -128,6 +128,7 @@ struct bzrtpChannelContext_struct {
/* flags */ /* flags */
uint8_t isSecure; /**< This flag is set to 1 when the ZRTP negociation ends and SRTP secrets are generated and confirmed for this channel */ uint8_t isSecure; /**< This flag is set to 1 when the ZRTP negociation ends and SRTP secrets are generated and confirmed for this channel */
uint8_t isMainChannel; /**< this flag is set for the firt channel only, allow to distinguish channel to be secured using DHM or multiStream */
/* Hash chains, self is generated at channel context init */ /* Hash chains, self is generated at channel context init */
uint8_t selfH[4][32]; /**< Store self 256 bits Hash images H0-H3 used to generate messages MAC */ uint8_t selfH[4][32]; /**< Store self 256 bits Hash images H0-H3 used to generate messages MAC */
...@@ -186,12 +187,14 @@ struct bzrtpChannelContext_struct { ...@@ -186,12 +187,14 @@ struct bzrtpChannelContext_struct {
* Store current state, timers, HMAC and encryption keys * Store current state, timers, HMAC and encryption keys
*/ */
struct bzrtpContext_struct { struct bzrtpContext_struct {
void *ZIDCacheData; /**< this is a pointer provided by the client which is then resent as a parameter of the ZID cache related callbacks functions. */
/* contexts */ /* contexts */
bctoolbox_rng_context_t *RNGContext; /**< context for random number generation */ bctoolbox_rng_context_t *RNGContext; /**< context for random number generation */
bctoolbox_DHMContext_t *DHMContext; /**< context for the Diffie-Hellman-Merkle operations. Only one DHM computation may be done during a call, so this belongs to the general context and not the channel one */ bctoolbox_DHMContext_t *DHMContext; /**< context for the Diffie-Hellman-Merkle operations. Only one DHM computation may be done during a call, so this belongs to the general context and not the channel one */
/* flags */ /* flags */
uint8_t isSecure; /**< this flag is set to 1 after the first channel have completed the ZRTP protocol exchange(i.e. when the responder have sent the conf2ACK message) */ uint8_t isInitialised; /**< this flag is set once the context was initialised : self ZID retrieved from cache or generated, used to unlock the creation of addtional channels */
uint8_t isSecure; /**< this flag is set to 1 after the first channel have completed the ZRTP protocol exchange(i.e. when the responder have sent the conf2ACK message), must be set in order to start an additional channel */
uint8_t peerSupportMultiChannel; /**< this flag is set to 1 when the first valid HELLO packet from peer arrives if it support Multichannel ZRTP */ uint8_t peerSupportMultiChannel; /**< this flag is set to 1 when the first valid HELLO packet from peer arrives if it support Multichannel ZRTP */
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 */ 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 */
......
...@@ -36,19 +36,18 @@ ...@@ -36,19 +36,18 @@
#define BZRTP_ERROR_INVALIDCHANNELCONTEXT 0x8001 #define BZRTP_ERROR_INVALIDCHANNELCONTEXT 0x8001
/* local functions prototypes */ /* local functions prototypes */
static int bzrtp_initChannelContext(bzrtpContext_t *zrtpContext, bzrtpChannelContext_t *zrtpChannelContext, uint32_t selfSSRC); static int bzrtp_initChannelContext(bzrtpContext_t *zrtpContext, bzrtpChannelContext_t *zrtpChannelContext, uint32_t selfSSRC, uint8_t isMain);
static void bzrtp_destroyChannelContext(bzrtpContext_t *zrtpContext, bzrtpChannelContext_t *zrtpChannelContext); static void bzrtp_destroyChannelContext(bzrtpContext_t *zrtpContext, bzrtpChannelContext_t *zrtpChannelContext);
static bzrtpChannelContext_t *getChannelContext(bzrtpContext_t *zrtpContext, uint32_t selfSSRC); static bzrtpChannelContext_t *getChannelContext(bzrtpContext_t *zrtpContext, uint32_t selfSSRC);
static uint8_t copyCryptoTypes(uint8_t destination[7], uint8_t source[7], uint8_t size); static uint8_t copyCryptoTypes(uint8_t destination[7], uint8_t source[7], uint8_t size);
/* /*
* Create context structure and initialise it * Create context structure and initialise it
* A channel context is created to, the selfSSRC is given to it
* *
* @return The ZRTP engine context data * @return The ZRTP engine context data
* *
*/ */
bzrtpContext_t *bzrtp_createBzrtpContext(uint32_t selfSSRC) { bzrtpContext_t *bzrtp_createBzrtpContext(void) {
int i; int i;
/*** create and intialise the context structure ***/ /*** create and intialise the context structure ***/
bzrtpContext_t *context = malloc(sizeof(bzrtpContext_t)); bzrtpContext_t *context = malloc(sizeof(bzrtpContext_t));
...@@ -62,6 +61,7 @@ bzrtpContext_t *bzrtp_createBzrtpContext(uint32_t selfSSRC) { ...@@ -62,6 +61,7 @@ bzrtpContext_t *bzrtp_createBzrtpContext(uint32_t selfSSRC) {
/* set flags */ /* set flags */
context->isSecure = 0; /* start unsecure */ context->isSecure = 0; /* start unsecure */
context->peerSupportMultiChannel = 0; /* peer does not support Multichannel by default */ context->peerSupportMultiChannel = 0; /* peer does not support Multichannel by default */
context->isInitialised = 0; /* will be set by bzrtp_initBzrtpContext */
/* set to NULL all callbacks pointer */ /* set to NULL all callbacks pointer */
context->zrtpCallbacks.bzrtp_loadCache = NULL; context->zrtpCallbacks.bzrtp_loadCache = NULL;
...@@ -71,10 +71,7 @@ bzrtpContext_t *bzrtp_createBzrtpContext(uint32_t selfSSRC) { ...@@ -71,10 +71,7 @@ bzrtpContext_t *bzrtp_createBzrtpContext(uint32_t selfSSRC) {
context->zrtpCallbacks.bzrtp_startSrtpSession = NULL; context->zrtpCallbacks.bzrtp_startSrtpSession = NULL;
context->zrtpCallbacks.bzrtp_contextReadyForExportedKeys = NULL; context->zrtpCallbacks.bzrtp_contextReadyForExportedKeys = NULL;
/* allocate 1 channel context, set all the others pointers to NULL */
context->channelContext[0] = (bzrtpChannelContext_t *)malloc(sizeof(bzrtpChannelContext_t));
memset(context->channelContext[0], 0, sizeof(bzrtpChannelContext_t));
bzrtp_initChannelContext(context, context->channelContext[0], selfSSRC);
for (i=1; i<ZRTP_MAX_CHANNEL_NUMBER; i++) { for (i=1; i<ZRTP_MAX_CHANNEL_NUMBER; i++) {
context->channelContext[i] = NULL; context->channelContext[i] = NULL;
...@@ -116,13 +113,22 @@ bzrtpContext_t *bzrtp_createBzrtpContext(uint32_t selfSSRC) { ...@@ -116,13 +113,22 @@ bzrtpContext_t *bzrtp_createBzrtpContext(uint32_t selfSSRC) {
* - load cache * - load cache
* - get ZID from cache or generate it * - get ZID from cache or generate it
* *
* Initialise the first channel
*
* @param[in] context The context to initialise * @param[in] context The context to initialise
* #param[in] selfSSRC SSRC of the first channel
*/ */
void bzrtp_initBzrtpContext(bzrtpContext_t *context) { void bzrtp_initBzrtpContext(bzrtpContext_t *context, uint32_t selfSSRC) {
/* initialise ZID. Randomly generated if no ZID is found in cache or no cache found */ /* initialise ZID. Randomly generated if no ZID is found in cache or no cache found */
/* This call will load the cache or create it if the cache callback functions are not null*/ /* This call will load the cache or create it if the cache callback functions are not null*/
bzrtp_getSelfZID(context, context->selfZID); bzrtp_getSelfZID(context, context->selfZID);
context->isInitialised = 1;
/* allocate 1 channel context, set all the others pointers to NULL */
context->channelContext[0] = (bzrtpChannelContext_t *)malloc(sizeof(bzrtpChannelContext_t));
memset(context->channelContext[0], 0, sizeof(bzrtpChannelContext_t));
bzrtp_initChannelContext(context, context->channelContext[0], selfSSRC, 1);
} }
/* /*
...@@ -233,23 +239,18 @@ int bzrtp_addChannel(bzrtpContext_t *zrtpContext, uint32_t selfSSRC) { ...@@ -233,23 +239,18 @@ int bzrtp_addChannel(bzrtpContext_t *zrtpContext, uint32_t selfSSRC) {
return BZRTP_ERROR_INVALIDCONTEXT; return BZRTP_ERROR_INVALIDCONTEXT;
} }
/* is ZRTP context able to add a channel (means channel 0 has already performed the secrets generation) */ /* context must be initialised(selfZID available) to enable the creation of an additional channel */
if (zrtpContext->isSecure == 0) { if (zrtpContext->isInitialised == 0) {
return BZRTP_ERROR_CONTEXTNOTREADY; return BZRTP_ERROR_CONTEXTNOTREADY;
} }
/* check the peer support Multichannel(shall be set in the first Hello message received) */
if (zrtpContext->peerSupportMultiChannel == 0) {
return BZRTP_ERROR_MULTICHANNELNOTSUPPORTEDBYPEER;
}
/* get the first free channel context from ZRTP context and create a channel context */ /* get the first free channel context from ZRTP context and create a channel context */
while(i<ZRTP_MAX_CHANNEL_NUMBER && zrtpChannelContext==NULL) { while(i<ZRTP_MAX_CHANNEL_NUMBER && zrtpChannelContext==NULL) {
if (zrtpContext->channelContext[i] == NULL) { if (zrtpContext->channelContext[i] == NULL) {
int retval; int retval;
zrtpChannelContext = (bzrtpChannelContext_t *)malloc(sizeof(bzrtpChannelContext_t)); zrtpChannelContext = (bzrtpChannelContext_t *)malloc(sizeof(bzrtpChannelContext_t));
memset(zrtpChannelContext, 0, sizeof(bzrtpChannelContext_t)); memset(zrtpChannelContext, 0, sizeof(bzrtpChannelContext_t));
retval = bzrtp_initChannelContext(zrtpContext, zrtpChannelContext, selfSSRC); retval = bzrtp_initChannelContext(zrtpContext, zrtpChannelContext, selfSSRC, 0);
if (retval != 0) { if (retval != 0) {
free(zrtpChannelContext); free(zrtpChannelContext);
return retval; return retval;
...@@ -289,6 +290,19 @@ int bzrtp_startChannelEngine(bzrtpContext_t *zrtpContext, uint32_t selfSSRC) { ...@@ -289,6 +290,19 @@ int bzrtp_startChannelEngine(bzrtpContext_t *zrtpContext, uint32_t selfSSRC) {
return BZRTP_ERROR_UNABLETOSTARTCHANNEL; return BZRTP_ERROR_UNABLETOSTARTCHANNEL;
} }
/* if this is an additional channel(not channel 0), we must be sure that channel 0 is already secured */
if (zrtpChannelContext->isMainChannel == 0) {
/* is ZRTP context able to add a channel (means channel 0 has already performed the secrets generation) */
if (zrtpContext->isSecure == 0) {
return BZRTP_ERROR_CONTEXTNOTREADY;
}
/* check the peer support Multichannel(shall be set in the first Hello message received) */
if (zrtpContext->peerSupportMultiChannel == 0) {
return BZRTP_ERROR_MULTICHANNELNOTSUPPORTEDBYPEER;
}
}
/* set the timer reference to 0 to force a message to be sent at first timer tick */ /* set the timer reference to 0 to force a message to be sent at first timer tick */
zrtpContext->timeReference = 0; zrtpContext->timeReference = 0;
...@@ -350,6 +364,26 @@ int bzrtp_iterate(bzrtpContext_t *zrtpContext, uint32_t selfSSRC, uint64_t timeR ...@@ -350,6 +364,26 @@ int bzrtp_iterate(bzrtpContext_t *zrtpContext, uint32_t selfSSRC, uint64_t timeR
return 0; return 0;
} }
/*
* @brief Set the ZID cache data pointer in the global zrtp context
* This pointer is returned to the client by the callbacks function linked to cache: bzrtp_loadCache, bzrtp_writeCache and bzrtp_contextReadyForExportedKeys
* @param[in/out] zrtpContext The ZRTP context we're dealing with
* @param[in] selfSSRC The SSRC identifying the channel to be linked to the client Data
* @param[in] ZIDCacheData The ZIDCacheData pointer, casted to a (void *)
*
* @return 0 on success
*
*/
int bzrtp_setZIDCacheData(bzrtpContext_t *zrtpContext, void *ZIDCacheData) {
if (zrtpContext == NULL) {
return BZRTP_ERROR_INVALIDCONTEXT;
}
zrtpContext->ZIDCacheData = ZIDCacheData;
return 0;
}
/* /*
* @brief Set the client data pointer in a channel context * @brief Set the client data pointer in a channel context
* This pointer is returned to the client by the callbacks function, used to store associated contexts (RTP session) * This pointer is returned to the client by the callbacks function, used to store associated contexts (RTP session)
...@@ -795,16 +829,17 @@ static bzrtpChannelContext_t *getChannelContext(bzrtpContext_t *zrtpContext, uin ...@@ -795,16 +829,17 @@ static bzrtpChannelContext_t *getChannelContext(bzrtpContext_t *zrtpContext, uin
return NULL; /* found no channel with this SSRC */ return NULL; /* found no channel with this SSRC */
} }
/** /**
* @brief Initialise the context of a channel * @brief Initialise the context of a channel and create and store the Hello packet
* Initialise some vectors * Initialise some vectors
* *
* @param[in] zrtpContext The zrtpContext hosting this channel, needed to acces the RNG * @param[in] zrtpContext The zrtpContext hosting this channel, needed to acces the RNG
* @param[out] zrtpChanneContext The channel context to be initialised * @param[out] zrtpChanneContext The channel context to be initialised
* @param[in] selfSSRC The SSRC allocated to this channel * @param[in] selfSSRC The SSRC allocated to this channel
* @param[in] isMain This channel is channel 0 or an additional channel
* *
* @return 0 on success, error code otherwise * @return 0 on success, error code otherwise
*/ */
static int bzrtp_initChannelContext(bzrtpContext_t *zrtpContext, bzrtpChannelContext_t *zrtpChannelContext, uint32_t selfSSRC) { static int bzrtp_initChannelContext(bzrtpContext_t *zrtpContext, bzrtpChannelContext_t *zrtpChannelContext, uint32_t selfSSRC, uint8_t isMain) {
int i; int i;
if (zrtpChannelContext == NULL) { if (zrtpChannelContext == NULL) {
return BZRTP_ERROR_INVALIDCHANNELCONTEXT; return BZRTP_ERROR_INVALIDCHANNELCONTEXT;
...@@ -823,6 +858,7 @@ static int bzrtp_initChannelContext(bzrtpContext_t *zrtpContext, bzrtpChannelCon ...@@ -823,6 +858,7 @@ static int bzrtp_initChannelContext(bzrtpContext_t *zrtpContext, bzrtpChannelCon
/* flags */ /* flags */
zrtpChannelContext->isSecure = 0; zrtpChannelContext->isSecure = 0;
zrtpChannelContext->isMainChannel = isMain;
/* initialise as initiator, switch to responder later if needed */ /* initialise as initiator, switch to responder later if needed */
zrtpChannelContext->role = INITIATOR; zrtpChannelContext->role = INITIATOR;
......
...@@ -1610,7 +1610,7 @@ int bzrtp_turnIntoResponder(bzrtpContext_t *zrtpContext, bzrtpChannelContext_t * ...@@ -1610,7 +1610,7 @@ int bzrtp_turnIntoResponder(bzrtpContext_t *zrtpContext, bzrtpChannelContext_t *
* *
* @param[in] zrtpContext The current zrtp Context * @param[in] zrtpContext The current zrtp Context
* @param[in/out] zrtpChannelContext The channel we are operating * @param[in/out] zrtpChannelContext The channel we are operating
* @param[in] zrtpPacket The zrtpPacket receives, it contains the commit message * @param[in] zrtpPacket The zrtpPacket received, it contains the hello message
* *
* @return 0 on succes, error code otherwise * @return 0 on succes, error code otherwise
*/ */
...@@ -1647,6 +1647,11 @@ int bzrtp_responseToHelloMessage(bzrtpContext_t *zrtpContext, bzrtpChannelContex ...@@ -1647,6 +1647,11 @@ int bzrtp_responseToHelloMessage(bzrtpContext_t *zrtpContext, bzrtpChannelContex
memcpy(zrtpChannelContext->peerH[3], helloMessage->H3, 32); /* H3 */ memcpy(zrtpChannelContext->peerH[3], helloMessage->H3, 32); /* H3 */
zrtpChannelContext->peerPackets[HELLO_MESSAGE_STORE_ID] = zrtpPacket; /* peer hello packet */ zrtpChannelContext->peerPackets[HELLO_MESSAGE_STORE_ID] = zrtpPacket; /* peer hello packet */
/* now select mode according to context */
if ((zrtpContext->peerSupportMultiChannel) == 1 && (zrtpContext->ZRTPSess != NULL)) { /* if we support multichannel and already have a ZRTPSess key, switch to multichannel mode */
zrtpChannelContext->keyAgreementAlgo = ZRTP_KEYAGREEMENT_Mult;
zrtpChannelContext->keyAgreementLength = 0;
} else { /* we are not in multiStream mode, so we shall compute the hash of shared secrets */
/* get from cache, if relevant, the retained secrets associated to the peer ZID */ /* get from cache, if relevant, the retained secrets associated to the peer ZID */
if (zrtpContext->cachedSecret.rs1 == NULL) { /* if we do not have already secret hashes in this session context. Note, they may be updated in cache file but they also will be in the context at the same time, so no need to parse the cache again */ if (zrtpContext->cachedSecret.rs1 == NULL) { /* if we do not have already secret hashes in this session context. Note, they may be updated in cache file but they also will be in the context at the same time, so no need to parse the cache again */
bzrtp_getPeerAssociatedSecretsHash(zrtpContext, helloMessage->ZID); bzrtp_getPeerAssociatedSecretsHash(zrtpContext, helloMessage->ZID);
...@@ -1686,10 +1691,6 @@ int bzrtp_responseToHelloMessage(bzrtpContext_t *zrtpContext, bzrtpChannelContex ...@@ -1686,10 +1691,6 @@ int bzrtp_responseToHelloMessage(bzrtpContext_t *zrtpContext, bzrtpChannelContex
bctoolbox_rng_get(zrtpContext->RNGContext, zrtpChannelContext->responderAuxsecretID, 8); bctoolbox_rng_get(zrtpContext->RNGContext, zrtpChannelContext->responderAuxsecretID, 8);
} }
/* now select mode according to context */
if ((zrtpContext->peerSupportMultiChannel) == 1 && (zrtpContext->ZRTPSess != NULL)) { /* if we support multichannel and already have a ZRTPSess key, switch to multichannel mode */
zrtpChannelContext->keyAgreementAlgo = ZRTP_KEYAGREEMENT_Mult;
zrtpChannelContext->keyAgreementLength = 0;
} }
/* When in PreShared mode Derive ZRTPSess, s0 from the retained secret and then all the other keys */ /* When in PreShared mode Derive ZRTPSess, s0 from the retained secret and then all the other keys */
...@@ -2151,7 +2152,7 @@ int bzrtp_updateCachedSecrets(bzrtpContext_t *zrtpContext, bzrtpChannelContext_t ...@@ -2151,7 +2152,7 @@ int bzrtp_updateCachedSecrets(bzrtpContext_t *zrtpContext, bzrtpChannelContext_t
/* if exist, call the callback function to perform custom cache operation that may use s0(writing exported key into cache) */ /* if exist, call the callback function to perform custom cache operation that may use s0(writing exported key into cache) */
if (zrtpContext->zrtpCallbacks.bzrtp_contextReadyForExportedKeys != NULL) { if (zrtpContext->zrtpCallbacks.bzrtp_contextReadyForExportedKeys != NULL) {
zrtpContext->zrtpCallbacks.bzrtp_contextReadyForExportedKeys(zrtpChannelContext->clientData, zrtpContext->peerZID, zrtpChannelContext->role); zrtpContext->zrtpCallbacks.bzrtp_contextReadyForExportedKeys(zrtpContext->ZIDCacheData, zrtpChannelContext->clientData, zrtpContext->peerZID, zrtpChannelContext->role);
} }
/* destroy s0 */ /* destroy s0 */
bzrtp_DestroyKey(zrtpChannelContext->s0, zrtpChannelContext->hashLength, zrtpContext->RNGContext); bzrtp_DestroyKey(zrtpChannelContext->s0, zrtpChannelContext->hashLength, zrtpContext->RNGContext);
......
...@@ -53,7 +53,7 @@ int bzrtp_getSelfZID(bzrtpContext_t *context, uint8_t selfZID[12]) { ...@@ -53,7 +53,7 @@ int bzrtp_getSelfZID(bzrtpContext_t *context, uint8_t selfZID[12]) {
uint8_t *cacheStringBuffer; uint8_t *cacheStringBuffer;
uint32_t cacheStringLength; uint32_t cacheStringLength;
zrtpFreeBuffer_callback cb=NULL; zrtpFreeBuffer_callback cb=NULL;
context->zrtpCallbacks.bzrtp_loadCache(context->channelContext[0]->clientData, &cacheStringBuffer, &cacheStringLength, &cb); context->zrtpCallbacks.bzrtp_loadCache(context->ZIDCacheData, &cacheStringBuffer, &cacheStringLength, &cb);
context->cacheBuffer = xmlParseDoc(cacheStringBuffer); context->cacheBuffer = xmlParseDoc(cacheStringBuffer);
if (cb!=NULL) cb(cacheStringBuffer); if (cb!=NULL) cb(cacheStringBuffer);
} else { } else {
...@@ -248,7 +248,7 @@ int bzrtp_writePeerNode(bzrtpContext_t *context, uint8_t peerZID[12], uint8_t *t ...@@ -248,7 +248,7 @@ int bzrtp_writePeerNode(bzrtpContext_t *context, uint8_t peerZID[12], uint8_t *t
/* reload cache from file locking it (TODO: lock) */ /* reload cache from file locking it (TODO: lock) */
xmlFreeDoc(context->cacheBuffer); xmlFreeDoc(context->cacheBuffer);
context->cacheBuffer = NULL; context->cacheBuffer = NULL;
context->zrtpCallbacks.bzrtp_loadCache(context->channelContext[0]->clientData, &cacheStringBuffer, &cacheStringLength,&cb); context->zrtpCallbacks.bzrtp_loadCache(context->ZIDCacheData, &cacheStringBuffer, &cacheStringLength,&cb);
context->cacheBuffer = xmlParseDoc(cacheStringBuffer); context->cacheBuffer = xmlParseDoc(cacheStringBuffer);
if (cb) cb(cacheStringBuffer); if (cb) cb(cacheStringBuffer);
} }
...@@ -342,7 +342,7 @@ static void bzrtp_writeCache(bzrtpContext_t *zrtpContext) { ...@@ -342,7 +342,7 @@ static void bzrtp_writeCache(bzrtpContext_t *zrtpContext) {
int xmlStringLength; int xmlStringLength;
xmlDocDumpFormatMemoryEnc(zrtpContext->cacheBuffer, &xmlStringOutput, &xmlStringLength, "UTF-8", 0); xmlDocDumpFormatMemoryEnc(zrtpContext->cacheBuffer, &xmlStringOutput, &xmlStringLength, "UTF-8", 0);
/* write it to the file */ /* write it to the file */
zrtpContext->zrtpCallbacks.bzrtp_writeCache(zrtpContext->channelContext[0]->clientData, xmlStringOutput, xmlStringLength); zrtpContext->zrtpCallbacks.bzrtp_writeCache(zrtpContext->ZIDCacheData, xmlStringOutput, xmlStringLength);
xmlFree(xmlStringOutput); xmlFree(xmlStringOutput);
} }
......
...@@ -170,7 +170,8 @@ static int compareAllAlgoTypesWithExpectedChangedOnly(bzrtpChannelContext_t *zrt ...@@ -170,7 +170,8 @@ static int compareAllAlgoTypesWithExpectedChangedOnly(bzrtpChannelContext_t *zrt
static int testAlgoType(uint8_t algoType, uint8_t *packetTypes, uint8_t packetTypesCount, uint8_t *contextTypes, uint8_t contextTypesCount, uint8_t expectedType) { static int testAlgoType(uint8_t algoType, uint8_t *packetTypes, uint8_t packetTypesCount, uint8_t *contextTypes, uint8_t contextTypesCount, uint8_t expectedType) {
int retval; int retval;
bzrtpContext_t *zrtpContext = bzrtp_createBzrtpContext(0x12345678); bzrtpContext_t *zrtpContext = bzrtp_createBzrtpContext();
bzrtp_initBzrtpContext(zrtpContext, 0x12345678);
bzrtpPacket_t *helloPacket = NULL; bzrtpPacket_t *helloPacket = NULL;
if (contextTypes != NULL) { if (contextTypes != NULL) {
bzrtp_setSupportedCryptoTypes(zrtpContext, algoType, contextTypes, contextTypesCount); bzrtp_setSupportedCryptoTypes(zrtpContext, algoType, contextTypes, contextTypesCount);
...@@ -352,7 +353,8 @@ static int testAlgoSetterGetter(uint8_t algoType, uint8_t *contextTypes, uint8_t ...@@ -352,7 +353,8 @@ static int testAlgoSetterGetter(uint8_t algoType, uint8_t *contextTypes, uint8_t
uint8_t compareTypes[8]; uint8_t compareTypes[8];
uint8_t compareTypesCount; uint8_t compareTypesCount;
bzrtpContext_t *zrtpContext = bzrtp_createBzrtpContext(0x12345678); bzrtpContext_t *zrtpContext = bzrtp_createBzrtpContext();
bzrtp_initBzrtpContext(zrtpContext, 0x12345678);
bzrtp_setSupportedCryptoTypes(zrtpContext, algoType, contextTypes, contextTypesCount); bzrtp_setSupportedCryptoTypes(zrtpContext, algoType, contextTypes, contextTypesCount);
compareTypesCount = bzrtp_getSupportedCryptoTypes(zrtpContext, algoType, compareTypes); compareTypesCount = bzrtp_getSupportedCryptoTypes(zrtpContext, algoType, compareTypes);
retval = compareAlgoTypes(compareTypes, compareTypesCount, expectedTypes, expectedTypesCount); retval = compareAlgoTypes(compareTypes, compareTypesCount, expectedTypes, expectedTypesCount);
......
...@@ -111,8 +111,10 @@ void test_parser_param(uint8_t hvi_trick) { ...@@ -111,8 +111,10 @@ void test_parser_param(uint8_t hvi_trick) {
bzrtpPacket_t *zrtpPacket; bzrtpPacket_t *zrtpPacket;
/* Create zrtp Context to use H0-H3 chains and others */ /* Create zrtp Context to use H0-H3 chains and others */
bzrtpContext_t *context87654321 = bzrtp_createBzrtpContext(0x87654321); bzrtpContext_t *context87654321 = bzrtp_createBzrtpContext();
bzrtpContext_t *context12345678 = bzrtp_createBzrtpContext(0x12345678); bzrtp_initBzrtpContext(context87654321, 0x87654321);
bzrtpContext_t *context12345678 = bzrtp_createBzrtpContext();
bzrtp_initBzrtpContext(context12345678, 0x12345678);
/* replace created H by the patterns one to be able to generate the correct packet */ /* replace created H by the patterns one to be able to generate the correct packet */
...@@ -282,16 +284,19 @@ typedef struct my_Context_struct { ...@@ -282,16 +284,19 @@ typedef struct my_Context_struct {
unsigned char nom[30]; /* nom du contexte */ unsigned char nom[30]; /* nom du contexte */
bzrtpContext_t *peerContext; bzrtpContext_t *peerContext;
bzrtpChannelContext_t *peerChannelContext; bzrtpChannelContext_t *peerChannelContext;
char zidFilename[80]; /* nom du fichier de cache */
} my_Context_t; } my_Context_t;
typedef struct my_ZIDCacheContext_struct {
char zidFilename[80]; /* nom du fichier de cache */
} my_ZIDCacheContext_t;
static void freeBuf(void* p){ static void freeBuf(void* p){
free(p); free(p);
} }
int floadAlice(void *clientData, uint8_t **output, uint32_t *size, zrtpFreeBuffer_callback *cb) { int floadAlice(void *clientData, uint8_t **output, uint32_t *size, zrtpFreeBuffer_callback *cb) {
/* get filename from ClientData */ /* get filename from ClientData */
my_Context_t *clientContext = (my_Context_t *)clientData; my_ZIDCacheContext_t *clientContext = (my_ZIDCacheContext_t *)clientData;
char *filename = clientContext->zidFilename; char *filename = clientContext->zidFilename;
FILE *ALICECACHE = fopen(filename, "r+"); FILE *ALICECACHE = fopen(filename, "r+");
fseek(ALICECACHE, 0L, SEEK_END); /* Position to end of file */ fseek(ALICECACHE, 0L, SEEK_END); /* Position to end of file */
...@@ -310,7 +315,7 @@ int floadAlice(void *clientData, uint8_t **output, uint32_t *size, zrtpFreeBuffe ...@@ -310,7 +315,7 @@ int floadAlice(void *clientData, uint8_t **output, uint32_t *size, zrtpFreeBuffe
int fwriteAlice(void *clientData, const uint8_t *input, uint32_t size) { int fwriteAlice(void *clientData, const uint8_t *input, uint32_t size) {
/* get filename from ClientData */ /* get filename from ClientData */
my_Context_t *clientContext = (my_Context_t *)clientData; my_ZIDCacheContext_t *clientContext = (my_ZIDCacheContext_t *)clientData;
char *filename = clientContext->zidFilename; char *filename = clientContext->zidFilename;
FILE *ALICECACHE = fopen(filename, "w+"); FILE *ALICECACHE = fopen(filename, "w+");
...@@ -321,7 +326,7 @@ int fwriteAlice(void *clientData, const uint8_t *input, uint32_t size) { ...@@ -321,7 +326,7 @@ int fwriteAlice(void *clientData, const uint8_t *input, uint32_t size) {
int floadBob(void *clientData, uint8_t **output, uint32_t *size, zrtpFreeBuffer_callback *cb) { int floadBob(void *clientData, uint8_t **output, uint32_t *size, zrtpFreeBuffer_callback *cb) {
/* get filename from ClientData */ /* get filename from ClientData */
my_Context_t *clientContext = (my_Context_t *)clientData; my_ZIDCacheContext_t *clientContext = (my_ZIDCacheContext_t *)clientData;
char *filename = clientContext->zidFilename; char *filename = clientContext->zidFilename;
FILE *BOBCACHE = fopen(filename, "r+"); FILE *BOBCACHE = fopen(filename, "r+");
...@@ -343,7 +348,7 @@ int floadBob(void *clientData, uint8_t **output, uint32_t *size, zrtpFreeBuffer_ ...@@ -343,7 +348,7 @@ int floadBob(void *clientData, uint8_t **output, uint32_t *size, zrtpFreeBuffer_
int fwriteBob(void *clientData, const uint8_t *input, uint32_t size) { int fwriteBob(void *clientData, const uint8_t *input, uint32_t size) {
/* get filename from ClientData */ /* get filename from ClientData */
my_Context_t *clientContext = (my_Context_t *)clientData; my_ZIDCacheContext_t *clientContext = (my_ZIDCacheContext_t *)clientData;
char *filename = clientContext->zidFilename; char *filename = clientContext->zidFilename;
FILE *BOBCACHE = fopen(filename, "w+"); FILE *BOBCACHE = fopen(filename, "w+");
...@@ -360,8 +365,8 @@ void test_parserComplete() { ...@@ -360,8 +365,8 @@ void test_parserComplete() {
/* bob's maintained packet */ /* bob's maintained packet */
bzrtpPacket_t *bob_Hello, *bob_HelloFromAlice, *bob_HelloACK, *bob_HelloACKFromAlice; bzrtpPacket_t *bob_Hello, *bob_HelloFromAlice, *bob_HelloACK, *bob_HelloACKFromAlice;
/* Create zrtp Context */ /* Create zrtp Context */
bzrtpContext_t *contextAlice = bzrtp_createBzrtpContext(0x12345678); /* Alice's SSRC of main channel is 12345678 */ bzrtpContext_t *contextAlice = bzrtp_createBzrtpContext();
bzrtpContext_t *contextBob = bzrtp_createBzrtpContext(0x87654321); /* Bob's SSRC of main channel is 87654321 */ bzrtpContext_t *contextBob = bzrtp_createBzrtpContext();
bzrtpHelloMessage_t *alice_HelloFromBob_message; bzrtpHelloMessage_t *alice_HelloFromBob_message;
bzrtpHelloMessage_t *bob_HelloFromAlice_message; bzrtpHelloMessage_t *bob_HelloFromAlice_message;
...@@ -412,29 +417,31 @@ void test_parserComplete() { ...@@ -412,29 +417,31 @@ void test_parserComplete() {
bzrtpCallbacks_t cbs={0}; bzrtpCallbacks_t cbs={0};
/* Create the client context, used for zidFilename only */ /* Create the client context, used for zidFilename only */
my_Context_t clientContextAlice; my_ZIDCacheContext_t clientContextAlice;
my_Context_t clientContextBob; my_ZIDCacheContext_t clientContextBob;
strcpy(clientContextAlice.zidFilename, "./ZIDAlice.txt"); strcpy(clientContextAlice.zidFilename, "./ZIDAlice.txt");
strcpy(clientContextBob.zidFilename, "./ZIDBob.txt"); strcpy(clientContextBob.zidFilename, "./ZIDBob.txt");
/* attach the clientContext to the bzrtp Context */ /* attach the ZIDCache Context to the bzrtp Context */
retval = bzrtp_setClientData(contextAlice, 0x12345678, (void *)&clientContextAlice); retval = bzrtp_setZIDCacheData(contextAlice, (void *)&clientContextAlice);
retval += bzrtp_setClientData(contextBob, 0x87654321, (void *)&clientContextBob); retval += bzrtp_setZIDCacheData(contextBob, (void *)&clientContextBob);
/* set the cache related callback functions */ /* set the cache related callback functions */
cbs.bzrtp_loadCache=floadAlice; cbs.bzrtp_loadCache=floadAlice;
cbs.bzrtp_writeCache=fwriteAlice; cbs.bzrtp_writeCache=fwriteAlice;
bzrtp_setCallbacks(contextAlice, &cbs); bzrtp_setCallbacks(contextAlice, &cbs);
cbs.bzrtp_loadCache=floadBob; cbs.bzrtp_loadCache=floadBob;
cbs.bzrtp_writeCache=fwriteBob; cbs.bzrtp_writeCache=fwriteBob;
bzrtp_setCallbacks(contextBob, &cbs); bzrtp_setCallbacks(contextBob, &cbs);
bzrtp_message ("Init the contexts\n"); bzrtp_message ("Init the contexts\n");
/* end the context init */ /* end the context init */
bzrtp_initBzrtpContext(contextAlice); bzrtp_initBzrtpContext(contextAlice, 0x12345678);/* Alice's SSRC of main channel is 12345678 */
bzrtp_initBzrtpContext(contextBob); bzrtp_initBzrtpContext(contextBob, 0x87654321); /* Bob's SSRC of main channel is 87654321 */
/* now create Alice and BOB Hello packet */ /* now create Alice and BOB Hello packet */
alice_Hello = bzrtp_createZrtpPacket(contextAlice, contextAlice->channelContext[0], MSGTYPE_HELLO, &retval); alice_Hello = bzrtp_createZrtpPacket(contextAlice, contextAlice->channelContext[0], MSGTYPE_HELLO, &retval);
...@@ -1675,6 +1682,7 @@ static void sleepMs(int ms){ ...@@ -1675,6 +1682,7 @@ static void sleepMs(int ms){
void test_stateMachine() { void test_stateMachine() {
int retval; int retval;
my_Context_t aliceClientData, bobClientData; my_Context_t aliceClientData, bobClientData;
my_ZIDCacheContext_t aliceZIDCacheData, bobZIDCacheData;
uint64_t initialTime; uint64_t initialTime;
uint8_t pingPacketString[ZRTP_PACKET_OVERHEAD+ZRTP_PINGMESSAGE_FIXED_LENGTH]; /* there is no builder for ping packet and it is 24 bytes long(12 bytes of message header, 12 of data + packet overhead*/ uint8_t pingPacketString[ZRTP_PACKET_OVERHEAD+ZRTP_PINGMESSAGE_FIXED_LENGTH]; /* there is no builder for ping packet and it is 24 bytes long(12 bytes of message header, 12 of data + packet overhead*/
uint32_t CRC; uint32_t CRC;
...@@ -1683,8 +1691,14 @@ void test_stateMachine() { ...@@ -1683,8 +1691,14 @@ void test_stateMachine() {
bzrtpCallbacks_t cbs={0} ; bzrtpCallbacks_t cbs={0} ;
/* Create zrtp Context */ /* Create zrtp Context */
bzrtpContext_t *contextAlice = bzrtp_createBzrtpContext(0x12345678); /* Alice's SSRC of main channel is 12345678 */ bzrtpContext_t *contextAlice = bzrtp_createBzrtpContext();
bzrtpContext_t *contextBob = bzrtp_createBzrtpContext(0x87654321); /* Bob's SSRC of main channel is 87654321 */ bzrtpContext_t *contextBob = bzrtp_createBzrtpContext();
/* Create the ZIDCache data and associate them to the zrtp contexts */
strcpy(aliceZIDCacheData.zidFilename, "./ZIDAlice.txt");
strcpy(bobZIDCacheData.zidFilename, "./ZIDBob.txt");
bzrtp_setZIDCacheData(contextAlice, (void *)&aliceZIDCacheData);
bzrtp_setZIDCacheData(contextBob, (void *)&bobZIDCacheData);
/* set the cache related callback functions */ /* set the cache related callback functions */
cbs.bzrtp_loadCache=floadAlice; cbs.bzrtp_loadCache=floadAlice;
...@@ -1704,17 +1718,16 @@ void test_stateMachine() { ...@@ -1704,17 +1718,16 @@ void test_stateMachine() {
aliceClientData.peerChannelContext = contextBob->channelContext[0]; aliceClientData.peerChannelContext = contextBob->channelContext[0];
bobClientData.peerContext = contextAlice; bobClientData.peerContext = contextAlice;
bobClientData.peerChannelContext = contextAlice->channelContext[0]; bobClientData.peerChannelContext = contextAlice->channelContext[0];
strcpy(aliceClientData.zidFilename, "./ZIDAlice.txt");
strcpy(bobClientData.zidFilename, "./ZIDBob.txt");
/* run the init */
bzrtp_initBzrtpContext(contextAlice, 0x12345678);/* Alice's SSRC of main channel is 12345678 */
bzrtp_initBzrtpContext(contextBob, 0x87654321); /* Bob's SSRC of main channel is 87654321 */
retval = bzrtp_setClientData(contextAlice, 0x12345678, (void *)&aliceClientData); retval = bzrtp_setClientData(contextAlice, 0x12345678, (void *)&aliceClientData);
retval += bzrtp_setClientData(contextBob, 0x87654321, (void *)&bobClientData); retval += bzrtp_setClientData(contextBob, 0x87654321, (void *)&bobClientData);
bzrtp_message("Set client data return %x\n", retval); bzrtp_message("Set client data return %x\n", retval);
/* run the init */
bzrtp_initBzrtpContext(contextAlice);