Commit 1ab274fa authored by Johan Pascal's avatar Johan Pascal

Add a setAuxSecret and a flag to check specific mismatch on it

parent f3de0484
......@@ -117,6 +117,7 @@ typedef struct bzrtpSrtpSecrets_struct {
uint8_t keyAgreementAlgo; /**< The key agreement algo selected during ZRTP negotiation */
uint8_t sasAlgo; /**< The SAS rendering algo selected during ZRTP negotiation */
uint8_t cacheMismatch; /**< Flag set to 1 in case of ZRTP cache mismatch, may occurs only on first channel(the one computing SAS) */
uint8_t auxSecretMismatch; /**< Flag set to 1 in case of auxiliary secret mismatch, may occurs only on first channel(the one computing SAS), in case of mismatch it is just ignored and we can still validate the SAS */
} bzrtpSrtpSecrets_t;
......@@ -391,6 +392,20 @@ BZRTP_EXPORT int bzrtp_getSelfHelloHash(bzrtpContext_t *zrtpContext, uint32_t se
*/
BZRTP_EXPORT int bzrtp_getChannelStatus(bzrtpContext_t *zrtpContext, uint32_t selfSSRC);
/**
* @brief Set Auxiliary Secret for this channel(shall be used only on primary audio channel)
* The given auxSecret is appended to any aux secret found in ZIDcache
* This function must be called before reception of peerHello packet
*
* @param[in] zrtpContext The ZRTP context we're dealing with
* @param[in] auxSecret A buffer holding the auxiliary shared secret to use (see RFC 6189 section 4.3)
* @param[in] auxSecretLength lenght of the previous buffer
*
* @return 0 on success, error code otherwise
*/
BZRTP_EXPORT int bzrtp_setAuxiliarySharedSecret(bzrtpContext_t *zrtpContext, const uint8_t *auxSecret, size_t auxSecretLength);
/*** Cache related functions ***/
/**
* @brief Check the given sqlite3 DB and create requested tables if needed
......
......@@ -249,6 +249,11 @@ struct bzrtpContext_struct {
uint8_t cacheMismatchFlag; /**< Flag set in case of cache mismatch(detected in DHM mode when DH part packet arrives) */
uint8_t peerPVS; /**< used to store value of PVS flag sent by peer in the confirm packet on first channel only, then used to compute the PVS value sent to the application */
/* transient auxiliary shared secret : in addition to the auxiliary shared secret stored in ZID cache, caller can provide a shared secret to the zrtp context which will be used for this transaction only */
/* both auxiliary secret are used and combined as transientAuxiliarySecret appended to cachedAuxiliarySecret*/
uint8_t *transientAuxSecret; /**< an auxiliary secret not stored in cache, provided after context creation and before the main channel is started */
size_t transientAuxSecretLength; /**< size of the previous buffer */
/* keys */
uint8_t *ZRTPSess; /**< ZRTP session key as described in rfc section 4.5.2 */
uint8_t ZRTPSessLength; /**< length of ZRTP session key depends on agreed hash algorithm */
......
......@@ -65,6 +65,7 @@ bzrtpContext_t *bzrtp_createBzrtpContext(void) {
context->isInitialised = 0; /* will be set by bzrtp_initBzrtpContext */
/* set to NULL all callbacks pointer */
context->zrtpCallbacks.bzrtp_statusMessage = NULL;
context->zrtpCallbacks.bzrtp_sendData = NULL;
context->zrtpCallbacks.bzrtp_srtpSecretsAvailable = NULL;
context->zrtpCallbacks.bzrtp_startSrtpSession = NULL;
......@@ -100,6 +101,10 @@ bzrtpContext_t *bzrtp_createBzrtpContext(void) {
context->cacheMismatchFlag = 0;
context->peerPVS = 0;
/* initialise transient shared auxiliary secret buffer */
context->transientAuxSecret = NULL;
context->transientAuxSecretLength = 0;
/* initialise key buffers */
context->ZRTPSess = NULL;
context->ZRTPSessLength = 0;
......@@ -247,6 +252,13 @@ int bzrtp_destroyBzrtpContext(bzrtpContext_t *context, uint32_t selfSSRC) {
free(context->selfURI);
free(context->peerURI);
/* transient shared auxiliary secret */
if (context->transientAuxSecret != NULL) {
bzrtp_DestroyKey(context->transientAuxSecret, context->transientAuxSecretLength, context->RNGContext);
free(context->transientAuxSecret);
context->transientAuxSecret=NULL;
}
/* destroy the RNG context at the end because it may be needed to destroy some keys */
bctbx_rng_context_free(context->RNGContext);
context->RNGContext = NULL;
......@@ -908,6 +920,38 @@ int bzrtp_getSelfHelloHash(bzrtpContext_t *zrtpContext, uint32_t selfSSRC, uint8
return 0;
}
/**
* @brief Set Auxiliary Secret for this channel(shall be used only on primary audio channel)
* The given auxSecret is appended to any aux secret found in ZIDcache
* This function must be called before reception of peerHello packet
*
* @param[in] zrtpContext The ZRTP context we're dealing with
* @param[in] auxSecret A buffer holding the auxiliary shared secret to use (see RFC 6189 section 4.3)
* @param[in] auxSecretLength lenght of the previous buffer
*
* @return 0 on success, error code otherwise
*/
BZRTP_EXPORT int bzrtp_setAuxiliarySharedSecret(bzrtpContext_t *zrtpContext, const uint8_t *auxSecret, size_t auxSecretLength) {
if (zrtpContext == NULL) {
return BZRTP_ERROR_INVALIDCONTEXT;
}
if (zrtpContext->channelContext[0] && zrtpContext->channelContext[0]->peerPackets[HELLO_MESSAGE_STORE_ID] != NULL) {
return BZRTP_ERROR_CONTEXTNOTREADY;
}
/* allocate memory to store the secret - check it wasn't already allocated */
if (zrtpContext->transientAuxSecret) {
free(zrtpContext->transientAuxSecret);
}
zrtpContext->transientAuxSecret = (uint8_t *)malloc(auxSecretLength*sizeof(uint8_t));
/* copy the aux secret and length */
memcpy(zrtpContext->transientAuxSecret, auxSecret, auxSecretLength);
zrtpContext->transientAuxSecretLength = auxSecretLength;
return 0;
}
/**
* @brief Get the channel status
......@@ -1061,6 +1105,7 @@ static int bzrtp_initChannelContext(bzrtpContext_t *zrtpContext, bzrtpChannelCon
zrtpChannelContext->srtpSecrets.keyAgreementAlgo = ZRTP_UNSET_ALGO;
zrtpChannelContext->srtpSecrets.sasAlgo = ZRTP_UNSET_ALGO;
zrtpChannelContext->srtpSecrets.cacheMismatch = 0;
zrtpChannelContext->srtpSecrets.auxSecretMismatch = 1; /* default is mismatch, explicitely set it to zero if we have a match */
/* create the Hello packet and store it */
helloPacket = bzrtp_createZrtpPacket(zrtpContext, zrtpChannelContext, MSGTYPE_HELLO, &retval);
......
......@@ -530,13 +530,17 @@ int state_keyAgreement_sendingCommit(bzrtpEvent_t event) {
}
}
/* if we have an aux secret check it match peer's one */
if (zrtpContext->cachedSecret.auxsecret!=NULL) {
if (memcmp(zrtpChannelContext->responderAuxsecretID, dhPart1Message->auxsecretID,8) != 0) {
if (memcmp(zrtpChannelContext->responderAuxsecretID, dhPart1Message->auxsecretID,8) != 0) { // they do not match, delete the aux secret as we must not use it
free(zrtpContext->cachedSecret.auxsecret);
zrtpContext->cachedSecret.auxsecret= NULL;
zrtpContext->cachedSecret.auxsecretLength = 0;
} else { // they do match, set the flag to 0 (its default is 1)
zrtpChannelContext->srtpSecrets.auxSecretMismatch=0;
}
}
if (zrtpContext->cachedSecret.pbxsecret!=NULL) {
if (memcmp(zrtpContext->responderCachedSecretHash.pbxsecretID, dhPart1Message->pbxsecretID,8) != 0) {
free(zrtpContext->cachedSecret.pbxsecret);
......@@ -830,22 +834,22 @@ int state_keyAgreement_responderSendingDHPart1(bzrtpEvent_t event) {
}
}
/* if we have an auxiliary secret, check it match peer's one */
if (zrtpContext->cachedSecret.auxsecret!=NULL) {
if (memcmp(zrtpChannelContext->initiatorAuxsecretID, dhPart2Message->auxsecretID,8) != 0) {
if (memcmp(zrtpChannelContext->initiatorAuxsecretID, dhPart2Message->auxsecretID,8) != 0) { // they do not match, delete the aux secret as we must not use it
free(zrtpContext->cachedSecret.auxsecret);
zrtpContext->cachedSecret.auxsecret= NULL;
zrtpContext->cachedSecret.auxsecretLength = 0;
/*bzrtp_freeZrtpPacket(zrtpPacket);
return BZRTP_ERROR_CACHEMISMATCH;*/
} else { // they do match, set the flag to 0 (its default is 1)
zrtpChannelContext->srtpSecrets.auxSecretMismatch=0;
}
}
if (zrtpContext->cachedSecret.pbxsecret!=NULL) {
if (memcmp(zrtpContext->initiatorCachedSecretHash.pbxsecretID, dhPart2Message->pbxsecretID,8) != 0) {
free(zrtpContext->cachedSecret.pbxsecret);
zrtpContext->cachedSecret.pbxsecret= NULL;
zrtpContext->cachedSecret.pbxsecretLength = 0;
/*bzrtp_freeZrtpPacket(zrtpPacket);
return BZRTP_ERROR_CACHEMISMATCH;*/
}
}
......@@ -1744,6 +1748,13 @@ int bzrtp_responseToHelloMessage(bzrtpContext_t *zrtpContext, bzrtpChannelContex
bctbx_rng_get(zrtpContext->RNGContext, zrtpContext->responderCachedSecretHash.pbxsecretID, 8);
}
/* if we have any transient auxiliary secret, append it to the one found in cache */
if (zrtpContext->transientAuxSecret!=NULL) {
zrtpContext->cachedSecret.auxsecret = (uint8_t *)realloc(zrtpContext->cachedSecret.auxsecret, zrtpContext->cachedSecret.auxsecretLength + zrtpContext->transientAuxSecretLength);
memcpy(zrtpContext->cachedSecret.auxsecret + zrtpContext->cachedSecret.auxsecretLength, zrtpContext->transientAuxSecret, zrtpContext->transientAuxSecretLength);
zrtpContext->cachedSecret.auxsecretLength += zrtpContext->transientAuxSecretLength;
}
if (zrtpContext->cachedSecret.auxsecret!=NULL) {
zrtpChannelContext->hmacFunction(zrtpContext->cachedSecret.auxsecret, zrtpContext->cachedSecret.auxsecretLength, zrtpChannelContext->selfH[3], 32, 8, zrtpChannelContext->initiatorAuxsecretID);
zrtpChannelContext->hmacFunction(zrtpContext->cachedSecret.auxsecret, zrtpContext->cachedSecret.auxsecretLength, zrtpChannelContext->peerH[3], 32, 8, zrtpChannelContext->responderAuxsecretID);
......
This diff is collapsed.
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