1 /*
2  * libZRTP SDK library, implements the ZRTP secure VoIP protocol.
3  * Copyright (c) 2006-2009 Philip R. Zimmermann.  All rights reserved.
4  * Contact: http://philzimmermann.com
5  * For licensing and other legal details, see the file zrtp_legal.c.
6  *
7  * Viktor Krykun <v.krikun at zfoneproject.com>
8  */
9 
10 #include "zrtp.h"
11 
12 #define _ZTU_ "zrtp utils"
13 
14 
15 /*----------------------------------------------------------------------------*/
_zrtp_prepare_secrets(zrtp_session_t * session)16 zrtp_status_t _zrtp_prepare_secrets(zrtp_session_t* session)
17 {
18 	zrtp_secrets_t* sec = &session->secrets;
19 	zrtp_status_t s = zrtp_status_ok;
20 
21 	/* Protect Secrets from race conditions on multistream calls. */
22 	zrtp_mutex_lock(session->streams_protector);
23 
24 	if (!sec->is_ready) {
25 		do {
26 			uint32_t verifiedflag = 0;
27 
28 			session->secrets.rs1->_cachedflag  = 0;
29 			session->secrets.rs2->_cachedflag  = 0;
30 			if (session->zrtp->cb.cache_cb.on_get) {
31 				s = session->zrtp->cb.cache_cb.on_get( ZSTR_GV(session->zid),
32 													   ZSTR_GV(session->peer_zid),
33 													   session->secrets.rs1,
34 													   0);
35 				session->secrets.rs1->_cachedflag = (zrtp_status_ok == s);
36 
37 				s = session->zrtp->cb.cache_cb.on_get( ZSTR_GV(session->zid),
38 													   ZSTR_GV(session->peer_zid),
39 													   session->secrets.rs2,
40 													   1);
41 				session->secrets.rs2->_cachedflag = (zrtp_status_ok == s);
42 			}
43 
44 			if (session->zrtp->cb.cache_cb.on_get_verified) {
45 				s = session->zrtp->cb.cache_cb.on_get_verified( ZSTR_GV(session->zid),
46 															   ZSTR_GV(session->peer_zid),
47 															   &verifiedflag);
48 			}
49 
50 			if (session->zrtp->cb.cache_cb.on_get_mitm) {
51 				s = session->zrtp->cb.cache_cb.on_get_mitm( ZSTR_GV(session->zid),
52 															ZSTR_GV(session->peer_zid),
53 															session->secrets.pbxs);
54 				session->secrets.pbxs->_cachedflag = (zrtp_status_ok == s);
55 			} else {
56 				session->secrets.pbxs->_cachedflag = 0;
57 			}
58 
59 			/* Duplicate all secrets flags to zrtp-context */
60 			session->secrets.cached |= session->secrets.rs1->_cachedflag ? ZRTP_BIT_RS1 : 0;
61 			session->secrets.cached |= session->secrets.rs2->_cachedflag ? ZRTP_BIT_RS2 : 0;
62 			session->secrets.cached |= session->secrets.pbxs->_cachedflag ? ZRTP_BIT_PBX : 0;
63 
64 			{
65 			char buff[128];
66 			char buff2[128];
67 			ZRTP_LOG(3,(_ZTU_,"\tRestoring Secrets: lZID=%s rZID=%s. V=%d sID=%u\n",
68 						hex2str(session->zid.buffer, session->zid.length, buff, sizeof(buff)),
69 						hex2str(session->peer_zid.buffer, session->peer_zid.length, buff2, sizeof(buff2)),
70 						verifiedflag,
71 						session->id));
72 			ZRTP_LOG(3,(_ZTU_,"\t\tRS1 <%s>\n",
73 						session->secrets.rs1->_cachedflag ?
74 						hex2str( session->secrets.rs1->value.buffer,
75 								session->secrets.rs1->value.length,
76 								buff, sizeof(buff) )     : "EMPTY"));
77 			ZRTP_LOG(3,(_ZTU_,"\t\tRS2 <%s>\n",
78 						session->secrets.rs2->_cachedflag ?
79 						hex2str( session->secrets.rs2->value.buffer,
80 								session->secrets.rs2->value.length,
81 								buff, sizeof(buff) )     : "EMPTY"));
82 			ZRTP_LOG(3,(_ZTU_,"\t\tPBX <%s>\n",
83 						session->secrets.pbxs->_cachedflag ?
84 						hex2str( session->secrets.pbxs->value.buffer,
85 								session->secrets.pbxs->value.length,
86 								buff, sizeof(buff) )     : "EMPTY"));
87 			}
88 
89 			sec->is_ready = 1;
90 			s = zrtp_status_ok;
91 		} while (0);
92 	}
93 
94 	zrtp_mutex_unlock(session->streams_protector);
95 
96 	return s;
97 }
98 
99 /*----------------------------------------------------------------------------*/
_zrtp_alloc_shared_secret(zrtp_session_t * session)100 zrtp_shared_secret_t *_zrtp_alloc_shared_secret(zrtp_session_t* session)
101 {
102     zrtp_shared_secret_t *ss = zrtp_sys_alloc(sizeof(zrtp_shared_secret_t));
103     if (ss) {
104     	zrtp_memset(ss, 0, sizeof(zrtp_shared_secret_t));
105 		ZSTR_SET_EMPTY(ss->value);
106 		ss->value.length = ZRTP_MIN(ss->value.max_length, ZRTP_RS_SIZE);
107 
108 		ss->lastused_at  = (uint32_t)(zrtp_time_now()/1000);
109 		ss->ttl			 = 0xFFFFFFFF;
110 		ss->_cachedflag	 = 0;
111     	ss->value.length = ZRTP_MIN(ss->value.max_length, ZRTP_RS_SIZE);
112 
113 		if (ss->value.length != zrtp_randstr( session->zrtp,
114 											 (unsigned char*)ss->value.buffer,
115 											 ss->value.length))
116 		{
117 			zrtp_sys_free(ss);
118 			ss = NULL;
119 		}
120     }
121 
122     return ss;
123 }
124 
125 /*----------------------------------------------------------------------------*/
_zrtp_can_start_stream(zrtp_stream_t * stream,zrtp_stream_t ** conc,zrtp_stream_mode_t mode)126 int _zrtp_can_start_stream(zrtp_stream_t* stream, zrtp_stream_t **conc, zrtp_stream_mode_t mode)
127 {
128 	uint8_t deny = 0;
129     mlist_t* node = NULL;
130 
131 	zrtp_mutex_lock(stream->zrtp->sessions_protector);
132 
133     mlist_for_each(node, &stream->zrtp->sessions_head)
134     {
135 		zrtp_session_t* tmp_sctx = mlist_get_struct(zrtp_session_t, _mlist, node);
136 
137 		if ( !zrtp_zstrcmp(ZSTR_GV(tmp_sctx->zid), ZSTR_GV(stream->session->zid)) &&
138 			!zrtp_zstrcmp(ZSTR_GV(tmp_sctx->peer_zid), ZSTR_GV(stream->session->peer_zid)) )
139 		{
140 			int i = 0;
141 
142 			zrtp_mutex_lock(tmp_sctx->streams_protector);
143 
144 			for (i=0; i<ZRTP_MAX_STREAMS_PER_SESSION; i++)
145 			{
146 				zrtp_stream_t* tmp_stctx = &tmp_sctx->streams[i];
147 
148 				/*
149 				 * We don't need to lock the stream because it have been already locked
150 				 * by high level function: zrtp_process_srtp() or _initiating_secure()
151 				 */
152 				if ((stream != tmp_stctx) && (tmp_stctx->state != ZRTP_STATE_NONE)) {
153 					deny = ( (tmp_stctx->state > ZRTP_STATE_START_INITIATINGSECURE) &&
154 							(tmp_stctx->state < ZRTP_STATE_SECURE) );
155 
156 					if ((mode == ZRTP_STREAM_MODE_MULT) && deny) {
157 						deny = !(tmp_stctx->mode == ZRTP_STREAM_MODE_MULT);
158 					}
159 
160 					if (deny) {
161 						*conc = tmp_stctx;
162 						break;
163 					}
164 				}
165 			}
166 
167 			zrtp_mutex_unlock(tmp_sctx->streams_protector);
168 
169 			if (deny) {
170 				break;
171 			}
172 		}
173     }
174 
175 	zrtp_mutex_unlock(stream->zrtp->sessions_protector);
176 
177 	if (!deny){
178 		*conc = NULL;
179 	}
180 
181     return !deny;
182 }
183 
184 /*----------------------------------------------------------------------------*/
_zrtp_choose_best_comp(zrtp_profile_t * profile,zrtp_packet_Hello_t * peer_hello,zrtp_crypto_comp_t type)185 uint8_t _zrtp_choose_best_comp( zrtp_profile_t *profile,
186 							   zrtp_packet_Hello_t* peer_hello,
187 							   zrtp_crypto_comp_t type )
188 {
189 	uint8_t* prof_elem = NULL;
190     int i=0, j=0;
191 	int offset = 0;
192 	int count = 0;
193 
194     switch (type)
195     {
196 		case ZRTP_CC_PKT:
197 		{
198 			uint8_t pref_peer_pk = ZRTP_COMP_UNKN;
199 			uint8_t pref_pk = ZRTP_COMP_UNKN;
200 			char *cp = NULL;
201 
202 			prof_elem = (uint8_t*)profile->pk_schemes;
203 			offset = (peer_hello->hc + peer_hello->cc + peer_hello->ac) * ZRTP_COMP_TYPE_SIZE;
204 			count = peer_hello->kc;
205 
206 			/* Looking for peer preferable DH scheme */
207 			cp = (char*)peer_hello->comp + offset;
208 			for (i=0; i<count; i++, cp+=ZRTP_COMP_TYPE_SIZE) {
209 				uint8_t tmp_pref_peer_pk = zrtp_comp_type2id(type, cp);
210 				j = 0;
211 				while (prof_elem[j]) {
212 					if (prof_elem[j++] == tmp_pref_peer_pk) {
213 						pref_peer_pk = tmp_pref_peer_pk;
214 						break;
215 					}
216 				}
217 				if (ZRTP_COMP_UNKN != pref_peer_pk) {
218 					break;
219 				}
220 			}
221 
222 			/* Looking for local preferable DH scheme */
223 			i=0;
224 			while (prof_elem[i]) {
225 				uint8_t tmp_pref_pk = prof_elem[i++];
226 				cp = (char*)peer_hello->comp + offset;
227 				for (j=0; j<count; j++, cp+=ZRTP_COMP_TYPE_SIZE) {
228 					if(tmp_pref_pk == zrtp_comp_type2id(type, cp)) {
229 						pref_pk = tmp_pref_pk;
230 						break;
231 					}
232 				}
233 				if (ZRTP_COMP_UNKN != pref_pk) {
234 					break;
235 				}
236 			}
237 
238 			ZRTP_LOG(3,(_ZTU_,"\t_zrtp_choose_best_comp() for PKT. local=%s remote=%s, choosen=%s\n",
239 						zrtp_comp_id2type(type, pref_pk), zrtp_comp_id2type(type, pref_peer_pk), zrtp_comp_id2type(type, ZRTP_MIN(pref_peer_pk, pref_pk))));
240 
241 			/* Choose the fastest one. */
242 			return ZRTP_MIN(pref_peer_pk, pref_pk);
243 		} break;
244 		case ZRTP_CC_HASH:
245 			prof_elem = (uint8_t*)&profile->hash_schemes;
246 			offset = 0;
247 			count = peer_hello->hc;
248 			break;
249 		case ZRTP_CC_SAS:
250 			prof_elem = (uint8_t*)profile->sas_schemes;
251 			offset = (peer_hello->hc + peer_hello->cc + peer_hello->ac + peer_hello->kc)* ZRTP_COMP_TYPE_SIZE;
252 			count = peer_hello->sc;
253 			break;
254 		case ZRTP_CC_CIPHER:
255 			prof_elem = (uint8_t*)profile->cipher_types;
256 			offset = peer_hello->hc * ZRTP_COMP_TYPE_SIZE;
257 			count = peer_hello->cc;
258 			break;
259 		case ZRTP_CC_ATL:
260 			prof_elem = (uint8_t*)profile->auth_tag_lens;
261 			offset = (peer_hello->hc + peer_hello->cc)*ZRTP_COMP_TYPE_SIZE;
262 			count = peer_hello->ac;
263 			break;
264 		default:
265 			return ZRTP_COMP_UNKN;
266     }
267 
268 	while (prof_elem[i])
269 	{
270 		char *cp = (char*)peer_hello->comp + offset;
271 		uint8_t comp_id = prof_elem[i++];
272 
273 		for (j=0; j<count; j++, cp+=ZRTP_COMP_TYPE_SIZE) {
274 			if (comp_id ==  zrtp_comp_type2id(type, cp)) {
275 				return comp_id;
276 			}
277 		}
278     }
279 
280 	return ZRTP_COMP_UNKN;
281 }
282 
283 /*----------------------------------------------------------------------------*/
_is_presh_in_hello(zrtp_packet_Hello_t * hello)284 static int _is_presh_in_hello(zrtp_packet_Hello_t* hello)
285 {
286 	int i = 0;
287 	char* cp = (char*)hello->comp + (hello->hc + hello->cc + hello->ac) * ZRTP_COMP_TYPE_SIZE;
288 	for (i=0; i < hello->kc; i++, cp+=ZRTP_COMP_TYPE_SIZE) {
289 		if (!zrtp_memcmp(cp, ZRTP_PRESHARED, ZRTP_COMP_TYPE_SIZE)) {
290 			return i;
291 		}
292 	}
293 
294 	return -1;
295 }
296 
_zrtp_is_dh_in_session(zrtp_stream_t * stream)297 int _zrtp_is_dh_in_session(zrtp_stream_t* stream)
298 {
299 	uint8_t i = 0;
300 	for (i=0; i< ZRTP_MAX_STREAMS_PER_SESSION; i++) {
301 		zrtp_stream_t *tmp_stream = &stream->session->streams[i];
302 		if ((tmp_stream != stream) && ZRTP_IS_STREAM_DH(tmp_stream)) {
303 			return 0;
304 		}
305 	}
306 	return -1;
307 }
308 
_zrtp_define_stream_mode(zrtp_stream_t * stream)309 zrtp_stream_mode_t _zrtp_define_stream_mode(zrtp_stream_t* stream)
310 {
311 	zrtp_session_t* session = stream->session;
312 
313 	/*
314 	 * If ZRTP Session key is available - use Multistream mode.
315 	 * If both sides ready for Preshared and we have RS1 and it has Verified flag - try Preshared.
316 	 * Use DH in other cases
317 	 */
318 	if (session->zrtpsess.length > 0) {
319 		stream->pubkeyscheme = zrtp_comp_find(ZRTP_CC_PKT, ZRTP_PKTYPE_MULT, session->zrtp);
320 		return ZRTP_STREAM_MODE_MULT;
321 	} else {
322 		/* If both sides ready for Preshared and we have RSes in our cache - try Preshared. */
323 		if (ZRTP_PKTYPE_PRESH == stream->pubkeyscheme->base.id)
324 		{
325 			do {
326 				uint32_t verifiedflag = 0;
327 				uint32_t calls_counter = 0;
328 
329 				if (_is_presh_in_hello(&stream->messages.peer_hello) < 0) {
330 					break;
331 				}
332 
333 				if (ZRTP_IS_STREAM_PRESH(stream) && session->zrtp->cb.cache_cb.on_presh_counter_get) {
334 					session->zrtp->cb.cache_cb.on_presh_counter_get( ZSTR_GV(session->zid),
335 																	ZSTR_GV(session->peer_zid),
336 																	&calls_counter);
337 					if (calls_counter >= ZRTP_PRESHARED_MAX_ALLOWED) {
338 						ZRTP_LOG(3,(_ZTU_,"\tDefine stream mode: user wants PRESHARED but Preshared"
339 									"calls counter reached the maximum value (ID=%u) -  Reset to DH.\n", stream->id));
340 						break;
341 					}
342 				}
343 
344 				if (session->zrtp->cb.cache_cb.on_get_verified) {
345 					session->zrtp->cb.cache_cb.on_get_verified( ZSTR_GV(session->zid),
346 															   ZSTR_GV(session->peer_zid),
347 															   &verifiedflag);
348 				}
349 
350 				if (!session->secrets.rs1->_cachedflag || !verifiedflag) {
351 					ZRTP_LOG(3,(_ZTU_,"\tDefine stream mode: user wants PRESHARED but we HAVE "
352 								"RS1=%d and V=%d. Reset to DH. ID=%u\n", session->secrets.rs1->_cachedflag, verifiedflag, stream->id));
353 					break;
354 				}
355 
356 				ZRTP_LOG(3,(_ZTU_,"\tDefine stream mode: user wants PRESHARED and we have RS1,"
357 							" calls_counter=%d. Use preshared. ID=%u\n", calls_counter, stream->id));
358 
359 				return ZRTP_STREAM_MODE_PRESHARED;
360 			} while (0);
361 		}
362 
363 		/* If Preshared not accepted by some reaseon - choose appropriate DH scheme. */
364 		if ( (ZRTP_PKTYPE_PRESH == stream->pubkeyscheme->base.id) ||
365 			(ZRTP_PKTYPE_MULT == stream->pubkeyscheme->base.id) )
366 		{
367 			int i=0, j=0;
368 			zrtp_packet_Hello_t* phello = &stream->messages.peer_hello;
369 			uint8_t comp_id = ZRTP_COMP_UNKN;
370 
371 			while (session->profile.pk_schemes[i])
372 			{
373 				char *cp = (char*)phello->comp + (phello->hc + phello->cc + phello->ac) * ZRTP_COMP_TYPE_SIZE;
374 				comp_id = session->profile.pk_schemes[i++];
375 				if ((comp_id != ZRTP_PKTYPE_PRESH) && (comp_id != ZRTP_PKTYPE_MULT))
376 				{
377 					for (j=0; j<phello->kc; j++, cp+=ZRTP_COMP_TYPE_SIZE) {
378 						if (comp_id == zrtp_comp_type2id(ZRTP_CC_PKT, cp)) {
379 							break;
380 						}
381 					}
382 					if (j != phello->kc) {
383 						break;
384 					}
385 				}
386 			}
387 
388 			stream->pubkeyscheme = zrtp_comp_find(ZRTP_CC_PKT, comp_id, session->zrtp);
389 		}
390 
391 		return ZRTP_STREAM_MODE_DH;
392 	}
393 }
394 
395 /*---------------------------------------------------------------------------*/
_zrtp_validate_message_hmac(zrtp_stream_t * stream,zrtp_msg_hdr_t * msg2check,char * hmackey)396 int _zrtp_validate_message_hmac( zrtp_stream_t *stream,
397 								 zrtp_msg_hdr_t* msg2check,
398 								 char* hmackey)
399 {
400 	zrtp_string32_t hash_str = ZSTR_INIT_EMPTY(hash_str);
401 	zrtp_hash_t *hash = zrtp_comp_find(ZRTP_CC_HASH, ZRTP_HASH_SHA256, stream->session->zrtp);
402 
403 	hash->hmac_truncated_c( hash,
404 						    hmackey,
405 						    ZRTP_MESSAGE_HASH_SIZE,
406 						    (char*)msg2check,
407 						    zrtp_ntoh16(msg2check->length)*4 - ZRTP_HMAC_SIZE,
408 						    ZRTP_HMAC_SIZE,
409 						    ZSTR_GV(hash_str));
410 
411 	if (0 != zrtp_memcmp((char*)msg2check + (zrtp_ntoh16(msg2check->length)*4 - ZRTP_HMAC_SIZE), hash_str.buffer, ZRTP_HMAC_SIZE))
412 	{
413 		if (stream->zrtp->cb.event_cb.on_zrtp_security_event) {
414 			stream->zrtp->cb.event_cb.on_zrtp_security_event(stream, ZRTP_EVENT_WRONG_MESSAGE_HMAC);
415 		}
416 		_zrtp_machine_enter_initiatingerror(stream, zrtp_error_wrong_meshmac, 0);
417 		return -1;
418 	}
419 
420 	return 0;
421 }
422 
423 /*---------------------------------------------------------------------------*/
_zrtp_compute_preshared_key(zrtp_session_t * session,zrtp_stringn_t * rs1,zrtp_stringn_t * auxs,zrtp_stringn_t * pbxs,zrtp_stringn_t * key,zrtp_stringn_t * key_id)424 zrtp_status_t _zrtp_compute_preshared_key( zrtp_session_t *session,
425 										   zrtp_stringn_t* rs1,
426 										   zrtp_stringn_t* auxs,
427 										   zrtp_stringn_t* pbxs,
428 										   zrtp_stringn_t* key,
429 										   zrtp_stringn_t* key_id)
430 {
431 	static const zrtp_string8_t presh_key_str	= ZSTR_INIT_WITH_CONST_CSTRING(ZRTP_COMMIT_HV_KEY_STR);
432 	zrtp_string32_t preshared_key = ZSTR_INIT_EMPTY(preshared_key);
433 	static uint32_t length_rs = ZRTP_RS_SIZE;
434 	static const uint32_t length_zero = 0;
435 
436 	void *hash_ctx = session->hash->hash_begin(session->hash);
437 	if (!hash_ctx) {
438 		return zrtp_status_alloc_fail;
439 	}
440 
441 	length_rs = zrtp_hton32(length_rs);
442 
443 	if (rs1) {
444 		session->hash->hash_update(session->hash, hash_ctx, (const int8_t*)&length_rs, 4);
445 		session->hash->hash_update(session->hash, hash_ctx, (const int8_t*)rs1->buffer, ZRTP_RS_SIZE);
446 	} else {
447 		session->hash->hash_update(session->hash, hash_ctx, (const int8_t*)&length_zero, 4);
448 	}
449 
450 	if (auxs) {
451 		session->hash->hash_update(session->hash, hash_ctx, (const int8_t*)&length_rs, 4);
452 		session->hash->hash_update(session->hash, hash_ctx, (const int8_t*)auxs->buffer, ZRTP_RS_SIZE);
453 	} else {
454 		session->hash->hash_update(session->hash, hash_ctx, (const int8_t*)&length_zero, 4);
455 	}
456 
457 	if (pbxs) {
458 		session->hash->hash_update(session->hash, hash_ctx, (const int8_t*)&length_rs, 4);
459 		session->hash->hash_update(session->hash, hash_ctx, (const int8_t*)pbxs->buffer, ZRTP_RS_SIZE);
460 	} else {
461 		session->hash->hash_update(session->hash, hash_ctx, (const int8_t*)&length_zero, 4);
462 	}
463 
464 	session->hash->hash_end(session->hash, hash_ctx, ZSTR_GV(preshared_key));
465 	if (key) {
466 		zrtp_zstrcpy(ZSTR_GVP(key), ZSTR_GV(preshared_key));
467 	}
468 
469 	if (key_id) {
470 		session->hash->hmac_truncated( session->hash,
471 									   ZSTR_GV(preshared_key),
472 									   ZSTR_GV(presh_key_str),
473 									   ZRTP_HV_KEY_SIZE,
474 									   ZSTR_GVP(key_id));
475 	}
476 
477 	return zrtp_status_ok;
478 }
479 
480 /*---------------------------------------------------------------------------*/
_zrtp_kdf(zrtp_stream_t * stream,zrtp_stringn_t * ki,zrtp_stringn_t * label,zrtp_stringn_t * context,uint32_t length,zrtp_stringn_t * digest)481 zrtp_status_t _zrtp_kdf( zrtp_stream_t* stream,
482 						 zrtp_stringn_t* ki,
483 						 zrtp_stringn_t* label,
484 						 zrtp_stringn_t* context,
485 						 uint32_t length,
486 						 zrtp_stringn_t* digest)
487 {
488 	/*KDF(KI, Label, Context, L) = HMAC(KI, i | Label | 0x00 | Context | L) */
489 	uint32_t i = 1;
490 	uint8_t o = 0;
491 	uint32_t L = zrtp_hton32(length*8);
492 	zrtp_hash_t* hash = stream->session->hash;
493 	void* ctx = hash->hmac_begin(hash, ki);
494 	if (!ctx) {
495 		return zrtp_status_alloc_fail;
496 	}
497 
498 	i = zrtp_hton32(i);
499 	hash->hmac_update(hash, ctx, (const char*)&i, sizeof(i));
500 	hash->hmac_update(hash, ctx, label->buffer, label->length);
501 	hash->hmac_update(hash, ctx, (const char*)&o, sizeof(o));
502 	hash->hmac_update(hash, ctx, context->buffer, context->length);
503 	hash->hmac_update(hash, ctx, (const char*)&L, sizeof(L));
504 
505 	hash->hmac_end(hash, ctx, digest, length);
506 
507 	return zrtp_status_ok;
508 }
509 
510 /*---------------------------------------------------------------------------*/
zrtp_verified_set(zrtp_global_t * zrtp,zrtp_string16_t * zid1,zrtp_string16_t * zid2,uint8_t verified)511 zrtp_status_t zrtp_verified_set( zrtp_global_t *zrtp,
512 								 zrtp_string16_t *zid1,
513 								 zrtp_string16_t *zid2,
514 								 uint8_t verified )
515 {
516 	mlist_t *node = NULL;
517 
518 	if (!zrtp) {
519 		return zrtp_status_bad_param;
520 	}
521 
522 	zrtp_mutex_lock(zrtp->sessions_protector);
523 
524 	mlist_for_each(node, &zrtp->sessions_head)
525 	{
526 		zrtp_session_t *session = mlist_get_struct(zrtp_session_t, _mlist, node);
527 		if ( ( !zrtp_zstrcmp(ZSTR_GV(session->zid), ZSTR_GVP(zid1)) ||
528 			  !zrtp_zstrcmp(ZSTR_GV(session->zid), ZSTR_GVP(zid2)) ) &&
529 			( !zrtp_zstrcmp(ZSTR_GV(session->peer_zid), ZSTR_GVP(zid1)) ||
530 			 !zrtp_zstrcmp(ZSTR_GV(session->peer_zid), ZSTR_GVP(zid2)) ) )
531 		{
532 			if (session->zrtp->cb.cache_cb.on_set_verified) {
533 				session->zrtp->cb.cache_cb.on_set_verified(ZSTR_GVP(zid1), ZSTR_GVP(zid2), verified);
534 			}
535 
536 			if (session->mitm_alert_detected) {
537 				session->mitm_alert_detected = 0;
538 				if (session->zrtp->cb.cache_cb.on_put) {
539 					session->zrtp->cb.cache_cb.on_put( ZSTR_GV(session->zid),
540 													   ZSTR_GV(session->peer_zid),
541 													   session->secrets.rs1);
542 				}
543 			}
544 		}
545 	}
546 
547 	zrtp_mutex_unlock(zrtp->sessions_protector);
548 	return zrtp_status_ok;
549 }
550 
551 /*----------------------------------------------------------------------------*/
_zrtp_get_timeout(uint32_t curr_timeout,zrtp_msg_type_t msg)552 uint32_t _zrtp_get_timeout(uint32_t curr_timeout, zrtp_msg_type_t msg)
553 {
554 	uint32_t timeout = curr_timeout;
555 	uint32_t base_interval = 0;
556 	uint32_t capping = 0;
557 #if (defined(ZRTP_BUILD_FOR_CSD) && (ZRTP_BUILD_FOR_CSD == 1))
558 	uint8_t  is_lineral = 1;
559 	capping				= 10000;
560 #else
561 	uint8_t  is_lineral = 0;
562 #endif
563 	switch (msg)
564 	{
565 		case ZRTP_NONE:
566 		case ZRTP_HELLOACK:
567 		case ZRTP_DHPART1:
568 		case ZRTP_CONFIRM1:
569 		case ZRTP_CONFIRM2ACK:
570 		case ZRTP_GOCLEARACK:
571 		case ZRTP_RELAYACK:
572 			return 0;
573 #if (defined(ZRTP_BUILD_FOR_CSD) && (ZRTP_BUILD_FOR_CSD == 1))
574 		case ZRTP_HELLO:
575 			base_interval = ZRTP_CSD_T1;
576 			break;
577 		case ZRTP_COMMIT:
578 			base_interval = ZRTP_CSD_T2;
579 			break;
580 		case ZRTP_DHPART2:
581 			base_interval = ZRTP_CSD_T3;
582 			break;
583 		case ZRTP_CONFIRM2:
584 			base_interval = ZRTP_CSD_T4;
585 			break;
586 		case ZRTP_GOCLEAR:
587 		case ZRTP_SASRELAY:
588 			base_interval = ZRTP_CSD_T2;
589 			break;
590 		case ZRTP_ERROR:
591 			base_interval = ZRTP_CSD_ET;
592 			break;
593 #else
594 		case ZRTP_HELLO:
595 			base_interval = ZRTP_T1;
596 			capping = ZRTP_T1_CAPPING;
597 			break;
598 		case ZRTP_COMMIT:
599 		case ZRTP_DHPART2:
600 		case ZRTP_CONFIRM2:
601 		case ZRTP_GOCLEAR:
602 		case ZRTP_SASRELAY:
603 			base_interval = ZRTP_T2;
604 			capping = ZRTP_T2_CAPPING;
605 			break;
606 		case ZRTP_ERROR:
607 		case ZRTP_ERRORACK:
608 			base_interval = ZRTP_ET;
609 			capping = ZRTP_T2_CAPPING;
610 			break;
611 #endif
612 		case ZRTP_PROCESS:
613 			base_interval = ZRTP_PROCESS_T1;
614 			break;
615 		default:
616 			return 0;
617 	}
618 
619 	if (0 == timeout) {
620 		timeout = base_interval;
621 	} else if (!is_lineral) {
622 		timeout *= 2;
623 	} else {
624 		timeout += base_interval;
625 	}
626 
627 	if (timeout > capping) {
628 		return capping;
629 	} else {
630 		return timeout;
631 	}
632 }
633 
634