Browse code

core:zrtp: fix ZID, double ZRTP initialization; place ZRTP init after onStart

Stefan Sayer authored on 03/11/2014 13:04:24
Showing 5 changed files
... ...
@@ -755,9 +755,6 @@ int AmRtpStream::init(const AmSdp& local,
755 755
 
756 756
 #ifdef WITH_ZRTP  
757 757
   if (session && session->enable_zrtp) {
758
-    if (session->zrtp_session_state.initSession(session))
759
-      return -1;
760
-
761 758
     session->zrtp_session_state.startStreams(get_ssrc());
762 759
   }
763 760
 #endif
... ...
@@ -279,15 +279,6 @@ void AmSession::run() {
279 279
 #endif
280 280
 
281 281
 bool AmSession::startup() {
282
-#ifdef WITH_ZRTP
283
-  if (enable_zrtp) {
284
-    if (zrtp_session_state.initSession(this))
285
-      return -1;
286
-      
287
-      DBG("initialized ZRTP session context OK\n");
288
-  }
289
-#endif
290
-
291 282
   session_started();
292 283
 
293 284
   try {
... ...
@@ -295,6 +286,16 @@ bool AmSession::startup() {
295 295
 
296 296
       onStart();
297 297
 
298
+#ifdef WITH_ZRTP
299
+      if (enable_zrtp) {
300
+	if (zrtp_session_state.initSession(this)) {
301
+	  ERROR("initializing ZRTP session\n");
302
+	  throw AmSession::Exception(500, SIP_REPLY_SERVER_INTERNAL_ERROR);
303
+	}
304
+	DBG("initialized ZRTP session context OK\n");
305
+      }
306
+#endif
307
+
298 308
     } 
299 309
     catch(const AmSession::Exception& e){ throw e; }
300 310
     catch(const string& str){
... ...
@@ -1322,9 +1323,9 @@ void AmSession::onZRTPProtocolEvent(zrtp_protocol_event_t event, zrtp_stream_t *
1322 1322
       break;
1323 1323
 
1324 1324
     case ZRTP_EVENT_IS_PASSIVE_RESTRICTION:
1325
-      INFO("ZRTP_EVENT_IS_PASSIVE_RESTRICTION\n");
1325
+     INFO("ZRTP_EVENT_IS_PASSIVE_RESTRICTION\n");
1326 1326
       break;
1327
-     
1327
+
1328 1328
     default: 
1329 1329
       INFO("unknown ZRTP_EVENT\n");
1330 1330
       break;
... ...
@@ -45,7 +45,7 @@ AmMutex AmZRTP::zrtp_cache_mut;
45 45
 
46 46
 zrtp_global_t* AmZRTP::zrtp_global;      // persistent storage for libzrtp data
47 47
 zrtp_config_t AmZRTP::zrtp_config;
48
-zrtp_zid_t AmZRTP::zrtp_instance_zid = {"defaultsems"}; // todo: generate one
48
+zrtp_zid_t AmZRTP::zrtp_instance_zid = {"defaultsems"}; // todo: generate one?
49 49
 
50 50
 void zrtp_log(int level, char *data, int len, int offset) {
51 51
   int sems_lvl = L_DBG;
... ...
@@ -68,25 +68,54 @@ int AmZRTP::init() {
68 68
   }
69 69
 
70 70
   cache_path = cfg.getParameter("cache_path");
71
-  string zid = cfg.getParameter("zid");
72
-  if (zid.length() != sizeof(zrtp_zid_t)) {
73
-    ERROR("ZID of this instance MUST be set for ZRTP.\n");
74
-    ERROR("ZID needs to be %lu characters long.\n", 
75
-	  sizeof(zrtp_zid_t));
76
-    return -1;
71
+  if (cfg.hasParameter("zid_hex")) {
72
+    string zid_hex = cfg.getParameter("zid_hex");
73
+    if (zid_hex.size() != 2*sizeof(zrtp_instance_zid)) {
74
+      ERROR("zid_hex config parameter in zrtp.conf must be %lu characters long.\n", 
75
+	    sizeof(zrtp_zid_t)*2);
76
+      return -1;
77
+    }
78
+
79
+    for (size_t i=0;i<sizeof(zrtp_instance_zid);i++) {
80
+      unsigned int h;
81
+      if (reverse_hex2int(zid_hex.substr(i*2, 2), h)) {
82
+	ERROR("in zid_hex in zrtp.conf: '%s' is no hex number\n", zid_hex.substr(i*2, 2).c_str());
83
+	return -1;
84
+      }
85
+
86
+      zrtp_instance_zid[i]=h % 0xff;
87
+    }
88
+
89
+  } else if (cfg.hasParameter("zid")) {
90
+    string zid = cfg.getParameter("zid");
91
+    WARN("zid parameter in zrtp.conf is only supported for backwards compatibility. Please use zid_hex\n");
92
+    if (zid.length() != sizeof(zrtp_zid_t)) {
93
+      ERROR("zid config parameter in zrtp.conf must be %lu characters long.\n", 
94
+	    sizeof(zrtp_zid_t));
95
+      return -1;
96
+    }
97
+    for (size_t i=0;i<zid.length();i++)
98
+      zrtp_instance_zid[i]=zid[i];
99
+  } else {
100
+    // generate one
101
+    string zid_hex;
102
+    for (size_t i=0;i<sizeof(zrtp_instance_zid);i++) {
103
+      zrtp_instance_zid[i]=get_random() % 0xff;
104
+      zid_hex+=char2hex(zrtp_instance_zid[i], true);
105
+    }
106
+
107
+    WARN("Generated random ZID. To support key continuity through key cache "
108
+	 "on the peers, add this to zrtp.conf: 'zid_hex=\"%s\"'", zid_hex.c_str());
77 109
   }
78 110
 
79
-  for (size_t i=0;i<zid.length();i++)
80
-    zrtp_instance_zid[i]=zid[i];
81 111
 
82
-  DBG("initializing ZRTP library with ZID '%s', cache path '%s'.\n",
83
-      zid.c_str(), cache_path.c_str());
112
+  DBG("initializing ZRTP library with cache path '%s'.\n", cache_path.c_str());
84 113
 
85 114
   zrtp_config_defaults(&zrtp_config);
86 115
 
87 116
   strcpy(zrtp_config.client_id, SEMS_CLIENT_ID);
117
+  memcpy((char*)zrtp_config.zid, (char*)zrtp_instance_zid, sizeof(zrtp_zid_t));
88 118
   zrtp_config.lic_mode = ZRTP_LICENSE_MODE_UNLIMITED;
89
-
90 119
   
91 120
   strncpy(zrtp_config.cache_file_cfg.cache_path, cache_path.c_str(), 256);
92 121
 
... ...
@@ -136,11 +165,9 @@ AmZRTPSessionState::AmZRTPSessionState()
136 136
 }
137 137
 
138 138
 int AmZRTPSessionState::initSession(AmSession* session) {
139
+  DBG("Initializing ZRTP stream...\n");
139 140
 
140
-  DBG("starting ZRTP stream...\n");
141
-  //
142
-  // Allocate zrtp session with default parameters
143
-  //
141
+  // Allocate zrtp session
144 142
   zrtp_status_t status =
145 143
     zrtp_session_init( AmZRTP::zrtp_global,
146 144
 		       &zrtp_profile,
... ...
@@ -154,9 +181,7 @@ int AmZRTPSessionState::initSession(AmSession* session) {
154 154
   // Set call-back pointer to our parent structure
155 155
   zrtp_session_set_userdata(zrtp_session, session);
156 156
 
157
-  // 
158
-  // Attach Audio and Video Streams
159
-  //
157
+  // Attach audio stream
160 158
   status = zrtp_stream_attach(zrtp_session, &zrtp_audio);
161 159
   if (zrtp_status_ok != status) {
162 160
     // Check error code and debug logs
... ...
@@ -272,32 +297,4 @@ void AmZRTP::on_zrtp_protocol_event(zrtp_stream_t *stream, zrtp_protocol_event_t
272 272
   sess->postEvent(new AmZRTPProtocolEvent(event, stream));
273 273
 }
274 274
 
275
-/*
276
-void zrtp_play_alert(zrtp_stream_t* ctx) {
277
-  INFO("zrtp_play_alert: ALERT!\n");
278
-  ctx->need_play_alert = zrtp_play_no;
279
-}
280
-*/
281
-
282
-// #define BUFFER_LOG_SIZE 256
283
-// void zrtp_print_log(log_level_t level, const char* format, ...)
284
-// {
285
-// 	char buffer[BUFFER_LOG_SIZE];
286
-//     va_list arg;
287
-
288
-//     va_start(arg, format);
289
-//     vsnprintf(buffer, BUFFER_LOG_SIZE, format, arg);
290
-//     va_end( arg );
291
-//     int sems_lvl = L_ERR;
292
-//     switch(level) {
293
-//     case ZRTP_LOG_DEBUG:   sems_lvl = L_DBG; break;
294
-//     case ZRTP_LOG_INFO:    sems_lvl = L_INFO; break;
295
-//     case ZRTP_LOG_WARNING: sems_lvl = L_WARN; break;
296
-//     case ZRTP_LOG_ERROR:   sems_lvl = L_ERR; break;
297
-//     case ZRTP_LOG_FATAL:   sems_lvl = L_ERR; break;
298
-//     case ZRTP_LOG_ALL:   sems_lvl = L_ERR; break;
299
-//     }
300
-//     _LOG(sems_lvl, "*** %s", buffer);
301
-// }
302
-
303 275
 #endif
... ...
@@ -4,9 +4,11 @@
4 4
 cache_path=zrtp_cache.dat
5 5
 
6 6
 #
7
-# ZID - must be set to a unique identifier on installation.
7
+# ZID - must be set to a unique random identifier on installation.
8
+# if none is provided, a random one will be generated - this should be
9
+# then taken into zrtp.conf to support key continuity. 
8 10
 #
9
-#zid=012345678901
11
+#zid_hex="d4d8bb2d7d3536244cb67598"
10 12
 
11 13
 # random_entropy_bytes - bytes to read from /dev/random to zrtp entropy pool
12 14
 # Warning: can stall the startup process if there's many bytes read. 
... ...
@@ -1,4 +1,4 @@
1
-/* \file info about ZRTP usage in SEMS
1
+/* \file info about using ZRTP with SEMS
2 2
  */
3 3
 
4 4
 /*!
... ...
@@ -15,7 +15,7 @@
15 15
  *  not supporting it are still possible, but unencrypted. The actual RTP encryption is done with 
16 16
  *  <a href="http://www.ietf.org/rfc/rfc3711.txt">SRTP</a>.
17 17
  *
18
- *  <p>ZRTP is one of the widest (if not the widest) supported end-to-end encryption methods for VoIP. 
18
+ *  <p>ZRTP is one of the most widely (if not the most widely) supported end-to-end encryption methods for VoIP. 
19 19
  *  Popular SIP clients that support ZRTP are <a href="http://www.jitsi.org">Jitsi</a>, CSipSimple, Twinkle, Linphone.</p>
20 20
  * 
21 21
  *  <p>For more information about ZRTP, see the