/** * @brief Destroy the context of a channel * Free allocated buffers, destroy keys * * @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, bzrtpChannelContext_t *zrtpChannelContext) { int i; /* check there is something to be freed */ if (zrtpChannelContext == NULL) { return; } /* reset state Machine */ zrtpChannelContext->stateMachine = NULL; /* set timer off */ zrtpChannelContext->timer.status = BZRTP_TIMER_OFF; /* destroy and free the key buffers */ bzrtp_DestroyKey(zrtpChannelContext->s0, zrtpChannelContext->hashLength, zrtpContext->RNGContext); bzrtp_DestroyKey(zrtpChannelContext->KDFContext, zrtpChannelContext->KDFContextLength, zrtpContext->RNGContext); bzrtp_DestroyKey(zrtpChannelContext->mackeyi, zrtpChannelContext->hashLength, zrtpContext->RNGContext); bzrtp_DestroyKey(zrtpChannelContext->mackeyr, zrtpChannelContext->hashLength, zrtpContext->RNGContext); bzrtp_DestroyKey(zrtpChannelContext->zrtpkeyi, zrtpChannelContext->cipherKeyLength, zrtpContext->RNGContext); bzrtp_DestroyKey(zrtpChannelContext->zrtpkeyr, zrtpChannelContext->cipherKeyLength, zrtpContext->RNGContext); free(zrtpChannelContext->s0); free(zrtpChannelContext->KDFContext); free(zrtpChannelContext->mackeyi); free(zrtpChannelContext->mackeyr); free(zrtpChannelContext->zrtpkeyi); free(zrtpChannelContext->zrtpkeyr); zrtpChannelContext->s0=NULL; zrtpChannelContext->KDFContext=NULL; zrtpChannelContext->mackeyi=NULL; zrtpChannelContext->mackeyr=NULL; zrtpChannelContext->zrtpkeyi=NULL; zrtpChannelContext->zrtpkeyr=NULL; /* free the allocated buffers */ for (i=0; i<PACKET_STORAGE_CAPACITY; i++) { bzrtp_freeZrtpPacket(zrtpChannelContext->selfPackets[i]); bzrtp_freeZrtpPacket(zrtpChannelContext->peerPackets[i]); 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); /* free the channel context */ free(zrtpChannelContext); }
static int testAlgoType(uint8_t algoType, uint8_t *packetTypes, uint8_t packetTypesCount, uint8_t *contextTypes, uint8_t contextTypesCount, uint8_t expectedType) { int retval; bzrtpContext_t *zrtpContext = bzrtp_createBzrtpContext(); bzrtpPacket_t *helloPacket = NULL; bzrtp_initBzrtpContext(zrtpContext, 0x12345678); if (contextTypes != NULL) { bzrtp_setSupportedCryptoTypes(zrtpContext, algoType, contextTypes, contextTypesCount); } helloPacket = bzrtp_createZrtpPacket(zrtpContext, zrtpContext->channelContext[0], MSGTYPE_HELLO, &retval); if (packetTypes != NULL) { bzrtpHelloMessage_t *helloMessage = (bzrtpHelloMessage_t *)helloPacket->messageData; setHelloMessageAlgo(helloMessage, algoType, packetTypes, packetTypesCount); } CU_ASSERT_FALSE(crypoAlgoAgreement(zrtpContext, zrtpContext->channelContext[0], helloPacket->messageData)); retval = compareAllAlgoTypesWithExpectedChangedOnly(zrtpContext->channelContext[0], algoType, expectedType); bzrtp_freeZrtpPacket(helloPacket); bzrtp_destroyBzrtpContext(zrtpContext, 0x12345678); return retval; }
/* * @brief Process a received message * * @param[in/out] zrtpContext The ZRTP context we're dealing with * @param[in] selfSSRC The SSRC identifying the channel receiving the message * @param[in] zrtpPacketString The packet received * @param[in] zrtpPacketStringLength Length of the packet in bytes * * @return 0 on success, errorcode otherwise */ int bzrtp_processMessage(bzrtpContext_t *zrtpContext, uint32_t selfSSRC, uint8_t *zrtpPacketString, uint16_t zrtpPacketStringLength) { int retval; bzrtpPacket_t *zrtpPacket; bzrtpEvent_t event; /* get channel context */ bzrtpChannelContext_t *zrtpChannelContext = getChannelContext(zrtpContext, selfSSRC); if (zrtpChannelContext == NULL) { return BZRTP_ERROR_INVALIDCONTEXT; } /* check the context is initialised (we may receive packets before initialisation is complete i.e. between channel initialisation and channel start) */ if (zrtpChannelContext->stateMachine == NULL) { return BZRTP_ERROR_INVALIDCONTEXT; /* drop the message */ } /* first check the packet */ 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 */ /* if we have a ping packet, just answer with a ping ACK and do not forward to the state machine */ if (zrtpPacket->messageType == MSGTYPE_PING) { bzrtpPacket_t *pingAckPacket = NULL; bzrtp_packetParser(zrtpContext, zrtpChannelContext, zrtpPacketString, zrtpPacketStringLength, zrtpPacket); /* store ping packet in the channel context as packet creator will need it to create the pingACK */ zrtpChannelContext->pingPacket = zrtpPacket; /* create the pingAck packet */ pingAckPacket = bzrtp_createZrtpPacket(zrtpContext, zrtpChannelContext, MSGTYPE_PINGACK, &retval); if (retval == 0) { retval = bzrtp_packetBuild(zrtpContext, zrtpChannelContext, pingAckPacket, zrtpChannelContext->selfSequenceNumber); if (retval==0 && zrtpContext->zrtpCallbacks.bzrtp_sendData!=NULL) { /* send the packet */ zrtpContext->zrtpCallbacks.bzrtp_sendData(zrtpChannelContext->clientData, pingAckPacket->packetString, pingAckPacket->messageLength+ZRTP_PACKET_OVERHEAD); zrtpChannelContext->selfSequenceNumber++; } } /* free packets and reset channel context storage */ bzrtp_freeZrtpPacket(zrtpPacket); bzrtp_freeZrtpPacket(pingAckPacket); zrtpChannelContext->pingPacket = NULL; return retval; } /* build a packet event of it and send it to the state machine */ event.eventType = BZRTP_EVENT_MESSAGE; event.bzrtpPacketString = zrtpPacketString; event.bzrtpPacketStringLength = zrtpPacketStringLength; event.bzrtpPacket = zrtpPacket; event.zrtpContext = zrtpContext; event.zrtpChannelContext = zrtpChannelContext; retval = zrtpChannelContext->stateMachine(event); return retval; }