Commit 6700df00 authored by johan's avatar johan

Merge branch 'master' into zrtphash

Conflicts:
	test/bzrtpParserTest.c
parents 43eef42c 9e1c7bf8
......@@ -42,6 +42,7 @@
#define BZRTP_PARSER_ERROR_UNMATCHINGHASHCHAIN 0xa080
#define BZRTP_PARSER_ERROR_UNMATCHINGMAC 0xa100
#define BZRTP_PARSER_ERROR_UNEXPECTEDMESSAGE 0xa200
#define BZRTP_PARSER_ERROR_UNMATCHINGHVI 0xa400
#define BZRTP_BUILDER_ERROR_INVALIDPACKET 0x5001
#define BZRTP_BUILDER_ERROR_INVALIDMESSAGE 0x5002
......
......@@ -157,23 +157,40 @@ void bzrtp_destroyBzrtpContext(bzrtpContext_t *context, uint32_t selfSSRC) {
/* We have no more channel, destroy the zrtp context */
/* DHM context shall already been destroyed after s0 computation, but just in case */
if (context->DHMContext != NULL) {
bctoolbox_DestroyDHMContext(context->DHMContext);
context->DHMContext = NULL;
}
/* free allocated buffers */
free(context->cachedSecret.rs1);
free(context->cachedSecret.rs2);
free(context->cachedSecret.pbxsecret);
free(context->cachedSecret.auxsecret);
free(context->ZRTPSess);
/* Destroy keys and secrets */
/* rs1, rs2, pbxsecret and auxsecret shall already been destroyed, just in case */
if (context->cachedSecret.rs1!=NULL) {
bzrtp_DestroyKey(context->cachedSecret.rs1, context->cachedSecret.rs1Length, context->RNGContext);
free(context->cachedSecret.rs1);
context->cachedSecret.rs1 = NULL;
}
if (context->cachedSecret.rs2!=NULL) {
bzrtp_DestroyKey(context->cachedSecret.rs2, context->cachedSecret.rs2Length, context->RNGContext);
free(context->cachedSecret.rs2);
context->cachedSecret.rs2 = NULL;
}
if (context->cachedSecret.auxsecret!=NULL) {
bzrtp_DestroyKey(context->cachedSecret.auxsecret, context->cachedSecret.auxsecretLength, context->RNGContext);
free(context->cachedSecret.auxsecret);
context->cachedSecret.auxsecret = NULL;
}
if (context->cachedSecret.pbxsecret!=NULL) {
bzrtp_DestroyKey(context->cachedSecret.pbxsecret, context->cachedSecret.pbxsecretLength, context->RNGContext);
free(context->cachedSecret.pbxsecret);
context->cachedSecret.pbxsecret = NULL;
}
context->cachedSecret.rs1=NULL;
context->cachedSecret.rs2=NULL;
context->cachedSecret.pbxsecret=NULL;
context->cachedSecret.auxsecret=NULL;
context->ZRTPSess=NULL;
if (context->ZRTPSess!=NULL) {
bzrtp_DestroyKey(context->ZRTPSess, context->ZRTPSessLength, context->RNGContext);
free(context->ZRTPSess);
context->ZRTPSess=NULL;
}
#ifdef HAVE_LIBXML2
xmlFreeDoc(context->cacheBuffer);
......
......@@ -454,6 +454,32 @@ int bzrtp_packetParser(bzrtpContext_t *zrtpContext, bzrtpChannelContext_t *zrtpC
free (messageData);
return BZRTP_PARSER_ERROR_UNMATCHINGMAC;
}
/* Check the hvi received in the commit message - RFC section 4.4.1.1*/
/* First compute the expected hvi */
/* hvi = hash(initiator's DHPart2 message(current zrtpPacket)) || responder's Hello message) using the agreed hash function truncated to 256 bits */
/* create a string with the messages concatenated */
{
uint8_t computedHvi[32];
uint16_t HelloMessageLength = zrtpChannelContext->selfPackets[HELLO_MESSAGE_STORE_ID]->messageLength;
uint16_t DHPartHelloMessageStringLength = zrtpPacket->messageLength + HelloMessageLength;
uint8_t *DHPartHelloMessageString = (uint8_t *)malloc(DHPartHelloMessageStringLength*sizeof(uint8_t));
memcpy(DHPartHelloMessageString, input+ZRTP_PACKET_HEADER_LENGTH, zrtpPacket->messageLength);
memcpy(DHPartHelloMessageString+zrtpPacket->messageLength, zrtpChannelContext->selfPackets[HELLO_MESSAGE_STORE_ID]->packetString+ZRTP_PACKET_HEADER_LENGTH, HelloMessageLength);
zrtpChannelContext->hashFunction(DHPartHelloMessageString, DHPartHelloMessageStringLength, 32, computedHvi);
free(DHPartHelloMessageString);
/* Compare computed and received hvi */
if (memcmp(computedHvi, peerCommitMessageData->hvi, 32)!=0) {
free (messageData);
return BZRTP_PARSER_ERROR_UNMATCHINGHVI;
}
}
} else { /* if we are initiator(we didn't received any commit message and then no H2), we must check that H3=SHA256(SHA256(H1)) and the Hello message MAC */
uint8_t checkH2[32];
uint8_t checkH3[32];
......@@ -498,7 +524,7 @@ int bzrtp_packetParser(bzrtpContext_t *zrtpContext, bzrtpChannelContext_t *zrtpC
/* attach the message structure to the packet one */
zrtpPacket->messageData = (void *)messageData;
/* the parsed commit packet must be saved as it is used to generate the total_hash */
/* the parsed packet must be saved as it is used to generate the total_hash */
zrtpPacket->packetString = (uint8_t *)malloc(inputLength*sizeof(uint8_t));
memcpy(zrtpPacket->packetString, input, inputLength); /* store the whole packet even if we may use the message only */
}
......
......@@ -1883,6 +1883,11 @@ int bzrtp_computeS0DHMMode(bzrtpContext_t *zrtpContext, bzrtpChannelContext_t *z
hashDataIndex += s3Length;
}
/* clean local s1,s2,s3 pointers as they are not needed anymore */
s1=NULL;
s2=NULL;
s3=NULL;
zrtpChannelContext->s0 = (uint8_t *)malloc(zrtpChannelContext->hashLength*sizeof(uint8_t));
zrtpChannelContext->hashFunction(dataToHash, hashDataLength, zrtpChannelContext->hashLength, zrtpChannelContext->s0);
......@@ -1899,33 +1904,12 @@ int bzrtp_computeS0DHMMode(bzrtpContext_t *zrtpContext, bzrtpChannelContext_t *z
(void (*)(uint8_t *, uint8_t, uint8_t *, uint32_t, uint8_t, uint8_t *))zrtpChannelContext->hmacFunction,
zrtpContext->ZRTPSess);
/* clean the DHM context (secret and key shall be erased by this operation) */
bctoolbox_DestroyDHMContext(zrtpContext->DHMContext);
zrtpContext->DHMContext = NULL;
/* now derive the other keys */
return bzrtp_deriveKeysFromS0(zrtpContext, zrtpChannelContext);
/* destroy all cached keys in context */
/* TODO : Check secret cache update?? */
/*if (contextAlice->cachedSecret.rs1!=NULL) {
bzrtp_DestroyKey(contextAlice->cachedSecret.rs1, contextAlice->cachedSecret.rs1Length, contextAlice->RNGContext);
free(contextAlice->cachedSecret.rs1);
contextAlice->cachedSecret.rs1 = NULL;
}
if (contextAlice->cachedSecret.rs2!=NULL) {
bzrtp_DestroyKey(contextAlice->cachedSecret.rs2, contextAlice->cachedSecret.rs2Length, contextAlice->RNGContext);
free(contextAlice->cachedSecret.rs2);
contextAlice->cachedSecret.rs2 = NULL;
}
if (contextAlice->cachedSecret.auxsecret!=NULL) {
bzrtp_DestroyKey(contextAlice->cachedSecret.auxsecret, contextAlice->cachedSecret.auxsecretLength, contextAlice->RNGContext);
free(contextAlice->cachedSecret.auxsecret);
contextAlice->cachedSecret.auxsecret = NULL;
}
if (contextAlice->cachedSecret.pbxsecret!=NULL) {
bzrtp_DestroyKey(contextAlice->cachedSecret.pbxsecret, contextAlice->cachedSecret.pbxsecretLength, contextAlice->RNGContext);
free(contextAlice->cachedSecret.pbxsecret);
contextAlice->cachedSecret.pbxsecret = NULL;
}*/
return 0;
}
/**
......@@ -2174,5 +2158,27 @@ int bzrtp_updateCachedSecrets(bzrtpContext_t *zrtpContext, bzrtpChannelContext_t
free(zrtpChannelContext->s0);
zrtpChannelContext->s0 = NULL;
/* destroy all cached keys in context they are not needed anymore (multistream mode doesn't use them to compute s0) */
if (zrtpContext->cachedSecret.rs1!=NULL) {
bzrtp_DestroyKey(zrtpContext->cachedSecret.rs1, zrtpContext->cachedSecret.rs1Length, zrtpContext->RNGContext);
free(zrtpContext->cachedSecret.rs1);
zrtpContext->cachedSecret.rs1 = NULL;
}
if (zrtpContext->cachedSecret.rs2!=NULL) {
bzrtp_DestroyKey(zrtpContext->cachedSecret.rs2, zrtpContext->cachedSecret.rs2Length, zrtpContext->RNGContext);
free(zrtpContext->cachedSecret.rs2);
zrtpContext->cachedSecret.rs2 = NULL;
}
if (zrtpContext->cachedSecret.auxsecret!=NULL) {
bzrtp_DestroyKey(zrtpContext->cachedSecret.auxsecret, zrtpContext->cachedSecret.auxsecretLength, zrtpContext->RNGContext);
free(zrtpContext->cachedSecret.auxsecret);
zrtpContext->cachedSecret.auxsecret = NULL;
}
if (zrtpContext->cachedSecret.pbxsecret!=NULL) {
bzrtp_DestroyKey(zrtpContext->cachedSecret.pbxsecret, zrtpContext->cachedSecret.pbxsecretLength, zrtpContext->RNGContext);
free(zrtpContext->cachedSecret.pbxsecret);
zrtpContext->cachedSecret.pbxsecret = NULL;
}
return 0;
}
......@@ -105,7 +105,8 @@ uint8_t mackeyr[32] = {0x3a, 0xa5, 0x22, 0x43, 0x26, 0x13, 0x8f, 0xd6, 0x54, 0x5
uint8_t zrtpkeyi[16] = {0x22, 0xf6, 0xea, 0xaa, 0xa4, 0xad, 0x53, 0x30, 0x71, 0x97, 0xcc, 0x68, 0x6b, 0xb0, 0xcb, 0x55};
uint8_t zrtpkeyr[16] = {0x09, 0x50, 0xcd, 0x9e, 0xc2, 0x78, 0x54, 0x31, 0x93, 0x2e, 0x99, 0x31, 0x15, 0x58, 0xd0, 0x2a};
void test_parser(void) {
void test_parser_param(uint8_t hvi_trick) {
int i, retval;
bzrtpPacket_t *zrtpPacket;
......@@ -166,15 +167,37 @@ void test_parser(void) {
/* parse a packet string from patterns */
zrtpPacket = bzrtp_packetCheck(patternZRTPPackets[i], patternZRTPMetaData[i][0], (patternZRTPMetaData[i][1])-1, &retval);
retval += bzrtp_packetParser((patternZRTPMetaData[i][2]==0x87654321)?context12345678:context87654321, (patternZRTPMetaData[i][2]==0x87654321)?context12345678->channelContext[0]:context87654321->channelContext[0], patternZRTPPackets[i], patternZRTPMetaData[i][0], zrtpPacket);
bzrtp_message("parsing Ret val is %x index is %d\n", retval, i);
CU_ASSERT_EQUAL_FATAL(retval,0);
if (hvi_trick==0) {
CU_ASSERT_EQUAL_FATAL(retval,0);
} else { /* when hvi trick is enable, the DH2 parsing shall fail and return BZRTP_PARSER_ERROR_UNMATCHINGHVI */
if (zrtpPacket->messageType==MSGTYPE_DHPART2) {
CU_ASSERT_EQUAL_FATAL(retval, BZRTP_PARSER_ERROR_UNMATCHINGHVI);
/* We shall then anyway skip the end of the test */
/* reset pointers to selfHello packet in order to avoid double free */
context87654321->channelContext[0]->selfPackets[HELLO_MESSAGE_STORE_ID] = NULL;
context12345678->channelContext[0]->selfPackets[HELLO_MESSAGE_STORE_ID] = NULL;
bzrtp_destroyBzrtpContext(context87654321, 0x87654321);
bzrtp_destroyBzrtpContext(context12345678, 0x12345678);
return;
} else {
CU_ASSERT_EQUAL_FATAL(retval,0);
}
}
bzrtp_message("parsing Ret val is %x index is %d\n", retval, i);
/* We must store some packets in the context if we want to be able to parse further packets */
/* Check also the zrtp hello hash */
if (zrtpPacket->messageType==MSGTYPE_HELLO) {
if (patternZRTPMetaData[i][2]==0x87654321) {
context12345678->channelContext[0]->peerPackets[HELLO_MESSAGE_STORE_ID] = zrtpPacket;
context87654321->channelContext[0]->selfPackets[HELLO_MESSAGE_STORE_ID] = zrtpPacket;
} else {
context87654321->channelContext[0]->peerPackets[HELLO_MESSAGE_STORE_ID] = zrtpPacket;
context12345678->channelContext[0]->selfPackets[HELLO_MESSAGE_STORE_ID] = zrtpPacket;
/* Set an incorrect peerHello Hash after the packet hello packet arrives */
retval = bzrtp_setPeerHelloHash(context87654321, 0x87654321, (uint8_t *)patternZRTPIncorrectHelloHash12345678, strlen((const char *)patternZRTPIncorrectHelloHash12345678));
......@@ -222,13 +245,38 @@ void test_parser(void) {
if (freePacketFlag == 1) {
bzrtp_freeZrtpPacket(zrtpPacket);
}
/* modify the hvi stored in the peerPackets, this shall result in parsing failure on DH2 packet */
if (hvi_trick == 1) {
if (zrtpPacket->messageType==MSGTYPE_COMMIT) {
if (patternZRTPMetaData[i][2]==0x87654321) {
bzrtpCommitMessage_t *peerCommitMessageData;
peerCommitMessageData = (bzrtpCommitMessage_t *)zrtpPacket->messageData;
peerCommitMessageData->hvi[0]=0xFF;
}
}
}
}
/* reset pointers to selfHello packet in order to avoid double free */
context87654321->channelContext[0]->selfPackets[HELLO_MESSAGE_STORE_ID] = NULL;
context12345678->channelContext[0]->selfPackets[HELLO_MESSAGE_STORE_ID] = NULL;
bzrtp_destroyBzrtpContext(context87654321, 0x87654321);
bzrtp_destroyBzrtpContext(context12345678, 0x12345678);
}
void test_parser(void) {
test_parser_param(0);
}
void test_parser_hvi(void) {
test_parser_param(1);
}
/* 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 */
......
......@@ -20,5 +20,6 @@
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
void test_parser(void);
void test_parser_hvi(void);
void test_parserComplete(void);
void test_stateMachine(void);
......@@ -75,6 +75,7 @@ int main(int argc, char *argv[] ) {
/* Add the parser suite to the registry */
parserTestSuite = CU_add_suite("Bzrtp ZRTP Packet Parser", NULL, NULL);
CU_add_test(parserTestSuite, "Parse", test_parser);
CU_add_test(parserTestSuite, "Parse hvi check fail", test_parser_hvi);
CU_add_test(parserTestSuite, "Parse Exchange", test_parserComplete);
CU_add_test(parserTestSuite, "State machine", test_stateMachine);
......
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