Commit 7515af93 authored by Johan Pascal's avatar Johan Pascal

Zid Cache resilient to first negotiation interruption or failure

+ do not store in cache any peer information until first negotiation succeeds
parent 41b2163c
......@@ -170,6 +170,7 @@ typedef struct bzrtpCallbacks_struct {
#define BZRTP_ERROR_CHANNELALREADYSTARTED 0x0100
#define BZRTP_ERROR_CACHEDISABLED 0x0200
#define BZRTP_ERROR_CACHEMIGRATIONFAILED 0x0400
#define BZRTP_ERROR_CACHE_PEERNOTFOUND 0x0800
/* channel status definition */
#define BZRTP_CHANNEL_NOTFOUND 0x1000
......@@ -432,21 +433,6 @@ BZRTP_EXPORT int bzrtp_initCache(void *db);
*/
BZRTP_EXPORT int bzrtp_getSelfZID(void *db, const char *selfURI, uint8_t selfZID[12], bctbx_rng_context_t *RNGContext);
/**
* @brief get the cache internal id used to bind local uri(hence local ZID associated to it)<->peer uri/peer ZID.
* Providing a valid local URI(already present in cache), a peer ZID and peer URI will return the zuid creating it if needed
* Any pair ZID/sipURI shall identify an account on a device.
*
* @param[in/out] db the opened sqlite database pointer
* @param[in] selfURI local URI, must be already associated to a ZID in the DB(association is performed by any call of getSelfZID on this URI)
* @param[in] peerURI peer URI
* @param[in] peerZID peer ZID
* @param[out] zuid the internal db reference to the data row matching this particular pair of correspondant
*
* @return 0 on success, error code otherwise
*/
BZRTP_EXPORT int bzrtp_cache_getZuid(void *dbPointer, const char *selfURI, const char *peerURI, const uint8_t peerZID[12], int *zuid);
/**
* @brief Write(insert or update) data in cache, adressing it by zuid (ZID/URI binding id used in cache)
* Get arrays of column names, values to be inserted, lengths of theses values
......
......@@ -47,4 +47,25 @@
*/
BZRTP_EXPORT int bzrtp_getPeerAssociatedSecrets(bzrtpContext_t *context, uint8_t peerZID[12]);
/**
* @brief get the cache internal id used to bind local uri(hence local ZID associated to it)<->peer uri/peer ZID.
* Providing a valid local URI(already present in cache), a peer ZID and peer URI will return the zuid creating it if needed and requested
* Any pair ZID/sipURI shall identify an account on a device.
*
* @param[in/out] db the opened sqlite database pointer
* @param[in] selfURI local URI, must be already associated to a ZID in the DB(association is performed by any call of getSelfZID on this URI)
* @param[in] peerURI peer URI
* @param[in] peerZID peer ZID
* @param[in] insertFlag A boolean managing insertion or not of a new row:
* - BZRTP_ZIDCACHE_DONT_INSERT_ZUID : if not found identity binding won't lead to insertion and return zuid will be 0
* - BZRTP_ZIDCACHE_INSERT_ZUID : if not found, insert a new row in ziduri table and return newly inserted zuid
* @param[out] zuid the internal db reference to the data row matching this particular pair of correspondant
* if identity binding is not found and insertFlag set to 0, this value is set to 0
*
* @return 0 on success, BZRTP_ERROR_CACHE_PEERNOTFOUND if peer was not in and the insert flag is not set to BZRTP_ZIDCACHE_INSERT_ZUID, error code otherwise
*/
#define BZRTP_ZIDCACHE_DONT_INSERT_ZUID 0
#define BZRTP_ZIDCACHE_INSERT_ZUID 1
BZRTP_EXPORT int bzrtp_cache_getZuid(void *dbPointer, const char *selfURI, const char *peerURI, const uint8_t peerZID[12], const uint8_t insertFlag, int *zuid);
#endif /* ZIDCACHE_H */
......@@ -2248,6 +2248,12 @@ int bzrtp_updateCachedSecrets(bzrtpContext_t *zrtpContext, bzrtpChannelContext_t
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);
colValues[0]=zrtpContext->cachedSecret.rs1;
/* before writing into cache, we must check we have the zuid correctly set, if not (it's our first successfull exchange with peer), insert it*/
if (zrtpContext->zuid==0) {
bzrtp_cache_getZuid((void *)zrtpContext->zidCache, zrtpContext->selfURI, zrtpContext->peerURI, zrtpContext->peerZID, BZRTP_ZIDCACHE_INSERT_ZUID, &zrtpContext->zuid);
}
bzrtp_cache_write(zrtpContext->zidCache, zrtpContext->zuid, "zrtp", colNames, colValues, colLength, 2);
/* if exist, call the callback function to perform custom cache operation that may use s0(writing exported key into cache) */
......
......@@ -293,7 +293,7 @@ int bzrtp_getPeerAssociatedSecrets(bzrtpContext_t *context, uint8_t peerZID[12])
}
/* get all secrets from zrtp table, ORDER BY is just to ensure consistent return in case of inconsistent table) */
stmt = sqlite3_mprintf("SELECT z.zuid, z.rs1, z.rs2, z.aux, z.pbx, z.pvs FROM ziduri as zu LEFT JOIN zrtp as z ON z.zuid=zu.zuid WHERE zu.selfuri=? AND zu.peeruri=? AND zu.zid=? ORDER BY zu.zuid LIMIT 1;");
stmt = sqlite3_mprintf("SELECT z.zuid, z.rs1, z.rs2, z.aux, z.pbx, z.pvs FROM ziduri as zu INNER JOIN zrtp as z ON z.zuid=zu.zuid WHERE zu.selfuri=? AND zu.peeruri=? AND zu.zid=? ORDER BY zu.zuid LIMIT 1;");
ret = sqlite3_prepare_v2(context->zidCache, stmt, -1, &sqlStmt, NULL);
sqlite3_free(stmt);
if (ret != SQLITE_OK) {
......@@ -307,8 +307,8 @@ int bzrtp_getPeerAssociatedSecrets(bzrtpContext_t *context, uint8_t peerZID[12])
if (ret!=SQLITE_ROW) {
sqlite3_finalize(sqlStmt);
if (ret == SQLITE_DONE) {/* not found in cache, just leave cached secrets reset, but retrieve (or create) zuid */
return bzrtp_cache_getZuid((void *)context->zidCache, context->selfURI, context->peerURI, context->peerZID, &context->zuid);
if (ret == SQLITE_DONE) {/* not found in cache, just leave cached secrets reset, but retrieve zuid, do not insert new peer ZID at this step, it must be done only when negotiation succeeds */
return bzrtp_cache_getZuid((void *)context->zidCache, context->selfURI, context->peerURI, context->peerZID, BZRTP_ZIDCACHE_DONT_INSERT_ZUID, &context->zuid);
} else { /* we had an error querying the DB... */
return BZRTP_ZIDCACHE_UNABLETOREAD;
}
......@@ -363,20 +363,25 @@ int bzrtp_getPeerAssociatedSecrets(bzrtpContext_t *context, uint8_t peerZID[12])
return 0;
}
/**
* @brief get the cache internal id used to bind local uri(hence local ZID associated to it)<->peer uri/peer ZID.
* Providing a valid local URI(already present in cache), a peer ZID and peer URI will return the zuid creating it if needed
* Providing a valid local URI(already present in cache), a peer ZID and peer URI will return the zuid creating it if needed and requested
* Any pair ZID/sipURI shall identify an account on a device.
*
* @param[in/out] db the opened sqlite database pointer
* @param[in] selfURI local URI, must be already associated to a ZID in the DB(association is performed by any call of getSelfZID on this URI)
* @param[in] peerURI peer URI
* @param[in] peerZID peer ZID
* @param[in] insertFlag A boolean managing insertion or not of a new row:
* - BZRTP_ZIDCACHE_DONT_INSERT_ZUID : if not found identity binding won't lead to insertion and return zuid will be 0
* - BZRTP_ZIDCACHE_INSERT_ZUID : if not found, insert a new row in ziduri table and return newly inserted zuid
* @param[out] zuid the internal db reference to the data row matching this particular pair of correspondant
* if identity binding is not found and insertFlag set to BZRTP_ZIDCACHE_DONT_INSERT_ZUID, this value is set to 0
*
* @return 0 on success, error code otherwise
* @return 0 on success, BZRTP_ERROR_CACHE_PEERNOTFOUND if peer was not in and the insert flag is not set to BZRTP_ZIDCACHE_INSERT_ZUID, error code otherwise
*/
int bzrtp_cache_getZuid(void *dbPointer, const char *selfURI, const char *peerURI, const uint8_t peerZID[12], int *zuid) {
int bzrtp_cache_getZuid(void *dbPointer, const char *selfURI, const char *peerURI, const uint8_t peerZID[12], const uint8_t insertFlag, int *zuid) {
char *stmt=NULL;
int ret;
sqlite3_stmt *sqlStmt = NULL;
......@@ -403,41 +408,47 @@ int bzrtp_cache_getZuid(void *dbPointer, const char *selfURI, const char *peerUR
if (ret!=SQLITE_ROW) { /* We didn't found this binding in the DB */
sqlite3_finalize(sqlStmt);
if (ret == SQLITE_DONE) { /* query executed correctly, just our data is not there */
uint8_t *localZID = NULL;
char *errmsg=NULL;
/* check that we have a self ZID matching the self URI and insert a new row */
stmt = sqlite3_mprintf("SELECT zid FROM ziduri WHERE selfuri=%Q AND peeruri='self' ORDER BY zuid LIMIT 1;",selfURI);
ret = sqlite3_exec(db,stmt,callback_getSelfZID,&localZID,&errmsg);
sqlite3_free(stmt);
if (ret != SQLITE_OK) {
sqlite3_free(errmsg);
return BZRTP_ZIDCACHE_UNABLETOREAD;
}
if (localZID==NULL) { /* this sip URI is not in our DB, do not create an association with the peer ZID/URI binding */
return BZRTP_ZIDCACHE_BADINPUTDATA;
} else { /* yes we know this URI on local device, add a row in the ziduri table */
free(localZID);
stmt = sqlite3_mprintf("INSERT INTO ziduri (zid,selfuri,peeruri) VALUES(?,?,?);");
ret = sqlite3_prepare_v2(db, stmt, -1, &sqlStmt, NULL);
/* shall we insert it? */
if (insertFlag == BZRTP_ZIDCACHE_INSERT_ZUID) {
uint8_t *localZID = NULL;
char *errmsg=NULL;
/* check that we have a self ZID matching the self URI and insert a new row */
stmt = sqlite3_mprintf("SELECT zid FROM ziduri WHERE selfuri=%Q AND peeruri='self' ORDER BY zuid LIMIT 1;",selfURI);
ret = sqlite3_exec(db,stmt,callback_getSelfZID,&localZID,&errmsg);
sqlite3_free(stmt);
if (ret != SQLITE_OK) {
return BZRTP_ZIDCACHE_UNABLETOUPDATE;
sqlite3_free(errmsg);
return BZRTP_ZIDCACHE_UNABLETOREAD;
}
sqlite3_free(stmt);
sqlite3_bind_blob(sqlStmt, 1, peerZID, 12, SQLITE_TRANSIENT);
sqlite3_bind_text(sqlStmt, 2, selfURI,-1,SQLITE_TRANSIENT);
sqlite3_bind_text(sqlStmt, 3, peerURI,-1,SQLITE_TRANSIENT);
if (localZID==NULL) { /* this sip URI is not in our DB, do not create an association with the peer ZID/URI binding */
return BZRTP_ZIDCACHE_BADINPUTDATA;
} else { /* yes we know this URI on local device, add a row in the ziduri table */
free(localZID);
stmt = sqlite3_mprintf("INSERT INTO ziduri (zid,selfuri,peeruri) VALUES(?,?,?);");
ret = sqlite3_prepare_v2(db, stmt, -1, &sqlStmt, NULL);
if (ret != SQLITE_OK) {
return BZRTP_ZIDCACHE_UNABLETOUPDATE;
}
sqlite3_free(stmt);
sqlite3_bind_blob(sqlStmt, 1, peerZID, 12, SQLITE_TRANSIENT);
sqlite3_bind_text(sqlStmt, 2, selfURI,-1,SQLITE_TRANSIENT);
sqlite3_bind_text(sqlStmt, 3, peerURI,-1,SQLITE_TRANSIENT);
ret = sqlite3_step(sqlStmt);
if (ret!=SQLITE_DONE) {
return BZRTP_ZIDCACHE_UNABLETOUPDATE;
ret = sqlite3_step(sqlStmt);
if (ret!=SQLITE_DONE) {
return BZRTP_ZIDCACHE_UNABLETOUPDATE;
}
sqlite3_finalize(sqlStmt);
/* get the zuid created */
*zuid = (int)sqlite3_last_insert_rowid(db);
return 0;
}
sqlite3_finalize(sqlStmt);
/* get the zuid created */
*zuid = (int)sqlite3_last_insert_rowid(db);
return 0;
} else { /* no found and not inserted */
*zuid = 0;
return BZRTP_ERROR_CACHE_PEERNOTFOUND;
}
} else { /* we had an error querying the DB... */
return BZRTP_ZIDCACHE_UNABLETOREAD;
......@@ -479,6 +490,10 @@ int bzrtp_cache_write(void *dbPointer, int zuid, const char *tableName, const ch
return BZRTP_ZIDCACHE_RUNTIME_CACHELESS;
}
if (zuid == 0) { /* we're giving an invalid zuid, means we were not able to retrieve it previously, just do nothing */
return BZRTP_ERROR_CACHE_PEERNOTFOUND;
}
/* As the zuid row may not be already present in the table, we must run an insert or update SQL command which is not provided by sqlite3 */
/* UPSERT strategy: run update first and check for changes */
......
......@@ -25,6 +25,7 @@
#include <time.h>
#include "bzrtp/bzrtp.h"
#include "zidCache.h"
#include "bzrtpTest.h"
#include "testUtils.h"
......@@ -102,6 +103,8 @@ static float fadingLostAlice=0.0; /* try not to throw away too many packet in a
static float fadingLostBob=0.0; /* try not to throw away too many packet in a row */
static int totalPacketLost=0; /* set a limit to the total number of packet we can loose to enforce completion of the exchange */
/* when timeout is set to this specific value, negotiation is aborted but silently fails */
#define ABORT_NEGOTIATION_TIMEOUT 24
static void resetGlobalParams() {
msSTC=0;
totalPacketLost =0;
......@@ -411,6 +414,20 @@ uint32_t multichannel_exchange_pvs_params(cryptoParams_t *aliceCryptoParams, cry
}
}
/* when timeOutLimit is set to this specific value, our intention is to start a negotiation but not to finish it, so just return without errors */
if (timeOutLimit == ABORT_NEGOTIATION_TIMEOUT) {
/*** Destroy Contexts ***/
while (bzrtp_destroyBzrtpContext(Alice.bzrtpContext, aliceSSRC)>0 && aliceSSRC>=ALICE_SSRC_BASE) {
aliceSSRC--;
}
while (bzrtp_destroyBzrtpContext(Bob.bzrtpContext, bobSSRC)>0 && bobSSRC>=BOB_SSRC_BASE) {
bobSSRC--;
}
return ret;
}
if ((retval=bzrtp_getChannelStatus(Alice.bzrtpContext, aliceSSRC))!=BZRTP_CHANNEL_SECURE) {
bzrtp_message("Fail Alice on channel1 loss rate is %d", loosePacketPercentage);
BC_ASSERT_EQUAL(retval, BZRTP_CHANNEL_SECURE, int, "%0x");
......@@ -692,6 +709,8 @@ static void test_cache_enabled_exchange(void) {
size_t colLengthBob[3];
int i;
resetGlobalParams();
/* create tempory DB files, just try to clean them from dir before, just in case */
remove("tmpZIDAlice_simpleCache.sqlite");
remove("tmpZIDBob_simpleCache.sqlite");
......@@ -706,8 +725,8 @@ static void test_cache_enabled_exchange(void) {
BC_ASSERT_EQUAL(bzrtp_getSelfZID((void *)aliceDB, "alice@sip.linphone.org", selfZIDalice, NULL), 0, int, "%x");
BC_ASSERT_EQUAL(bzrtp_getSelfZID((void *)bobDB, "bob@sip.linphone.org", selfZIDbob, NULL), 0, int, "%x");
/* then get the matching zuid in cache */
BC_ASSERT_EQUAL(bzrtp_cache_getZuid((void *)aliceDB, "alice@sip.linphone.org", "bob@sip.linphone.org", selfZIDbob, &zuidAlice), 0, int, "%x");
BC_ASSERT_EQUAL(bzrtp_cache_getZuid((void *)bobDB, "bob@sip.linphone.org", "alice@sip.linphone.org", selfZIDalice, &zuidBob), 0, int, "%x");
BC_ASSERT_EQUAL(bzrtp_cache_getZuid((void *)aliceDB, "alice@sip.linphone.org", "bob@sip.linphone.org", selfZIDbob, BZRTP_ZIDCACHE_DONT_INSERT_ZUID, &zuidAlice), 0, int, "%x");
BC_ASSERT_EQUAL(bzrtp_cache_getZuid((void *)bobDB, "bob@sip.linphone.org", "alice@sip.linphone.org", selfZIDalice, BZRTP_ZIDCACHE_DONT_INSERT_ZUID, &zuidBob), 0, int, "%x");
/* retrieve the values */
BC_ASSERT_EQUAL(bzrtp_cache_read((void *)aliceDB, zuidAlice, "zrtp", colNames, colValuesAlice, colLengthAlice, 3), 0, int, "%x");
BC_ASSERT_EQUAL(bzrtp_cache_read((void *)bobDB, zuidBob, "zrtp", colNames, colValuesBob, colLengthBob, 3), 0, int, "%x");
......@@ -804,8 +823,8 @@ static void test_cache_mismatch_exchange(void) {
BC_ASSERT_EQUAL(bzrtp_getSelfZID((void *)aliceDB, "alice@sip.linphone.org", selfZIDalice, NULL), 0, int, "%x");
BC_ASSERT_EQUAL(bzrtp_getSelfZID((void *)bobDB, "bob@sip.linphone.org", selfZIDbob, NULL), 0, int, "%x");
/* then get the matching zuid in cache */
BC_ASSERT_EQUAL(bzrtp_cache_getZuid((void *)aliceDB, "alice@sip.linphone.org", "bob@sip.linphone.org", selfZIDbob, &zuidAlice), 0, int, "%x");
BC_ASSERT_EQUAL(bzrtp_cache_getZuid((void *)bobDB, "bob@sip.linphone.org", "alice@sip.linphone.org", selfZIDalice, &zuidBob), 0, int, "%x");
BC_ASSERT_EQUAL(bzrtp_cache_getZuid((void *)aliceDB, "alice@sip.linphone.org", "bob@sip.linphone.org", selfZIDbob, BZRTP_ZIDCACHE_DONT_INSERT_ZUID, &zuidAlice), 0, int, "%x");
BC_ASSERT_EQUAL(bzrtp_cache_getZuid((void *)bobDB, "bob@sip.linphone.org", "alice@sip.linphone.org", selfZIDalice, BZRTP_ZIDCACHE_DONT_INSERT_ZUID, &zuidBob), 0, int, "%x");
/* retrieve the values */
BC_ASSERT_EQUAL(bzrtp_cache_read((void *)aliceDB, zuidAlice, "zrtp", colNames, colValuesAlice, colLengthAlice, 3), 0, int, "%x");
BC_ASSERT_EQUAL(bzrtp_cache_read((void *)bobDB, zuidBob, "zrtp", colNames, colValuesBob, colLengthBob, 3), 0, int, "%x");
......@@ -941,8 +960,8 @@ static void test_cache_sas_not_confirmed(void) {
BC_ASSERT_EQUAL(bzrtp_getSelfZID((void *)aliceDB, "alice@sip.linphone.org", selfZIDalice, NULL), 0, int, "%x");
BC_ASSERT_EQUAL(bzrtp_getSelfZID((void *)bobDB, "bob@sip.linphone.org", selfZIDbob, NULL), 0, int, "%x");
/* then get the matching zuid in cache */
BC_ASSERT_EQUAL(bzrtp_cache_getZuid((void *)aliceDB, "alice@sip.linphone.org", "bob@sip.linphone.org", selfZIDbob, &zuidAlice), 0, int, "%x");
BC_ASSERT_EQUAL(bzrtp_cache_getZuid((void *)bobDB, "bob@sip.linphone.org", "alice@sip.linphone.org", selfZIDalice, &zuidBob), 0, int, "%x");
BC_ASSERT_EQUAL(bzrtp_cache_getZuid((void *)aliceDB, "alice@sip.linphone.org", "bob@sip.linphone.org", selfZIDbob, BZRTP_ZIDCACHE_DONT_INSERT_ZUID, &zuidAlice), 0, int, "%x");
BC_ASSERT_EQUAL(bzrtp_cache_getZuid((void *)bobDB, "bob@sip.linphone.org", "alice@sip.linphone.org", selfZIDalice, BZRTP_ZIDCACHE_DONT_INSERT_ZUID, &zuidBob), 0, int, "%x");
/* retrieve the values */
BC_ASSERT_EQUAL(bzrtp_cache_read((void *)aliceDB, zuidAlice, "zrtp", colNames, colValuesAlice, colLengthAlice, 3), 0, int, "%x");
BC_ASSERT_EQUAL(bzrtp_cache_read((void *)bobDB, zuidBob, "zrtp", colNames, colValuesBob, colLengthBob, 3), 0, int, "%x");
......@@ -1208,13 +1227,111 @@ static void test_auxiliary_secret() {
BC_ASSERT_EQUAL(test_auxiliary_secret_params(secret1, sizeof(secret1), secret1, sizeof(secret1), 1, 1), 0, int, "%d");
};
/**
* scenario:
* - create new users with empty zid cache
* - start a firt exchange but abort it before conclusion
* - make a successive exchange going correctly to the end
*/
static void test_abort_retry(void) {
#ifdef ZIDCACHE_ENABLED
sqlite3 *aliceDB=NULL;
sqlite3 *bobDB=NULL;
uint8_t selfZIDalice[12];
uint8_t selfZIDbob[12];
int zuidAlice=0,zuidBob=0;
const char *colNames[] = {"rs1", "rs2", "pvs"};
uint8_t *colValuesAlice[3];
size_t colLengthAlice[3];
uint8_t *colValuesBob[3];
size_t colLengthBob[3];
int i;
resetGlobalParams();
/* create tempory DB files, just try to clean them from dir before, just in case */
remove("tmpZIDAlice_abortRetry.sqlite");
remove("tmpZIDBob_abortRetry.sqlite");
bzrtptester_sqlite3_open(bc_tester_file("tmpZIDAlice_abortRetry.sqlite"), &aliceDB);
bzrtptester_sqlite3_open(bc_tester_file("tmpZIDBob_abortRetry.sqlite"), &bobDB);
/* make a first exchange but abort it */
timeOutLimit = ABORT_NEGOTIATION_TIMEOUT; /* set timeout to ABORT_NEGOTIATION_TIMEOUT aborts an ongoing negotiation without errors */
BC_ASSERT_EQUAL(multichannel_exchange(NULL, NULL, defaultCryptoAlgoSelection(), aliceDB, "alice@sip.linphone.org", bobDB, "bob@sip.linphone.org"), 0, int, "%x");
/* after the first exchange we shall have only self ZID, peer ZID must not be inserted in cache */
/* first get each ZIDs, note give NULL as RNG context may lead to segfault in case of error(caches were not created correctly)*/
BC_ASSERT_EQUAL(bzrtp_getSelfZID((void *)aliceDB, "alice@sip.linphone.org", selfZIDalice, NULL), 0, int, "%x");
BC_ASSERT_EQUAL(bzrtp_getSelfZID((void *)bobDB, "bob@sip.linphone.org", selfZIDbob, NULL), 0, int, "%x");
/* try to get the matching zuid in cache: it shall not be there as the negotiation didn't completed */
BC_ASSERT_EQUAL(bzrtp_cache_getZuid((void *)aliceDB, "alice@sip.linphone.org", "bob@sip.linphone.org", selfZIDbob, BZRTP_ZIDCACHE_DONT_INSERT_ZUID, &zuidAlice), BZRTP_ERROR_CACHE_PEERNOTFOUND, int, "%x");
BC_ASSERT_EQUAL(bzrtp_cache_getZuid((void *)bobDB, "bob@sip.linphone.org", "alice@sip.linphone.org", selfZIDalice, BZRTP_ZIDCACHE_DONT_INSERT_ZUID, &zuidBob), BZRTP_ERROR_CACHE_PEERNOTFOUND, int, "%x");
/* make a second exchange */
resetGlobalParams(); /* this one goes to the end of it */
BC_ASSERT_EQUAL(multichannel_exchange(NULL, NULL, defaultCryptoAlgoSelection(), aliceDB, "alice@sip.linphone.org", bobDB, "bob@sip.linphone.org"), 0, int, "%x");
/* after the exchange we shall have both pvs values at 1 and both rs1 identical and rs2 null, retrieve them from cache and check it */
/* first get each ZIDs, note give NULL as RNG context may lead to segfault in case of error(caches were not created correctly)*/
/* get the matching zuid in cache */
BC_ASSERT_EQUAL(bzrtp_cache_getZuid((void *)aliceDB, "alice@sip.linphone.org", "bob@sip.linphone.org", selfZIDbob, BZRTP_ZIDCACHE_DONT_INSERT_ZUID, &zuidAlice), 0, int, "%x");
BC_ASSERT_EQUAL(bzrtp_cache_getZuid((void *)bobDB, "bob@sip.linphone.org", "alice@sip.linphone.org", selfZIDalice, BZRTP_ZIDCACHE_DONT_INSERT_ZUID, &zuidBob), 0, int, "%x");
if (zuidAlice==0 || zuidBob==0) {//abort if we didn't retrieve valid zuid values, keep tmp sqlite files for inspection
sqlite3_close(aliceDB);
sqlite3_close(bobDB);
return;
}
/* retrieve the values */
BC_ASSERT_EQUAL(bzrtp_cache_read((void *)aliceDB, zuidAlice, "zrtp", colNames, colValuesAlice, colLengthAlice, 3), 0, int, "%x");
BC_ASSERT_EQUAL(bzrtp_cache_read((void *)bobDB, zuidBob, "zrtp", colNames, colValuesBob, colLengthBob, 3), 0, int, "%x");
/* and compare to expected */
/* rs1 is set and they are both the same */
BC_ASSERT_EQUAL(colLengthAlice[0], 32, int, "%d");
BC_ASSERT_EQUAL(colLengthBob[0], 32, int, "%d");
BC_ASSERT_EQUAL(memcmp(colValuesAlice[0], colValuesBob[0], 32), 0, int, "%d");
/* rs2 is unset(NULL) */
BC_ASSERT_EQUAL(colLengthAlice[1], 0, int, "%d");
BC_ASSERT_EQUAL(colLengthBob[1], 0, int, "%d");
BC_ASSERT_PTR_NULL(colValuesAlice[1]);
BC_ASSERT_PTR_NULL(colValuesBob[1]);
/* pvs is equal to 1 */
BC_ASSERT_EQUAL(colLengthAlice[2], 1, int, "%d");
BC_ASSERT_EQUAL(colLengthBob[2], 1, int, "%d");
BC_ASSERT_EQUAL(*colValuesAlice[2], 1, int, "%d");
BC_ASSERT_EQUAL(*colValuesBob[2], 1, int, "%d");
/* free buffers */
for (i=0; i<3; i++) {
free(colValuesBob[i]);
colValuesBob[i]=NULL;
}
/* free buffers */
for (i=0; i<3; i++) {
free(colValuesAlice[i]);
free(colValuesBob[i]);
}
sqlite3_close(aliceDB);
sqlite3_close(bobDB);
/* clean temporary files */
remove("tmpZIDAlice_simpleCache.sqlite");
remove("tmpZIDBob_simpleCache.sqlite");
#endif /* ZIDCACHE_ENABLED */
}
static test_t key_exchange_tests[] = {
TEST_NO_TAG("Cacheless multi channel", test_cacheless_exchange),
TEST_NO_TAG("Cached Simple", test_cache_enabled_exchange),
TEST_NO_TAG("Cached mismatch", test_cache_mismatch_exchange),
TEST_NO_TAG("Loosy network", test_loosy_network),
TEST_NO_TAG("Cached PVS", test_cache_sas_not_confirmed),
TEST_NO_TAG("Auxiliary Secret", test_auxiliary_secret)
TEST_NO_TAG("Auxiliary Secret", test_auxiliary_secret),
TEST_NO_TAG("Abort and retry", test_abort_retry)
};
test_suite_t key_exchange_test_suite = {
......
......@@ -95,9 +95,9 @@ static void test_cache_getSelfZID(void) {
BC_ASSERT_EQUAL(memcmp(selfZIDalice, aliceContext->selfZID, 12), 0, int, "%d");
/* try to get a zuid on alice/bob+patternZIDbob, at first the row shall be created */
BC_ASSERT_EQUAL(bzrtp_cache_getZuid((void *)aliceDB, "alice@sip.linphone.org", "bob@sip.linphone.org", patternZIDbob, &zuidalicebob), 0, int, "%x");
BC_ASSERT_EQUAL(bzrtp_cache_getZuid((void *)aliceDB, "alice@sip.linphone.org", "bob@sip.linphone.org", patternZIDbob, BZRTP_ZIDCACHE_INSERT_ZUID, &zuidalicebob), 0, int, "%x");
/* ask for it again and check they are the same */
BC_ASSERT_EQUAL(bzrtp_cache_getZuid((void *)aliceDB, "alice@sip.linphone.org", "bob@sip.linphone.org", patternZIDbob, &zuidCheck), 0, int, "%x");
BC_ASSERT_EQUAL(bzrtp_cache_getZuid((void *)aliceDB, "alice@sip.linphone.org", "bob@sip.linphone.org", patternZIDbob, BZRTP_ZIDCACHE_DONT_INSERT_ZUID, &zuidCheck), 0, int, "%x");
BC_ASSERT_EQUAL(zuidalicebob, zuidCheck, int, "%d");
/* Then write in cache zrtp table */
......@@ -130,7 +130,7 @@ static void test_cache_getSelfZID(void) {
BC_ASSERT_EQUAL(memcmp(selfZIDalice, patternZIDalice, 12), 0, int, "%x");
/* test the getZuid function */
BC_ASSERT_EQUAL(bzrtp_cache_getZuid((void *)aliceDB, "alice@sip.linphone.org", "bob@sip.linphone.org", patternZIDbob, &zuidalicebob), 0, int, "%x");
BC_ASSERT_EQUAL(bzrtp_cache_getZuid((void *)aliceDB, "alice@sip.linphone.org", "bob@sip.linphone.org", patternZIDbob, BZRTP_ZIDCACHE_DONT_INSERT_ZUID, &zuidalicebob), 0, int, "%x");
BC_ASSERT_EQUAL(zuidalicebob, 5, int, "%d"); /* from the pattern DB: the zuid for alice/bob+provided ZID is 5 */
BC_ASSERT_EQUAL(bzrtp_getSelfZID(aliceDB, "ecila@sip.linphone.org", selfZIDecila, aliceContext->RNGContext), 0, int, "%x");
......
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