blob: 85887440ed46c70a99d7dddd2cbba51efe297b36 [file] [log] [blame]
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001/*
2 * Tivi client glue code for ZRTP.
3 * Copyright (c) 2012 Slient Circle LLC. All rights reserved.
4 *
5 *
6 * @author Werner Dittmann <Werner.Dittmann@t-online.de>
7 */
8
9#include <string>
10#include <stdio.h>
11
12#include <libzrtpcpp/ZIDCache.h>
13#include <libzrtpcpp/ZRtp.h>
14
15#include <CtZrtpStream.h>
16#include <CtZrtpCallback.h>
17#include <CtZrtpSession.h>
18
19#include <common/Thread.h>
20
21static CMutexClass sessionLock;
22
23const char *getZrtpBuildInfo()
24{
25 return zrtpBuildInfo;
26}
27CtZrtpSession::CtZrtpSession() : mitmMode(false), signSas(false), enableParanoidMode(false), isReady(false),
28 zrtpEnabled(true), sdesEnabled(true) {
29
30 clientIdString = clientId;
31 streams[AudioStream] = NULL;
32 streams[VideoStream] = NULL;
33}
34
35int CtZrtpSession::initCache(const char *zidFilename) {
36 ZIDCache* zf = getZidCacheInstance();
37 if (!zf->isOpen()) {
38 std::string fname;
39 if (zidFilename == NULL) {
40 char *home = getenv("HOME");
41 std::string baseDir = (home != NULL) ? (std::string(home) + std::string("/."))
42 : std::string(".");
43 fname = baseDir + std::string("GNUZRTP.zid");
44 zidFilename = fname.c_str();
45 }
46 if (zf->open((char *)zidFilename) < 0) {
47 return -1;
48 }
49 }
50 return 1;
51}
52
53int CtZrtpSession::init(bool audio, bool video, ZrtpConfigure* config)
54{
55 int32_t ret = 1;
56
57 synchEnter();
58
59 ZrtpConfigure* configOwn = NULL;
60 if (config == NULL) {
61 config = configOwn = new ZrtpConfigure();
62 setupConfiguration(config);
63 config->setTrustedMitM(true);
64 }
65 config->setParanoidMode(enableParanoidMode);
66
67 ZIDCache* zf = getZidCacheInstance();
68 if (!zf->isOpen()) {
69 ret = -1;
70 }
71 if (ret > 0) {
72 const uint8_t* ownZid = zf->getZid();
73 CtZrtpStream *stream;
74
75 // Create CTZrtpStream object only once, they are availbe for the whole
76 // lifetime of the session.
77 if (audio) {
78 if (streams[AudioStream] == NULL)
79 streams[AudioStream] = new CtZrtpStream();
80 stream = streams[AudioStream];
81 stream->zrtpEngine = new ZRtp((uint8_t*)ownZid, stream, clientIdString, config, mitmMode, signSas);
82 stream->type = Master;
83 stream->index = AudioStream;
84 stream->session = this;
85 }
86 if (video) {
87 if (streams[VideoStream] == NULL)
88 streams[VideoStream] = new CtZrtpStream();
89 stream = streams[VideoStream];
90 stream->zrtpEngine = new ZRtp((uint8_t*)ownZid, stream, clientIdString, config);
91 stream->type = Slave;
92 stream->index = VideoStream;
93 stream->session = this;
94 }
95 }
96 if (configOwn != NULL) {
97 delete configOwn;
98 }
99 synchLeave();
100 isReady = true;
101 return ret;
102}
103
104CtZrtpSession::~CtZrtpSession() {
105
106 delete streams[AudioStream];
107 delete streams[VideoStream];
108}
109
110void zrtp_log(const char *tag, const char *buf);
111void CtZrtpSession::setupConfiguration(ZrtpConfigure *conf) {
112
113// Set _WITHOUT_TIVI_ENV to a real name that is TRUE if the Tivi client is compiled/built.
114#ifdef _WITHOUT_TIVI_ENV
115#define GET_CFG_I(RET,_KEY)
116#else
117void *findGlobalCfgKey(char *key, int iKeyLen, int &iSize, char **opt, int *type);
118#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;}
119#endif
120
121
122// The next three vars are used in case of a real Tivi compile, see macro above.
123 int iSZ;
124 char *opt;
125 int type;
126 void zrtp_log( const char *tag, const char *buf);
127
128 int b32sas = 0, iDisableDH2K = 0, iDisableAES256 = 0, iPreferDH2K = 0;
129 int iDisableECDH256 = 0, iDisableECDH384 = 0, iEnableSHA384 = 1;
130 int iDisableSkein = 0, iDisableTwofish = 0, iPreferNIST = 0;
131 int iDisableSkeinHash = 0, iDisableBernsteinCurve25519 = 0, iDisableBernsteinCurve3617 = 0;
132
133 GET_CFG_I(b32sas, "iDisable256SAS");
134 GET_CFG_I(iDisableAES256, "iDisableAES256");
135 GET_CFG_I(iDisableDH2K, "iDisableDH2K");
136 GET_CFG_I(iPreferDH2K, "iPreferDH2K");
137
138 GET_CFG_I(iDisableECDH256, "iDisableECDH256");
139 GET_CFG_I(iDisableECDH384, "iDisableECDH384");
140 GET_CFG_I(iEnableSHA384, "iEnableSHA384");
141 GET_CFG_I(iDisableSkein, "iDisableSkein");
142 GET_CFG_I(iDisableTwofish, "iDisableTwofish");
143 GET_CFG_I(iPreferNIST, "iPreferNIST");
144
145 GET_CFG_I(iDisableSkeinHash, "iDisableSkeinHash");
146 GET_CFG_I(iDisableBernsteinCurve25519, "iDisableBernsteinCurve25519");
147 GET_CFG_I(iDisableBernsteinCurve3617, "iDisableBernsteinCurve3617");
148
149 conf->clear();
150
151 /*
152 * Setting the selection policy is a more generic policy than the iPreferNIST
153 * configuration set by the user. The selection policy is a decision of the
154 * client, not the user
155 */
156 conf->setSelectionPolicy(ZrtpConfigure::PreferNonNist);
157
158 /*
159 * Handling of iPreferNIST: if this is false (== 0) then we add the non-NIST algorithms
160 * to the configuration and place them in front of the NIST algorithms. Refer to RFC6189
161 * section 4.1.2 regarding selection of the public key algorithm.
162 *
163 * With the configuration flags we can enable/disable each ECC PK algorithm separately.
164 *
165 */
166 if (iPreferNIST == 0) {
167 if (iDisableBernsteinCurve3617 == 0)
168 conf->addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName("E414"));
169 if (iDisableECDH384 == 0)
170 conf->addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName("EC38"));
171 }
172 else {
173 if (iDisableECDH384 == 0)
174 conf->addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName("EC38"));
175 if (iDisableBernsteinCurve3617 == 0)
176 conf->addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName("E414"));
177 }
178
179 if (iPreferNIST == 0) {
180 if (iDisableBernsteinCurve25519 == 0)
181 conf->addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName("E255"));
182 if (iDisableECDH256 == 0)
183 conf->addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName("EC25"));
184 }
185 else {
186 if (iDisableECDH256 == 0)
187 conf->addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName("EC25"));
188 if (iDisableBernsteinCurve25519 == 0)
189 conf->addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName("E255"));
190 }
191
192 // DH2K handling: if DH2K not disabled and prefered put it infrom of DH3K,
193 // If not preferred and not disabled put if after DH3K. Don't use DH2K if
194 // it's not enabled at all (iDisableDH2K == 1)
195 if (iPreferDH2K && iDisableDH2K == 0) {
196 conf->addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName("DH2k"));
197 }
198 conf->addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName("DH3k"));
199 if (iPreferDH2K == 0 && iDisableDH2K == 0)
200 conf->addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName("DH2k"));
201
202 conf->addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName("Mult"));
203
204
205 // Handling of Hash algorithms: similar to PK, if PreferNIST is false
206 // then put Skein in fromt oF SHA. Regardless if the Hash is enabled or
207 // not: if configuration enables a large curve then also use the large
208 // hashes.
209 if (iPreferNIST == 0) {
210 if (iDisableSkeinHash == 0 || iDisableBernsteinCurve3617 == 0)
211 conf->addAlgo(HashAlgorithm, zrtpHashes.getByName("SKN3"));
212 if (iEnableSHA384 == 1 || iDisableECDH384 == 0)
213 conf->addAlgo(HashAlgorithm, zrtpHashes.getByName("S384"));
214 }
215 else {
216 if (iEnableSHA384 == 1 || iDisableECDH384 == 0)
217 conf->addAlgo(HashAlgorithm, zrtpHashes.getByName("S384"));
218 if (iDisableSkeinHash == 0 || iDisableBernsteinCurve3617 == 0)
219 conf->addAlgo(HashAlgorithm, zrtpHashes.getByName("SKN3"));
220 }
221
222 if (iPreferNIST == 0) {
223 if (iDisableSkeinHash == 0)
224 conf->addAlgo(HashAlgorithm, zrtpHashes.getByName("SKN2"));
225 conf->addAlgo(HashAlgorithm, zrtpHashes.getByName("S256"));
226 }
227 else {
228 conf->addAlgo(HashAlgorithm, zrtpHashes.getByName("S256"));
229 if (iDisableSkeinHash == 0)
230 conf->addAlgo(HashAlgorithm, zrtpHashes.getByName("SKN2"));
231 }
232
233 // Handling of Symmetric algorithms: always prefer twofish (regardless
234 // of NIST setting) if it is not disabled. iDisableAES256 means: disable
235 // large ciphers
236 if (iDisableAES256 == 0) {
237 if (iDisableTwofish == 0)
238 conf->addAlgo(CipherAlgorithm, zrtpSymCiphers.getByName("2FS3"));
239 conf->addAlgo(CipherAlgorithm, zrtpSymCiphers.getByName("AES3"));
240 }
241
242 if (iDisableTwofish == 0)
243 conf->addAlgo(CipherAlgorithm, zrtpSymCiphers.getByName("2FS1"));
244 conf->addAlgo(CipherAlgorithm, zrtpSymCiphers.getByName("AES1"));
245
246 if (b32sas == 1) {
247 conf->addAlgo(SasType, zrtpSasTypes.getByName("B32 "));
248 }
249 else {
250 conf->addAlgo(SasType, zrtpSasTypes.getByName("B256"));
251 conf->addAlgo(SasType, zrtpSasTypes.getByName("B32 "));
252 }
253
254 if (iPreferNIST == 0) {
255 if (iDisableSkein == 0) {
256 conf->addAlgo(AuthLength, zrtpAuthLengths.getByName("SK32"));
257 conf->addAlgo(AuthLength, zrtpAuthLengths.getByName("SK64"));
258 }
259 conf->addAlgo(AuthLength, zrtpAuthLengths.getByName("HS32"));
260 conf->addAlgo(AuthLength, zrtpAuthLengths.getByName("HS80"));
261 }
262 else {
263 conf->addAlgo(AuthLength, zrtpAuthLengths.getByName("HS32"));
264 conf->addAlgo(AuthLength, zrtpAuthLengths.getByName("HS80"));
265 if (iDisableSkein == 0) {
266 conf->addAlgo(AuthLength, zrtpAuthLengths.getByName("SK32"));
267 conf->addAlgo(AuthLength, zrtpAuthLengths.getByName("SK64"));
268 }
269 }
270}
271
272void CtZrtpSession::setUserCallback(CtZrtpCb* ucb, streamName streamNm) {
273 if (!(streamNm >= 0 && streamNm <= AllStreams && streams[streamNm] != NULL))
274 return;
275
276 if (streamNm == AllStreams) {
277 for (int sn = 0; sn < AllStreams; sn++)
278 streams[sn]->setUserCallback(ucb);
279 }
280 else
281 streams[streamNm]->setUserCallback(ucb);
282}
283
284void CtZrtpSession::setSendCallback(CtZrtpSendCb* scb, streamName streamNm) {
285 if (!(streamNm >= 0 && streamNm <= AllStreams && streams[streamNm] != NULL))
286 return;
287
288 if (streamNm == AllStreams) {
289 for (int sn = 0; sn < AllStreams; sn++)
290 streams[sn]->setSendCallback(scb);
291 }
292 else
293 streams[streamNm]->setSendCallback(scb);
294
295}
296
297void CtZrtpSession::masterStreamSecure(CtZrtpStream *masterStream) {
298 // Here we know that the AudioStream is the master and VideoStream the slave.
299 // Otherwise we need to loop and find the Master stream and the Slave streams.
300
301 multiStreamParameter = masterStream->zrtpEngine->getMultiStrParams();
302 CtZrtpStream *strm = streams[VideoStream];
303 if (strm->enableZrtp) {
304 strm->zrtpEngine->setMultiStrParams(multiStreamParameter);
305 strm->zrtpEngine->startZrtpEngine();
306 strm->started = true;
307 strm->tiviState = eLookingPeer;
308 if (strm->zrtpUserCallback != 0)
309 strm->zrtpUserCallback->onNewZrtpStatus(this, NULL, strm->index);
310
311 }
312}
313
314int CtZrtpSession::startIfNotStarted(unsigned int uiSSRC, int streamNm) {
315 if (!(streamNm >= 0 && streamNm < AllStreams && streams[streamNm] != NULL))
316 return 0;
317
318 if ((streamNm == VideoStream && !isSecure(AudioStream)) || streams[streamNm]->started)
319 return 0;
320
321 start(uiSSRC, streamNm == VideoStream ? CtZrtpSession::VideoStream : CtZrtpSession::AudioStream);
322 return 0;
323}
324
325void CtZrtpSession::start(unsigned int uiSSRC, CtZrtpSession::streamName streamNm) {
326 if (!zrtpEnabled || !(streamNm >= 0 && streamNm < AllStreams && streams[streamNm] != NULL))
327 return;
328
329 CtZrtpStream *stream = streams[streamNm];
330
331 stream->ownSSRC = uiSSRC;
332 stream->enableZrtp = true;
333 if (stream->type == Master) {
334 stream->zrtpEngine->startZrtpEngine();
335 stream->started = true;
336 stream->tiviState = eLookingPeer;
337 if (stream->zrtpUserCallback != 0)
338 stream->zrtpUserCallback->onNewZrtpStatus(this, NULL, stream->index);
339 return;
340 }
341 // Process a Slave stream.
342 if (!multiStreamParameter.empty()) { // Multi-stream parameters available
343 stream->zrtpEngine->setMultiStrParams(multiStreamParameter);
344 stream->zrtpEngine->startZrtpEngine();
345 stream->started = true;
346 stream->tiviState = eLookingPeer;
347 if (stream->zrtpUserCallback != 0)
348 stream->zrtpUserCallback->onNewZrtpStatus(this, NULL, stream->index);
349 }
350}
351
352void CtZrtpSession::stop(streamName streamNm) {
353 if (!(streamNm >= 0 && streamNm < AllStreams && streams[streamNm] != NULL))
354 return;
355
356 streams[streamNm]->isStopped = true;
357}
358
359void CtZrtpSession::release() {
360 release(AudioStream);
361 release(VideoStream);
362}
363
364void CtZrtpSession::release(streamName streamNm) {
365 if (!(streamNm >= 0 && streamNm < AllStreams && streams[streamNm] != NULL))
366 return;
367
368 CtZrtpStream *stream = streams[streamNm];
369 stream->stopStream(); // stop and reset stream
370}
371
372void CtZrtpSession::setLastPeerNameVerify(const char *name, int iIsMitm) {
373 CtZrtpStream *stream = streams[AudioStream];
374
375 if (!isReady || !stream || stream->isStopped)
376 return;
377
378 uint8_t peerZid[IDENTIFIER_LEN];
379 std::string nm(name);
380 stream->zrtpEngine->getPeerZid(peerZid);
381 getZidCacheInstance()->putPeerName(peerZid, nm);
382 setVerify(1);
383}
384
385int CtZrtpSession::isSecure(streamName streamNm) {
386 if (!(streamNm >= 0 && streamNm < AllStreams && streams[streamNm] != NULL))
387 return 0;
388
389 CtZrtpStream *stream = streams[streamNm];
390 return stream->isSecure();
391}
392
393bool CtZrtpSession::processOutoingRtp(uint8_t *buffer, size_t length, size_t *newLength, streamName streamNm) {
394 if (!isReady || !(streamNm >= 0 && streamNm < AllStreams && streams[streamNm] != NULL))
395 return false;
396
397 CtZrtpStream *stream = streams[streamNm];
398 if (stream->isStopped)
399 return false;
400
401 return stream->processOutgoingRtp(buffer, length, newLength);
402}
403
404int32_t CtZrtpSession::processIncomingRtp(uint8_t *buffer, size_t length, size_t *newLength, streamName streamNm) {
405 if (!isReady || !(streamNm >= 0 && streamNm < AllStreams && streams[streamNm] != NULL))
406 return fail;
407
408 CtZrtpStream *stream = streams[streamNm];
409 if (stream->isStopped)
410 return fail;
411
412 return stream->processIncomingRtp(buffer, length, newLength);
413}
414
415bool CtZrtpSession::isStarted(streamName streamNm) {
416 if (!isReady || !(streamNm >= 0 && streamNm < AllStreams && streams[streamNm] != NULL))
417 return false;
418
419 return streams[streamNm]->isStarted();
420}
421
422bool CtZrtpSession::isEnabled(streamName streamNm) {
423 if (!isReady || !(streamNm >= 0 && streamNm < AllStreams && streams[streamNm] != NULL))
424 return false;
425
426 CtZrtpStream *stream = streams[streamNm];
427 if (stream->isStopped)
428 return false;
429
430 return stream->isEnabled();
431}
432
433CtZrtpSession::tiviStatus CtZrtpSession::getCurrentState(streamName streamNm) {
434 if (!isReady || !(streamNm >= 0 && streamNm < AllStreams && streams[streamNm] != NULL))
435 return eWrongStream;
436
437 CtZrtpStream *stream = streams[streamNm];
438 if (stream->isStopped)
439 return eWrongStream;
440
441 return stream->getCurrentState();
442}
443
444CtZrtpSession::tiviStatus CtZrtpSession::getPreviousState(streamName streamNm) {
445 if (!isReady || !(streamNm >= 0 && streamNm < AllStreams && streams[streamNm] != NULL))
446 return eWrongStream;
447
448 CtZrtpStream *stream = streams[streamNm];
449 if (stream->isStopped)
450 return eWrongStream;
451
452 return stream->getPreviousState();
453}
454
455bool CtZrtpSession::isZrtpEnabled() {
456 return zrtpEnabled;
457}
458
459bool CtZrtpSession::isSdesEnabled() {
460 return sdesEnabled;
461}
462
463void CtZrtpSession::setZrtpEnabled(bool yesNo) {
464 zrtpEnabled = yesNo;
465}
466
467void CtZrtpSession::setSdesEnabled(bool yesNo) {
468 sdesEnabled = yesNo;
469}
470
471int CtZrtpSession::getSignalingHelloHash(char *helloHash, streamName streamNm, int32_t index) {
472 if (!isReady || !(streamNm >= 0 && streamNm < AllStreams && streams[streamNm] != NULL))
473 return 0;
474
475 CtZrtpStream *stream = streams[streamNm];
476 if (stream->isStopped)
477 return 0;
478
479 return stream->getSignalingHelloHash(helloHash, index);
480}
481
482void CtZrtpSession::setSignalingHelloHash(const char *helloHash, streamName streamNm) {
483 if (!isReady || !(streamNm >= 0 && streamNm < AllStreams && streams[streamNm] != NULL))
484 return;
485
486 CtZrtpStream *stream = streams[streamNm];
487 if (stream->isStopped)
488 return;
489
490 stream->setSignalingHelloHash(helloHash);
491}
492
493void CtZrtpSession::setVerify(int iVerified) {
494 CtZrtpStream *stream = streams[AudioStream];
495
496 if (!isReady || !stream || stream->isStopped)
497 return;
498
499 if (iVerified) {
500 stream->zrtpEngine->SASVerified();
501 stream->sasVerified = true;
502 }
503 else {
504 stream->zrtpEngine->resetSASVerified();
505 stream->sasVerified = false;
506 }
507}
508
509int CtZrtpSession::getInfo(const char *key, uint8_t *buffer, size_t maxLen, streamName streamNm) {
510 if (!isReady || !(streamNm >= 0 && streamNm < AllStreams && streams[streamNm] != NULL))
511 return fail;
512
513 CtZrtpStream *stream = streams[streamNm];
514 return stream->getInfo(key, (char*)buffer, (int)maxLen);
515}
516
517int CtZrtpSession::enrollAccepted(char *p) {
518 if (!isReady || !(streams[AudioStream] != NULL))
519 return fail;
520
521 CtZrtpStream *stream = streams[AudioStream];
522 int ret = stream->enrollAccepted(p);
523 setVerify(true);
524 return ret;
525}
526
527int CtZrtpSession::enrollDenied() {
528 if (!isReady || !(streams[AudioStream] != NULL))
529 return fail;
530
531 CtZrtpStream *stream = streams[AudioStream];
532 int ret = stream->enrollDenied();
533 setVerify(true); // TODO : Janis -> is that correct in this case?
534 return ret;
535}
536
537void CtZrtpSession::setClientId(std::string id) {
538 clientIdString = id;
539}
540
541bool CtZrtpSession::createSdes(char *cryptoString, size_t *maxLen, streamName streamNm, const sdesSuites suite) {
542
543 if (!isReady || !sdesEnabled || !(streamNm >= 0 && streamNm < AllStreams && streams[streamNm] != NULL))
544 return fail;
545
546 CtZrtpStream *stream = streams[streamNm];
547 return stream->createSdes(cryptoString, maxLen, static_cast<ZrtpSdesStream::sdesSuites>(suite));
548}
549
550bool CtZrtpSession::parseSdes(char *recvCryptoStr, size_t recvLength, char *sendCryptoStr,
551 size_t *sendLength, bool sipInvite, streamName streamNm) {
552
553 if (!isReady || !sdesEnabled || !(streamNm >= 0 && streamNm < AllStreams && streams[streamNm] != NULL))
554 return fail;
555
556 CtZrtpStream *stream = streams[streamNm];
557 return stream->parseSdes(recvCryptoStr, recvLength, sendCryptoStr, sendLength, sipInvite);
558}
559
560bool CtZrtpSession::getSavedSdes(char *sendCryptoStr, size_t *sendLength, streamName streamNm) {
561 if (!isReady || !sdesEnabled || !(streamNm >= 0 && streamNm < AllStreams && streams[streamNm] != NULL))
562 return fail;
563
564 CtZrtpStream *stream = streams[streamNm];
565 return stream->getSavedSdes(sendCryptoStr, sendLength);
566}
567
568bool CtZrtpSession::isSdesActive(streamName streamNm) {
569 if (!isReady || !sdesEnabled || !(streamNm >= 0 && streamNm < AllStreams && streams[streamNm] != NULL))
570 return fail;
571
572 CtZrtpStream *stream = streams[streamNm];
573 return stream->isSdesActive();
574}
575
576int CtZrtpSession::getCryptoMixAttribute(char *algoNames, size_t length, streamName streamNm) {
577 if (!isReady || !sdesEnabled || !(streamNm >= 0 && streamNm < AllStreams && streams[streamNm] != NULL))
578 return 0;
579
580 CtZrtpStream *stream = streams[streamNm];
581 return stream->getCryptoMixAttribute(algoNames, length);
582}
583
584bool CtZrtpSession::setCryptoMixAttribute(const char *algoNames, streamName streamNm) {
585 if (!isReady || !sdesEnabled || !(streamNm >= 0 && streamNm < AllStreams && streams[streamNm] != NULL))
586 return fail;
587
588 CtZrtpStream *stream = streams[streamNm];
589 return stream->setCryptoMixAttribute(algoNames);
590}
591
592void CtZrtpSession::resetSdesContext(streamName streamNm, bool force) {
593 if (!isReady || !(streamNm >= 0 && streamNm < AllStreams && streams[streamNm] != NULL))
594 return;
595
596 CtZrtpStream *stream = streams[streamNm];
597 stream->resetSdesContext(force);
598}
599
600
601int32_t CtZrtpSession::getNumberSupportedVersions(streamName streamNm) {
602 if (!isReady || !(streamNm >= 0 && streamNm < AllStreams && streams[streamNm] != NULL))
603 return 0;
604
605 CtZrtpStream *stream = streams[streamNm];
606 return stream->getNumberSupportedVersions();
607}
608
609const char* CtZrtpSession::getZrtpEncapAttribute(streamName streamNm) {
610 if (!isReady || !(streamNm >= 0 && streamNm < AllStreams && streams[streamNm] != NULL))
611 return NULL;
612
613 CtZrtpStream *stream = streams[streamNm];
614 if (stream->isStopped)
615 return NULL;
616
617 return stream->getZrtpEncapAttribute();
618}
619
620void CtZrtpSession::setZrtpEncapAttribute(const char *attribute, streamName streamNm) {
621 if (!isReady || !(streamNm >= 0 && streamNm < AllStreams && streams[streamNm] != NULL))
622 return;
623
624 CtZrtpStream *stream = streams[streamNm];
625 if (stream->isStopped)
626 return;
627
628 stream->setZrtpEncapAttribute(attribute);
629}
630
631void CtZrtpSession::setAuxSecret(const unsigned char *secret, int length) {
632 if (!isReady || !(streams[AudioStream] != NULL))
633 return;
634
635 CtZrtpStream *stream = streams[AudioStream];
636 if (stream->isStopped)
637 return;
638
639 stream->setAuxSecret(secret, length);
640}
641
642void CtZrtpSession::cleanCache() {
643 getZidCacheInstance()->cleanup();
644}
645
646void CtZrtpSession::synchEnter() {
647 sessionLock.Lock();
648}
649
650void CtZrtpSession::synchLeave() {
651 sessionLock.Unlock();
652}