* #35924 (zrtp): switch to libzrtpcpp
diff --git a/jni/libzrtp/sources/clients/tivi/CtZrtpSession.cpp b/jni/libzrtp/sources/clients/tivi/CtZrtpSession.cpp
new file mode 100644
index 0000000..8588744
--- /dev/null
+++ b/jni/libzrtp/sources/clients/tivi/CtZrtpSession.cpp
@@ -0,0 +1,652 @@
+/*
+ * Tivi client glue code for ZRTP.
+ * Copyright (c) 2012 Slient Circle LLC. All rights reserved.
+ *
+ *
+ * @author Werner Dittmann <Werner.Dittmann@t-online.de>
+ */
+
+#include <string>
+#include <stdio.h>
+
+#include <libzrtpcpp/ZIDCache.h>
+#include <libzrtpcpp/ZRtp.h>
+
+#include <CtZrtpStream.h>
+#include <CtZrtpCallback.h>
+#include <CtZrtpSession.h>
+
+#include <common/Thread.h>
+
+static CMutexClass sessionLock;
+
+const char *getZrtpBuildInfo()
+{
+ return zrtpBuildInfo;
+}
+CtZrtpSession::CtZrtpSession() : mitmMode(false), signSas(false), enableParanoidMode(false), isReady(false),
+ zrtpEnabled(true), sdesEnabled(true) {
+
+ clientIdString = clientId;
+ streams[AudioStream] = NULL;
+ streams[VideoStream] = NULL;
+}
+
+int CtZrtpSession::initCache(const char *zidFilename) {
+ ZIDCache* zf = getZidCacheInstance();
+ if (!zf->isOpen()) {
+ std::string fname;
+ if (zidFilename == NULL) {
+ char *home = getenv("HOME");
+ std::string baseDir = (home != NULL) ? (std::string(home) + std::string("/."))
+ : std::string(".");
+ fname = baseDir + std::string("GNUZRTP.zid");
+ zidFilename = fname.c_str();
+ }
+ if (zf->open((char *)zidFilename) < 0) {
+ return -1;
+ }
+ }
+ return 1;
+}
+
+int CtZrtpSession::init(bool audio, bool video, ZrtpConfigure* config)
+{
+ int32_t ret = 1;
+
+ synchEnter();
+
+ ZrtpConfigure* configOwn = NULL;
+ if (config == NULL) {
+ config = configOwn = new ZrtpConfigure();
+ setupConfiguration(config);
+ config->setTrustedMitM(true);
+ }
+ config->setParanoidMode(enableParanoidMode);
+
+ ZIDCache* zf = getZidCacheInstance();
+ if (!zf->isOpen()) {
+ ret = -1;
+ }
+ if (ret > 0) {
+ const uint8_t* ownZid = zf->getZid();
+ CtZrtpStream *stream;
+
+ // Create CTZrtpStream object only once, they are availbe for the whole
+ // lifetime of the session.
+ if (audio) {
+ if (streams[AudioStream] == NULL)
+ streams[AudioStream] = new CtZrtpStream();
+ stream = streams[AudioStream];
+ stream->zrtpEngine = new ZRtp((uint8_t*)ownZid, stream, clientIdString, config, mitmMode, signSas);
+ stream->type = Master;
+ stream->index = AudioStream;
+ stream->session = this;
+ }
+ if (video) {
+ if (streams[VideoStream] == NULL)
+ streams[VideoStream] = new CtZrtpStream();
+ stream = streams[VideoStream];
+ stream->zrtpEngine = new ZRtp((uint8_t*)ownZid, stream, clientIdString, config);
+ stream->type = Slave;
+ stream->index = VideoStream;
+ stream->session = this;
+ }
+ }
+ if (configOwn != NULL) {
+ delete configOwn;
+ }
+ synchLeave();
+ isReady = true;
+ return ret;
+}
+
+CtZrtpSession::~CtZrtpSession() {
+
+ delete streams[AudioStream];
+ delete streams[VideoStream];
+}
+
+void zrtp_log(const char *tag, const char *buf);
+void CtZrtpSession::setupConfiguration(ZrtpConfigure *conf) {
+
+// Set _WITHOUT_TIVI_ENV to a real name that is TRUE if the Tivi client is compiled/built.
+#ifdef _WITHOUT_TIVI_ENV
+#define GET_CFG_I(RET,_KEY)
+#else
+void *findGlobalCfgKey(char *key, int iKeyLen, int &iSize, char **opt, int *type);
+#define GET_CFG_I(RET,_KEY) {int *p=(int*)findGlobalCfgKey((char*)_KEY,sizeof(_KEY)-1,iSZ,&opt,&type);if(p && iSZ==4)RET=*p;else RET=-1;}
+#endif
+
+
+// The next three vars are used in case of a real Tivi compile, see macro above.
+ int iSZ;
+ char *opt;
+ int type;
+ void zrtp_log( const char *tag, const char *buf);
+
+ int b32sas = 0, iDisableDH2K = 0, iDisableAES256 = 0, iPreferDH2K = 0;
+ int iDisableECDH256 = 0, iDisableECDH384 = 0, iEnableSHA384 = 1;
+ int iDisableSkein = 0, iDisableTwofish = 0, iPreferNIST = 0;
+ int iDisableSkeinHash = 0, iDisableBernsteinCurve25519 = 0, iDisableBernsteinCurve3617 = 0;
+
+ GET_CFG_I(b32sas, "iDisable256SAS");
+ GET_CFG_I(iDisableAES256, "iDisableAES256");
+ GET_CFG_I(iDisableDH2K, "iDisableDH2K");
+ GET_CFG_I(iPreferDH2K, "iPreferDH2K");
+
+ GET_CFG_I(iDisableECDH256, "iDisableECDH256");
+ GET_CFG_I(iDisableECDH384, "iDisableECDH384");
+ GET_CFG_I(iEnableSHA384, "iEnableSHA384");
+ GET_CFG_I(iDisableSkein, "iDisableSkein");
+ GET_CFG_I(iDisableTwofish, "iDisableTwofish");
+ GET_CFG_I(iPreferNIST, "iPreferNIST");
+
+ GET_CFG_I(iDisableSkeinHash, "iDisableSkeinHash");
+ GET_CFG_I(iDisableBernsteinCurve25519, "iDisableBernsteinCurve25519");
+ GET_CFG_I(iDisableBernsteinCurve3617, "iDisableBernsteinCurve3617");
+
+ conf->clear();
+
+ /*
+ * Setting the selection policy is a more generic policy than the iPreferNIST
+ * configuration set by the user. The selection policy is a decision of the
+ * client, not the user
+ */
+ conf->setSelectionPolicy(ZrtpConfigure::PreferNonNist);
+
+ /*
+ * Handling of iPreferNIST: if this is false (== 0) then we add the non-NIST algorithms
+ * to the configuration and place them in front of the NIST algorithms. Refer to RFC6189
+ * section 4.1.2 regarding selection of the public key algorithm.
+ *
+ * With the configuration flags we can enable/disable each ECC PK algorithm separately.
+ *
+ */
+ if (iPreferNIST == 0) {
+ if (iDisableBernsteinCurve3617 == 0)
+ conf->addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName("E414"));
+ if (iDisableECDH384 == 0)
+ conf->addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName("EC38"));
+ }
+ else {
+ if (iDisableECDH384 == 0)
+ conf->addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName("EC38"));
+ if (iDisableBernsteinCurve3617 == 0)
+ conf->addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName("E414"));
+ }
+
+ if (iPreferNIST == 0) {
+ if (iDisableBernsteinCurve25519 == 0)
+ conf->addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName("E255"));
+ if (iDisableECDH256 == 0)
+ conf->addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName("EC25"));
+ }
+ else {
+ if (iDisableECDH256 == 0)
+ conf->addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName("EC25"));
+ if (iDisableBernsteinCurve25519 == 0)
+ conf->addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName("E255"));
+ }
+
+ // DH2K handling: if DH2K not disabled and prefered put it infrom of DH3K,
+ // If not preferred and not disabled put if after DH3K. Don't use DH2K if
+ // it's not enabled at all (iDisableDH2K == 1)
+ if (iPreferDH2K && iDisableDH2K == 0) {
+ conf->addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName("DH2k"));
+ }
+ conf->addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName("DH3k"));
+ if (iPreferDH2K == 0 && iDisableDH2K == 0)
+ conf->addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName("DH2k"));
+
+ conf->addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName("Mult"));
+
+
+ // Handling of Hash algorithms: similar to PK, if PreferNIST is false
+ // then put Skein in fromt oF SHA. Regardless if the Hash is enabled or
+ // not: if configuration enables a large curve then also use the large
+ // hashes.
+ if (iPreferNIST == 0) {
+ if (iDisableSkeinHash == 0 || iDisableBernsteinCurve3617 == 0)
+ conf->addAlgo(HashAlgorithm, zrtpHashes.getByName("SKN3"));
+ if (iEnableSHA384 == 1 || iDisableECDH384 == 0)
+ conf->addAlgo(HashAlgorithm, zrtpHashes.getByName("S384"));
+ }
+ else {
+ if (iEnableSHA384 == 1 || iDisableECDH384 == 0)
+ conf->addAlgo(HashAlgorithm, zrtpHashes.getByName("S384"));
+ if (iDisableSkeinHash == 0 || iDisableBernsteinCurve3617 == 0)
+ conf->addAlgo(HashAlgorithm, zrtpHashes.getByName("SKN3"));
+ }
+
+ if (iPreferNIST == 0) {
+ if (iDisableSkeinHash == 0)
+ conf->addAlgo(HashAlgorithm, zrtpHashes.getByName("SKN2"));
+ conf->addAlgo(HashAlgorithm, zrtpHashes.getByName("S256"));
+ }
+ else {
+ conf->addAlgo(HashAlgorithm, zrtpHashes.getByName("S256"));
+ if (iDisableSkeinHash == 0)
+ conf->addAlgo(HashAlgorithm, zrtpHashes.getByName("SKN2"));
+ }
+
+ // Handling of Symmetric algorithms: always prefer twofish (regardless
+ // of NIST setting) if it is not disabled. iDisableAES256 means: disable
+ // large ciphers
+ if (iDisableAES256 == 0) {
+ if (iDisableTwofish == 0)
+ conf->addAlgo(CipherAlgorithm, zrtpSymCiphers.getByName("2FS3"));
+ conf->addAlgo(CipherAlgorithm, zrtpSymCiphers.getByName("AES3"));
+ }
+
+ if (iDisableTwofish == 0)
+ conf->addAlgo(CipherAlgorithm, zrtpSymCiphers.getByName("2FS1"));
+ conf->addAlgo(CipherAlgorithm, zrtpSymCiphers.getByName("AES1"));
+
+ if (b32sas == 1) {
+ conf->addAlgo(SasType, zrtpSasTypes.getByName("B32 "));
+ }
+ else {
+ conf->addAlgo(SasType, zrtpSasTypes.getByName("B256"));
+ conf->addAlgo(SasType, zrtpSasTypes.getByName("B32 "));
+ }
+
+ if (iPreferNIST == 0) {
+ if (iDisableSkein == 0) {
+ conf->addAlgo(AuthLength, zrtpAuthLengths.getByName("SK32"));
+ conf->addAlgo(AuthLength, zrtpAuthLengths.getByName("SK64"));
+ }
+ conf->addAlgo(AuthLength, zrtpAuthLengths.getByName("HS32"));
+ conf->addAlgo(AuthLength, zrtpAuthLengths.getByName("HS80"));
+ }
+ else {
+ conf->addAlgo(AuthLength, zrtpAuthLengths.getByName("HS32"));
+ conf->addAlgo(AuthLength, zrtpAuthLengths.getByName("HS80"));
+ if (iDisableSkein == 0) {
+ conf->addAlgo(AuthLength, zrtpAuthLengths.getByName("SK32"));
+ conf->addAlgo(AuthLength, zrtpAuthLengths.getByName("SK64"));
+ }
+ }
+}
+
+void CtZrtpSession::setUserCallback(CtZrtpCb* ucb, streamName streamNm) {
+ if (!(streamNm >= 0 && streamNm <= AllStreams && streams[streamNm] != NULL))
+ return;
+
+ if (streamNm == AllStreams) {
+ for (int sn = 0; sn < AllStreams; sn++)
+ streams[sn]->setUserCallback(ucb);
+ }
+ else
+ streams[streamNm]->setUserCallback(ucb);
+}
+
+void CtZrtpSession::setSendCallback(CtZrtpSendCb* scb, streamName streamNm) {
+ if (!(streamNm >= 0 && streamNm <= AllStreams && streams[streamNm] != NULL))
+ return;
+
+ if (streamNm == AllStreams) {
+ for (int sn = 0; sn < AllStreams; sn++)
+ streams[sn]->setSendCallback(scb);
+ }
+ else
+ streams[streamNm]->setSendCallback(scb);
+
+}
+
+void CtZrtpSession::masterStreamSecure(CtZrtpStream *masterStream) {
+ // Here we know that the AudioStream is the master and VideoStream the slave.
+ // Otherwise we need to loop and find the Master stream and the Slave streams.
+
+ multiStreamParameter = masterStream->zrtpEngine->getMultiStrParams();
+ CtZrtpStream *strm = streams[VideoStream];
+ if (strm->enableZrtp) {
+ strm->zrtpEngine->setMultiStrParams(multiStreamParameter);
+ strm->zrtpEngine->startZrtpEngine();
+ strm->started = true;
+ strm->tiviState = eLookingPeer;
+ if (strm->zrtpUserCallback != 0)
+ strm->zrtpUserCallback->onNewZrtpStatus(this, NULL, strm->index);
+
+ }
+}
+
+int CtZrtpSession::startIfNotStarted(unsigned int uiSSRC, int streamNm) {
+ if (!(streamNm >= 0 && streamNm < AllStreams && streams[streamNm] != NULL))
+ return 0;
+
+ if ((streamNm == VideoStream && !isSecure(AudioStream)) || streams[streamNm]->started)
+ return 0;
+
+ start(uiSSRC, streamNm == VideoStream ? CtZrtpSession::VideoStream : CtZrtpSession::AudioStream);
+ return 0;
+}
+
+void CtZrtpSession::start(unsigned int uiSSRC, CtZrtpSession::streamName streamNm) {
+ if (!zrtpEnabled || !(streamNm >= 0 && streamNm < AllStreams && streams[streamNm] != NULL))
+ return;
+
+ CtZrtpStream *stream = streams[streamNm];
+
+ stream->ownSSRC = uiSSRC;
+ stream->enableZrtp = true;
+ if (stream->type == Master) {
+ stream->zrtpEngine->startZrtpEngine();
+ stream->started = true;
+ stream->tiviState = eLookingPeer;
+ if (stream->zrtpUserCallback != 0)
+ stream->zrtpUserCallback->onNewZrtpStatus(this, NULL, stream->index);
+ return;
+ }
+ // Process a Slave stream.
+ if (!multiStreamParameter.empty()) { // Multi-stream parameters available
+ stream->zrtpEngine->setMultiStrParams(multiStreamParameter);
+ stream->zrtpEngine->startZrtpEngine();
+ stream->started = true;
+ stream->tiviState = eLookingPeer;
+ if (stream->zrtpUserCallback != 0)
+ stream->zrtpUserCallback->onNewZrtpStatus(this, NULL, stream->index);
+ }
+}
+
+void CtZrtpSession::stop(streamName streamNm) {
+ if (!(streamNm >= 0 && streamNm < AllStreams && streams[streamNm] != NULL))
+ return;
+
+ streams[streamNm]->isStopped = true;
+}
+
+void CtZrtpSession::release() {
+ release(AudioStream);
+ release(VideoStream);
+}
+
+void CtZrtpSession::release(streamName streamNm) {
+ if (!(streamNm >= 0 && streamNm < AllStreams && streams[streamNm] != NULL))
+ return;
+
+ CtZrtpStream *stream = streams[streamNm];
+ stream->stopStream(); // stop and reset stream
+}
+
+void CtZrtpSession::setLastPeerNameVerify(const char *name, int iIsMitm) {
+ CtZrtpStream *stream = streams[AudioStream];
+
+ if (!isReady || !stream || stream->isStopped)
+ return;
+
+ uint8_t peerZid[IDENTIFIER_LEN];
+ std::string nm(name);
+ stream->zrtpEngine->getPeerZid(peerZid);
+ getZidCacheInstance()->putPeerName(peerZid, nm);
+ setVerify(1);
+}
+
+int CtZrtpSession::isSecure(streamName streamNm) {
+ if (!(streamNm >= 0 && streamNm < AllStreams && streams[streamNm] != NULL))
+ return 0;
+
+ CtZrtpStream *stream = streams[streamNm];
+ return stream->isSecure();
+}
+
+bool CtZrtpSession::processOutoingRtp(uint8_t *buffer, size_t length, size_t *newLength, streamName streamNm) {
+ if (!isReady || !(streamNm >= 0 && streamNm < AllStreams && streams[streamNm] != NULL))
+ return false;
+
+ CtZrtpStream *stream = streams[streamNm];
+ if (stream->isStopped)
+ return false;
+
+ return stream->processOutgoingRtp(buffer, length, newLength);
+}
+
+int32_t CtZrtpSession::processIncomingRtp(uint8_t *buffer, size_t length, size_t *newLength, streamName streamNm) {
+ if (!isReady || !(streamNm >= 0 && streamNm < AllStreams && streams[streamNm] != NULL))
+ return fail;
+
+ CtZrtpStream *stream = streams[streamNm];
+ if (stream->isStopped)
+ return fail;
+
+ return stream->processIncomingRtp(buffer, length, newLength);
+}
+
+bool CtZrtpSession::isStarted(streamName streamNm) {
+ if (!isReady || !(streamNm >= 0 && streamNm < AllStreams && streams[streamNm] != NULL))
+ return false;
+
+ return streams[streamNm]->isStarted();
+}
+
+bool CtZrtpSession::isEnabled(streamName streamNm) {
+ if (!isReady || !(streamNm >= 0 && streamNm < AllStreams && streams[streamNm] != NULL))
+ return false;
+
+ CtZrtpStream *stream = streams[streamNm];
+ if (stream->isStopped)
+ return false;
+
+ return stream->isEnabled();
+}
+
+CtZrtpSession::tiviStatus CtZrtpSession::getCurrentState(streamName streamNm) {
+ if (!isReady || !(streamNm >= 0 && streamNm < AllStreams && streams[streamNm] != NULL))
+ return eWrongStream;
+
+ CtZrtpStream *stream = streams[streamNm];
+ if (stream->isStopped)
+ return eWrongStream;
+
+ return stream->getCurrentState();
+}
+
+CtZrtpSession::tiviStatus CtZrtpSession::getPreviousState(streamName streamNm) {
+ if (!isReady || !(streamNm >= 0 && streamNm < AllStreams && streams[streamNm] != NULL))
+ return eWrongStream;
+
+ CtZrtpStream *stream = streams[streamNm];
+ if (stream->isStopped)
+ return eWrongStream;
+
+ return stream->getPreviousState();
+}
+
+bool CtZrtpSession::isZrtpEnabled() {
+ return zrtpEnabled;
+}
+
+bool CtZrtpSession::isSdesEnabled() {
+ return sdesEnabled;
+}
+
+void CtZrtpSession::setZrtpEnabled(bool yesNo) {
+ zrtpEnabled = yesNo;
+}
+
+void CtZrtpSession::setSdesEnabled(bool yesNo) {
+ sdesEnabled = yesNo;
+}
+
+int CtZrtpSession::getSignalingHelloHash(char *helloHash, streamName streamNm, int32_t index) {
+ if (!isReady || !(streamNm >= 0 && streamNm < AllStreams && streams[streamNm] != NULL))
+ return 0;
+
+ CtZrtpStream *stream = streams[streamNm];
+ if (stream->isStopped)
+ return 0;
+
+ return stream->getSignalingHelloHash(helloHash, index);
+}
+
+void CtZrtpSession::setSignalingHelloHash(const char *helloHash, streamName streamNm) {
+ if (!isReady || !(streamNm >= 0 && streamNm < AllStreams && streams[streamNm] != NULL))
+ return;
+
+ CtZrtpStream *stream = streams[streamNm];
+ if (stream->isStopped)
+ return;
+
+ stream->setSignalingHelloHash(helloHash);
+}
+
+void CtZrtpSession::setVerify(int iVerified) {
+ CtZrtpStream *stream = streams[AudioStream];
+
+ if (!isReady || !stream || stream->isStopped)
+ return;
+
+ if (iVerified) {
+ stream->zrtpEngine->SASVerified();
+ stream->sasVerified = true;
+ }
+ else {
+ stream->zrtpEngine->resetSASVerified();
+ stream->sasVerified = false;
+ }
+}
+
+int CtZrtpSession::getInfo(const char *key, uint8_t *buffer, size_t maxLen, streamName streamNm) {
+ if (!isReady || !(streamNm >= 0 && streamNm < AllStreams && streams[streamNm] != NULL))
+ return fail;
+
+ CtZrtpStream *stream = streams[streamNm];
+ return stream->getInfo(key, (char*)buffer, (int)maxLen);
+}
+
+int CtZrtpSession::enrollAccepted(char *p) {
+ if (!isReady || !(streams[AudioStream] != NULL))
+ return fail;
+
+ CtZrtpStream *stream = streams[AudioStream];
+ int ret = stream->enrollAccepted(p);
+ setVerify(true);
+ return ret;
+}
+
+int CtZrtpSession::enrollDenied() {
+ if (!isReady || !(streams[AudioStream] != NULL))
+ return fail;
+
+ CtZrtpStream *stream = streams[AudioStream];
+ int ret = stream->enrollDenied();
+ setVerify(true); // TODO : Janis -> is that correct in this case?
+ return ret;
+}
+
+void CtZrtpSession::setClientId(std::string id) {
+ clientIdString = id;
+}
+
+bool CtZrtpSession::createSdes(char *cryptoString, size_t *maxLen, streamName streamNm, const sdesSuites suite) {
+
+ if (!isReady || !sdesEnabled || !(streamNm >= 0 && streamNm < AllStreams && streams[streamNm] != NULL))
+ return fail;
+
+ CtZrtpStream *stream = streams[streamNm];
+ return stream->createSdes(cryptoString, maxLen, static_cast<ZrtpSdesStream::sdesSuites>(suite));
+}
+
+bool CtZrtpSession::parseSdes(char *recvCryptoStr, size_t recvLength, char *sendCryptoStr,
+ size_t *sendLength, bool sipInvite, streamName streamNm) {
+
+ if (!isReady || !sdesEnabled || !(streamNm >= 0 && streamNm < AllStreams && streams[streamNm] != NULL))
+ return fail;
+
+ CtZrtpStream *stream = streams[streamNm];
+ return stream->parseSdes(recvCryptoStr, recvLength, sendCryptoStr, sendLength, sipInvite);
+}
+
+bool CtZrtpSession::getSavedSdes(char *sendCryptoStr, size_t *sendLength, streamName streamNm) {
+ if (!isReady || !sdesEnabled || !(streamNm >= 0 && streamNm < AllStreams && streams[streamNm] != NULL))
+ return fail;
+
+ CtZrtpStream *stream = streams[streamNm];
+ return stream->getSavedSdes(sendCryptoStr, sendLength);
+}
+
+bool CtZrtpSession::isSdesActive(streamName streamNm) {
+ if (!isReady || !sdesEnabled || !(streamNm >= 0 && streamNm < AllStreams && streams[streamNm] != NULL))
+ return fail;
+
+ CtZrtpStream *stream = streams[streamNm];
+ return stream->isSdesActive();
+}
+
+int CtZrtpSession::getCryptoMixAttribute(char *algoNames, size_t length, streamName streamNm) {
+ if (!isReady || !sdesEnabled || !(streamNm >= 0 && streamNm < AllStreams && streams[streamNm] != NULL))
+ return 0;
+
+ CtZrtpStream *stream = streams[streamNm];
+ return stream->getCryptoMixAttribute(algoNames, length);
+}
+
+bool CtZrtpSession::setCryptoMixAttribute(const char *algoNames, streamName streamNm) {
+ if (!isReady || !sdesEnabled || !(streamNm >= 0 && streamNm < AllStreams && streams[streamNm] != NULL))
+ return fail;
+
+ CtZrtpStream *stream = streams[streamNm];
+ return stream->setCryptoMixAttribute(algoNames);
+}
+
+void CtZrtpSession::resetSdesContext(streamName streamNm, bool force) {
+ if (!isReady || !(streamNm >= 0 && streamNm < AllStreams && streams[streamNm] != NULL))
+ return;
+
+ CtZrtpStream *stream = streams[streamNm];
+ stream->resetSdesContext(force);
+}
+
+
+int32_t CtZrtpSession::getNumberSupportedVersions(streamName streamNm) {
+ if (!isReady || !(streamNm >= 0 && streamNm < AllStreams && streams[streamNm] != NULL))
+ return 0;
+
+ CtZrtpStream *stream = streams[streamNm];
+ return stream->getNumberSupportedVersions();
+}
+
+const char* CtZrtpSession::getZrtpEncapAttribute(streamName streamNm) {
+ if (!isReady || !(streamNm >= 0 && streamNm < AllStreams && streams[streamNm] != NULL))
+ return NULL;
+
+ CtZrtpStream *stream = streams[streamNm];
+ if (stream->isStopped)
+ return NULL;
+
+ return stream->getZrtpEncapAttribute();
+}
+
+void CtZrtpSession::setZrtpEncapAttribute(const char *attribute, streamName streamNm) {
+ if (!isReady || !(streamNm >= 0 && streamNm < AllStreams && streams[streamNm] != NULL))
+ return;
+
+ CtZrtpStream *stream = streams[streamNm];
+ if (stream->isStopped)
+ return;
+
+ stream->setZrtpEncapAttribute(attribute);
+}
+
+void CtZrtpSession::setAuxSecret(const unsigned char *secret, int length) {
+ if (!isReady || !(streams[AudioStream] != NULL))
+ return;
+
+ CtZrtpStream *stream = streams[AudioStream];
+ if (stream->isStopped)
+ return;
+
+ stream->setAuxSecret(secret, length);
+}
+
+void CtZrtpSession::cleanCache() {
+ getZidCacheInstance()->cleanup();
+}
+
+void CtZrtpSession::synchEnter() {
+ sessionLock.Lock();
+}
+
+void CtZrtpSession::synchLeave() {
+ sessionLock.Unlock();
+}