Commit 3ada46aa authored by johan's avatar johan

Multistream mode functional

+ srtp secrets send first receiver then sender to the client to
meet protocol requirement allowing optional sending of conf2ACK packet
+ move packet check in processMessage function
to prepare for ping and error zrtp message processing
parent d177fb87
......@@ -42,6 +42,12 @@ typedef struct bzrtpContext_struct bzrtpContext_t;
#define ZRTP_AUTHTAG_SK32 0x33
#define ZRTP_AUTHTAG_SK64 0x34
/**
* Define to give client indication on which srtp secrets are valid when given
*/
#define ZRTP_SRTP_SECRETS_FOR_SENDER 0x01
#define ZRTP_SRTP_SECRETS_FOR_RECEIVER 0x02
/**
* brief The data structure containing the keys and algorithms to be used by srtp */
typedef struct bzrtpSrtpSecrets_struct {
......@@ -57,6 +63,7 @@ typedef struct bzrtpSrtpSecrets_struct {
uint8_t cipherKeyLength; /**< The key length in bytes for the cipher block algorithm used by srtp */
uint8_t authTagAlgo; /**< srtp authentication tag algorithm agreed on after Hello packet exchange */
char *sas; /* a null terminated char containing the Short Authentication String */
uint8_t sasLength; /* The lenght of sas, including the termination character */
} bzrtpSrtpSecrets_t;
#define ZRTP_MAGIC_COOKIE 0x5a525450
......@@ -97,11 +104,12 @@ __attribute__ ((visibility ("default"))) bzrtpContext_t *bzrtp_createBzrtpContex
__attribute__ ((visibility ("default"))) void bzrtp_initBzrtpContext(bzrtpContext_t *context);
/**
* Free memory of context structure
* @param[in] context BZRtp context to be destroyed.
* Free memory of context structure to a channel, if all channels are freed, free the global zrtp context
* @param[in] context Context hosting the channel to be destroyed.(note: the context zrtp context itself is destroyed with the last channel)
* @param[in] selfSSRC The SSRC identifying the channel to be destroyed
*
*/
__attribute__ ((visibility ("default"))) void bzrtp_destroyBzrtpContext(bzrtpContext_t *context);
__attribute__ ((visibility ("default"))) void bzrtp_destroyBzrtpContext(bzrtpContext_t *context, uint32_t selfSSRC);
#define ZRTP_CALLBACK_READCACHE 0x0101
#define ZRTP_CALLBACK_WRITECACHE 0x0102
......
......@@ -46,6 +46,7 @@ typedef struct bzrtpEvent_struct {
uint8_t eventType; /**< Event can be a message or a timer's end */
uint8_t *bzrtpPacketString; /**< a pointer to the zrtp packet string, NULL in case of timer event */
uint16_t bzrtpPacketStringLength; /**< the length of packet string in bytes */
bzrtpPacket_t *bzrtpPacket; /**< a pointer to the zrtp packet structure created by the processMessage function */
bzrtpContext_t *zrtpContext; /**< the current ZRTP context */
bzrtpChannelContext_t *zrtpChannelContext; /**< the current ZRTP channel hosting this state machine context */
} bzrtpEvent_t;
......
......@@ -110,7 +110,7 @@ typedef struct zrtpCallbacks_struct {
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); /**< Send the srtp secrets to the client, it may wait for the end of ZRTP process before using it */
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 */
} zrtpCallbacks_t;
......@@ -157,6 +157,7 @@ typedef struct bzrtpChannelContext_struct {
uint8_t keyAgreementAlgo; /**< key agreement algorithm agreed on after Hello packet exchange, stored using integer mapping defined in cryptoWrapper.h */
uint16_t keyAgreementLength; /**< the length in byte of the secret generated by the agreed key exchange algo */
uint8_t sasAlgo; /**< sas rendering algorithm agreed on after Hello packet exchange, stored using integer mapping defined in cryptoWrapper.h */
uint8_t sasLength; /**< lenght of the SAS depends on the algorithm agreed */
/* function pointer to the agreed algorithms - Note, key agreement manage directly this selection so it is not set here */
void (*hmacFunction)(const uint8_t *key, uint8_t keyLength, const uint8_t *input, uint32_t inputLength, uint8_t hmacLength, uint8_t *output); /**< function pointer to the agreed hmacFunction */
......
......@@ -38,7 +38,7 @@
/* local functions */
int bzrtp_initChannelContext(bzrtpContext_t *zrtpContext, bzrtpChannelContext_t *zrtpChannelContext, uint32_t selfSSRC);
void bzrtp_destroyChannelContext(bzrtpContext_t *zrtpContext, uint8_t channelIndex);
void bzrtp_destroyChannelContext(bzrtpContext_t *zrtpContext, bzrtpChannelContext_t *zrtpChannelContext);
bzrtpChannelContext_t *getChannelContext(bzrtpContext_t *zrtpContext, uint32_t selfSSRC);
/*
......@@ -120,23 +120,41 @@ void bzrtp_initBzrtpContext(bzrtpContext_t *context) {
getSelfZID(context, context->selfZID);
}
/**
* Free memory of context structure
* @param[in] context BZRtp context to be destroyed.
/*
* Free memory of context structure to a channel, if all channels are freed, free the global zrtp context
* @param[in] context Context hosting the channel to be destroyed.(note: the context zrtp context itself is destroyed with the last channel)
* @param[in] selfSSRC The SSRC identifying the channel to be destroyed
*
*/
void bzrtp_destroyBzrtpContext(bzrtpContext_t *context)
void bzrtp_destroyBzrtpContext(bzrtpContext_t *context, uint32_t selfSSRC)
{
if (context == NULL) {
return;
}
int i;
/* destroy contexts */
bzrtpCrypto_DestroyDHMContext(context->DHMContext);
context->DHMContext = NULL;
/* Find the channel to be destroyed, destroy it and check if we have anymore valid channels */
int validChannelsNumber = 0;
for (i=0; i<ZRTP_MAX_CHANNEL_NUMBER; i++) {
if (context->channelContext[i] != NULL) {
if (context->channelContext[i]->selfSSRC == selfSSRC) {
bzrtp_destroyChannelContext(context, context->channelContext[i]);
context->channelContext[i] = NULL;
} else {
validChannelsNumber++;
}
}
}
if (validChannelsNumber>0) {
return; /* we have more valid channels, keep the zrtp context */
}
/* destroy channel contexts */
for (i=0; i<ZRTP_MAX_CHANNEL_NUMBER; i++) {
bzrtp_destroyChannelContext(context, i);
context->channelContext[i] = NULL;
/* We have no more channel, destroy the zrtp context */
if (context->DHMContext != NULL) {
bzrtpCrypto_DestroyDHMContext(context->DHMContext);
context->DHMContext = NULL;
}
/* free allocated buffers */
......@@ -186,7 +204,7 @@ int bzrtp_setCallback(bzrtpContext_t *context, int (*functionPointer)(), uint16_
context->zrtpCallbacks.bzrtp_sendData = (int (*)(void *, uint8_t *, uint16_t))functionPointer;
break;
case ZRTP_CALLBACK_SRTPSECRETSAVAILABLE:
context->zrtpCallbacks.bzrtp_srtpSecretsAvailable = (int (*)(void *, bzrtpSrtpSecrets_t *))functionPointer;
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;
......@@ -364,15 +382,26 @@ int bzrtp_processMessage(bzrtpContext_t *zrtpContext, uint32_t selfSSRC, uint8_t
return BZRTP_ERROR_INVALIDCONTEXT;
}
/* first check the packet */
int retval;
bzrtpPacket_t *zrtpPacket = bzrtp_packetCheck(zrtpPacketString, zrtpPacketStringLength, zrtpChannelContext->peerSequenceNumber, &retval);
if (retval != 0) {
/*TODO: check the returned error code and do something or silent drop? */
return retval;
}
/* TODO: Intercept error and ping zrtp packets */
/* build a packet event of it and send it to the state machine */
bzrtpEvent_t event;
event.eventType = BZRTP_EVENT_MESSAGE;
event.bzrtpPacketString = zrtpPacketString;
event.bzrtpPacketStringLength = zrtpPacketStringLength;
event.bzrtpPacket = zrtpPacket;
event.zrtpContext = zrtpContext;
event.zrtpChannelContext = zrtpChannelContext;
int retval = zrtpChannelContext->stateMachine(event);
retval = zrtpChannelContext->stateMachine(event);
return retval;
}
......@@ -512,17 +541,11 @@ int bzrtp_initChannelContext(bzrtpContext_t *zrtpContext, bzrtpChannelContext_t
* @brief Destroy the context of a channel
* Free allocated buffers, destroy keys
*
* @param[in] zrtpContext The zrtpContext hosting this channel
* @param[in/out] channelIndex The index of the channel to be freed in the ZRTP context channel array
* @param[in] zrtpContext The zrtpContext hosting this channel, needed to acces the RNG
* @param[in] zrtpChannelContext The channel context to be destroyed
*/
void bzrtp_destroyChannelContext(bzrtpContext_t *zrtpContext, uint8_t channelIndex) {
void bzrtp_destroyChannelContext(bzrtpContext_t *zrtpContext, bzrtpChannelContext_t *zrtpChannelContext) {
int i;
if (zrtpContext == NULL) {
return;
}
bzrtpChannelContext_t *zrtpChannelContext = zrtpContext->channelContext[channelIndex];
/* check there is something to be freed */
if (zrtpChannelContext == NULL) {
......@@ -564,4 +587,17 @@ void bzrtp_destroyChannelContext(bzrtpContext_t *zrtpContext, uint8_t channelInd
zrtpChannelContext->selfPackets[i] = NULL;
zrtpChannelContext->peerPackets[i] = NULL;
}
/* destroy and free the srtp and sas struture */
bzrtp_DestroyKey(zrtpChannelContext->srtpSecrets.selfSrtpKey, zrtpChannelContext->srtpSecrets.selfSrtpKeyLength, zrtpContext->RNGContext);
bzrtp_DestroyKey(zrtpChannelContext->srtpSecrets.selfSrtpSalt, zrtpChannelContext->srtpSecrets.selfSrtpSaltLength, zrtpContext->RNGContext);
bzrtp_DestroyKey(zrtpChannelContext->srtpSecrets.peerSrtpKey, zrtpChannelContext->srtpSecrets.peerSrtpKeyLength, zrtpContext->RNGContext);
bzrtp_DestroyKey(zrtpChannelContext->srtpSecrets.peerSrtpSalt, zrtpChannelContext->srtpSecrets.peerSrtpSaltLength, zrtpContext->RNGContext);
bzrtp_DestroyKey((uint8_t *)zrtpChannelContext->srtpSecrets.sas, zrtpChannelContext->srtpSecrets.sasLength, zrtpContext->RNGContext);
free(zrtpChannelContext->srtpSecrets.selfSrtpKey);
free(zrtpChannelContext->srtpSecrets.selfSrtpSalt);
free(zrtpChannelContext->srtpSecrets.peerSrtpKey);
free(zrtpChannelContext->srtpSecrets.peerSrtpSalt);
free(zrtpChannelContext->srtpSecrets.sas);
}
......@@ -403,9 +403,11 @@ int updateCryptoFunctionPointers(bzrtpChannelContext_t *zrtpChannelContext) {
switch(zrtpChannelContext->sasAlgo) {
case ZRTP_SAS_B32:
zrtpChannelContext->sasFunction = bzrtp_base32;
zrtpChannelContext->sasLength = 4;
break;
case ZRTP_UNSET_ALGO :
zrtpChannelContext->sasFunction = NULL;
zrtpChannelContext->sasLength = 0;
break;
default:
return ZRTP_CRYPTOAGREEMENT_INVALIDSAS;
......
This diff is collapsed.
......@@ -497,5 +497,5 @@ void test_algoAgreement(void) {
CU_FAIL("Algo agreement test 2");
}
bzrtp_destroyBzrtpContext(zrtpContext);
bzrtp_destroyBzrtpContext(zrtpContext, 0x12345678);
}
......@@ -157,8 +157,8 @@ void test_parser(void) {
bzrtp_freeZrtpPacket(zrtpPacket);
}
bzrtp_destroyBzrtpContext(context69473e6a);
bzrtp_destroyBzrtpContext(context5516868e);
bzrtp_destroyBzrtpContext(context69473e6a, 0x69473e6a);
bzrtp_destroyBzrtpContext(context5516868e, 0x5516868e);
}
......@@ -1376,8 +1376,8 @@ void test_parserComplete() {
dumpContext("\nBob", contextBob);
*/
/* destroy the context */
bzrtp_destroyBzrtpContext(contextBob);
bzrtp_destroyBzrtpContext(contextAlice);
bzrtp_destroyBzrtpContext(contextBob, 0x87654321);
bzrtp_destroyBzrtpContext(contextAlice, 0x12345678);
}
......
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