wernerd / ZRTPCPP

C++ Implementation of ZRTP protocol - GNU ZRTP C++
Other
116 stars 50 forks source link

SAS Verified flag in multistream mode #39

Open glenvt18 opened 7 years ago

glenvt18 commented 7 years ago

I've come across an interoperability issue with libzrtp. This library was originally made for ZFone, and is used by baresip and FreeSWITCH.

The issue. ZRTPCPP doesn't fill in V and E flags in multistream mode while composing Confirm1 and Confirm2 messages (in ZRtp::prepareConfirm1MultiStream() and ZRtp::prepareConfirm2MultiStream()). Though, in multistream mode, it makes little sense, libzrtp doesn't ignore these flags: https://freeswitch.org/stash/projects/FS/repos/freeswitch/browse/libs/libzrtp/src/zrtp_protocol.c#1424

Every time it sees V=0 in a multistream Confirm packet, it resets its own V flag and updates the cache. Thus, if there are more than one streams, it's impossible to establish a "verified" session.

While ignoring those flags in multistream mode is still the best choice, how about adding them for those who don't ignore? BTW linphone UA works exactly that way.

This patch did the job for me:

diff --git a/zrtp/ZRtp.cpp b/zrtp/ZRtp.cpp
index 0b96a9c..a116772 100755
--- a/zrtp/ZRtp.cpp
+++ b/zrtp/ZRtp.cpp
@@ -935,6 +935,10 @@ ZrtpPacketConfirm* ZRtp::prepareConfirm1MultiStream(ZrtpPacketCommit* commit, ui
     if (configureAlgos.isDisclosureFlag()) {
         zrtpConfirm1.setDisclosureFlag();
     }
+    // get verified flag from the cache
+    if (masterStream && masterStream->zidRec && masterStream->zidRec->isSasVerified()) {
+        zrtpConfirm1.setSASFlag();
+    }
     zrtpConfirm1.setExpTime(0xFFFFFFFF);
     zrtpConfirm1.setIv(randomIV);
     zrtpConfirm1.setHashH0(H0);
@@ -1148,6 +1152,10 @@ ZrtpPacketConfirm* ZRtp::prepareConfirm2MultiStream(ZrtpPacketConfirm* confirm1,
     if (configureAlgos.isDisclosureFlag()) {
         zrtpConfirm2.setDisclosureFlag();
     }
+    // get verified flag from the cache
+    if (masterStream && masterStream->zidRec && masterStream->zidRec->isSasVerified()) {
+        zrtpConfirm2.setSASFlag();
+    }
     zrtpConfirm2.setHashH0(H0);
     zrtpConfirm2.setExpTime(0xFFFFFFFF);
     zrtpConfirm2.setIv(randomIV);