| /* |
| * 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(); |
| } |