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 dengine"
13 
14 
15 #if (defined(ZRTP_BUILD_FOR_CSD) && (ZRTP_BUILD_FOR_CSD == 1))
16 
17 extern zrtp_status_t _zrtp_machine_process_hello(zrtp_stream_t* stream, zrtp_rtp_info_t* packet);
18 extern zrtp_status_t start_send_and_resend_hello(zrtp_stream_t* stream);
19 extern zrtp_status_t start_initiating_secure(zrtp_stream_t *stream);
20 extern zrtp_status_t _zrtp_machine_start_send_and_resend_hello(zrtp_stream_t* stream);
21 
22 
23 /*----------------------------------------------------------------------------*/
zrtp_driven_stream_start(zrtp_stream_t * stream,zrtp_statemachine_type_t role)24 void zrtp_driven_stream_start(zrtp_stream_t* stream, zrtp_statemachine_type_t role)
25 {
26 
27 	ZRTP_LOG(3,(_ZTU_,"START Driven %s Stream ID=%u mode=%s state=%s.",
28 				(ZRTP_STATEMACHINE_INITIATOR == role)?"INITIATOR":"RESPONDER",
29 				stream->id, zrtp_log_mode2str(stream->mode), zrtp_log_state2str(stream->state)));
30 
31 	/* This function can be called in parallel to the main processing loop protect internal stream data. */
32 	zrtp_mutex_lock(stream->stream_protector);
33 
34 	if ( (ZRTP_STATE_ACTIVE != stream->state) &&
35 		 (ZRTP_STATE_ERROR != stream->state) &&
36 	     (ZRTP_STATE_NO_ZRTP != stream->state))
37 	{
38 		ZRTP_LOG(1,(_ZTU_,"ERROR! can't start stream ID=%u from state %d.", stream->id, stream->state));
39 	}
40 	else
41 	{
42 		if (ZRTP_STATEMACHINE_INITIATOR == role) {
43 			_zrtp_change_state(stream, ZRTP_STATE_DRIVEN_INITIATOR);
44 			_zrtp_machine_start_send_and_resend_hello(stream);
45 		} else if (ZRTP_STATEMACHINE_RESPONDER == role) {
46 			_zrtp_change_state(stream, ZRTP_STATE_DRIVEN_RESPONDER);
47 		}
48 	}
49 
50 	zrtp_mutex_unlock(stream->stream_protector);
51 }
52 
53 /*---------------------------------------------------------------------------*/
_zrtp_machine_process_while_in_driven_initiator(zrtp_stream_t * stream,zrtp_rtp_info_t * packet)54 zrtp_status_t _zrtp_machine_process_while_in_driven_initiator( zrtp_stream_t* stream,
55 															   zrtp_rtp_info_t* packet)
56 {
57 	zrtp_status_t s = zrtp_status_ok;
58 
59 	switch (packet->type)
60 	{
61 	case ZRTP_HELLO: {
62 		s = _zrtp_machine_process_hello(stream, packet);
63 		if (zrtp_status_ok != s) {
64 			ZRTP_LOG(1,(_ZTU_,"ERROR! _zrtp_machine_process_hello()4 failed with status=%d. ID=%u",s, stream->id));
65 			break; /* Just stay in DRIVEN_INITIATOR state. */
66 		}
67 
68 		/* Now we have ZIDs for both sides and can upload secrets from the cache */
69 		s = _zrtp_prepare_secrets(stream->session);
70 		if (zrtp_status_ok != s) {
71 			ZRTP_LOG(1,(_ZTU_,"ERROR! _zrtp_prepare_secrets()3 failed with status=%d. ID=%u",s, stream->id));
72 			break; /* Just stay in START state. */
73 		}
74 
75 		// TODO: handle autosecure and licensing modes there
76 		_zrtp_cancel_send_packet_later(stream, ZRTP_HELLO);
77 		stream->mode = _zrtp_define_stream_mode(stream);
78 		s = _zrtp_machine_enter_initiatingsecure(stream);
79 	} break;
80 
81 	default:
82 		break;
83 	}
84 
85 	return s;
86 }
87 
_zrtp_machine_process_while_in_driven_responder(zrtp_stream_t * stream,zrtp_rtp_info_t * packet)88 zrtp_status_t _zrtp_machine_process_while_in_driven_responder( zrtp_stream_t* stream,
89 															   zrtp_rtp_info_t* packet)
90 {
91 	zrtp_status_t s = zrtp_status_ok;
92 
93 	switch (packet->type)
94 	{
95 	case ZRTP_HELLO: {
96 		s = _zrtp_machine_process_hello(stream, packet);
97 		if (zrtp_status_ok != s) {
98 			ZRTP_LOG(1,(_ZTU_,"ERROR! _zrtp_machine_process_hello()5 failed with status=%d. ID=%u", s, stream->id));
99 			break; /* Just stay in DRIVEN_INITIATOR state. */
100 		}
101 
102 		/* Now we have ZIDs for both sides and can upload secrets from the cache */
103 		s = _zrtp_prepare_secrets(stream->session);
104 		if (zrtp_status_ok != s) {
105 			ZRTP_LOG(1,(_ZTU_,"ERROR! _zrtp_prepare_secrets()4 failed with status=%d. ID=%u", s, stream->id));
106 			break; /* Just stay in START state. */
107 		}
108 
109 		// TODO: handle autosecure and licensing modes there
110 		s = _zrtp_packet_send_message(stream, ZRTP_HELLO, &stream->messages.hello);
111 		if (zrtp_status_ok == s) {
112 			_zrtp_change_state(stream, ZRTP_STATE_DRIVEN_PENDING);
113 		}
114 	} break;
115 
116 	default:
117 		break;
118 	}
119 
120 	return s;
121 }
122 
_zrtp_machine_process_while_in_driven_pending(zrtp_stream_t * stream,zrtp_rtp_info_t * packet)123 zrtp_status_t _zrtp_machine_process_while_in_driven_pending( zrtp_stream_t* stream,
124 															 zrtp_rtp_info_t* packet)
125 {
126 	zrtp_status_t s = zrtp_status_ok;
127 
128 	switch (packet->type)
129 	{
130 	case ZRTP_HELLO: {
131 		s = _zrtp_packet_send_message(stream, ZRTP_HELLO, &stream->messages.hello);
132 	} break;
133 
134 	case ZRTP_COMMIT: {
135 		zrtp_statemachine_type_t role = _zrtp_machine_preparse_commit(stream, packet);
136 		if (ZRTP_STATEMACHINE_RESPONDER == role) {
137 			s = _zrtp_machine_enter_pendingsecure(stream, packet);
138 		} else if (ZRTP_STATEMACHINE_INITIATOR == role) {
139 			s = _zrtp_machine_start_initiating_secure(stream);
140 		} else {
141 			s = zrtp_status_fail;
142 		}
143 	} break;
144 
145 	default:
146 		break;
147 	}
148 
149 	return s;
150 }
151 
152 #endif /* ZRTP_BUILD_FOR_CSD */
153