[jitsi-dev] Re: [jitsi~svn:9015] New ZRTP library that supports trusted MitM/PBX feature and implement SRT


#1

Hi Werner,

I have discovered a small problem in your code.

The variable zrtcpTransformer is initialized as null, never get another value and is used in the code which throw a NullPointerException after a call is established. And it causes that after 1 or 2 seconds, nobody can hear something.

Does zrtcpTransformer needs to be initialized in getRTCPTransformer() like this:
     public PacketTransformer getRTCPTransformer()
     {
         if(zrtcpTransformer == null)
             zrtcpTransformer = new ZRTCPTransformer(this);

         return zrtcpTransformer;
     }

or should it be in another methods (in srtpSecretsReady if the variable is null, ...) ?

The first should fix the issue (everybody hear each others) but I got these exceptions from the console (the last comes when we close the call).

      [java] java.io.IOException: Invalid RTCP Version
      [java] at net.sf.fmj.media.rtp.RTCPHeader.<init>(RTCPHeader.java:149)
      [java] at net.sf.fmj.media.rtp.RTCPReport.readSourceDescription(RTCPReport.java:123)
      [java] at net.sf.fmj.media.rtp.RTCPSenderReport.<init>(RTCPSenderReport.java:74)
      [java] at net.java.sip.communicator.impl.neomedia.transform.rtcp.StatisticsEngine.transform(StatisticsEngine.java:98)
      [java] at net.java.sip.communicator.impl.neomedia.transform.TransformEngineChain$PacketTransformerChain.transform(TransformEngineChain.java:131)
      [java] at net.java.sip.communicator.impl.neomedia.transform.TransformUDPOutputStream.createRawPacket(TransformUDPOutputStream.java:67)
      [java] at net.java.sip.communicator.impl.neomedia.RTPConnectorOutputStream.write(RTPConnectorOutputStream.java:294)
      [java] at com.sun.media.rtp.util.RTPPacketSender.sendTo(RTPPacketSender.java:36)
      [java] at com.sun.media.rtp.util.PacketFilter.sendTo(PacketFilter.java:72)
      [java] at com.sun.media.rtp.RTCPTransmitter.transmit(RTCPTransmitter.java:86)
      [java] at com.sun.media.rtp.RTCPTransmitter.report(RTCPTransmitter.java:110)
      [java] at com.sun.media.rtp.RTCPReporter.run(RTCPReporter.java:193)
      [java] at java.lang.Thread.run(Thread.java:680)
      [java] java.io.IOException: Invalid RTCP Version
      [java] at net.sf.fmj.media.rtp.RTCPHeader.<init>(RTCPHeader.java:149)
      [java] at net.sf.fmj.media.rtp.RTCPReport.readSourceDescription(RTCPReport.java:123)
      [java] at net.sf.fmj.media.rtp.RTCPSenderReport.<init>(RTCPSenderReport.java:74)
      [java] at net.java.sip.communicator.impl.neomedia.transform.rtcp.StatisticsEngine.transform(StatisticsEngine.java:98)
      [java] at net.java.sip.communicator.impl.neomedia.transform.TransformEngineChain$PacketTransformerChain.transform(TransformEngineChain.java:131)
      [java] at net.java.sip.communicator.impl.neomedia.transform.TransformUDPOutputStream.createRawPacket(TransformUDPOutputStream.java:67)
      [java] at net.java.sip.communicator.impl.neomedia.RTPConnectorOutputStream.write(RTPConnectorOutputStream.java:294)
      [java] at com.sun.media.rtp.util.RTPPacketSender.sendTo(RTPPacketSender.java:36)
      [java] at com.sun.media.rtp.util.PacketFilter.sendTo(PacketFilter.java:72)
      [java] at com.sun.media.rtp.RTCPTransmitter.transmit(RTCPTransmitter.java:86)
      [java] at com.sun.media.rtp.RTCPTransmitter.report(RTCPTransmitter.java:110)
      [java] at com.sun.media.rtp.RTCPReporter.run(RTCPReporter.java:193)
      [java] at java.lang.Thread.run(Thread.java:680)
      [java] java.io.IOException: Invalid RTCP Version
      [java] at net.sf.fmj.media.rtp.RTCPHeader.<init>(RTCPHeader.java:149)
      [java] at net.sf.fmj.media.rtp.RTCPReport.readSourceDescription(RTCPReport.java:123)
      [java] at net.sf.fmj.media.rtp.RTCPSenderReport.<init>(RTCPSenderReport.java:74)
      [java] at net.java.sip.communicator.impl.neomedia.transform.rtcp.StatisticsEngine.transform(StatisticsEngine.java:98)
      [java] at net.java.sip.communicator.impl.neomedia.transform.TransformEngineChain$PacketTransformerChain.transform(TransformEngineChain.java:131)
      [java] at net.java.sip.communicator.impl.neomedia.transform.TransformUDPOutputStream.createRawPacket(TransformUDPOutputStream.java:67)
      [java] at net.java.sip.communicator.impl.neomedia.RTPConnectorOutputStream.write(RTPConnectorOutputStream.java:294)
      [java] at com.sun.media.rtp.util.RTPPacketSender.sendTo(RTPPacketSender.java:36)
      [java] at com.sun.media.rtp.util.PacketFilter.sendTo(PacketFilter.java:72)
      [java] at com.sun.media.rtp.RTCPTransmitter.transmit(RTCPTransmitter.java:86)
      [java] at com.sun.media.rtp.RTCPTransmitter.bye(RTCPTransmitter.java:187)
      [java] at com.sun.media.rtp.RTCPTransmitter.bye(RTCPTransmitter.java:119)
      [java] at com.sun.media.rtp.RTCPReporter.releasessrc(RTCPReporter.java:137)
      [java] at com.sun.media.rtp.RTCPReporter.close(RTCPReporter.java:132)
      [java] at com.sun.media.rtp.RTPSessionMgr.stopParticipating(RTPSessionMgr.java:2471)
      [java] at com.sun.media.rtp.RTPSessionMgr.removeSendStream(RTPSessionMgr.java:1614)
      [java] at com.sun.media.rtp.SendSSRCInfo.close(SendSSRCInfo.java:254)
      [java] at net.java.sip.communicator.impl.neomedia.MediaStreamImpl.stopSendStreams(MediaStreamImpl.java:1972)
      [java] at net.java.sip.communicator.impl.neomedia.MediaStreamImpl.stopSendStreams(MediaStreamImpl.java:1934)
      [java] at net.java.sip.communicator.impl.neomedia.MediaStreamImpl.closeSendStreams(MediaStreamImpl.java:565)
      [java] at net.java.sip.communicator.impl.neomedia.MediaStreamImpl.close(MediaStreamImpl.java:503)
      [java] at net.java.sip.communicator.impl.neomedia.AudioMediaStreamImpl.close(AudioMediaStreamImpl.java:419)
      [java] at net.java.sip.communicator.service.protocol.media.CallPeerMediaHandler.setAudioStream(CallPeerMediaHandler.java:789)
      [java] at net.java.sip.communicator.service.protocol.media.CallPeerMediaHandler.closeStream(CallPeerMediaHandler.java:418)
      [java] at net.java.sip.communicator.service.protocol.media.CallPeerMediaHandler.close(CallPeerMediaHandler.java:403)
      [java] at net.java.sip.communicator.service.protocol.media.MediaAwareCallPeer.setState(MediaAwareCallPeer.java:485)
      [java] at net.java.sip.communicator.service.protocol.AbstractCallPeer.setState(AbstractCallPeer.java:435)
      [java] at net.java.sip.communicator.service.protocol.AbstractCallPeer.setState(AbstractCallPeer.java:479)
      [java] at net.java.sip.communicator.impl.protocol.jabber.CallPeerJabberImpl.hangup(CallPeerJabberImpl.java:384)
      [java] at net.java.sip.communicator.impl.protocol.jabber.OperationSetBasicTelephonyJabberImpl.hangupCallPeer(OperationSetBasicTelephonyJabberImpl.java:550)
      [java] at net.java.sip.communicator.impl.gui.main.call.CallManager$HangupCallThread.run(CallManager.java:1458)

Regards,

···

--
Seb

Le 16/10/11 09:31, wernerd@java.net a écrit :

Index: trunk/src/net/java/sip/communicator/impl/neomedia/transform/zrtp/ZRTPTransformEngine.java

--- trunk/src/net/java/sip/communicator/impl/neomedia/transform/zrtp/ZRTPTransformEngine.java (revision 9014)
+++ trunk/src/net/java/sip/communicator/impl/neomedia/transform/zrtp/ZRTPTransformEngine.java (revision 9015)
@@ -356,6 +356,10 @@
       */
      private boolean muted = false;

+ private boolean mitmMode = false;
+
+ private ZRTCPTransformer zrtcpTransformer = null;
+
      /**
       * Construct a ZRTPTransformEngine.
       *
@@ -372,7 +376,7 @@
       */
      public PacketTransformer getRTCPTransformer()
      {
- return new ZRTPCTransformer(this);
+ return new ZRTCPTransformer(this);
      }

      /**
@@ -503,7 +507,7 @@
              config.setStandardConfig();
          }

- zrtpEngine = new ZRtp(zf.getZid(), this, clientIdString, config);
+ zrtpEngine = new ZRtp(zf.getZid(), this, clientIdString, config, mitmMode);

          if (timeoutProvider == null)
          {
@@ -796,6 +800,7 @@
                          srtpPolicy, srtpPolicy);

                  srtpOutTransformer = engine.getRTPTransformer();
+ zrtcpTransformer.setSrtcpOut(engine.getRTCPTransformer());
              }
              else
              {
@@ -810,6 +815,7 @@
                          .getKeyResponder(), secrets.getSaltResponder(),
                          srtpPolicy, srtpPolicy);
                  srtpOutTransformer = engine.getRTPTransformer();
+ zrtcpTransformer.setSrtcpOut(engine.getRTCPTransformer());
              }
          }

@@ -831,6 +837,7 @@
                          .getKeyResponder(), secrets.getSaltResponder(),
                          srtpPolicy, srtpPolicy);
                  srtpInTransformer = engine.getRTPTransformer();
+ zrtcpTransformer.setSrtcpIn(engine.getRTCPTransformer());
                  this.muted = false;
              }
              else
@@ -846,6 +853,7 @@
                          .getKeyInitiator(), secrets.getSaltInitiator(),
                          srtpPolicy, srtpPolicy);
                  srtpInTransformer = engine.getRTPTransformer();
+ zrtcpTransformer.setSrtcpIn(engine.getRTCPTransformer());
                  this.muted = false;
              }
          }
@@ -979,7 +987,7 @@
       * Zrtp ask for Enrollment.
       * @param info supplied info.
       */
- public void zrtpAskEnrollment(String info)
+ public void zrtpAskEnrollment(ZrtpCodes.InfoEnrollment info)
      {
          if (securityEventManager != null)
          {
@@ -992,7 +1000,7 @@
       * @param info
       * @see gnu.java.zrtp.ZrtpCallback#zrtpInformEnrollment(java.lang.String)
       */
- public void zrtpInformEnrollment(String info)
+ public void zrtpInformEnrollment(ZrtpCodes.InfoEnrollment info)
      {
          if (securityEventManager != null)
          {
@@ -1096,18 +1104,7 @@
              zrtpEngine.setAuxSecret(data);
      }

-
      /**
- * Sets the PBX secret data
- *
- * @param data The PBX secret data
- */
- public void setPbxSecret(byte[] data) {
- if (zrtpEngine != null)
- zrtpEngine.setPbxSecret(data);
- }
-
- /**
       * Sets the client ID
       *
       * @param id The client ID
@@ -1192,6 +1189,101 @@
      }

      /**
+ * Get the commited SAS rendering algorithm for this ZRTP session.
+ *
+ * @return the commited SAS rendering algorithm
+ */
+ public ZrtpConstants.SupportedSASTypes getSasType() {
+ if (zrtpEngine != null)
+ return zrtpEngine.getSasType();
+ else
+ return null;
+ }
+
+ /**
+ * Get the computed SAS hash for this ZRTP session.
+ *
+ * @return a refernce to the byte array that contains the full
+ * SAS hash.
+ */
+ public byte[] getSasHash() {
+ if (zrtpEngine != null)
+ return zrtpEngine.getSasHash();
+ else
+ return null;
+ }
+
+ /**
+ * Send the SAS relay packet.
+ *
+ * The method creates and sends a SAS relay packet according to the ZRTP
+ * specifications. Usually only a MitM capable user agent (PBX) uses this
+ * function.
+ *
+ * @param sh the full SAS hash value
+ * @param render the SAS rendering algorithm
+ */
+ public boolean sendSASRelayPacket(byte[] sh, ZrtpConstants.SupportedSASTypes render) {
+ if (zrtpEngine != null)
+ return zrtpEngine.sendSASRelayPacket(sh, render);
+ else
+ return false;
+ }
+ /**
+ * Check the state of the MitM mode flag.
+ *
+ * If true then this ZRTP session acts as MitM, usually enabled by a PBX
+ * based client (user agent)
+ *
+ * @return state of mitmMode
+ */
+ public boolean isMitmMode() {
+ return mitmMode;
+ }
+
+ /**
+ * Set the state of the MitM mode flag.
+ *
+ * If MitM mode is set to true this ZRTP session acts as MitM, usually
+ * enabled by a PBX based client (user agent).
+ *
+ * @param mitmMode defines the new state of the mitmMode flag
+ */
+ public void setMitmMode(boolean mitmMode) {
+ this.mitmMode = mitmMode;
+ }
+
+ /**
+ * Check the state of the enrollment mode.
+ *
+ * If true then we will set the enrollment flag (E) in the confirm
+ * packets and performs the enrollment actions. A MitM (PBX) enrollment service sets this flagstarted this ZRTP
+ * session. Can be set to true only if mitmMode is also true.
+ * @return status of the enrollmentMode flag.
+ */
+ public boolean isEnrollmentMode() {
+ if (zrtpEngine != null)
+ return zrtpEngine.isEnrollmentMode();
+ else
+ return false;
+ }
+
+ /**
+ * Set the state of the enrollment mode.
+ *
+ * If true then we will set the enrollment flag (E) in the confirm
+ * packets and perform the enrollment actions. A MitM (PBX) enrollment
+ * service must sets this mode to true.
+ *
+ * Can be set to true only if mitmMode is also true.
+ *
+ * @param enrollmentMode defines the new state of the enrollmentMode flag
+ */
+ public void setEnrollmentMode(boolean enrollmentMode) {
+ if (zrtpEngine != null)
+ zrtpEngine.setEnrollmentMode(enrollmentMode);
+ }
+ /**
       * Sets signature data for the Confirm packets
       *
       * @param data the signature data
@@ -1226,16 +1318,6 @@
          return ((zrtpEngine != null) ? zrtpEngine.getSignatureLength() : 0);
      }

- /**
- * Sets the PBX enrollment flag (see chapter 8.3 of ZRTP standards)
- * (The PBX part needs further development)
- * @param yesNo The PBX enrollment flag
- */
- public void setPBXEnrollment(boolean yesNo)
- {
- if (zrtpEngine != null)
- zrtpEngine.setPBXEnrollment(yesNo);
- }

      /**
       * Method called by the Zrtp class as result of a GoClear request from the
@@ -1302,8 +1384,8 @@
       *
       * @return the ZID data as byte array.
       */
- public byte[] getZid()
+ public byte[] getPeerZid()
      {
- return ((zrtpEngine != null) ? zrtpEngine.getZid() : null);
+ return ((zrtpEngine != null) ? zrtpEngine.getPeerZid() : null);
      }
  }


#2

I don't know about the ZRTCPTransformer stuff. The other exceptions are because the SRTP/SRTCP encryption is done _before_ the StatisticsEngine kicks in. If the SRTCP is now encrypted, the Statics obviously can't deal with the packets anymore :slight_smile:

-> I move the encryption down after the StatisticsEngine. Wait a few more minutes...

Ingo

···

-----Original Message-----
From: Sebastien Vincent [mailto:seb@jitsi.org]
Sent: Montag, 17. Oktober 2011 11:15
To: dev@jitsi.java.net
Subject: [jitsi-dev] Re: [jitsi~svn:9015] New ZRTP library that supports
trusted MitM/PBX feature and implement SRT

Hi Werner,

I have discovered a small problem in your code.

The variable zrtcpTransformer is initialized as null, never get another
value and is used in the code which throw a NullPointerException after a
call is established. And it causes that after 1 or 2 seconds, nobody can
hear something.

Does zrtcpTransformer needs to be initialized in getRTCPTransformer()
like this:
     public PacketTransformer getRTCPTransformer()
     {
         if(zrtcpTransformer == null)
             zrtcpTransformer = new ZRTCPTransformer(this);

         return zrtcpTransformer;
     }

or should it be in another methods (in srtpSecretsReady if the variable
is null, ...) ?

The first should fix the issue (everybody hear each others) but I got
these exceptions from the console (the last comes when we close the call).

      [java] java.io.IOException: Invalid RTCP Version
      [java] at
net.sf.fmj.media.rtp.RTCPHeader.<init>(RTCPHeader.java:149)
      [java] at
net.sf.fmj.media.rtp.RTCPReport.readSourceDescription(RTCPReport.java:123)
      [java] at
net.sf.fmj.media.rtp.RTCPSenderReport.<init>(RTCPSenderReport.java:74)
      [java] at
net.java.sip.communicator.impl.neomedia.transform.rtcp.StatisticsEngine.tr
ansform(StatisticsEngine.java:98)
      [java] at
net.java.sip.communicator.impl.neomedia.transform.TransformEngineChain$Pac
ketTransformerChain.transform(TransformEngineChain.java:131)
      [java] at
net.java.sip.communicator.impl.neomedia.transform.TransformUDPOutputStream
.createRawPacket(TransformUDPOutputStream.java:67)
      [java] at
net.java.sip.communicator.impl.neomedia.RTPConnectorOutputStream.write(RTP
ConnectorOutputStream.java:294)
      [java] at
com.sun.media.rtp.util.RTPPacketSender.sendTo(RTPPacketSender.java:36)
      [java] at
com.sun.media.rtp.util.PacketFilter.sendTo(PacketFilter.java:72)
      [java] at
com.sun.media.rtp.RTCPTransmitter.transmit(RTCPTransmitter.java:86)
      [java] at
com.sun.media.rtp.RTCPTransmitter.report(RTCPTransmitter.java:110)
      [java] at
com.sun.media.rtp.RTCPReporter.run(RTCPReporter.java:193)
      [java] at java.lang.Thread.run(Thread.java:680)
      [java] java.io.IOException: Invalid RTCP Version
      [java] at
net.sf.fmj.media.rtp.RTCPHeader.<init>(RTCPHeader.java:149)
      [java] at
net.sf.fmj.media.rtp.RTCPReport.readSourceDescription(RTCPReport.java:123)
      [java] at
net.sf.fmj.media.rtp.RTCPSenderReport.<init>(RTCPSenderReport.java:74)
      [java] at
net.java.sip.communicator.impl.neomedia.transform.rtcp.StatisticsEngine.tr
ansform(StatisticsEngine.java:98)
      [java] at
net.java.sip.communicator.impl.neomedia.transform.TransformEngineChain$Pac
ketTransformerChain.transform(TransformEngineChain.java:131)
      [java] at
net.java.sip.communicator.impl.neomedia.transform.TransformUDPOutputStream
.createRawPacket(TransformUDPOutputStream.java:67)
      [java] at
net.java.sip.communicator.impl.neomedia.RTPConnectorOutputStream.write(RTP
ConnectorOutputStream.java:294)
      [java] at
com.sun.media.rtp.util.RTPPacketSender.sendTo(RTPPacketSender.java:36)
      [java] at
com.sun.media.rtp.util.PacketFilter.sendTo(PacketFilter.java:72)
      [java] at
com.sun.media.rtp.RTCPTransmitter.transmit(RTCPTransmitter.java:86)
      [java] at
com.sun.media.rtp.RTCPTransmitter.report(RTCPTransmitter.java:110)
      [java] at
com.sun.media.rtp.RTCPReporter.run(RTCPReporter.java:193)
      [java] at java.lang.Thread.run(Thread.java:680)
      [java] java.io.IOException: Invalid RTCP Version
      [java] at
net.sf.fmj.media.rtp.RTCPHeader.<init>(RTCPHeader.java:149)
      [java] at
net.sf.fmj.media.rtp.RTCPReport.readSourceDescription(RTCPReport.java:123)
      [java] at
net.sf.fmj.media.rtp.RTCPSenderReport.<init>(RTCPSenderReport.java:74)
      [java] at
net.java.sip.communicator.impl.neomedia.transform.rtcp.StatisticsEngine.tr
ansform(StatisticsEngine.java:98)
      [java] at
net.java.sip.communicator.impl.neomedia.transform.TransformEngineChain$Pac
ketTransformerChain.transform(TransformEngineChain.java:131)
      [java] at
net.java.sip.communicator.impl.neomedia.transform.TransformUDPOutputStream
.createRawPacket(TransformUDPOutputStream.java:67)
      [java] at
net.java.sip.communicator.impl.neomedia.RTPConnectorOutputStream.write(RTP
ConnectorOutputStream.java:294)
      [java] at
com.sun.media.rtp.util.RTPPacketSender.sendTo(RTPPacketSender.java:36)
      [java] at
com.sun.media.rtp.util.PacketFilter.sendTo(PacketFilter.java:72)
      [java] at
com.sun.media.rtp.RTCPTransmitter.transmit(RTCPTransmitter.java:86)
      [java] at
com.sun.media.rtp.RTCPTransmitter.bye(RTCPTransmitter.java:187)
      [java] at
com.sun.media.rtp.RTCPTransmitter.bye(RTCPTransmitter.java:119)
      [java] at
com.sun.media.rtp.RTCPReporter.releasessrc(RTCPReporter.java:137)
      [java] at
com.sun.media.rtp.RTCPReporter.close(RTCPReporter.java:132)
      [java] at
com.sun.media.rtp.RTPSessionMgr.stopParticipating(RTPSessionMgr.java:2471)
      [java] at
com.sun.media.rtp.RTPSessionMgr.removeSendStream(RTPSessionMgr.java:1614)
      [java] at
com.sun.media.rtp.SendSSRCInfo.close(SendSSRCInfo.java:254)
      [java] at
net.java.sip.communicator.impl.neomedia.MediaStreamImpl.stopSendStreams(Me
diaStreamImpl.java:1972)
      [java] at
net.java.sip.communicator.impl.neomedia.MediaStreamImpl.stopSendStreams(Me
diaStreamImpl.java:1934)
      [java] at
net.java.sip.communicator.impl.neomedia.MediaStreamImpl.closeSendStreams(M
ediaStreamImpl.java:565)
      [java] at
net.java.sip.communicator.impl.neomedia.MediaStreamImpl.close(MediaStreamI
mpl.java:503)
      [java] at
net.java.sip.communicator.impl.neomedia.AudioMediaStreamImpl.close(AudioMe
diaStreamImpl.java:419)
      [java] at
net.java.sip.communicator.service.protocol.media.CallPeerMediaHandler.setA
udioStream(CallPeerMediaHandler.java:789)
      [java] at
net.java.sip.communicator.service.protocol.media.CallPeerMediaHandler.clos
eStream(CallPeerMediaHandler.java:418)
      [java] at
net.java.sip.communicator.service.protocol.media.CallPeerMediaHandler.clos
e(CallPeerMediaHandler.java:403)
      [java] at
net.java.sip.communicator.service.protocol.media.MediaAwareCallPeer.setSta
te(MediaAwareCallPeer.java:485)
      [java] at
net.java.sip.communicator.service.protocol.AbstractCallPeer.setState(Abstr
actCallPeer.java:435)
      [java] at
net.java.sip.communicator.service.protocol.AbstractCallPeer.setState(Abstr
actCallPeer.java:479)
      [java] at
net.java.sip.communicator.impl.protocol.jabber.CallPeerJabberImpl.hangup(C
allPeerJabberImpl.java:384)
      [java] at
net.java.sip.communicator.impl.protocol.jabber.OperationSetBasicTelephonyJ
abberImpl.hangupCallPeer(OperationSetBasicTelephonyJabberImpl.java:550)
      [java] at
net.java.sip.communicator.impl.gui.main.call.CallManager$HangupCallThread.
run(CallManager.java:1458)

Regards,
--
Seb

Le 16/10/11 09:31, wernerd@java.net a écrit :
> Index:
trunk/src/net/java/sip/communicator/impl/neomedia/transform/zrtp/ZRTPTrans
formEngine.java
> ===================================================================
> ---
trunk/src/net/java/sip/communicator/impl/neomedia/transform/zrtp/ZRTPTrans
formEngine.java (revision 9014)
> +++
trunk/src/net/java/sip/communicator/impl/neomedia/transform/zrtp/ZRTPTrans
formEngine.java (revision 9015)
> @@ -356,6 +356,10 @@
> */
> private boolean muted = false;
>
> + private boolean mitmMode = false;
> +
> + private ZRTCPTransformer zrtcpTransformer = null;
> +
> /**
> * Construct a ZRTPTransformEngine.
> *
> @@ -372,7 +376,7 @@
> */
> public PacketTransformer getRTCPTransformer()
> {
> - return new ZRTPCTransformer(this);
> + return new ZRTCPTransformer(this);
> }
>
> /**
> @@ -503,7 +507,7 @@
> config.setStandardConfig();
> }
>
> - zrtpEngine = new ZRtp(zf.getZid(), this, clientIdString,
config);
> + zrtpEngine = new ZRtp(zf.getZid(), this, clientIdString,
config, mitmMode);
>
> if (timeoutProvider == null)
> {
> @@ -796,6 +800,7 @@
> srtpPolicy, srtpPolicy);
>
> srtpOutTransformer = engine.getRTPTransformer();
> +
zrtcpTransformer.setSrtcpOut(engine.getRTCPTransformer());
> }
> else
> {
> @@ -810,6 +815,7 @@
> .getKeyResponder(),
secrets.getSaltResponder(),
> srtpPolicy, srtpPolicy);
> srtpOutTransformer = engine.getRTPTransformer();
> +
zrtcpTransformer.setSrtcpOut(engine.getRTCPTransformer());
> }
> }
>
> @@ -831,6 +837,7 @@
> .getKeyResponder(),
secrets.getSaltResponder(),
> srtpPolicy, srtpPolicy);
> srtpInTransformer = engine.getRTPTransformer();
> +
zrtcpTransformer.setSrtcpIn(engine.getRTCPTransformer());
> this.muted = false;
> }
> else
> @@ -846,6 +853,7 @@
> .getKeyInitiator(),
secrets.getSaltInitiator(),
> srtpPolicy, srtpPolicy);
> srtpInTransformer = engine.getRTPTransformer();
> +
zrtcpTransformer.setSrtcpIn(engine.getRTCPTransformer());
> this.muted = false;
> }
> }
> @@ -979,7 +987,7 @@
> * Zrtp ask for Enrollment.
> * @param info supplied info.
> */
> - public void zrtpAskEnrollment(String info)
> + public void zrtpAskEnrollment(ZrtpCodes.InfoEnrollment info)
> {
> if (securityEventManager != null)
> {
> @@ -992,7 +1000,7 @@
> * @param info
> * @see
gnu.java.zrtp.ZrtpCallback#zrtpInformEnrollment(java.lang.String)
> */
> - public void zrtpInformEnrollment(String info)
> + public void zrtpInformEnrollment(ZrtpCodes.InfoEnrollment info)
> {
> if (securityEventManager != null)
> {
> @@ -1096,18 +1104,7 @@
> zrtpEngine.setAuxSecret(data);
> }
>
> -
> /**
> - * Sets the PBX secret data
> - *
> - * @param data The PBX secret data
> - */
> - public void setPbxSecret(byte[] data) {
> - if (zrtpEngine != null)
> - zrtpEngine.setPbxSecret(data);
> - }
> -
> - /**
> * Sets the client ID
> *
> * @param id The client ID
> @@ -1192,6 +1189,101 @@
> }
>
> /**
> + * Get the commited SAS rendering algorithm for this ZRTP session.
> + *
> + * @return the commited SAS rendering algorithm
> + */
> + public ZrtpConstants.SupportedSASTypes getSasType() {
> + if (zrtpEngine != null)
> + return zrtpEngine.getSasType();
> + else
> + return null;
> + }
> +
> + /**
> + * Get the computed SAS hash for this ZRTP session.
> + *
> + * @return a refernce to the byte array that contains the full
> + * SAS hash.
> + */
> + public byte[] getSasHash() {
> + if (zrtpEngine != null)
> + return zrtpEngine.getSasHash();
> + else
> + return null;
> + }
> +
> + /**
> + * Send the SAS relay packet.
> + *
> + * The method creates and sends a SAS relay packet according to the
ZRTP
> + * specifications. Usually only a MitM capable user agent (PBX)
uses this
> + * function.
> + *
> + * @param sh the full SAS hash value
> + * @param render the SAS rendering algorithm
> + */
> + public boolean sendSASRelayPacket(byte[] sh,
ZrtpConstants.SupportedSASTypes render) {
> + if (zrtpEngine != null)
> + return zrtpEngine.sendSASRelayPacket(sh, render);
> + else
> + return false;
> + }
> + /**
> + * Check the state of the MitM mode flag.
> + *
> + * If true then this ZRTP session acts as MitM, usually enabled by
a PBX
> + * based client (user agent)
> + *
> + * @return state of mitmMode
> + */
> + public boolean isMitmMode() {
> + return mitmMode;
> + }
> +
> + /**
> + * Set the state of the MitM mode flag.
> + *
> + * If MitM mode is set to true this ZRTP session acts as MitM,
usually
> + * enabled by a PBX based client (user agent).
> + *
> + * @param mitmMode defines the new state of the mitmMode flag
> + */
> + public void setMitmMode(boolean mitmMode) {
> + this.mitmMode = mitmMode;
> + }
> +
> + /**
> + * Check the state of the enrollment mode.
> + *
> + * If true then we will set the enrollment flag (E) in the confirm
> + * packets and performs the enrollment actions. A MitM (PBX)
enrollment service sets this flagstarted this ZRTP
> + * session. Can be set to true only if mitmMode is also true.
> + * @return status of the enrollmentMode flag.
> + */
> + public boolean isEnrollmentMode() {
> + if (zrtpEngine != null)
> + return zrtpEngine.isEnrollmentMode();
> + else
> + return false;
> + }
> +
> + /**
> + * Set the state of the enrollment mode.
> + *
> + * If true then we will set the enrollment flag (E) in the confirm
> + * packets and perform the enrollment actions. A MitM (PBX)
enrollment
> + * service must sets this mode to true.
> + *
> + * Can be set to true only if mitmMode is also true.
> + *
> + * @param enrollmentMode defines the new state of the
enrollmentMode flag
> + */
> + public void setEnrollmentMode(boolean enrollmentMode) {
> + if (zrtpEngine != null)
> + zrtpEngine.setEnrollmentMode(enrollmentMode);
> + }
> + /**
> * Sets signature data for the Confirm packets
> *
> * @param data the signature data
> @@ -1226,16 +1318,6 @@
> return ((zrtpEngine != null) ? zrtpEngine.getSignatureLength()
: 0);
> }
>
> - /**
> - * Sets the PBX enrollment flag (see chapter 8.3 of ZRTP standards)
> - * (The PBX part needs further development)
> - * @param yesNo The PBX enrollment flag
> - */
> - public void setPBXEnrollment(boolean yesNo)
> - {
> - if (zrtpEngine != null)
> - zrtpEngine.setPBXEnrollment(yesNo);
> - }
>
> /**
> * Method called by the Zrtp class as result of a GoClear request
from the
> @@ -1302,8 +1384,8 @@
> *
> * @return the ZID data as byte array.
> */
> - public byte[] getZid()
> + public byte[] getPeerZid()
> {
> - return ((zrtpEngine != null) ? zrtpEngine.getZid() : null);
> + return ((zrtpEngine != null) ? zrtpEngine.getPeerZid() :
null);
> }
> }


#3

Hi Ingo,

···

Le 17/10/11 11:41, Bauersachs Ingo a écrit :

I don't know about the ZRTCPTransformer stuff. The other exceptions are because the SRTP/SRTCP encryption is done _before_ the StatisticsEngine kicks in. If the SRTCP is now encrypted, the Statics obviously can't deal with the packets anymore :slight_smile:

OK thanks for explanation.

With your last commit (revision 9018), everything works fine. Thank you.

Regards,
--
Seb

-> I move the encryption down after the StatisticsEngine. Wait a few more minutes...

Ingo

-----Original Message-----
From: Sebastien Vincent [mailto:seb@jitsi.org]
Sent: Montag, 17. Oktober 2011 11:15
To: dev@jitsi.java.net
Subject: [jitsi-dev] Re: [jitsi~svn:9015] New ZRTP library that supports
trusted MitM/PBX feature and implement SRT

Hi Werner,

I have discovered a small problem in your code.

The variable zrtcpTransformer is initialized as null, never get another
value and is used in the code which throw a NullPointerException after a
call is established. And it causes that after 1 or 2 seconds, nobody can
hear something.

Does zrtcpTransformer needs to be initialized in getRTCPTransformer()
like this:
      public PacketTransformer getRTCPTransformer()
      {
          if(zrtcpTransformer == null)
              zrtcpTransformer = new ZRTCPTransformer(this);

          return zrtcpTransformer;
      }

or should it be in another methods (in srtpSecretsReady if the variable
is null, ...) ?

The first should fix the issue (everybody hear each others) but I got
these exceptions from the console (the last comes when we close the call).

       [java] java.io.IOException: Invalid RTCP Version
       [java] at
net.sf.fmj.media.rtp.RTCPHeader.<init>(RTCPHeader.java:149)
       [java] at
net.sf.fmj.media.rtp.RTCPReport.readSourceDescription(RTCPReport.java:123)
       [java] at
net.sf.fmj.media.rtp.RTCPSenderReport.<init>(RTCPSenderReport.java:74)
       [java] at
net.java.sip.communicator.impl.neomedia.transform.rtcp.StatisticsEngine.tr
ansform(StatisticsEngine.java:98)
       [java] at
net.java.sip.communicator.impl.neomedia.transform.TransformEngineChain$Pac
ketTransformerChain.transform(TransformEngineChain.java:131)
       [java] at
net.java.sip.communicator.impl.neomedia.transform.TransformUDPOutputStream
.createRawPacket(TransformUDPOutputStream.java:67)
       [java] at
net.java.sip.communicator.impl.neomedia.RTPConnectorOutputStream.write(RTP
ConnectorOutputStream.java:294)
       [java] at
com.sun.media.rtp.util.RTPPacketSender.sendTo(RTPPacketSender.java:36)
       [java] at
com.sun.media.rtp.util.PacketFilter.sendTo(PacketFilter.java:72)
       [java] at
com.sun.media.rtp.RTCPTransmitter.transmit(RTCPTransmitter.java:86)
       [java] at
com.sun.media.rtp.RTCPTransmitter.report(RTCPTransmitter.java:110)
       [java] at
com.sun.media.rtp.RTCPReporter.run(RTCPReporter.java:193)
       [java] at java.lang.Thread.run(Thread.java:680)
       [java] java.io.IOException: Invalid RTCP Version
       [java] at
net.sf.fmj.media.rtp.RTCPHeader.<init>(RTCPHeader.java:149)
       [java] at
net.sf.fmj.media.rtp.RTCPReport.readSourceDescription(RTCPReport.java:123)
       [java] at
net.sf.fmj.media.rtp.RTCPSenderReport.<init>(RTCPSenderReport.java:74)
       [java] at
net.java.sip.communicator.impl.neomedia.transform.rtcp.StatisticsEngine.tr
ansform(StatisticsEngine.java:98)
       [java] at
net.java.sip.communicator.impl.neomedia.transform.TransformEngineChain$Pac
ketTransformerChain.transform(TransformEngineChain.java:131)
       [java] at
net.java.sip.communicator.impl.neomedia.transform.TransformUDPOutputStream
.createRawPacket(TransformUDPOutputStream.java:67)
       [java] at
net.java.sip.communicator.impl.neomedia.RTPConnectorOutputStream.write(RTP
ConnectorOutputStream.java:294)
       [java] at
com.sun.media.rtp.util.RTPPacketSender.sendTo(RTPPacketSender.java:36)
       [java] at
com.sun.media.rtp.util.PacketFilter.sendTo(PacketFilter.java:72)
       [java] at
com.sun.media.rtp.RTCPTransmitter.transmit(RTCPTransmitter.java:86)
       [java] at
com.sun.media.rtp.RTCPTransmitter.report(RTCPTransmitter.java:110)
       [java] at
com.sun.media.rtp.RTCPReporter.run(RTCPReporter.java:193)
       [java] at java.lang.Thread.run(Thread.java:680)
       [java] java.io.IOException: Invalid RTCP Version
       [java] at
net.sf.fmj.media.rtp.RTCPHeader.<init>(RTCPHeader.java:149)
       [java] at
net.sf.fmj.media.rtp.RTCPReport.readSourceDescription(RTCPReport.java:123)
       [java] at
net.sf.fmj.media.rtp.RTCPSenderReport.<init>(RTCPSenderReport.java:74)
       [java] at
net.java.sip.communicator.impl.neomedia.transform.rtcp.StatisticsEngine.tr
ansform(StatisticsEngine.java:98)
       [java] at
net.java.sip.communicator.impl.neomedia.transform.TransformEngineChain$Pac
ketTransformerChain.transform(TransformEngineChain.java:131)
       [java] at
net.java.sip.communicator.impl.neomedia.transform.TransformUDPOutputStream
.createRawPacket(TransformUDPOutputStream.java:67)
       [java] at
net.java.sip.communicator.impl.neomedia.RTPConnectorOutputStream.write(RTP
ConnectorOutputStream.java:294)
       [java] at
com.sun.media.rtp.util.RTPPacketSender.sendTo(RTPPacketSender.java:36)
       [java] at
com.sun.media.rtp.util.PacketFilter.sendTo(PacketFilter.java:72)
       [java] at
com.sun.media.rtp.RTCPTransmitter.transmit(RTCPTransmitter.java:86)
       [java] at
com.sun.media.rtp.RTCPTransmitter.bye(RTCPTransmitter.java:187)
       [java] at
com.sun.media.rtp.RTCPTransmitter.bye(RTCPTransmitter.java:119)
       [java] at
com.sun.media.rtp.RTCPReporter.releasessrc(RTCPReporter.java:137)
       [java] at
com.sun.media.rtp.RTCPReporter.close(RTCPReporter.java:132)
       [java] at
com.sun.media.rtp.RTPSessionMgr.stopParticipating(RTPSessionMgr.java:2471)
       [java] at
com.sun.media.rtp.RTPSessionMgr.removeSendStream(RTPSessionMgr.java:1614)
       [java] at
com.sun.media.rtp.SendSSRCInfo.close(SendSSRCInfo.java:254)
       [java] at
net.java.sip.communicator.impl.neomedia.MediaStreamImpl.stopSendStreams(Me
diaStreamImpl.java:1972)
       [java] at
net.java.sip.communicator.impl.neomedia.MediaStreamImpl.stopSendStreams(Me
diaStreamImpl.java:1934)
       [java] at
net.java.sip.communicator.impl.neomedia.MediaStreamImpl.closeSendStreams(M
ediaStreamImpl.java:565)
       [java] at
net.java.sip.communicator.impl.neomedia.MediaStreamImpl.close(MediaStreamI
mpl.java:503)
       [java] at
net.java.sip.communicator.impl.neomedia.AudioMediaStreamImpl.close(AudioMe
diaStreamImpl.java:419)
       [java] at
net.java.sip.communicator.service.protocol.media.CallPeerMediaHandler.setA
udioStream(CallPeerMediaHandler.java:789)
       [java] at
net.java.sip.communicator.service.protocol.media.CallPeerMediaHandler.clos
eStream(CallPeerMediaHandler.java:418)
       [java] at
net.java.sip.communicator.service.protocol.media.CallPeerMediaHandler.clos
e(CallPeerMediaHandler.java:403)
       [java] at
net.java.sip.communicator.service.protocol.media.MediaAwareCallPeer.setSta
te(MediaAwareCallPeer.java:485)
       [java] at
net.java.sip.communicator.service.protocol.AbstractCallPeer.setState(Abstr
actCallPeer.java:435)
       [java] at
net.java.sip.communicator.service.protocol.AbstractCallPeer.setState(Abstr
actCallPeer.java:479)
       [java] at
net.java.sip.communicator.impl.protocol.jabber.CallPeerJabberImpl.hangup(C
allPeerJabberImpl.java:384)
       [java] at
net.java.sip.communicator.impl.protocol.jabber.OperationSetBasicTelephonyJ
abberImpl.hangupCallPeer(OperationSetBasicTelephonyJabberImpl.java:550)
       [java] at
net.java.sip.communicator.impl.gui.main.call.CallManager$HangupCallThread.
run(CallManager.java:1458)

Regards,
--
Seb

Le 16/10/11 09:31, wernerd@java.net a écrit :

Index:

trunk/src/net/java/sip/communicator/impl/neomedia/transform/zrtp/ZRTPTrans
formEngine.java

===================================================================
---

trunk/src/net/java/sip/communicator/impl/neomedia/transform/zrtp/ZRTPTrans
formEngine.java (revision 9014)

+++

trunk/src/net/java/sip/communicator/impl/neomedia/transform/zrtp/ZRTPTrans
formEngine.java (revision 9015)

@@ -356,6 +356,10 @@
        */
       private boolean muted = false;

+ private boolean mitmMode = false;
+
+ private ZRTCPTransformer zrtcpTransformer = null;
+
       /**
        * Construct a ZRTPTransformEngine.
        *
@@ -372,7 +376,7 @@
        */
       public PacketTransformer getRTCPTransformer()
       {
- return new ZRTPCTransformer(this);
+ return new ZRTCPTransformer(this);
       }

       /**
@@ -503,7 +507,7 @@
               config.setStandardConfig();
           }

- zrtpEngine = new ZRtp(zf.getZid(), this, clientIdString,

config);

+ zrtpEngine = new ZRtp(zf.getZid(), this, clientIdString,

config, mitmMode);

           if (timeoutProvider == null)
           {
@@ -796,6 +800,7 @@
                           srtpPolicy, srtpPolicy);

                   srtpOutTransformer = engine.getRTPTransformer();
+

zrtcpTransformer.setSrtcpOut(engine.getRTCPTransformer());

               }
               else
               {
@@ -810,6 +815,7 @@
                           .getKeyResponder(),

secrets.getSaltResponder(),

                           srtpPolicy, srtpPolicy);
                   srtpOutTransformer = engine.getRTPTransformer();
+

zrtcpTransformer.setSrtcpOut(engine.getRTCPTransformer());

               }
           }

@@ -831,6 +837,7 @@
                           .getKeyResponder(),

secrets.getSaltResponder(),

                           srtpPolicy, srtpPolicy);
                   srtpInTransformer = engine.getRTPTransformer();
+

zrtcpTransformer.setSrtcpIn(engine.getRTCPTransformer());

                   this.muted = false;
               }
               else
@@ -846,6 +853,7 @@
                           .getKeyInitiator(),

secrets.getSaltInitiator(),

                           srtpPolicy, srtpPolicy);
                   srtpInTransformer = engine.getRTPTransformer();
+

zrtcpTransformer.setSrtcpIn(engine.getRTCPTransformer());

                   this.muted = false;
               }
           }
@@ -979,7 +987,7 @@
        * Zrtp ask for Enrollment.
        * @param info supplied info.
        */
- public void zrtpAskEnrollment(String info)
+ public void zrtpAskEnrollment(ZrtpCodes.InfoEnrollment info)
       {
           if (securityEventManager != null)
           {
@@ -992,7 +1000,7 @@
        * @param info
        * @see

gnu.java.zrtp.ZrtpCallback#zrtpInformEnrollment(java.lang.String)

        */
- public void zrtpInformEnrollment(String info)
+ public void zrtpInformEnrollment(ZrtpCodes.InfoEnrollment info)
       {
           if (securityEventManager != null)
           {
@@ -1096,18 +1104,7 @@
               zrtpEngine.setAuxSecret(data);
       }

-
       /**
- * Sets the PBX secret data
- *
- * @param data The PBX secret data
- */
- public void setPbxSecret(byte[] data) {
- if (zrtpEngine != null)
- zrtpEngine.setPbxSecret(data);
- }
-
- /**
        * Sets the client ID
        *
        * @param id The client ID
@@ -1192,6 +1189,101 @@
       }

       /**
+ * Get the commited SAS rendering algorithm for this ZRTP session.
+ *
+ * @return the commited SAS rendering algorithm
+ */
+ public ZrtpConstants.SupportedSASTypes getSasType() {
+ if (zrtpEngine != null)
+ return zrtpEngine.getSasType();
+ else
+ return null;
+ }
+
+ /**
+ * Get the computed SAS hash for this ZRTP session.
+ *
+ * @return a refernce to the byte array that contains the full
+ * SAS hash.
+ */
+ public byte[] getSasHash() {
+ if (zrtpEngine != null)
+ return zrtpEngine.getSasHash();
+ else
+ return null;
+ }
+
+ /**
+ * Send the SAS relay packet.
+ *
+ * The method creates and sends a SAS relay packet according to the

ZRTP

+ * specifications. Usually only a MitM capable user agent (PBX)

uses this

+ * function.
+ *
+ * @param sh the full SAS hash value
+ * @param render the SAS rendering algorithm
+ */
+ public boolean sendSASRelayPacket(byte[] sh,

ZrtpConstants.SupportedSASTypes render) {

+ if (zrtpEngine != null)
+ return zrtpEngine.sendSASRelayPacket(sh, render);
+ else
+ return false;
+ }
+ /**
+ * Check the state of the MitM mode flag.
+ *
+ * If true then this ZRTP session acts as MitM, usually enabled by

a PBX

+ * based client (user agent)
+ *
+ * @return state of mitmMode
+ */
+ public boolean isMitmMode() {
+ return mitmMode;
+ }
+
+ /**
+ * Set the state of the MitM mode flag.
+ *
+ * If MitM mode is set to true this ZRTP session acts as MitM,

usually

+ * enabled by a PBX based client (user agent).
+ *
+ * @param mitmMode defines the new state of the mitmMode flag
+ */
+ public void setMitmMode(boolean mitmMode) {
+ this.mitmMode = mitmMode;
+ }
+
+ /**
+ * Check the state of the enrollment mode.
+ *
+ * If true then we will set the enrollment flag (E) in the confirm
+ * packets and performs the enrollment actions. A MitM (PBX)

enrollment service sets this flagstarted this ZRTP

+ * session. Can be set to true only if mitmMode is also true.
+ * @return status of the enrollmentMode flag.
+ */
+ public boolean isEnrollmentMode() {
+ if (zrtpEngine != null)
+ return zrtpEngine.isEnrollmentMode();
+ else
+ return false;
+ }
+
+ /**
+ * Set the state of the enrollment mode.
+ *
+ * If true then we will set the enrollment flag (E) in the confirm
+ * packets and perform the enrollment actions. A MitM (PBX)

enrollment

+ * service must sets this mode to true.
+ *
+ * Can be set to true only if mitmMode is also true.
+ *
+ * @param enrollmentMode defines the new state of the

enrollmentMode flag

+ */
+ public void setEnrollmentMode(boolean enrollmentMode) {
+ if (zrtpEngine != null)
+ zrtpEngine.setEnrollmentMode(enrollmentMode);
+ }
+ /**
        * Sets signature data for the Confirm packets
        *
        * @param data the signature data
@@ -1226,16 +1318,6 @@
           return ((zrtpEngine != null) ? zrtpEngine.getSignatureLength()

: 0);

       }

- /**
- * Sets the PBX enrollment flag (see chapter 8.3 of ZRTP standards)
- * (The PBX part needs further development)
- * @param yesNo The PBX enrollment flag
- */
- public void setPBXEnrollment(boolean yesNo)
- {
- if (zrtpEngine != null)
- zrtpEngine.setPBXEnrollment(yesNo);
- }

       /**
        * Method called by the Zrtp class as result of a GoClear request

from the

@@ -1302,8 +1384,8 @@
        *
        * @return the ZID data as byte array.
        */
- public byte[] getZid()
+ public byte[] getPeerZid()
       {
- return ((zrtpEngine != null) ? zrtpEngine.getZid() : null);
+ return ((zrtpEngine != null) ? zrtpEngine.getPeerZid() :

null);

       }
   }