Commit f1f3d3cb authored by johan's avatar johan

Fix cache update in case of cache mismatch

parent 35c031d1
......@@ -193,4 +193,15 @@ int state_confirmation_initiatorSendingConfirm2(bzrtpEvent_t event);
*
*/
int state_secure(bzrtpEvent_t event);
/**
* @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);
#endif /* STATEMACHINE_H */
......@@ -467,6 +467,11 @@ int bzrtp_isSecure(bzrtpContext_t *zrtpContext, uint32_t selfSSRC) {
*/
void bzrtp_SASVerified(bzrtpContext_t *zrtpContext) {
if (zrtpContext != NULL) {
/* check if we must update the cache(delayed until sas verified in case of cache mismatch) */
if (zrtpContext->cacheMismatchFlag == 1) {
zrtpContext->cacheMismatchFlag = 0;
bzrtp_updateCachedSecrets(zrtpContext, zrtpContext->channelContext[0]); /* channel[0] is the only one in DHM mode, so the only one able to have a cache mismatch */
}
uint8_t pvsFlag = 1;
bzrtp_writePeerNode(zrtpContext, zrtpContext->peerZID, (uint8_t *)"pvs", 3, &pvsFlag, 1, BZRTP_CACHE_TAGISBYTE|BZRTP_CACHE_NOMULTIPLETAGS, BZRTP_CACHE_LOADFILE|BZRTP_CACHE_WRITEFILE);
}
......
......@@ -2100,6 +2100,7 @@ int bzrtp_deriveSrtpKeysFromS0(bzrtpContext_t *zrtpContext, bzrtpChannelContext_
*/
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 */
......@@ -2109,6 +2110,11 @@ int bzrtp_updateCachedSecrets(bzrtpContext_t *zrtpContext, bzrtpChannelContext_t
return 0;
}
/* if we had a cache mismatch, the update must be delayed until Sas confirmation by user, just do nothing, the update function will be called again when done */
if (zrtpContext->cacheMismatchFlag == 1) {
return 0;
}
/* if this channel context is in DHM mode, backup rs1 in rs2 if it exists */
if (zrtpChannelContext->keyAgreementAlgo != ZRTP_KEYAGREEMENT_Prsh) {
if (zrtpContext->cachedSecret.rs1 != NULL) {
......@@ -2121,7 +2127,7 @@ int bzrtp_updateCachedSecrets(bzrtpContext_t *zrtpContext, bzrtpChannelContext_t
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_keyDerivationFunction(zrtpChannelContext->s0, zrtpChannelContext->hashLength, (uint8_t *)"retained secret", 15, zrtpChannelContext->KDFContext, zrtpChannelContext->KDFContextLength, RETAINED_SECRET_LENGTH, (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, BZRTP_CACHE_TAGISBYTE|BZRTP_CACHE_NOMULTIPLETAGS, BZRTP_CACHE_LOADFILE|BZRTP_CACHE_WRITEFILE);
/* if exist, call the callback function to perform custom cache operation that may use s0(writing exported key into cache) */
......
......@@ -1636,7 +1636,14 @@ void test_stateMachine() {
}
/* compare SAS and check we are in secure mode */
CU_ASSERT_TRUE((memcmp(contextAlice->channelContext[0]->srtpSecrets.sas, contextBob->channelContext[0]->srtpSecrets.sas, 4) == 0) && (contextAlice->isSecure == 1) && (contextBob->isSecure == 1));
if ((contextAlice->isSecure == 1) && (contextBob->isSecure == 1)) { /* don't compare sas if we're not secure at we may not have it */
CU_ASSERT_TRUE((memcmp(contextAlice->channelContext[0]->srtpSecrets.sas, contextBob->channelContext[0]->srtpSecrets.sas, 4) == 0));
/* call the set verified Sas function */
bzrtp_SASVerified(contextAlice);
bzrtp_SASVerified(contextBob);
} else {
CU_FAIL("Unable to reach secure state");
}
/*** Send alice a ping message from Bob ***/
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*/
......
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