r2694 - in trunk: libminisip/include/libminisip/mediahandler libminisip/include/libminisip/zrtp libminisip/source libminisip/source/mediahandler libminisip/source/zrtp minisip/minisip/gui/gtkgui

werner at minisip.org werner at minisip.org
Sun Jul 9 15:18:37 CEST 2006


Author: werner
Date: 2006-07-09 15:18:35 +0200 (Sun, 09 Jul 2006)
New Revision: 2694

Modified:
   trunk/libminisip/include/libminisip/mediahandler/MediaHandler.h
   trunk/libminisip/include/libminisip/zrtp/Base32.h
   trunk/libminisip/include/libminisip/zrtp/ZIDFile.h
   trunk/libminisip/include/libminisip/zrtp/ZRtp.h
   trunk/libminisip/include/libminisip/zrtp/ZrtpCallback.h
   trunk/libminisip/include/libminisip/zrtp/ZrtpHostBridgeMinisip.h
   trunk/libminisip/include/libminisip/zrtp/ZrtpPacketBase.h
   trunk/libminisip/include/libminisip/zrtp/ZrtpPacketCommit.h
   trunk/libminisip/include/libminisip/zrtp/ZrtpPacketConf2Ack.h
   trunk/libminisip/include/libminisip/zrtp/ZrtpPacketConfirm.h
   trunk/libminisip/include/libminisip/zrtp/ZrtpPacketDHPart.h
   trunk/libminisip/include/libminisip/zrtp/ZrtpPacketError.h
   trunk/libminisip/include/libminisip/zrtp/ZrtpPacketHello.h
   trunk/libminisip/include/libminisip/zrtp/ZrtpPacketHelloAck.h
   trunk/libminisip/include/libminisip/zrtp/ZrtpStateClass.h
   trunk/libminisip/include/libminisip/zrtp/ZrtpStates.h
   trunk/libminisip/include/libminisip/zrtp/ZrtpTextData.h
   trunk/libminisip/source/Minisip.cxx
   trunk/libminisip/source/mediahandler/MediaHandler.cxx
   trunk/libminisip/source/mediahandler/RtpReceiver.cxx
   trunk/libminisip/source/mediahandler/Session.cxx
   trunk/libminisip/source/zrtp/Base32.cxx
   trunk/libminisip/source/zrtp/ZIDFile.cxx
   trunk/libminisip/source/zrtp/ZIDRecord.cxx
   trunk/libminisip/source/zrtp/ZRtp.cxx
   trunk/libminisip/source/zrtp/ZrtpHostBridgeMinisip.cxx
   trunk/libminisip/source/zrtp/ZrtpPacketCommit.cxx
   trunk/libminisip/source/zrtp/ZrtpPacketConf2Ack.cxx
   trunk/libminisip/source/zrtp/ZrtpPacketConfirm.cxx
   trunk/libminisip/source/zrtp/ZrtpPacketDHPart.cxx
   trunk/libminisip/source/zrtp/ZrtpPacketError.cxx
   trunk/libminisip/source/zrtp/ZrtpPacketHello.cxx
   trunk/libminisip/source/zrtp/ZrtpPacketHelloAck.cxx
   trunk/libminisip/source/zrtp/ZrtpStateClass.cxx
   trunk/libminisip/source/zrtp/ZrtpTextData.cxx
   trunk/minisip/minisip/gui/gtkgui/CallWidget.cxx
Log:
ZRTP for minisip - first complete checkin with GTK GUI integration (partly)

Modified: trunk/libminisip/include/libminisip/mediahandler/MediaHandler.h
===================================================================
--- trunk/libminisip/include/libminisip/mediahandler/MediaHandler.h	2006-07-09 10:50:02 UTC (rev 2693)
+++ trunk/libminisip/include/libminisip/mediahandler/MediaHandler.h	2006-07-09 13:18:35 UTC (rev 2694)
@@ -86,7 +86,29 @@
 		 */
 		std::string getExtIP();
 		
-		
+                /**
+                 * Set the callback (interface) to Minisip's message router.
+                 * 
+                 * The Media handler uses this callback to send message to other subsystems
+                 * of Minisip. 
+                 * 
+                 * @param callback
+                 *     The pointer to the message router object.
+                 */
+                void setMessageRouterCallback(MRef<CommandReceiver*> callback) {
+                    messageRouterCallback = callback; }        
+                            
+                /**
+                 * Get the callback (interface) to Minisip's message router.
+                 * 
+                 * The Media handler uses this callback to send message to other subsystems
+                 * of Minisip. 
+                 * 
+                 * @returns
+                 *     The pointer to the message router object.
+                 */
+                MRef<CommandReceiver *> getMessageRouterCallback() { return messageRouterCallback;}
+
 		virtual std::string getMemObjectType(){return "MediaHandler";}
 
 #ifdef DEBUG_OUTPUT	
@@ -112,6 +134,8 @@
 		MRef<AudioMedia *> audioMedia;
 		MRef<IpProvider *> ipProvider;
 		MRef<SipSoftPhoneConfiguration *> config;
+                
+                MRef<CommandReceiver*> messageRouterCallback;
 		
 		/**
 		Looks for a Session with callid. If found, set the audio settings

Modified: trunk/libminisip/include/libminisip/zrtp/Base32.h
===================================================================
--- trunk/libminisip/include/libminisip/zrtp/Base32.h	2006-07-09 10:50:02 UTC (rev 2693)
+++ trunk/libminisip/include/libminisip/zrtp/Base32.h	2006-07-09 13:18:35 UTC (rev 2694)
@@ -21,7 +21,7 @@
  * FROM, OUT OF OR IN CONNECTION WITH THIS SOFTWARE OR THE USE OR OTHER
  * DEALINGS IN THIS SOFTWARE.
  *
- * Edited into C++ by:
+ * Convert to C++ by:
  *
  *	@author Werner Dittmann <Werner.Dittmann at t-online.de>
  */
@@ -42,7 +42,7 @@
  public:
     
     /**
-     * Constructor accepts a string that contains base32 encoded data.
+     * A Constructor that decodes from base32 into binary.
      * 
      * The constructor decodes the base32 encoded data back into binary
      * data. Use <code>getBinaryData(...)</code> to get the binary data.
@@ -53,11 +53,12 @@
     Base32(const string encoded);
     
     /**
-     * Constructor using an encoded string and number of bits to decode.
+     * A Constructor that decodes from base32 into binary.
      * 
-     * he constructor decodes the base32 encoded data back into binary
-     * data. Only noOfBits bits a decoded (should be a multiple of 5).
-     * Use <code>getBinaryData(...)</code> to get the binary data.
+     * This constructor decodes the base32 encoded data back into
+     * binary data. Only the specified number of bits are decoded
+     * (should be a multiple of 5).  Use
+     * <code>getBinaryData(...)</code> to get the binary data.
      * 
      * @param encoded
      *     The string that contains the base32 encoded data.
@@ -67,15 +68,17 @@
     Base32(const string encoded, int32_t noOfBits); 
     
     /**
-     * Constructor accepts a pointer to binary data and a number of bits.
+     * A Constructor that encodes binary data.
      * 
-     * The constructor converts the first number of bits into a base32
-     * presentation. Use <code>getEncoded</code> to get the encoded data. 
+     * The constructor converts the firstspecified number of bits of
+     * the binary data into a base32 presentation. Use
+     * <code>getEncoded</code> to get the encoded data.
      * 
      * @param data
-     *     A pointer to the first bits (byte) of binary data
+     *    A pointer to the first bits (byte) of binary data
      * @param noOfBits
-     *     How many bits to use for encoding. Should be a multiple of 5.
+     *    How many bits to use for encoding. Should be a
+     *    multiple of 5.
      */
     Base32(const uint8_t* data, int32_t noOfBits);
 
@@ -85,9 +88,17 @@
      * Get the decoded binary data and its length.
      * 
      * The method returns the decoded binary data if the appropriate
-     * Constructor was uses. Otherwise we return <code>NULL</code> pointer
-     * and length zero.
+     * Constructor was used. Otherwise we return <code>NULL</code>
+     * pointer and length zero.
+     *
+     * <p/>
      * 
+     * <em>Note:</em> This method returns a pointer to the decoded
+     * binary data. The Base32 object manages this pointer, thus you
+     * may need to copy the data to a save place before deleting this
+     * object. If the object is deleted this pointer is no longer
+     * valid.
+     *
      * @param length
      *     A reference to an integer.
      * @return
@@ -99,8 +110,8 @@
      * Get the encoded base32 string.
      * 
      * The method returns a string that contains the base32 encoded
-     * data if the appropriate constructor was used. Otherwise we return
-     * an empty string.
+     * data if the appropriate constructor was used. Otherwise we
+     * return an empty string.
      * 
      * @return
      *     The string containing the base32 encoded data.
@@ -108,7 +119,8 @@
     const string getEncoded() { return encoded; };
     
     /**
-     * Compute the number of base32 encoded characters given the number of bits.
+     * Compute the number of base32 encoded characters given the
+     * number of bits.
      * 
      * @param lengthInBits 
      *      The length of the data in bits

Modified: trunk/libminisip/include/libminisip/zrtp/ZIDFile.h
===================================================================
--- trunk/libminisip/include/libminisip/zrtp/ZIDFile.h	2006-07-09 10:50:02 UTC (rev 2693)
+++ trunk/libminisip/include/libminisip/zrtp/ZIDFile.h	2006-07-09 13:18:35 UTC (rev 2694)
@@ -42,7 +42,7 @@
 
 private:
 
-    FILE *zidFile;
+    FILE* zidFile;
     uint8_t associatedZid[IDENTIFIER_LEN];
     /**
      * The private ZID file constructor.
@@ -63,7 +63,7 @@
      * @return
      *    A pointer to the global ZIDFile singleton instance.
      */
-    static ZIDFile *getInstance();
+    static ZIDFile* getInstance();
     /**
      * Open the named ZID file and return a ZID file class.
      *

Modified: trunk/libminisip/include/libminisip/zrtp/ZRtp.h
===================================================================
--- trunk/libminisip/include/libminisip/zrtp/ZRtp.h	2006-07-09 10:50:02 UTC (rev 2693)
+++ trunk/libminisip/include/libminisip/zrtp/ZRtp.h	2006-07-09 13:18:35 UTC (rev 2694)
@@ -70,7 +70,7 @@
          * Constructor intializes all relevant data but does not start the
          * engine.
          */
-	ZRtp(uint8_t *myZid, ZrtpCallback *cb);
+	ZRtp(uint8_t* myZid, ZrtpCallback* cb);
 
         /**
 	 * Destructor cleans up.
@@ -130,7 +130,7 @@
     /**
      * The state engine takes care of protocol processing.
      */
-    ZrtpStateClass *stateEngine;
+    ZrtpStateClass* stateEngine;
 
     /**
      * This is my ZID that I send to the peer.
@@ -146,12 +146,12 @@
      * The callback class provides me with the interface to send
      * data and to deal with timer management of the hosting system.
      */
-    ZrtpCallback *callback;
+    ZrtpCallback* callback;
 
     /**
      * My active Diffie-Helman context
      */
-    ZrtpDH *dhContext;
+    ZrtpDH* dhContext;
 
     /**
      * The computed DH shared secret
@@ -236,7 +236,7 @@
     /**
      * Pre-initialized packets to start off the whole game.
      */
-    ZrtpPacketHello* zrtpHello;
+    ZrtpPacketHello*    zrtpHello;
     ZrtpPacketHelloAck* zrtpHelloAck;
     ZrtpPacketConf2Ack* zrtpConf2Ack;
     

Modified: trunk/libminisip/include/libminisip/zrtp/ZrtpCallback.h
===================================================================
--- trunk/libminisip/include/libminisip/zrtp/ZrtpCallback.h	2006-07-09 10:50:02 UTC (rev 2693)
+++ trunk/libminisip/include/libminisip/zrtp/ZrtpCallback.h	2006-07-09 13:18:35 UTC (rev 2694)
@@ -130,6 +130,9 @@
     /**
      * Send a ZRTP packet via RTP.
      *
+     * ZRTP call this method if it needs to send data via RTP. The
+     * data must not be encrypted before transfer.
+     *
      * @param data
      *    Points to ZRTP packet to send as RTP extension header.
      * @param length
@@ -137,11 +140,14 @@
      * @return
      *    zero if sending failed, one if packet was send
      */
-    virtual int32_t sendDataRTP(const uint8_t *data, int32_t length) =0;
+    virtual int32_t sendDataRTP(const uint8_t* data, int32_t length) =0;
 
     /**
      * Send a ZRTP packet via SRTP.
      *
+     * ZRTP call this method if it needs to send data via SRTP. The
+     * data must be encrypted before transfer.
+     *
      * @param dataHeader
      *    Points to ZRTP packet to send as RTP extension header
      * @param lengthHeader
@@ -153,8 +159,8 @@
      * @return
      *    zero if sending failed, one if packet was send
      */
-    virtual int32_t sendDataSRTP(const uint8_t *dataHeader, int32_t lengthHeader,
-				 char *dataContent, int32_t lengthContent) =0;
+    virtual int32_t sendDataSRTP(const uint8_t* dataHeader, int32_t lengthHeader,
+				 char* dataContent, int32_t lengthContent) =0;
 
     /**
      * Activate timer.
@@ -177,10 +183,10 @@
     /**
      * Send information messages to the hosting environment.
      * 
-     * The ZRTP implementation uses this method to send information messages
-     * to the host. Along with the message ZRTP provides a severity indicator
-     * that defines: Info, Warning, Error, Alert. Refer to the MessageSeverity
-     * enum above.
+     * The ZRTP implementation uses this method to send information
+     * messages to the host. Along with the message ZRTP provides a
+     * severity indicator that defines: Info, Warning, Error,
+     * Alert. Refer to the <code>MessageSeverity</code> enum above.
      *
      * @param severity
      *     This defines the message's severity
@@ -193,17 +199,18 @@
     /**
      * This method gets call by ZRTP as soon as the SRTP secrets are available.
      * 
-     * The ZRTP implementation call this method right after all SRTP secrets
-     * are computed and ready to be used. The parameter points to a structure
-     * that contains pointers to the SRTP secrets and a enum Role. The called
-     * host method (the implementation of this abstract method) must save the
-     * pointers to the SRTP secrets it needs into a save place. The 
-     * SrtpSecret_t structure is destroy when the callback nethod returns to
-     * the ZRTP implementation.
+     * The ZRTP implementation calls this method right after all SRTP
+     * secrets are computed and ready to be used. The parameter points
+     * to a structure that contains pointers to the SRTP secrets and a
+     * <code>enum Role</code>. The called host method (the
+     * implementation of this abstract method) must copy the pointers
+     * to the SRTP secrets it needs into a save place. The
+     * SrtpSecret_t structure is destroyed when the callback method
+     * returns to the ZRTP implementation.
      * 
-     * The SRTP secrets themselfs are ontaines in the ZRtp object and are valid
-     * as long as the ZRtp object is active. The destructor the ZRtp clears the
-     * secrets.
+     * The SRTP secrets themselfs are ontained in the ZRtp object and
+     * are valid as long as the ZRtp object is active. TheZRtp's
+     * destructor clears the secrets.
      * 
      * @param secrets
      *     A pointer to a SrtpSecret_t structure that contains all necessary

Modified: trunk/libminisip/include/libminisip/zrtp/ZrtpHostBridgeMinisip.h
===================================================================
--- trunk/libminisip/include/libminisip/zrtp/ZrtpHostBridgeMinisip.h	2006-07-09 10:50:02 UTC (rev 2693)
+++ trunk/libminisip/include/libminisip/zrtp/ZrtpHostBridgeMinisip.h	2006-07-09 13:18:35 UTC (rev 2694)
@@ -30,8 +30,9 @@
 #include <stdint.h>
 #include <string.h>
 
-#include<libmutil/StateMachine.h>
-#include<libmsip/SipSMCommand.h>
+#include <libmutil/StateMachine.h>
+#include <libmutil/MessageRouter.h>
+#include <libmsip/SipSMCommand.h>
 
 #include <libminisip/mediahandler/MediaStream.h>
 #include <libminisip/rtp/SRtpPacket.h>
@@ -41,25 +42,25 @@
 #include <libminisip/zrtp/ZRtp.h>
 
 /**
- * The connection between the ZRTP implementation and Minisip
+ * The connection between the ZRTP implementation and Minisip.
  *
- * The ZRPT implementation is fairly independent from the underlying SIP and
- * RTP/SRTP implementation. This class implements specific functions and
- * interfaces that ZRTP uses to link to functions of the host. In this
- * case the host is Minisip.
+ * The ZRPT implementation is fairly independent from the underlying
+ * SIP and RTP/SRTP implementation. This class implements specific
+ * functions and interfaces that ZRTP uses to call functions of the
+ * hosting SIP client. In this case the host is Minisip.
  *
  * <p/>
  *
- * This bridge class implement the ZrtpCallback interface that ZRTP uses to
- * send data and to activate timer. A very Minisip specific part is the
- * handling of the timeout provider.
+ * As required by ZRTP base implementation the bridge implements
+ * the ZrtpCallback interface.
  *
  * <p/>
  *
- * The minisip <e>startSip</e> method call the bridge's <e>initialize</e>
- * method after the whole SIP was initialized. To avoid a new timeout provider
- * this bridge reuses the timeout provider created by SipStack. Thus the
- * initialize call looks like:
+ * The most minisip specific part is the implementation of the timer.
+ * The minisip <e>startSip</e> method calls the bridge's
+ * <e>initialize</e> method after the whole SIP was initialized. To
+ * avoid a new timeout provider this bridge reuses the timeout
+ * provider created by SipStack. Thus the initialize call looks like:
  *
  * <br>
  *
@@ -67,10 +68,11 @@
  *
  * <br/>
  *
- * The initialize method stores the timeout provider and reuses it for every
- * instance. To do so the bridge inherits from <e>StateMachine<e/> but does use
- * the timeout specific parts only. The destructor frees the StateMachine to
- * maintain the timout provide reference counter.
+ * The <code>initialize</code> method stores the timeout provider and
+ * reuses it for every instance. To do so the bridge inherits from
+ * Minisip's <e>StateMachine<e/> but does use the timeout specific
+ * parts only. The destructor frees the StateMachine to maintain the
+ * timout provider's reference counter.
  */
 
 class ZrtpHostBridgeMinisip : public StateMachine<SipSMCommand,std::string>, public ZrtpCallback {
@@ -82,10 +84,10 @@
     /**
      * Initialize the host bridge.
      *
-     * This static method must be called before any use of the host
-     * bridge. If the caller does not provide a filename for the ZID
-     * file the method opens the ZID file with the default name <e>
-     * ~/.minisip.zid<e/>. This is a binary file.
+     * This static method must be called before <e>any</e> use of the
+     * host bridge. If the caller does not provide a filename for the
+     * ZID file the method opens the ZID file with the default name
+     * <e> ~/.minisip.zid<e/>. This is a binary file.
      *
      * @param tp
      *    The timeout provider to use. In this case it shall be the 
@@ -98,7 +100,7 @@
     static int32_t initialize(MRef<TimeoutProvider<std::string, MRef<StateMachine<SipSMCommand,std::string>*> > *> tp,
 		     const char *zidFilename =NULL);
 
-    ZrtpHostBridgeMinisip();
+    ZrtpHostBridgeMinisip(std::string id, MRef<CommandReceiver*> callback);
     ~ZrtpHostBridgeMinisip();
 
 
@@ -115,13 +117,14 @@
     uint32_t getSsrcSender()                        { return senderSsrc; };
     int32_t isSecureStateSender()                   { return senderSecure; }
 
-
+    void setCallId(std::string id)                  { callId = id; }
     /**
      * Set the IP address of our remote peer.
      * 
-     * We use this IP address to find the right ZRTP host
-     * bridge when we receive packets on the receiver port allocated
-     * by the MediaStreamReceiver.
+     * The host (Minisip) shall call this mehtod to set the IP address
+     * of the remote peer. We use the address to find the right ZRTP
+     * host bridge when we receive packets on the receiver port
+     * allocated by the MediaStreamReceiver.
      *
      * This is (fairly) save because one remote peer shall not have
      * several different RTP sessions for one of my receiver ports.
@@ -140,8 +143,7 @@
     MRef<IPAddress *> getRemoteAddress() { return remoteAddress; };
 
     /**
-     * Process a received packet with an extension header and known
-     * payload type.
+     * Process a received packet with an extension header.
      *
      * This packet has an extension header and may have payload data
      * to process.  The method checks if it is a ZRTP packet, if yes
@@ -162,12 +164,16 @@
     int32_t processPacket(MRef<SRtpPacket *> packet);
 
     /**
-     * Handle timeout event forwarded by TimeoutProvider.
+     * Handle timeout event forwarded by Minisip's (SipStack)
+     * TimeoutProvider.
      *
      * Just call the ZRTP engine for further processing.
      */
     void handleTimeout(const std::string &c) { zrtpEngine->processTimeout(); };
 
+    /*
+     * Refer to ZrtpCallback.h
+     */
     int32_t sendDataRTP(const unsigned char* data, int32_t length);
 
     int32_t sendDataSRTP(const unsigned char* dataHeader, int32_t lengthHeader,
@@ -193,9 +199,9 @@
      * Switch on the security for the defined part.
      *
      * Create an CryproContext with the negotiated ZRTP data and
-     * register it with the repective part (sender or receiver) thus
+     * register it with the respective part (sender or receiver) thus
      * replacing the current active context (usually an empty
-     * context).
+     * context). This effectively enables SRTP.
      *
      * @param secrets
      *    The secret keys and salt negotiated by ZRTP
@@ -209,7 +215,7 @@
      *
      * Create an empty CryproContext and register it with the
      * repective part (sender or receiver) thus replacing the current
-     * active context.
+     * active context. This effectively disables SRTP.
      *
      * @param part
      *    An enum that defines sender, receiver, or both.
@@ -222,13 +228,14 @@
      *
      * The receiver detected a wrong SSRC during a session with our
      * remote peer. This could indicate a security problem - just
-     * switch security off and Alert the user.
+     * disable SRTP and alert the user.
      */
     void rtpSessionError();
 
  private:
     ZRtp *zrtpEngine;
     SrtpSecret_t secret;
+    int32_t secureParts;
 
     MRef<IPAddress *> remoteAddress;
     
@@ -240,6 +247,13 @@
     MRef<MediaStreamSender *> sStream;
     uint32_t senderSsrc;
     uint32_t senderSecure;
+    
+    /*
+     * The call id of our call
+    */
+    std::string callId;
+    
+    MRef<CommandReceiver*> messageRouterCallback;
 };
 
 #endif // _ZIDHOSTBRIDGEMINISIP_H_

Modified: trunk/libminisip/include/libminisip/zrtp/ZrtpPacketBase.h
===================================================================
--- trunk/libminisip/include/libminisip/zrtp/ZrtpPacketBase.h	2006-07-09 10:50:02 UTC (rev 2693)
+++ trunk/libminisip/include/libminisip/zrtp/ZrtpPacketBase.h	2006-07-09 13:18:35 UTC (rev 2694)
@@ -41,15 +41,15 @@
 	
   protected:
       void* allocated;
-      zrtpPacketHeader_t *zrtpHeader;
+      zrtpPacketHeader_t* zrtpHeader;
 
   public:
       virtual ~ZrtpPacketBase() {};
     
-    const uint8_t *getHeaderBase() { return (const uint8_t*)zrtpHeader; };
+    const uint8_t* getHeaderBase() { return (const uint8_t*)zrtpHeader; };
     bool isZrtpPacket()            { return (ntoh16(zrtpHeader->zrtpId) == zrtpId); };
     uint16_t getLength()           { return ntoh16(zrtpHeader->length); };
-    uint8_t *getMessage()          { return zrtpHeader->message; };
+    uint8_t* getMessage()          { return zrtpHeader->message; };
 
     void setLength(uint16_t len)  { zrtpHeader->length = hton16(len); };
     void setMessage(uint8_t *msg) { memcpy(zrtpHeader->message, msg, ZRTP_MSG_SIZE); };

Modified: trunk/libminisip/include/libminisip/zrtp/ZrtpPacketCommit.h
===================================================================
--- trunk/libminisip/include/libminisip/zrtp/ZrtpPacketCommit.h	2006-07-09 10:50:02 UTC (rev 2693)
+++ trunk/libminisip/include/libminisip/zrtp/ZrtpPacketCommit.h	2006-07-09 13:18:35 UTC (rev 2694)
@@ -27,26 +27,26 @@
 class ZrtpPacketCommit : public ZrtpPacketBase {
 
  protected:
-    Commit_t *commitHeader;
+    Commit_t* commitHeader;
 
  public:
     ZrtpPacketCommit();		 /* Creates a Commit packet with default data */
-    ZrtpPacketCommit(uint8_t *data); /* Creates a Commit packet from received data */
+    ZrtpPacketCommit(uint8_t* data); /* Creates a Commit packet from received data */
     virtual ~ZrtpPacketCommit();
 
-    uint8_t *getHashType()    { return commitHeader->hash; };
-    uint8_t *getCipherType()  { return commitHeader->cipher; };
-    uint8_t *getPubKeysType() { return commitHeader->pubkey; };
-    uint8_t *getSasType()     { return commitHeader->sas; };
-    uint8_t *getZid()         { return commitHeader->zid; };
-    uint8_t *getHvi()         { return commitHeader->hvi; };
+    uint8_t* getHashType()    { return commitHeader->hash; };
+    uint8_t* getCipherType()  { return commitHeader->cipher; };
+    uint8_t* getPubKeysType() { return commitHeader->pubkey; };
+    uint8_t* getSasType()     { return commitHeader->sas; };
+    uint8_t* getZid()         { return commitHeader->zid; };
+    uint8_t* getHvi()         { return commitHeader->hvi; };
 
-    void setHashType(uint8_t *text)    { memcpy(commitHeader->hash, text, 8); };
-    void setCipherType(uint8_t *text)  { memcpy(commitHeader->cipher, text, 8); };
-    void setPubKeyType(uint8_t *text)  { memcpy(commitHeader->pubkey, text, 8); };
-    void setSasType(uint8_t *text)     { memcpy(commitHeader->sas, text, 8); };
-    void setZid(uint8_t *text)         { memcpy(commitHeader->zid, text, 12); };
-    void setHvi(uint8_t *text)         { memcpy(commitHeader->hvi, text, 32); };
+    void setHashType(uint8_t* text)    { memcpy(commitHeader->hash, text, 8); };
+    void setCipherType(uint8_t* text)  { memcpy(commitHeader->cipher, text, 8); };
+    void setPubKeyType(uint8_t* text)  { memcpy(commitHeader->pubkey, text, 8); };
+    void setSasType(uint8_t* text)     { memcpy(commitHeader->sas, text, 8); };
+    void setZid(uint8_t* text)         { memcpy(commitHeader->zid, text, 12); };
+    void setHvi(uint8_t* text)         { memcpy(commitHeader->hvi, text, 32); };
  private:
 };
 

Modified: trunk/libminisip/include/libminisip/zrtp/ZrtpPacketConf2Ack.h
===================================================================
--- trunk/libminisip/include/libminisip/zrtp/ZrtpPacketConf2Ack.h	2006-07-09 10:50:02 UTC (rev 2693)
+++ trunk/libminisip/include/libminisip/zrtp/ZrtpPacketConf2Ack.h	2006-07-09 13:18:35 UTC (rev 2694)
@@ -28,7 +28,7 @@
 
  public:
     ZrtpPacketConf2Ack();		/* Creates a Conf2Ack packet with default data */
-    ZrtpPacketConf2Ack(char *data);	/* Creates a Conf2Ack packet from received data */
+    ZrtpPacketConf2Ack(char* data);	/* Creates a Conf2Ack packet from received data */
     virtual ~ZrtpPacketConf2Ack();
 
  private:

Modified: trunk/libminisip/include/libminisip/zrtp/ZrtpPacketConfirm.h
===================================================================
--- trunk/libminisip/include/libminisip/zrtp/ZrtpPacketConfirm.h	2006-07-09 10:50:02 UTC (rev 2693)
+++ trunk/libminisip/include/libminisip/zrtp/ZrtpPacketConfirm.h	2006-07-09 13:18:35 UTC (rev 2694)
@@ -27,19 +27,19 @@
 class ZrtpPacketConfirm : public ZrtpPacketBase {
 
     private:
-	Confirm_t *confirmHeader;
+	Confirm_t* confirmHeader;
  public:
     ZrtpPacketConfirm();		/* Creates a Confirm packet with default data */
-    ZrtpPacketConfirm(uint8_t *data, uint8_t* content);	/* Creates a Confirm packet from received data */
+    ZrtpPacketConfirm(uint8_t* data, uint8_t* content);	/* Creates a Confirm packet from received data */
     virtual ~ZrtpPacketConfirm();
     
-    const uint8_t *getPlainText()     { return confirmHeader->plaintext; };
+    const uint8_t* getPlainText()     { return confirmHeader->plaintext; };
     uint8_t getSASFlag()              { return confirmHeader->flag; }
-    const uint8_t *getHmac()          { return confirmHeader->hmac; };
+    const uint8_t* getHmac()          { return confirmHeader->hmac; };
     
-    void setPlainText(uint8_t *text)  { memcpy(confirmHeader->plaintext, text, 15); };
+    void setPlainText(uint8_t* text)  { memcpy(confirmHeader->plaintext, text, 15); };
     void setSASFlag(uint8_t flg)      { confirmHeader->flag = flg; };
-    void setHmac(uint8_t *text)       { memcpy(confirmHeader->hmac, text, 32); };
+    void setHmac(uint8_t* text)       { memcpy(confirmHeader->hmac, text, 32); };
 
 };
 

Modified: trunk/libminisip/include/libminisip/zrtp/ZrtpPacketDHPart.h
===================================================================
--- trunk/libminisip/include/libminisip/zrtp/ZrtpPacketDHPart.h	2006-07-09 10:50:02 UTC (rev 2693)
+++ trunk/libminisip/include/libminisip/zrtp/ZrtpPacketDHPart.h	2006-07-09 13:18:35 UTC (rev 2694)
@@ -28,26 +28,26 @@
 
  protected:
     uint8_t *pv;
-    DHPart_t *DHPartHeader;
+    DHPart_t* DHPartHeader;
 
  public:
     ZrtpPacketDHPart(SupportedPubKeys pkt);	/* Creates a DHPart packet with default data */
-    ZrtpPacketDHPart(uint8_t *data);            /* Creates a DHPart packet from received data */
+    ZrtpPacketDHPart(uint8_t* data);            /* Creates a DHPart packet from received data */
     virtual ~ZrtpPacketDHPart();
 
-    uint8_t *getPv()             { return pv; }
-    uint8_t *getRs1Id()          { return DHPartHeader->rs1Id; };
-    uint8_t *getRs2Id()          { return DHPartHeader->rs2Id; };
-    uint8_t *getSigsId()         { return DHPartHeader->sigsId; };
-    uint8_t *getSrtpsId()        { return DHPartHeader->srtpsId; };
-    uint8_t *getOtherSecretId() { return DHPartHeader->otherSecretId; };
+    uint8_t* getPv()             { return pv; }
+    uint8_t* getRs1Id()          { return DHPartHeader->rs1Id; };
+    uint8_t* getRs2Id()          { return DHPartHeader->rs2Id; };
+    uint8_t* getSigsId()         { return DHPartHeader->sigsId; };
+    uint8_t* getSrtpsId()        { return DHPartHeader->srtpsId; };
+    uint8_t* getOtherSecretId() { return DHPartHeader->otherSecretId; };
 
-    void setPv(uint8_t *text) 	         { memcpy(pv, text, ((pktype == Dh3072) ? 384 :512)); };
-    void setRs1Id(uint8_t *text)         { memcpy(DHPartHeader->rs1Id, text, 8); };
-    void setRs2Id(uint8_t *text)         { memcpy(DHPartHeader->rs2Id, text, 8); };
-    void setSigsId(uint8_t *text)        { memcpy(DHPartHeader->sigsId, text, 8); };
-    void setSrtpsId(uint8_t *text)       { memcpy(DHPartHeader->srtpsId, text, 8); };
-    void setOtherSecretId(uint8_t *text) { memcpy(DHPartHeader->otherSecretId, text, 8); };
+    void setPv(uint8_t* text) 	         { memcpy(pv, text, ((pktype == Dh3072) ? 384 :512)); };
+    void setRs1Id(uint8_t* text)         { memcpy(DHPartHeader->rs1Id, text, 8); };
+    void setRs2Id(uint8_t* text)         { memcpy(DHPartHeader->rs2Id, text, 8); };
+    void setSigsId(uint8_t* text)        { memcpy(DHPartHeader->sigsId, text, 8); };
+    void setSrtpsId(uint8_t* text)       { memcpy(DHPartHeader->srtpsId, text, 8); };
+    void setOtherSecretId(uint8_t* text) { memcpy(DHPartHeader->otherSecretId, text, 8); };
 
  private:
     SupportedPubKeys pktype;

Modified: trunk/libminisip/include/libminisip/zrtp/ZrtpPacketError.h
===================================================================
--- trunk/libminisip/include/libminisip/zrtp/ZrtpPacketError.h	2006-07-09 10:50:02 UTC (rev 2693)
+++ trunk/libminisip/include/libminisip/zrtp/ZrtpPacketError.h	2006-07-09 13:18:35 UTC (rev 2694)
@@ -27,14 +27,14 @@
 class ZrtpPacketError : public ZrtpPacketBase {
 
  protected:
-    Error_t *errorHeader;
+    Error_t* errorHeader;
 
  public:
     ZrtpPacketError();		/* Creates a Error packet with default data */
-    ZrtpPacketError(char *data);	/* Creates a Error packet from received data */
+    ZrtpPacketError(char* data);	/* Creates a Error packet from received data */
     virtual ~ZrtpPacketError();
 
-    uint8_t *getErrorType() { return errorHeader->type; };
+    uint8_t* getErrorType() { return errorHeader->type; };
 
     void setErrorType(uint8_t *text) { memcpy(errorHeader->type, text, 8); };
 

Modified: trunk/libminisip/include/libminisip/zrtp/ZrtpPacketHello.h
===================================================================
--- trunk/libminisip/include/libminisip/zrtp/ZrtpPacketHello.h	2006-07-09 10:50:02 UTC (rev 2693)
+++ trunk/libminisip/include/libminisip/zrtp/ZrtpPacketHello.h	2006-07-09 13:18:35 UTC (rev 2694)
@@ -28,22 +28,22 @@
 class ZrtpPacketHello : public ZrtpPacketBase {
 
  protected:
-    Hello_t *helloHeader;
+    Hello_t* helloHeader;
 
  public:
     ZrtpPacketHello();		 /* Creates a Hello packet with default data */
     ZrtpPacketHello(uint8_t *data); /* Creates a Hello packet from received data */
     virtual ~ZrtpPacketHello();
 
-    uint8_t *getVersion()  { return helloHeader->version; };
-    uint8_t *getClientId() { return helloHeader->clientId; };
+    uint8_t* getVersion()  { return helloHeader->version; };
+    uint8_t* getClientId() { return helloHeader->clientId; };
     bool isPassive()       { return ((helloHeader->flag & 0x1) == 0x1); };
 
-    uint8_t *getHashType(uint32_t number)    { return helloHeader->hashes[number]; };
-    uint8_t *getCipherType(uint32_t number)  { return helloHeader->ciphers[number]; };
-    uint8_t *getPubKeysType(uint32_t number) { return helloHeader->pubkeys[number]; };
-    uint8_t *getSasType(uint32_t number)     { return helloHeader->sas[number]; };
-    uint8_t *getZid()                        { return helloHeader->zid; };
+    uint8_t* getHashType(uint32_t number)    { return helloHeader->hashes[number]; };
+    uint8_t* getCipherType(uint32_t number)  { return helloHeader->ciphers[number]; };
+    uint8_t* getPubKeysType(uint32_t number) { return helloHeader->pubkeys[number]; };
+    uint8_t* getSasType(uint32_t number)     { return helloHeader->sas[number]; };
+    uint8_t* getZid()                        { return helloHeader->zid; };
 
     void setVersion(uint8_t *text)                   { memcpy(helloHeader->version, text, 4); }
     void setClientId(uint8_t *text)                  { memcpy(helloHeader->clientId, text, 15); }

Modified: trunk/libminisip/include/libminisip/zrtp/ZrtpPacketHelloAck.h
===================================================================
--- trunk/libminisip/include/libminisip/zrtp/ZrtpPacketHelloAck.h	2006-07-09 10:50:02 UTC (rev 2693)
+++ trunk/libminisip/include/libminisip/zrtp/ZrtpPacketHelloAck.h	2006-07-09 13:18:35 UTC (rev 2694)
@@ -28,7 +28,7 @@
 
  public:
     ZrtpPacketHelloAck();		/* Creates a HelloAck packet with default data */
-    ZrtpPacketHelloAck(char *data);	/* Creates a HelloAck packet from received data */
+    ZrtpPacketHelloAck(char* data);	/* Creates a HelloAck packet from received data */
     virtual ~ZrtpPacketHelloAck();
 
  private:

Modified: trunk/libminisip/include/libminisip/zrtp/ZrtpStateClass.h
===================================================================
--- trunk/libminisip/include/libminisip/zrtp/ZrtpStateClass.h	2006-07-09 10:50:02 UTC (rev 2693)
+++ trunk/libminisip/include/libminisip/zrtp/ZrtpStateClass.h	2006-07-09 13:18:35 UTC (rev 2694)
@@ -101,9 +101,9 @@
 class ZrtpStateClass {
 
 private:
-    ZRtp *parent;
-    ZrtpStates *engine;
-    Event_t *event;
+    ZRtp* parent;
+    ZrtpStates* engine;
+    Event_t* event;
 
     /**
      * The last packet that was sent.

Modified: trunk/libminisip/include/libminisip/zrtp/ZrtpStates.h
===================================================================
--- trunk/libminisip/include/libminisip/zrtp/ZrtpStates.h	2006-07-09 10:50:02 UTC (rev 2693)
+++ trunk/libminisip/include/libminisip/zrtp/ZrtpStates.h	2006-07-09 13:18:35 UTC (rev 2694)
@@ -63,7 +63,7 @@
 
  private:
     const int32_t numStates;
-    const state_t *states;
+    const state_t* states;
     int32_t  state;
 
     ZrtpStates();

Modified: trunk/libminisip/include/libminisip/zrtp/ZrtpTextData.h
===================================================================
--- trunk/libminisip/include/libminisip/zrtp/ZrtpTextData.h	2006-07-09 10:50:02 UTC (rev 2693)
+++ trunk/libminisip/include/libminisip/zrtp/ZrtpTextData.h	2006-07-09 13:18:35 UTC (rev 2694)
@@ -26,37 +26,37 @@
 /**
  *
  */
-extern char *clientId;
-extern char *zrtpVersion;
+extern char* clientId;
+extern char* zrtpVersion;
 
 /**
  *
  */
-extern char *HelloMsg;
-extern char *HelloAckMsg;
-extern char *CommitMsg;
-extern char *DHPart1Msg;
-extern char *DHPart2Msg;
-extern char *Confirm1Msg;
-extern char *Confirm2Msg;
-extern char *Conf2AckMsg;
-extern char *ErrorMsg;
+extern char* HelloMsg;
+extern char* HelloAckMsg;
+extern char* CommitMsg;
+extern char* DHPart1Msg;
+extern char* DHPart2Msg;
+extern char* Confirm1Msg;
+extern char* Confirm2Msg;
+extern char* Conf2AckMsg;
+extern char* ErrorMsg;
 
 /**
  *
  */
-extern char *responder;
-extern char *initiator;
-extern char *iniMasterKey;
-extern char *iniMasterSalt;
-extern char *respMasterKey;
-extern char *respMasterSalt;
+extern char* responder;
+extern char* initiator;
+extern char* iniMasterKey;
+extern char* iniMasterSalt;
+extern char* respMasterKey;
+extern char* respMasterSalt;
 
-extern char *hmacKey;
-extern char *retainedSec;
-extern char *knownPlain;
+extern char* hmacKey;
+extern char* retainedSec;
+extern char* knownPlain;
 
-extern char *sasString;
+extern char* sasString;
 /**
  *
  */
@@ -67,7 +67,7 @@
     Sha256,
     NumSupportedHashes
 };
-extern char *supportedHashes[];
+extern char* supportedHashes[];
 
 // Keep the Cipher identifers in supportedCipher in the same order than the
 // following enum, starting with zero.
@@ -76,7 +76,7 @@
     Aes128,
     NumSupportedSymCiphers
 };
-extern char *supportedCipher[];
+extern char* supportedCipher[];
 
 // Keep the PubKey identifers in supportedPubKey in the same order than the
 // following enum, starting with zero.
@@ -85,7 +85,7 @@
     Dh3072,
     NumSupportedPubKeys
 };
-extern char *supportedPubKey[];
+extern char* supportedPubKey[];
 
 // Keep the SAS identifers in supportedSASType in the same order than the
 // following enum, starting with zero.
@@ -93,7 +93,7 @@
     Libase32,
     NumSupportedSASTypes
 };
-extern char *supportedSASType[];
+extern char* supportedSASType[];
 
 #endif     // _ZRTPTEXTDATA_H_
 

Modified: trunk/libminisip/source/Minisip.cxx
===================================================================
--- trunk/libminisip/source/Minisip.cxx	2006-07-09 10:50:02 UTC (rev 2693)
+++ trunk/libminisip/source/Minisip.cxx	2006-07-09 13:18:35 UTC (rev 2694)
@@ -316,6 +316,7 @@
 		mediaHandler = new MediaHandler( phoneConf, ipProvider );
 		confMessageRouter->setMediaHandler( mediaHandler );
 		messageRouter->addSubsystem("media",*mediaHandler);
+                mediaHandler->setMessageRouterCallback(*messageRouter);
 
 		if( consoleDbg ){
 			consoleDbg->setMediaHandler( mediaHandler );

Modified: trunk/libminisip/source/mediahandler/MediaHandler.cxx
===================================================================
--- trunk/libminisip/source/mediahandler/MediaHandler.cxx	2006-07-09 10:50:02 UTC (rev 2693)
+++ trunk/libminisip/source/mediahandler/MediaHandler.cxx	2006-07-09 13:18:35 UTC (rev 2694)
@@ -93,7 +93,7 @@
 
 //	muteAllButOne = config->muteAllButOne;
 	
-	ringtoneFile = config->ringtone;
+        ringtoneFile = config->ringtone;
 }
 
 // MediaHandler::~MediaHandler() {
@@ -136,10 +136,10 @@
 #ifdef ZRTP_SUPPORT
 		    if(securityConfig.use_zrtp) {
 #ifdef DEBUG_OUTPUT
-		        cerr << "MediaHandler::createSession: enabling ZRTP for receiver" << endl;
+		        cerr << "MediaHandler::createSession: enabling ZRTP for receiver" << callId << endl;
 #endif
 
-			zhb = new ZrtpHostBridgeMinisip();
+			zhb = new ZrtpHostBridgeMinisip(callId, *messageRouterCallback);
 			zhb->setReceiver(rStream);
 			rStream->setZrtpHostBridge(zhb);
 		    }
@@ -155,10 +155,10 @@
 #ifdef ZRTP_SUPPORT
 		    if(securityConfig.use_zrtp) {
 #ifdef DEBUG_OUTPUT
-		        cerr << "MediaHandler::createSession: enabling ZRTP for sender" << endl;
+		        cerr << "MediaHandler::createSession: enabling ZRTP for sender: " << callId << endl;
 #endif
 			if (!zhb) {
-			    zhb = new ZrtpHostBridgeMinisip();
+                            zhb = new ZrtpHostBridgeMinisip(callId, *messageRouterCallback);
 			}
 			zhb->setSender(sStream);
 			sStream->setZrtpHostBridge(zhb);

Modified: trunk/libminisip/source/mediahandler/RtpReceiver.cxx
===================================================================
--- trunk/libminisip/source/mediahandler/RtpReceiver.cxx	2006-07-09 10:50:02 UTC (rev 2693)
+++ trunk/libminisip/source/mediahandler/RtpReceiver.cxx	2006-07-09 13:18:35 UTC (rev 2694)
@@ -278,7 +278,7 @@
                         if (zhb->getSsrcReceiver() == 0) {
                             zhb->setSsrcReceiver(packetSsrc);
                         }
-                        continue;           // not a ZRTP packet 
+                        continue;           // not a ZRTP packet TODO check this - need a better way to do it
                     }                        
 /*                  cerr << "From: " << from->getString();
                     cerr << ", zhbFrom: " << zhb->getRemoteAddress()->getString();
@@ -298,9 +298,8 @@
                          */
 //                        cerr << "ZP " << endl;
 
-                        if (packetSsrc == 0xdeadbeef) { // it's a ZRTP packet 
+                        if (packetSsrc == 0xdeadbeef) { // it's a ZRTP packet TODO check this
                             (*i)->handleRtpPacketExt(packet);
-                            continue;
                         }
                     }
 #endif // ZRTP_SUPPORT

Modified: trunk/libminisip/source/mediahandler/Session.cxx
===================================================================
--- trunk/libminisip/source/mediahandler/Session.cxx	2006-07-09 10:50:02 UTC (rev 2693)
+++ trunk/libminisip/source/mediahandler/Session.cxx	2006-07-09 13:18:35 UTC (rev 2694)
@@ -50,6 +50,10 @@
 #include<libmutil/itoa.h>
 #include<libmutil/Timestamp.h>
 
+#ifdef ZRTP_SUPPORT
+#include <libminisip/zrtp/ZrtpHostBridgeMinisip.h>
+#endif
+
 #ifdef _WIN32_WCE
 #	include"../include/minisip_wce_extra_includes.h"
 #endif
@@ -551,6 +555,18 @@
 
 void Session::setCallId( const string callId ){
 	this->callId = callId;
+#ifdef ZRTP_SUPPORT
+	mediaStreamSendersLock.lock();
+	for ( std::list< MRef<MediaStreamSender *> >::iterator it =  mediaStreamSenders.begin();
+                     it !=  mediaStreamSenders.end(); it++ ) { // TODO - need better support to set call id in ZHB
+                        MRef<ZrtpHostBridgeMinisip*> zhb = (*it)->getZrtpHostBridge();
+                        if (zhb) {
+                            zhb->setCallId(callId);
+                        }
+        }   
+        mediaStreamSendersLock.unlock();
+
+#endif
 }
 
 void Session::sendDtmf( uint8_t symbol ){

Modified: trunk/libminisip/source/zrtp/Base32.cxx
===================================================================
--- trunk/libminisip/source/zrtp/Base32.cxx	2006-07-09 10:50:02 UTC (rev 2693)
+++ trunk/libminisip/source/zrtp/Base32.cxx	2006-07-09 13:18:35 UTC (rev 2694)
@@ -18,7 +18,7 @@
  * FROM, OUT OF OR IN CONNECTION WITH THIS SOFTWARE OR THE USE OR OTHER
  * DEALINGS IN THIS SOFTWARE.
  *
- * Converted into C++ by:
+ * Converted to C++ by:
  *
  *	@author Werner Dittmann <Werner.Dittmann at t-online.de>
  */
@@ -52,15 +52,15 @@
     255, 255, 255, 255, 255, 255, 255, 255, 
     255, 255, 255, 255, 255, 255, 255, 255, 
     255,  18, 255,  25,  26,  27,  30,  29,
-    7,  31, 255, 255, 255, 255, 255, 255, 
+      7,  31, 255, 255, 255, 255, 255, 255, 
     255, 255, 255, 255, 255, 255, 255, 255, 
     255, 255, 255, 255, 255, 255, 255, 255, 
     255, 255, 255, 255, 255, 255, 255, 255, 
     255, 255, 255, 255, 255, 255, 255, 255, 
     255,  24,   1,  12,   3,   8,   5,   6,
-    28,  21,   9,  10, 255,  11,   2,  16,  
-    13,  14,   4,  22,  17,  19, 255,  20,  
-    15,   0,  23, 255, 255, 255, 255, 255, 
+    28,   21,   9,  10, 255,  11,   2,  16,  
+    13,   14,   4,  22,  17,  19, 255,  20,  
+    15,    0,  23, 255, 255, 255, 255, 255, 
     255, 255, 255, 255, 255, 255, 255, 255, 
     255, 255, 255, 255, 255, 255, 255, 255, 
     255, 255, 255, 255, 255, 255, 255, 255, 
@@ -172,14 +172,15 @@
 }
 
 void Base32::a2b_l(const string cs, size_t size, const size_t lengthinbits ) {
-    unsigned long x=0;                         // to hold up to 32 bits worth of the input
+    unsigned long x = 0;	// to hold up to 32 bits worth of the input
     
     int32_t len = divceil(size*5, 8);
     
     /* if lengthinbits is not a multiple of 5 then this is
-       allocating space for 0 or 1 extra octets that will be
-       truncated at the end of this function if they are 
-       not needed */
+     * allocating space for 0 or 1 extra octets that will be
+     * truncated at the end of this function if they are 
+     * not needed 
+     */
     
     if (len < 128) {
         binaryResult = smallBuffer;
@@ -189,11 +190,13 @@
     }
     
     /* pointer into the result buffer, initially pointing to 
-       the "one-past-the-end" octet */
+     * the "one-past-the-end" octet 
+     */
     uint8_t* resp = binaryResult + len;
         
     /* index into the input buffer, initially pointing to the
-       "one-past-the-end" character */    
+     * "one-past-the-end" character 
+     */    
     int32_t csp = size;
           
     /* Now this is a real live Duff's device.  You gotta love it. */

Modified: trunk/libminisip/source/zrtp/ZIDFile.cxx
===================================================================
--- trunk/libminisip/source/zrtp/ZIDFile.cxx	2006-07-09 10:50:02 UTC (rev 2693)
+++ trunk/libminisip/source/zrtp/ZIDFile.cxx	2006-07-09 13:18:35 UTC (rev 2694)
@@ -21,6 +21,8 @@
  */
 // #define UNIT_TEST
 
+#include <time.h>
+
 #include <libminisip/zrtp/ZIDFile.h>
 
 static ZIDFile* instance;
@@ -37,14 +39,44 @@
 }
 
 int32_t ZIDFile::open(char *name) {
-
+    zidrecord_t rec;
+    uint32_t t;
+    uint32_t* ip;
+    
     // check for an already active ZID file
     if (zidFile != NULL) {
 	return 0;
     }
     if ((zidFile = fopen(name, "rb+")) == NULL) {
 	zidFile = fopen(name, "wb+");
+	// New file, genere an associated ZID and save it as first record
+	// should use some other randomize but that's good as well.
+	if (zidFile != NULL) {
+	    ip = (uint32_t*)associatedZid;
+	    memset(&rec, 0, sizeof(zidrecord_t));
+	    t = time(NULL);
+	    t += ((uint64_t)&rec & 0xffffffff);
+	    *ip++ = t;
+	    t += ((uint64_t)zidFile & 0xffffffff);
+	    *ip++ = t;
+	    t += ((uint64_t)name  & 0xffffffff);
+	    *ip = t;
+	    memcpy(rec.identifier, associatedZid, IDENTIFIER_LEN);
+	    fseek(zidFile, 0L, SEEK_SET);
+	    rec.ownZid = 1;
+	    fwrite(&rec, sizeof(zidrecord_t), 1, zidFile);
+	}
     }
+    else {
+	fseek(zidFile, 0L, SEEK_SET);
+	if (fread(&rec, sizeof(zidrecord_t), 1, zidFile) != 1) {
+	    return -1;
+	}
+	if (rec.ownZid != 1) {
+	    return -1;
+	}
+	memcpy(associatedZid, rec.identifier, IDENTIFIER_LEN);
+    }
     return ((zidFile == NULL) ? -1 : 1);
 }
 
@@ -61,14 +93,14 @@
     zidrecord_t rec;
     int numRead;
 
-    fseek(zidFile, 0L, SEEK_SET);
+    fseek(zidFile, (long)(sizeof(zidrecord_t)), SEEK_SET);
 
     do {
 	pos = ftell(zidFile);
 	numRead = fread(&rec, sizeof(zidrecord_t), 1, zidFile);
 
 	// skip invalid records
-	while(rec.recValid == 0 && numRead == 1) {
+	while(rec.ownZid == 1 && rec.recValid == 0 && numRead == 1) {
 	    numRead = fread(&rec, sizeof(zidrecord_t), 1, zidFile);
 	}
 
@@ -77,11 +109,15 @@
 	if (numRead == 0) {
 	    memset(&rec, 0, sizeof(zidrecord_t));
 	    memcpy(rec.identifier, zidRecord->record.identifier, IDENTIFIER_LEN);
+	    rec.recValid = 1;
 	    fwrite(&rec, sizeof(zidrecord_t), 1, zidFile);
 	    break;
 	}
     } while (memcmp(zidRecord->record.identifier, rec.identifier, IDENTIFIER_LEN) != 0);
 
+    // Copy the read data into the record structure
+    memcpy(&zidRecord->record, &rec, sizeof(zidrecord_t));
+    
     //  remember position of record in file for save operation
     zidRecord->position = pos;
     return 1;
@@ -89,7 +125,6 @@
 
 uint32_t ZIDFile::saveRecord(ZIDRecord *zidRecord) {
 
-    zidRecord->record.recValid = 1;
     fseek(zidFile, zidRecord->position, SEEK_SET);
     fwrite(&zidRecord->record, sizeof(zidrecord_t), 1, zidFile);
     return 1;

Modified: trunk/libminisip/source/zrtp/ZIDRecord.cxx
===================================================================
--- trunk/libminisip/source/zrtp/ZIDRecord.cxx	2006-07-09 10:50:02 UTC (rev 2693)
+++ trunk/libminisip/source/zrtp/ZIDRecord.cxx	2006-07-09 13:18:35 UTC (rev 2694)
@@ -22,7 +22,7 @@
 
 #include <libminisip/zrtp/ZIDRecord.h>
 
-void ZIDRecord::setNewRs1(const char *data) {
+void ZIDRecord::setNewRs1(const uint8_t *data) {
 
   // shift RS1 data and flag into RS2
   memcpy(record.rs2Data, record.rs1Data, RS_LENGTH);

Modified: trunk/libminisip/source/zrtp/ZRtp.cxx
===================================================================
--- trunk/libminisip/source/zrtp/ZRtp.cxx	2006-07-09 10:50:02 UTC (rev 2693)
+++ trunk/libminisip/source/zrtp/ZRtp.cxx	2006-07-09 13:18:35 UTC (rev 2694)
@@ -22,25 +22,950 @@
 
 #include <libminisip/zrtp/ZRtp.h>
 #include <libminisip/zrtp/ZrtpStateClass.h>
+#include <libminisip/zrtp/ZIDFile.h>
+#include <libminisip/zrtp/ZIDRecord.h>
+#include <libminisip/zrtp/Base32.h>
 #include <libmcrypto/ZrtpDH.h>
 
 
-ZRtp:: ZRtp(uint8_t *myZid, ZrtpCallback *cb): zid(myZid), 
-					       callback(cb), 
-					       dhContext(NULL) {
+void hexdump(const char* title, const unsigned char *s, int l) {
+    int n=0;
 
-    zrtpHello.setZid(zid);
+    printf("%s",title);
+    for( ; n < l ; ++n)
+    {
+        if((n%16) == 0)
+            printf("\n%04x",n);
+        printf(" %02x",s[n]);
+    }
+    printf("\n");
+}
 
-    dhContext = new ZrtpDH(4096); // try best security: key for AES256
-    dhContext->generateKey();	// produce a public key
+
+ZRtp:: ZRtp(uint8_t *myZid, ZrtpCallback *cb): 
+    callback(cb), dhContext(NULL) {
+						   
+    zrtpHello = NULL;
+    zrtpHelloAck = NULL;
+    zrtpConf2Ack = NULL;
+    DHss = NULL;
+    pubKeyBytes = NULL;
+    
+    memcpy(zid, myZid, 12);
+    zrtpHello = new ZrtpPacketHello(); 
+    zrtpHello->setZid(zid);
+    zrtpHelloAck = new ZrtpPacketHelloAck();
+    zrtpConf2Ack = new ZrtpPacketConf2Ack();
+
+    stateEngine = new ZrtpStateClass(this);
 }
 
-
 ZRtp::~ZRtp() {
+    if (DHss != NULL) {
+	free(DHss);
+    }
+    if (pubKeyBytes != NULL) {
+        free(pubKeyBytes);
+    }
+    if (zrtpHello != NULL) {
+	delete zrtpHello;
+    }
+    if (zrtpHelloAck != NULL) {
+	delete zrtpHelloAck;
+    }
+    if (zrtpConf2Ack != NULL) {
+	delete zrtpConf2Ack;
+    }
+    if (stateEngine != NULL) {
+	delete stateEngine;
+    }
+    if (dhContext != NULL) {
+	delete dhContext;
+    }
 
+    memset(hmacSrtp, 0, SHA256_DIGEST_LENGTH);
+    
+    /*
+     * Clear the Initiator's srtp key and salt
+     */
+    memset(srtpKeyI, 0, SHA256_DIGEST_LENGTH);
+    memset(srtpSaltI, 0,  SHA256_DIGEST_LENGTH);
+    
+    /*
+     * Clear he Responder's srtp key and salt
+     */
+    memset (srtpKeyR, 0, SHA256_DIGEST_LENGTH);
+    memset (srtpSaltR, 0, SHA256_DIGEST_LENGTH);
+
 }
 
+int32_t ZRtp::processExtensionHeader(uint8_t *extHeader, uint8_t* content) {
+    Event_t ev;
+    
+    ev.type = ZrtpPacket;
+    ev.data.packet = extHeader;
+    ev.content = content;
+    return stateEngine->processEvent(&ev);
+}
+
+int32_t ZRtp::processTimeout() {
+    Event_t ev;
+    
+    ev.type = Timer;
+    ev.data.packet = NULL;
+    ev.content = NULL;
+    return stateEngine->processEvent(&ev);
+}
+
+void ZRtp::startZrtpEngine() {
+    Event_t ev;
+    
+    ev.type = ZrtpInitial;
+    stateEngine->processEvent(&ev);
+}
+
+void ZRtp::stopZrtp() {
+    Event_t ev;
+    
+    ev.type = ZrtpClose;
+    stateEngine->processEvent(&ev);
+}
+
+
 ZrtpPacketCommit* ZRtp::prepareCommit(ZrtpPacketHello *hello) {
 
+    memcpy(peerZid, hello->getZid(), 12);
+    
+    sendInfo(Info, "Hello received, preparing a Commit");
+    
+    cipher = findBestCipher(hello);
+    if (cipher >= NumSupportedSymCiphers) {
+	sendInfo(Error, "Hello message does not contain a supported Cipher");
+	return NULL;
+    }
+    hash = findBestHash(hello);
+    if (hash >= NumSupportedHashes) {
+	sendInfo(Error, "Hello message does not contain a supported Hash");
+	return NULL;
+    }
+    pubKey = findBestPubkey(hello);
+    if (pubKey >= NumSupportedPubKeys) {
+	sendInfo(Error, "Hello message does not contain a supported public key algorithm");
+	return NULL;
+    }
+    sasType = findBestSASType(hello);
+    if (sasType >= NumSupportedSASTypes) {
+	sendInfo(Error, "Hello message does not contain a supported SAS algorithm");
+	return NULL;
+    }
+
+    if (cipher == Aes256 && pubKey != Dh4096) {
+	sendInfo(Warning, "Hello offers an AES256 cipher but does not offer a Diffie-Helman 4096");
+    }
+    
+    int32_t maxPubKeySize;
+
+    if (pubKey == Dh3072) {
+	dhContext = new ZrtpDH(3072);
+	maxPubKeySize = 384;
+
+    }
+    else if (pubKey == Dh4096) {
+	dhContext = new ZrtpDH(4096);
+	maxPubKeySize = 512;
+    }
+    else {
+	return NULL;
+	// Error - shouldn't happen 
+    }
+    dhContext->generateKey();
+    pubKeyLen = dhContext->getPubKeySize();
+    pubKeyBytes = (uint8_t*)malloc(pubKeyLen);
+    if (pubKeyBytes == NULL) {
+        sendInfo(Error, "Out of memory");	// serious error
+        return NULL;
+    }
+    dhContext->getPubKeyBytes(pubKeyBytes);
+
+    computeHvi(pubKeyBytes, maxPubKeySize, hello);
+    
+    char buffer[128];
+    snprintf((char *)buffer, 128, "Generated a public DH key of size: %d", dhContext->getPubKeySize());
+    sendInfo(Info, buffer);
+    
+    ZrtpPacketCommit *commit = new ZrtpPacketCommit();
+    commit->setZid(zid);
+    commit->setHashType((uint8_t*)supportedHashes[hash]);
+    commit->setCipherType((uint8_t*)supportedCipher[cipher]);
+    commit->setPubKeyType((uint8_t*)supportedPubKey[pubKey]);
+    commit->setSasType((uint8_t*)supportedSASType[sasType]);
+    commit->setHvi(hvi);
+    return commit;
 }
 
+ZrtpPacketDHPart* ZRtp::prepareDHPart1(ZrtpPacketCommit *commit) {
+
+    int i;
+
+    sendInfo(Info, "Responder: Commit received, preparing DHPart1");
+    
+    // check if we support the commited Cipher type
+    uint8_t *cp = commit->getCipherType();
+    for (i = 0; i < NumSupportedSymCiphers; i++) {
+	if (!memcmp(cp, supportedCipher[i], 8)) {
+	    break;
+	}
+    }
+    if (i >= NumSupportedSymCiphers) { // no match - something went wrong
+	sendInfo(Alert, "Cannot find a supported Cipher in Commit message");
+	return NULL;
+    }
+    cipher = (SupportedSymCiphers)i;
+
+    // check if we support the commited hash type
+    cp = commit->getHashType();
+    for (i = 0; i < NumSupportedHashes; i++) {
+	if (!memcmp(cp, supportedHashes[i], 8)) {
+	    break;
+	}
+    }
+    if (i >= NumSupportedHashes) { // no match - something went wrong
+	sendInfo(Alert, "Cannot find a supported Hash in Commit message");
+	return NULL;
+    }
+    hash = (SupportedHashes)i;
+
+    // check if we support the commited pub key type
+    cp = commit->getPubKeysType();
+    for (i = 0; i < NumSupportedPubKeys; i++) {
+	if (!memcmp(cp, supportedPubKey[i], 8)) {
+	    break;
+	}
+    }
+    if (i >= NumSupportedPubKeys) { // no match - something went wrong
+	sendInfo(Alert, "Cannot find a supported public key algorithm in Commit message");
+	return NULL;
+    }
+    pubKey = (SupportedPubKeys)i;
+
+    // check if we support the commited SAS type
+    cp = commit->getSasType();
+    for (i = 0; i < NumSupportedSASTypes; i++) {
+	if (!memcmp(cp, supportedSASType[i], 8)) {
+	    break;
+	}
+    }
+    if (i >= NumSupportedSASTypes) { // no match - something went wrong
+	sendInfo(Alert, "Cannot find a supported SAS algorithm in Commit message");
+	return NULL;
+    }
+    sasType = (SupportedSASTypes)i;
+
+    if (dhContext != NULL) {
+	delete dhContext;
+    }
+
+    int32_t maxPubKeySize;
+    
+    if (cipher == Aes256 && pubKey != Dh4096) {
+	sendInfo(Warning, "Commit contains an AES256 cipher but does not offer a Diffie-Helman 4096");
+	// generate a warning
+    }
+    // setup the DH context and generate a fresh public / secret key
+    if (pubKey == Dh3072) {
+	dhContext = new ZrtpDH(3072);
+	maxPubKeySize = 384;
+
+    }
+    else if (pubKey == Dh4096) {
+	dhContext = new ZrtpDH(4096);
+	maxPubKeySize = 512;
+    }
+    else {
+	return NULL;
+	// Error - shouldn't happen 
+    }
+    dhContext->generateKey();
+    pubKeyLen = dhContext->getPubKeySize();
+
+    char buffer[128];
+    snprintf(buffer, 128, "Generated a public DH key of size: %d", pubKeyLen);
+    sendInfo(Info, buffer);
+
+    if (pubKeyLen > maxPubKeySize) {
+	snprintf(buffer, 128, "Generated DH public key too big: %d, max: %d", pubKeyLen, maxPubKeySize);
+	sendInfo(Error, buffer);
+	return NULL;
+    }
+    pubKeyBytes = (uint8_t*)malloc(pubKeyLen);
+    if (pubKeyBytes == NULL) {
+        sendInfo(Error, "Out of memory");	// serious error
+        return NULL;
+    }
+    dhContext->getPubKeyBytes(pubKeyBytes);
+
+
+    // Initialize a ZID record to get retained secrets for this peer
+    memcpy(peerZid, commit->getZid(), 12);
+    ZIDRecord zidRec(peerZid);
+
+    // ZID file should be opened during initialization step, not here
+    // thus get the singleton instance to the open file
+    ZIDFile *zid = ZIDFile::getInstance();
+    zid->getRecord(&zidRec);
+
+    /*
+     * Compute the shared Secret Ids. Because here we are responder the real
+     * keys, salt, and HAMACS are computed after we got the DHPart2.
+     */
+    computeSharedSecretSet(zidRec);
+
+    ZrtpPacketDHPart *zpDH = new ZrtpPacketDHPart(pubKey);
+    
+    // Fill the values in the DHPart1 packet
+    zpDH->setMessage((uint8_t*)DHPart1Msg);
+    zpDH->setRs1Id(rs1IDr);
+    zpDH->setRs2Id(rs2IDr);
+    zpDH->setSigsId(sigsIDr);
+    zpDH->setSrtpsId(srtpsIDr);
+    zpDH->setOtherSecretId(otherSecretIDr);
+
+    // here the public key value
+    zpDH->setPv(pubKeyBytes);
+
+    // We are definitly responder. Save the peer's hvi for later compare.
+    myRole = Responder;
+    memcpy(peerHvi, commit->getHvi(), SHA256_DIGEST_LENGTH);
+    
+    return zpDH;
+}
+
+ZrtpPacketDHPart* ZRtp::prepareDHPart2(ZrtpPacketDHPart *dhPart1) {
+
+    uint8_t* pvr;
+    uint8_t *data[4];
+    unsigned int length[4];
+    uint8_t sas[SHA256_DIGEST_LENGTH];
+    
+    sendInfo(Info, "Initiator: DHPart1 received, preparing DHPart2");
+    
+    DHss = (uint8_t*)malloc(dhContext->getSecretSize());
+    if (DHss == NULL) {
+	sendInfo(Error, "Out of memory");	// serious error
+	return NULL;
+    }
+    data[0] = pubKeyBytes;
+    length[0] = pubKeyLen;
+    
+    data[1] = pvr = dhPart1->getPv();
+
+    data[2] = (uint8_t *)sasString;
+    length[2] = strlen(sasString);
+    data[3] = NULL;
+    
+    // TODO Check the pvr to avoid MITM
+    if (pubKey == Dh3072) {
+	dhContext->computeKey(pvr, 384, DHss);
+        length[1] = 384;
+        sha256(data, length, sas);
+
+    }
+    else {
+        dhContext->computeKey(pvr, 512, DHss);
+        length[1] = 512;
+        sha256(data, length, sas);
+    }
+    SAS = Base32(sas, 20).getEncoded();
+    
+    // Initialize a ZID record to get peer's retained secrets
+    ZIDRecord zidRec(peerZid);
+
+    // ZID file should be opened during initialization step, not here.
+    // Thus get the singleton instance to the open file
+    ZIDFile *zid = ZIDFile::getInstance();
+    zid->getRecord(&zidRec);
+
+    uint32_t macLen;
+    uint8_t randBuf[RS_LENGTH];
+    
+    /*
+     * After the next function call my set of shared secrets and the expected
+     * set of shared secrets are ready. The expected shared secrets are in the
+     * *r variables. This is "set A" as defined in the ZRTP specification. The
+     * received DHPart1 packet contains the "Set B". Now go on and select the 
+     * real shared secrets that we will use to generate s0, all depended 
+     * keys, and the new RS1 value of the ZID record.
+     */
+    computeSharedSecretSet(zidRec);
+    generateS0Initiator(dhPart1, zidRec);
+    zid->saveRecord(&zidRec);
+    
+    ZrtpPacketDHPart *zpDH = new ZrtpPacketDHPart(pubKey);
+
+    // Fill the values in the DHPart2 packet
+    zpDH->setMessage((uint8_t*)DHPart2Msg);
+    zpDH->setRs1Id(rs1IDi);
+    zpDH->setRs2Id(rs2IDi);
+    zpDH->setSigsId(sigsIDi);
+    zpDH->setSrtpsId(srtpsIDi);
+    zpDH->setOtherSecretId(otherSecretIDi);
+
+    // here the public key value
+    zpDH->setPv(pubKeyBytes);
+
+    myRole = Initiator;
+    
+    delete dhContext;
+    dhContext = NULL;
+
+    return zpDH;
+}
+
+ZrtpPacketConfirm* ZRtp::prepareConfirm1(ZrtpPacketDHPart *dhPart2) {
+    
+    uint8_t* pvi;
+    uint8_t *data[4];
+    unsigned int length[4];
+    uint8_t sas[SHA256_DIGEST_LENGTH];
+
+    sendInfo(Info, "Responder: DHPart2 received, preparing Confirm1");
+
+    DHss = (uint8_t*)malloc(dhContext->getSecretSize());
+    if (DHss == NULL) {
+	// serious error
+	return NULL;
+    }
+    data[0] = pvi = dhPart2->getPv();
+    
+    /*
+     * Prepare the data to compute the SAS hash.
+     */
+    data[1] = pubKeyBytes;
+    length[1] = pubKeyLen;
+
+    data[2] = (uint8_t*)sasString;
+    length[2] = strlen(sasString);
+    data[3] = NULL;
+    
+    // TODO Check the pvi to avoid MITM
+    if (pubKey == Dh3072) {
+	dhContext->computeKey(pvi, 384, DHss);
+        length[0] = 384;
+        sha256(data, length, sas);
+    }
+    else {
+        dhContext->computeKey(pvi, 512, DHss);
+        length[0] = 512;
+        sha256(data, length, sas);
+    }
+    SAS = Base32(sas, 20).getEncoded();
+
+    // Here we have the peers pv. Because we are responder re-compute my hvi
+    // using my Hello packet and the Initiator's pv and compare with 
+    // hvi sent in commit packet. If it doesn't macht then a MitM attack 
+    // may have occured. 
+    computeHvi(pvi, ((pubKey == Dh3072) ? 384 : 512), zrtpHello);
+    if (memcmp(hvi, peerHvi, SHA256_DIGEST_LENGTH) != 0) {
+	sendInfo(Alert, "Mismatch of HVI values. Possible MitM problem?");
+	return NULL;
+    }
+    
+    // Initialize a ZID record to get peer's retained secrets
+    ZIDRecord zidRec(peerZid);
+
+    // ZID file should be opened during initialization step, not here
+    // thus get the singleton instance to the open file
+    ZIDFile *zid = ZIDFile::getInstance();
+    zid->getRecord(&zidRec);
+
+    /*
+     * The expected shared secret Ids were already computed when we built the
+     * DHPart1 packet. Generate s0, all depended keys, and the new RS1 value
+     * for the ZID record.
+     */
+    generateS0Responder(dhPart2, zidRec);
+    
+    delete dhContext;
+    dhContext = NULL;
+
+    zid->saveRecord(&zidRec);
+
+    ZrtpPacketConfirm* zpConf = new ZrtpPacketConfirm();
+    zpConf->setMessage((uint8_t*)Confirm1Msg);
+    zpConf->setPlainText((uint8_t*)knownPlain);
+    zpConf->setSASFlag(0);
+    
+    uint8_t confMac[SHA256_DIGEST_LENGTH];
+    unsigned int macLen;
+    
+    // The HMAC with length 16 includes the SAS flag inside the Confirm packet
+    hmac_sha256(hmacSrtp, SHA256_DIGEST_LENGTH, (unsigned char*)zpConf->getPlainText(),
+		16, confMac, &macLen);
+
+    zpConf->setHmac(confMac);
+    return zpConf;
+}
+
+ZrtpPacketConfirm* ZRtp::prepareConfirm2(ZrtpPacketConfirm *confirm1) {
+
+    sendInfo(Info, "Initiator: Confirm1 received, preparing Confirm2");
+
+    uint8_t sasFlag = confirm1->getSASFlag();
+    if (sasFlag & 0x1) {
+	// prepare the SAS data and display to user 
+    }
+    if (memcmp(knownPlain, confirm1->getPlainText(), 15) != 0) {
+	sendInfo(Error, "Cannot read confirm1 message");
+	return NULL;
+    }
+    uint8_t confMac[SHA256_DIGEST_LENGTH];
+    unsigned int macLen;
+    
+    // The HMAC with length 16 includes the SAS flag inside the Confirm packet
+    hmac_sha256(hmacSrtp, SHA256_DIGEST_LENGTH, (unsigned char*)confirm1->getPlainText(),
+		16, confMac, &macLen);
+
+    if (memcmp(confMac, confirm1->getHmac(), 32) != 0) {
+	sendInfo(Error, "HMAC verification of Confirm1 message failed");
+	return NULL;
+    }
+    
+    // now generate my Confirm2 message
+    ZrtpPacketConfirm* zpConf = new ZrtpPacketConfirm();
+    zpConf->setMessage((uint8_t*)Confirm2Msg);
+    zpConf->setPlainText((uint8_t*)knownPlain);
+    zpConf->setSASFlag(0);
+    
+    // The HMAC with length 16 includes the SAS flag inside the Confirm packet
+    hmac_sha256(hmacSrtp, SHA256_DIGEST_LENGTH, (unsigned char*)confirm1->getPlainText(),
+		16, confMac, &macLen);
+
+    zpConf->setHmac(confMac);
+    return zpConf;
+}
+
+ZrtpPacketConf2Ack* ZRtp::prepareConf2Ack(ZrtpPacketConfirm *confirm2) {
+    
+    sendInfo(Info, "Respnder: Confirm2 received, preparing Conf2Ack");
+    
+    uint8_t sasFlag = confirm2->getSASFlag();
+    if (sasFlag & 0x1) {
+	// prepare the SAS data and display to user 
+    }
+    if (memcmp(knownPlain, confirm2->getPlainText(), 15) != 0) {
+	sendInfo(Error, "Cannot read confirm2 message");
+	return NULL;
+    }
+    uint8_t confMac[SHA256_DIGEST_LENGTH];
+    unsigned int macLen;
+
+    // The hmac with length 16 includes the SAS flag inside the Confirm packet
+    hmac_sha256(hmacSrtp, SHA256_DIGEST_LENGTH, (unsigned char*)confirm2->getPlainText(),
+		16, confMac, &macLen);
+
+    if (memcmp(confMac, confirm2->getHmac(), 32) != 0) {
+	sendInfo(Error, "HMAC verification of Confirm2 message failed");
+	return NULL;
+    }
+    return zrtpConf2Ack;
+}
+
+SupportedHashes ZRtp::findBestHash(ZrtpPacketHello *hello) {
+
+    int i;
+    int ii;
+
+    for (i = 0; i < NumSupportedHashes; i++) {
+	for (ii = 0; ii < 5; ii++) {
+	    if (!memcmp(hello->getHashType(ii), supportedHashes[i], 8)) {
+		break;
+	    }
+	}
+	// if ii < 5 we found the hash i in the packet, done
+	if (ii < 5) {
+	    break;
+	}
+    }
+    return (SupportedHashes)i;
+}
+
+SupportedSymCiphers ZRtp::findBestCipher(ZrtpPacketHello *hello) {
+
+    int i;
+    int ii;
+
+    for (i = 0; i < NumSupportedSymCiphers; i++) {
+	for (ii = 0; ii < 5; ii++) {
+	    if (!memcmp(hello->getCipherType(ii), supportedCipher[i], 8)) {
+		break;
+	    }
+	}
+	// if ii < 5 we found the cipher i in the packet, done
+	if (ii < 5) {
+	    break;
+	}
+    }
+    return (SupportedSymCiphers)i;
+}
+
+SupportedPubKeys ZRtp::findBestPubkey(ZrtpPacketHello *hello) {
+
+    int i;
+    int ii;
+
+    for (i = 0; i < NumSupportedPubKeys; i++) {
+	for (ii = 0; ii < 5; ii++) {
+	    if (!memcmp(hello->getPubKeysType(ii), supportedPubKey[i], 8)) {
+		break;
+	    }
+	}
+	// if ii < 5 we found the cipher i in the packet, done
+	if (ii < 5) {
+	    break;
+	}
+    }
+    return (SupportedPubKeys)i;
+}
+
+SupportedSASTypes ZRtp::findBestSASType(ZrtpPacketHello *hello) {
+
+    int  i;
+    int ii;
+
+    for (i = 0; i < NumSupportedSASTypes ; i++) {
+	for (ii = 0; ii < 5; ii++) {
+	    if (!memcmp(hello->getSasType(ii), supportedSASType[i], 8)) {
+		break;
+	    }
+	}
+	// if ii < 5 we found the cipher i in the packet, done
+	if (ii < 5) {
+	    break;
+	}
+    }
+    return (SupportedSASTypes)i;
+}
+
+void ZRtp::computeHvi(uint8_t *pv, uint32_t pvLength, ZrtpPacketHello *hello) {
+
+    unsigned char* data[22];
+    unsigned int length[22];
+    int i;
+
+    /*
+    * populate the vector to compute the HVI hash according to the
+    * ZRTP specification.
+    */
+    data[0] = pv;
+    length[0] = pvLength;
+
+    for (i = 0; i < 5; i++) {
+	data[1+i] = (unsigned char*)hello->getHashType((uint32_t)i);
+	length[1+i] = 8;
+    }
+
+    for (i = 0; i < 5; i++) {
+	data[6+i] = (unsigned char*)hello->getCipherType((uint32_t)i);
+	length[6+i] = 8;
+    }
+
+    for (i = 0; i < 5; i++) {
+	data[11+i] = (unsigned char*)hello->getPubKeysType((uint32_t)i);
+	length[11+i] = 8;
+    }
+
+    for (i = 0; i < 5; i++) {
+	data[16+i] = (unsigned char*)hello->getSasType((uint32_t)i);
+	length[16+i] = 8;
+    }
+
+    data[21] = NULL;            // terminate data chunk
+    sha256(data, length, hvi);
+    return;
+}
+
+void ZRtp:: computeSharedSecretSet(ZIDRecord &zidRec) {
+    
+   /*
+    * Compute the Initiator's and Reponder's retained shared secret Ids.
+    */    
+    uint8_t randBuf[RS_LENGTH];
+    unsigned int macLen;
+    
+    if (!zidRec.isRs1Valid()) {
+	dhContext->random(randBuf, RS_LENGTH);
+	hmac_sha256(randBuf, RS_LENGTH, (unsigned char*)initiator,
+		    strlen(initiator), rs1IDi, &macLen);
+	hmac_sha256(randBuf, RS_LENGTH, (unsigned char*)responder,
+		    strlen(responder), rs1IDr, &macLen);
+    }
+    else {
+	hmac_sha256((unsigned char*)zidRec.getRs1(), RS_LENGTH, 
+		     (unsigned char*)initiator, strlen(initiator), 
+		     rs1IDi, &macLen);
+	hmac_sha256((unsigned char*)zidRec.getRs1(), RS_LENGTH, 
+		     (unsigned char*)responder, strlen(responder), 
+		     rs1IDr, &macLen);
+    }
+
+    if (!zidRec.isRs2Valid()) {
+	dhContext->random(randBuf, RS_LENGTH);
+	hmac_sha256(randBuf, RS_LENGTH, (unsigned char*)initiator, 
+		    strlen(initiator), rs2IDi, &macLen);
+	hmac_sha256(randBuf, RS_LENGTH, (unsigned char*)responder, 
+		    strlen(responder), rs2IDr, &macLen);
+    }
+    else {
+	hmac_sha256((unsigned char*)zidRec.getRs2(), RS_LENGTH, 
+		     (unsigned char*)initiator, strlen(initiator), 
+		     rs2IDi, &macLen);
+	hmac_sha256((unsigned char*)zidRec.getRs2(), RS_LENGTH, 
+		     (unsigned char*)responder, strlen(responder), 
+		     rs2IDr, &macLen);
+    }
+
+    /*
+    * For the time being we don't support these types of shared secrect. Could be
+    * easily done: somebody sets some data into our ZRtp object, check it here
+    * and use it. Otherwise use the random data.
+    */
+    dhContext->random(randBuf, RS_LENGTH);
+    hmac_sha256(randBuf, RS_LENGTH, (unsigned char*)initiator, 
+		strlen(initiator), sigsIDi, &macLen);
+    hmac_sha256(randBuf, RS_LENGTH, (unsigned char*)responder, 
+		strlen(responder), sigsIDr, &macLen);
+
+    dhContext->random(randBuf, RS_LENGTH);
+    hmac_sha256(randBuf, RS_LENGTH, (unsigned char*)initiator, 
+		strlen(initiator), srtpsIDi, &macLen);
+    hmac_sha256(randBuf, RS_LENGTH, (unsigned char*)responder, 
+		strlen(responder), srtpsIDr, &macLen);
+
+    dhContext->random(randBuf, RS_LENGTH);
+    hmac_sha256(randBuf, RS_LENGTH, (unsigned char*)initiator, 
+		strlen(initiator), otherSecretIDi, &macLen);
+    hmac_sha256(randBuf, RS_LENGTH, (unsigned char*)responder, 
+		strlen(responder), otherSecretIDr, &macLen);
+}
+
+void ZRtp::generateS0Initiator(ZrtpPacketDHPart *dhPart, ZIDRecord& zidRec) {
+    uint8_t* setC[5];
+    const uint8_t* setD[5];
+    const uint8_t* setE[5];
+    
+    setC[0] = (memcmp(rs1IDr, dhPart->getRs1Id(), 8) == 0) ? rs1IDr : NULL;
+    setC[1] = (memcmp(rs2IDr, dhPart->getRs2Id(), 8) == 0) ? rs2IDr : NULL;
+    setC[2] = (memcmp(sigsIDr, dhPart->getSigsId(), 8) == 0) ? sigsIDr : NULL;
+    setC[3] = (memcmp(srtpsIDr, dhPart->getSrtpsId(), 8) == 0) ? srtpsIDr : NULL;
+    setC[4] = (memcmp(otherSecretIDr, dhPart->getOtherSecretId(), 8) == 0) ? otherSecretIDr : NULL;
+    
+    /*
+     * SetC contains the intersection of shared secret Ids in the order seen
+     * above. Now select the real secrets into setD and the secret Ids of DHPart1
+     * message into setE in same order.
+     */
+    int matchingSecrets = 0;
+    if (setC[0] != NULL) {
+	DEBUGOUT((fprintf(stdout, "%c: Match for Rs1 found\n", zid[0])));
+	setD[matchingSecrets] = zidRec.getRs1();
+	setE[matchingSecrets++] = rs1IDi;  // rs1IDi will be sent in DHPart2 message
+    }
+
+    if (setC[1] != NULL) {
+	DEBUGOUT((fprintf(stdout, "%c: Match for Rs2 found\n", zid[0])));
+	setD[matchingSecrets] = zidRec.getRs2();
+	setE[matchingSecrets++] = rs2IDi;  // rs2IDi will be sent in DHPart2 message
+    }
+
+    // other shared secrets not yet supported - set to NULL
+    setD[2] = setE[2] = NULL;
+    setD[3] = setE[3] = NULL;
+    setD[4] = setE[4] = NULL;
+    
+    int32_t i;
+    const uint8_t* tmpP;
+    int32_t notDone = 1;
+    if (matchingSecrets > 1) {
+	/*
+	 * only very few elements, a simple bubble sort will do here
+	 */
+        while (notDone) {
+	   notDone = 0;
+	   for (i = 0; i < matchingSecrets - 1; i++) {
+	       if (memcmp(setE[i], setE[i+1], 32) > 0) {
+	           tmpP = setE[i];
+	           setE[i] = setE[i+1];
+	           setE[i+1] = tmpP;
+	           tmpP = setD[i];
+	           setD[i] = setD[i+1];
+	           setD[i+1] = tmpP;
+	           notDone = 1;
+	       }
+	   }
+        }
+    }
+
+    /*
+     * ready to generate s0 here.
+     * Hash the DH shared secret and the available shared secrets (max. 5).
+     */
+    unsigned char* data[7];
+    uint32_t  length[7];
+
+    data[0] = DHss;
+    length[0] = dhContext->getSecretSize();
+    data[1] = NULL;
+    sha256(data, length, DHss);
+    
+    data[0] = DHss;
+    length[0] = SHA256_DIGEST_LENGTH;
+    
+    for (i = 0; i < matchingSecrets; i++) {
+	data[1+i] = (unsigned char*)setD[i];
+        length[1+i] = SHA256_DIGEST_LENGTH;
+    }
+    data[1+i] = NULL;
+    sha256(data, length, s0);
+    
+    memset(DHss, 0, dhContext->getSecretSize());
+    free(DHss);
+    DHss = NULL;
+
+    computeSRTPKeys(zidRec);
+}
+
+void ZRtp::generateS0Responder(ZrtpPacketDHPart *dhPart, ZIDRecord& zidRec) {
+    uint8_t* setC[5];
+    const uint8_t* setD[5];
+    const uint8_t* setE[5];     // Set E is the "compressed" C (no NULLs) for sort
+    
+    setC[0] = (memcmp(rs1IDi, dhPart->getRs1Id(), 8) == 0) ? rs1IDi : NULL;
+    setC[1] = (memcmp(rs2IDi, dhPart->getRs2Id(), 8) == 0) ? rs2IDi : NULL;
+    setC[2] = (memcmp(sigsIDi, dhPart->getSigsId(), 8) == 0) ? sigsIDi : NULL;
+    setC[3] = (memcmp(srtpsIDi, dhPart->getSrtpsId(), 8) == 0) ? srtpsIDi : NULL;
+    setC[4] = (memcmp(otherSecretIDi, dhPart->getOtherSecretId(), 8) == 0) ? otherSecretIDi : NULL;
+    
+    /*
+    * SetC contains the intersection of shared secret Ids in the order seen
+    * above. Now select the real secrets into setD and the secret Ids of DHPart1
+    * message into setE in same order.
+    */
+    int matchingSecrets = 0;
+    if (setC[0] != NULL) {
+	DEBUGOUT((fprintf(stdout, "%c: Match for Rs1 found\n", zid[0])));
+	setD[matchingSecrets] = zidRec.getRs1();
+	setE[matchingSecrets++] = rs1IDi;
+    }
+
+    if (setC[1] != NULL) {
+	DEBUGOUT((fprintf(stdout, "%c: Match for Rs2 found\n", zid[0])));
+	setD[matchingSecrets] = zidRec.getRs2();
+	setE[matchingSecrets++] = rs2IDi;  // rs2IDi will be sent in DHPart2 message
+    }
+
+    // other shared secrets not yet supported - set to NULL
+    setD[2] = setE[2] = NULL;
+    setD[3] = setE[3] = NULL;
+    setD[4] = setE[4] = NULL;
+    
+    int32_t i;
+    const uint8_t* tmpP;
+    int32_t notDone = 1;
+    if (matchingSecrets > 1) {
+	/*
+	* only very few elements, a simple bubble sort will do here
+	*/
+	while (notDone) {
+	    notDone = 0;
+	    for (i = 0; i < matchingSecrets - 1; i++) {
+		if (memcmp(setE[i], setE[i+1], 32) > 0) {
+		    tmpP = setE[i];
+		    setE[i] = setE[i+1];
+		    setE[i+1] = tmpP;
+		    tmpP = setD[i];
+		    setD[i] = setD[i+1];
+		    setD[i+1] = tmpP;
+		    notDone = 1;
+		}
+	    }
+	}
+    }
+
+    /*
+    * ready to generate s0 here.
+    * Hash the DH shared secret and the available shared secrets (max. 5).
+    */
+    unsigned char* data[7];
+    uint32_t  length[7];
+    
+    data[0] = DHss;
+    length[0] = dhContext->getSecretSize();
+    data[1] = NULL;
+    sha256(data, length, DHss);
+    
+    data[0] = DHss;
+    length[0] = SHA256_DIGEST_LENGTH;
+    
+    for (i = 0; i < matchingSecrets; i++) {
+	data[1+i] = (unsigned char*)setD[i];
+        length[1+i] = SHA256_DIGEST_LENGTH;
+    }
+    data[1+i] = NULL;
+    sha256(data, length, s0);
+    
+    memset(DHss, 0, dhContext->getSecretSize());
+    free(DHss);
+    DHss = NULL;
+
+    computeSRTPKeys(zidRec);
+}
+
+void ZRtp::computeSRTPKeys(ZIDRecord& zidRec) {
+    
+    unsigned int macLen;   
+
+    uint8_t newRs1[RS_LENGTH];
+    
+    hmac_sha256(s0, SHA256_DIGEST_LENGTH, (unsigned char*)iniMasterKey, strlen(iniMasterKey),
+		srtpKeyI, &macLen);
+    hmac_sha256(s0, SHA256_DIGEST_LENGTH, (unsigned char*)iniMasterSalt, strlen(iniMasterSalt),
+		srtpSaltI, &macLen);
+    
+    hmac_sha256(s0, SHA256_DIGEST_LENGTH, (unsigned char*)respMasterKey, strlen(respMasterKey),
+		srtpKeyR, &macLen);
+    hmac_sha256(s0, SHA256_DIGEST_LENGTH, (unsigned char*)respMasterSalt, strlen(respMasterSalt),
+		srtpSaltR, &macLen);
+
+    hmac_sha256(s0, SHA256_DIGEST_LENGTH, (unsigned char*)hmacKey, strlen(hmacKey),
+		hmacSrtp, &macLen);
+
+    hmac_sha256(s0, SHA256_DIGEST_LENGTH, (unsigned char*)retainedSec, strlen(retainedSec),
+		newRs1, &macLen);
+    zidRec.setNewRs1((const uint8_t*)newRs1);
+
+    memset(s0, 0, SHA256_DIGEST_LENGTH);
+}
+
+void ZRtp::srtpSecretsReady(EnableSecurity part) {
+    
+    SrtpSecret_t sec;
+
+    sec.keyInitiator = srtpKeyI;
+    sec.initKeyLen = (cipher == Aes128) ? 128 :256;
+    sec.saltInitiator = srtpSaltI;
+    sec.initSaltLen = 112;
+    sec.keyResponder = srtpKeyR;
+    sec.respKeyLen = (cipher == Aes128) ? 128 :256;
+    sec.saltResponder = srtpSaltR;
+    sec.respSaltLen = 112;
+    sec.srtpAuthTagLen = 80;
+    sec.sas = SAS;
+    sec.role = myRole;
+    
+    callback->srtpSecretsReady(&sec, part);
+}
+
+void ZRtp::srtpSecretsOff(EnableSecurity part) {
+    callback->srtpSecretsOff(part);
+}
+

Modified: trunk/libminisip/source/zrtp/ZrtpHostBridgeMinisip.cxx
===================================================================
--- trunk/libminisip/source/zrtp/ZrtpHostBridgeMinisip.cxx	2006-07-09 10:50:02 UTC (rev 2693)
+++ trunk/libminisip/source/zrtp/ZrtpHostBridgeMinisip.cxx	2006-07-09 13:18:35 UTC (rev 2694)
@@ -24,25 +24,242 @@
 
 #include <libminisip/zrtp/ZrtpHostBridgeMinisip.h>
 #include <libminisip/zrtp/ZIDFile.h>
-#include <libminisip/zrtp/ZRtp.h>
+#include <libminisip/zrtp/ZrtpStateClass.h>
+#include <libminisip/zrtp/ZrtpHostBridgeMinisip.h>
 
+#include <libmikey/MikeyPayloadSP.h>
+#include <libminisip/configbackend/UserConfig.h>
+#include <libmutil/CommandString.h>
+
 static MRef<TimeoutProvider<std::string, MRef<StateMachine<SipSMCommand,std::string>*> > *>staticTimeoutProvider;
 
-int32_t ZrtpHostBridgeMinisip::initialze(MRef<TimeoutProvider<std::string, MRef<StateMachine<SipSMCommand,std::string>*> > *>tp,
-				  char *zidFilename) {
+int32_t ZrtpHostBridgeMinisip::initialize(MRef<TimeoutProvider<std::string,
+                                          MRef<StateMachine<SipSMCommand,std::string>*> > *>tp,
+                                          const char *zidFilename) {
+                                             
+    std::string fname;                                             
     staticTimeoutProvider = tp;
+    if (zidFilename == NULL) {
+        fname = UserConfig::getFileName("minisip.zid");
+        zidFilename = fname.c_str();
+    }
     ZIDFile *zf = ZIDFile::getInstance();
-    zf->open(zidFilename);
+    zf->open((char *)zidFilename);
     return 1;
 }
 
-ZrtpHostBridgeMinisip::ZrtpHostBridgeMinisip(uint8_t *zid): 
-    StateMachine<SipSMCommand,std::string>(staticTimeoutProvider) {
+ZrtpHostBridgeMinisip::ZrtpHostBridgeMinisip(std::string id, MRef<CommandReceiver*> callback): 
+        StateMachine<SipSMCommand, std::string>(staticTimeoutProvider), 
+        callId(id),
+        messageRouterCallback(callback) {
+            
+    secureParts = 0;
+    zrtpEngine = NULL;
 
-    zrtpEngine = new ZRtp(zid, static_cast<ZrtpCallback *>(this));
+    senderSecure = 0;
+    receiverSecure = 0;
+
+    receiverSsrc = 0;
+    senderSsrc = 0;
+
+    rStream = NULL;
+    sStream = NULL;
 } 
 
 ZrtpHostBridgeMinisip::~ZrtpHostBridgeMinisip() {
 
-    freeStateMachine();
+    freeStateMachine();		// to clean up the TimeoutProvider
+    delete zrtpEngine;
 }
+
+
+void ZrtpHostBridgeMinisip::start() {
+    ZIDFile *zid = ZIDFile::getInstance();
+    const uint8_t* ownZid = zid->getZid();
+
+    if (zrtpEngine == NULL) {
+        zrtpEngine = new ZRtp((uint8_t*)ownZid, (ZrtpCallback*)this);
+        zrtpEngine->startZrtpEngine();
+    }
+}
+
+void ZrtpHostBridgeMinisip::stop() {
+    zrtpEngine->stopZrtp();
+    delete zrtpEngine;
+}
+
+int32_t ZrtpHostBridgeMinisip::processPacket(MRef<SRtpPacket *> packet) {
+
+    unsigned char* extHeader = packet->getExtensionHeader();
+    uint16_t magic = *((uint16_t*)extHeader);
+    
+    magic = ntoh16(magic);
+
+    // If not a ZRTP packet - back to caller for further actions
+    if (magic != ZRTP_EXT_PACKET) {
+	return 1;
+    }
+
+    /*
+     * It's a ZRTP packet, check if ZRTP already started. If not return zero
+     * to dismiss packet.
+     */
+    if (zrtpEngine == NULL) {
+        return 0;
+    }
+    receiverSeqNo = packet->getHeader().getSeqNo();
+
+    int ret = zrtpEngine->processExtensionHeader(extHeader, packet->getContent());
+
+    // Fail is only a fail of the protocol state, already handled but
+    // payload usually not affected - thus caller may process it
+    return ((ret == Fail || ret == Done) ? 1 : 0);
+}
+
+int32_t ZrtpHostBridgeMinisip::sendDataRTP(const unsigned char *data, int32_t length) {
+    sStream->sendZrtp((unsigned char*)data, length, NULL, 0);
+    return 1;
+}
+
+int32_t ZrtpHostBridgeMinisip::sendDataSRTP(const unsigned char *dataHeader, int32_t lengthHeader,
+					    char *dataContent, int32_t lengthContent) {
+    sStream->sendZrtp((unsigned char*)dataHeader, lengthHeader, 
+		       (unsigned char*)dataContent, lengthContent);
+    return 1;
+}
+
+void ZrtpHostBridgeMinisip::srtpSecretsReady(SrtpSecret_t* secrets, EnableSecurity part) {
+    MRef<CryptoContext *> cryptoContext;
+    int64_t keydr = 1;
+    char buffer[128];
+    
+    if (part == ForSender || part == (EnableSecurity)ForSender+ForReceiver) {
+    // encrypting packets, intiator uses initiator keys, responder uses responders keys
+	if (secrets->role == Initiator) {
+	    cryptoContext = new CryptoContext(
+		    senderSsrc, 
+                    0 /*roc*/, 
+                    sStream->getSeqNo(), 
+                    0L,                                      // keydr << 48,
+                    MIKEY_SRTP_EALG_AESCM,                   // encryption algo
+                    MIKEY_SRTP_AALG_SHA1HMAC,                // authtication algo
+                    (unsigned char*)secrets->keyInitiator,   // Master Key
+                    secrets->initKeyLen / 8,                 // Master Key length
+                    (unsigned char*)secrets->saltInitiator,  // Master Salt
+                    secrets->initSaltLen / 8,                // Master Salt length
+                    secrets->initKeyLen / 8,                 // encryption keyl
+                    20,                                      // authentication key len
+                    secrets->initSaltLen / 8,                // session salt len
+                    1, 
+                    1, 
+                    secrets->srtpAuthTagLen / 8);            // authentication tag lenA 
+	}
+        else {
+            cryptoContext = new CryptoContext(
+		    senderSsrc, 
+                    0 /*roc*/, 
+                    sStream->getSeqNo(), 
+                    0L,                                      // keydr << 48,
+                    MIKEY_SRTP_EALG_AESCM,                   // encryption algo
+                    MIKEY_SRTP_AALG_SHA1HMAC,                // authtication algo
+                    (unsigned char*)secrets->keyResponder,   // Master Key
+                    secrets->respKeyLen / 8,                 // Master Key length
+                    (unsigned char*)secrets->saltResponder,  // Master Salt
+                    secrets->respSaltLen / 8,                // Master Salt length
+                    secrets->respKeyLen / 8,                 // encryption keyl
+                    20,                                      // authentication key len
+                    secrets->respSaltLen / 8,                // session salt len
+                    1, 
+                    1, 
+                    secrets->srtpAuthTagLen / 8);            // authentication tag len
+        }
+        cryptoContext->derive_srtp_keys( sStream->getSeqNo() );   // TODO check this
+        sStream->setKeyAgreementZrtp(cryptoContext);
+        snprintf(buffer, 120, "SAS Value(S): %s\n", secrets->sas.c_str());
+        sendInfo(Info, buffer);
+        secureParts += (int32_t)ForSender;
+
+    }
+    if (part == ForReceiver || part == (EnableSecurity)ForSender+ForReceiver) {
+    // decrypting packets, intiator uses responder keys, responder initiator keys
+	if (secrets->role == Initiator) {
+	    cryptoContext = new CryptoContext(
+		    receiverSsrc, 
+                    0 /*roc*/, 
+                    receiverSeqNo, 
+                    0L,                                      // keydr << 48,
+                    MIKEY_SRTP_EALG_AESCM,                   // encryption algo
+                    MIKEY_SRTP_AALG_SHA1HMAC,                // authtication algo
+                    (unsigned char*)secrets->keyResponder,   // Master Key
+                    secrets->respKeyLen / 8,                 // Master Key length
+                    (unsigned char*)secrets->saltResponder,  // Master Salt
+                    secrets->respSaltLen / 8,                // Master Salt length
+                    secrets->respKeyLen / 8,                 // encryption keyl
+                    20,                                      // authentication key len
+                    secrets->respSaltLen / 8,                // session salt len
+                    1, 
+                    1, 
+                    secrets->srtpAuthTagLen / 8);            // authentication tag len 
+	}
+	else {
+	    cryptoContext = new CryptoContext(
+		    receiverSsrc, 
+                    0 /*roc*/, 
+                    receiverSeqNo, 
+                    0L,                                      // keydr << 48,
+                    MIKEY_SRTP_EALG_AESCM,                   // encryption algo
+                    MIKEY_SRTP_AALG_SHA1HMAC,                // authtication algo
+                    (unsigned char*)secrets->keyInitiator,   // Master Key
+                    secrets->initKeyLen / 8,                 // Master Key length
+                    (unsigned char*)secrets->saltInitiator,  // Master Salt
+                    secrets->initSaltLen / 8,                // Master Salt length
+                    secrets->initKeyLen / 8,                 // encryption keyl
+                    20,                                      // authentication key len
+                    secrets->initSaltLen / 8,                // session salt len
+                    1, 
+                    1, 
+                    secrets->srtpAuthTagLen / 8);            // authentication tag len 
+	}
+        // roc << 16 | seqNo
+        cryptoContext->derive_srtp_keys( sStream->getSeqNo() );   // TODO check this
+        rStream->setKeyAgreementZrtp(cryptoContext);
+        snprintf(buffer, 120, "SAS Value(R): %s\n", secrets->sas.c_str());
+        sendInfo(Info, buffer);
+        secureParts += (int32_t)ForReceiver;
+    }
+    if (secureParts == ForSender+ForReceiver) {
+        CommandString cmd(callId, "zrtp_security_change", "secure");
+        messageRouterCallback->handleCommand("gui", cmd);
+    }
+}
+
+void ZrtpHostBridgeMinisip::srtpSecretsOff(EnableSecurity part) {
+    MRef<CryptoContext *> cryptoContext;
+
+    if (part == ForSender || part == (EnableSecurity)ForSender+ForReceiver) {
+	cryptoContext = new CryptoContext(senderSsrc);
+	sStream->setKeyAgreementZrtp(cryptoContext);
+    }
+    if (part == ForReceiver || part == (EnableSecurity)ForSender+ForReceiver) {
+	cryptoContext = new CryptoContext(receiverSsrc);
+	sStream->setKeyAgreementZrtp(cryptoContext);
+    }
+}
+
+void ZrtpHostBridgeMinisip::rtpSessionError() {
+    MRef<CryptoContext *> cryptoContext;
+
+    cryptoContext = new CryptoContext(senderSsrc);
+    sStream->setKeyAgreementZrtp(cryptoContext);
+    
+    cryptoContext = new CryptoContext(receiverSsrc);
+    sStream->setKeyAgreementZrtp(cryptoContext);
+    
+    sendInfo(Alert, "RTP session error - security switched off!");
+    
+    CommandString cmd(callId, "zrtp_security_change", "insecure");
+    messageRouterCallback->handleCommand("gui", cmd);
+}
+
+
+

Modified: trunk/libminisip/source/zrtp/ZrtpPacketCommit.cxx
===================================================================
--- trunk/libminisip/source/zrtp/ZrtpPacketCommit.cxx	2006-07-09 10:50:02 UTC (rev 2693)
+++ trunk/libminisip/source/zrtp/ZrtpPacketCommit.cxx	2006-07-09 13:18:35 UTC (rev 2694)
@@ -25,22 +25,31 @@
 
 
 ZrtpPacketCommit::ZrtpPacketCommit() {
+    DEBUGOUT((fprintf(stdout, "Creating commit packet without data\n")));
 
-    void *p = malloc(sizeof (CommitPacket_t));
+    allocated = malloc(sizeof (CommitPacket_t));
 
-    if ( p == NULL) {
+    if (allocated == NULL) {
     }
 
-    zrtpHeader = (zrtpPacketHeader_t *)&((CommitPacket_t *)p)->hdr;	// the standard header
-    commitHeader = (Commit_t *)&((CommitPacket_t *)p)->commit;
+    zrtpHeader = (zrtpPacketHeader_t *)&((CommitPacket_t *)allocated)->hdr;	// the standard header
+    commitHeader = (Commit_t *)&((CommitPacket_t *)allocated)->commit;
 
     setZrtpId();
     setLength(COMMIT_LENGTH + MESSAGE_LENGTH);
-    setMessage(CommitMsg);
+    setMessage((uint8_t*)CommitMsg);
 }
 
-ZrtpPacketCommit::ZrtpPacketCommit(char *data) {
+ZrtpPacketCommit::ZrtpPacketCommit(uint8_t *data) {
+    DEBUGOUT((fprintf(stdout, "Creating commit packet from data\n")));
+    allocated = NULL;
     zrtpHeader = (zrtpPacketHeader_t *)&((CommitPacket_t *)data)->hdr;	// the standard header
     commitHeader = (Commit_t *)&((CommitPacket_t *)data)->commit;
 }
 
+ZrtpPacketCommit::~ZrtpPacketCommit() {
+    DEBUGOUT((fprintf(stdout, "Deleting commit packet: alloc: %x\n", allocated)));
+    if (allocated != NULL) {
+	free(allocated);
+    }
+}

Modified: trunk/libminisip/source/zrtp/ZrtpPacketConf2Ack.cxx
===================================================================
--- trunk/libminisip/source/zrtp/ZrtpPacketConf2Ack.cxx	2006-07-09 10:50:02 UTC (rev 2693)
+++ trunk/libminisip/source/zrtp/ZrtpPacketConf2Ack.cxx	2006-07-09 13:18:35 UTC (rev 2694)
@@ -24,18 +24,28 @@
 #include <malloc.h>
 
 ZrtpPacketConf2Ack::ZrtpPacketConf2Ack() {
+    DEBUGOUT((fprintf(stdout, "Creating Conf2Ack packet without data\n")));
 
-  void *p = malloc(sizeof (Conf2Ack_t));
-  if ( p == NULL) {
-  }
-    zrtpHeader = (zrtpPacketHeader_t *)&((Conf2Ack_t *)p)->hdr;	// the standard header
+    allocated = malloc(sizeof (Conf2Ack_t));
+    if (allocated == NULL) {
+    }
+    zrtpHeader = (zrtpPacketHeader_t *)&((Conf2Ack_t *)allocated)->hdr;	// the standard header
 
     setZrtpId();
     setLength(MESSAGE_LENGTH);
-    setMessage(Conf2AckMsg);
+    setMessage((uint8_t*)Conf2AckMsg);
 }
 
 ZrtpPacketConf2Ack::ZrtpPacketConf2Ack(char *data) {
+    DEBUGOUT((fprintf(stdout, "Creating Conf2Ack packet from data\n")));
+
+    allocated = NULL;
     zrtpHeader = (zrtpPacketHeader_t *)&((Conf2Ack_t *)data)->hdr;	// the standard header
 }
 
+ZrtpPacketConf2Ack::~ZrtpPacketConf2Ack() {
+    DEBUGOUT((fprintf(stdout, "Deleting Conf2Ack packet: alloc: %x\n", allocated)));
+    if (allocated != NULL) {
+	free(allocated);
+    }
+}

Modified: trunk/libminisip/source/zrtp/ZrtpPacketConfirm.cxx
===================================================================
--- trunk/libminisip/source/zrtp/ZrtpPacketConfirm.cxx	2006-07-09 10:50:02 UTC (rev 2693)
+++ trunk/libminisip/source/zrtp/ZrtpPacketConfirm.cxx	2006-07-09 13:18:35 UTC (rev 2694)
@@ -24,17 +24,29 @@
 #include <malloc.h>
 
 ZrtpPacketConfirm::ZrtpPacketConfirm() {
+    DEBUGOUT((fprintf(stdout, "Creating Confirm packet without data\n")));
 
-  void *p = malloc(sizeof (ConfirmPacket_t));
-  if ( p == NULL) {
-  }
-    zrtpHeader = (zrtpPacketHeader_t *)&((ConfirmPacket_t *)p)->hdr;	// the standard header
+    allocated = malloc(sizeof (ConfirmPacket_t));
+    if (allocated == NULL) {
+    }
+    zrtpHeader = (zrtpPacketHeader_t *)&((ConfirmPacket_t *)allocated)->hdr;	// the standard header
+    confirmHeader = (Confirm_t *)&((ConfirmPacket_t *)allocated)->confirm;
 
     setZrtpId();
     setLength(MESSAGE_LENGTH);
 }
 
-ZrtpPacketConfirm::ZrtpPacketConfirm(char *data) {
+ZrtpPacketConfirm::ZrtpPacketConfirm(uint8_t* data, uint8_t* content) {
+    DEBUGOUT((fprintf(stdout, "Creating Confirm packet from data\n")));
+
+    allocated = NULL;
     zrtpHeader = (zrtpPacketHeader_t *)&((ConfirmPacket_t *)data)->hdr;	// the standard header
+    confirmHeader = (Confirm_t *)content; 
 }
 
+ZrtpPacketConfirm::~ZrtpPacketConfirm() {
+    DEBUGOUT((fprintf(stdout, "Deleting Confirm packet: alloc: %x\n", allocated)));
+    if (allocated != NULL) {
+	free(allocated);
+    }
+}

Modified: trunk/libminisip/source/zrtp/ZrtpPacketDHPart.cxx
===================================================================
--- trunk/libminisip/source/zrtp/ZrtpPacketDHPart.cxx	2006-07-09 10:50:02 UTC (rev 2693)
+++ trunk/libminisip/source/zrtp/ZrtpPacketDHPart.cxx	2006-07-09 13:18:35 UTC (rev 2694)
@@ -24,33 +24,59 @@
 #include <malloc.h>
 
 
-ZrtpPacketDHPart::ZrtpPacketDHPart(PKType pkt) {
+ZrtpPacketDHPart::ZrtpPacketDHPart(SupportedPubKeys pkt) {
+    DEBUGOUT((fprintf(stdout, "Creating DHPart packet without data\n")));
 
     int length = sizeof(zrtpPacketHeader_t) + sizeof(DHPart_t);
-    void *p;
 
-    length += ((pkt == DH3072) ? 384 : 512); // length according to DH type
-    p = malloc(length);
+    length += ((pkt == Dh3072) ? 384 : 512); // length according to DH type
+    allocated = malloc(length);
+    memset(allocated, 0, length);
 
-    if ( p == NULL) {
+    if (allocated == NULL) {
 	// TODO error handling
     }
 
     pktype = pkt;
     
-    zrtpHeader = (zrtpPacketHeader_t *)&((DHPartPacket_t *)p)->hdr;	// the standard header
-    pv = ((char *)p) + sizeof(zrtpPacketHeader_t); 			// point to the public key value
-    DHPartHeader = (DHPart_t *)(((char *)p) + sizeof(zrtpPacketHeader_t) + ((pkt == DH3072) ? 384 : 512));
+    zrtpHeader = (zrtpPacketHeader_t *)&((DHPartPacket_t *)allocated)->hdr;	// the standard header
+    pv = ((uint8_t *)allocated) + sizeof(zrtpPacketHeader_t); 		// point to the public key value
+    DHPartHeader = (DHPart_t *)(((char *)allocated)+sizeof(zrtpPacketHeader_t)+((pkt == Dh3072) ? 384 : 512));
 
     setZrtpId();
-    setLength(DHPART_LENGTH + MESSAGE_LENGTH + ((pkt == DH3072) ? 96 : 128));
+    setLength(DHPART_LENGTH + MESSAGE_LENGTH + ((pkt == Dh3072) ? 96 : 128));
 }
 
-ZrtpPacketDHPart::ZrtpPacketDHPart(char *data, PKType pkt) {
+ZrtpPacketDHPart::ZrtpPacketDHPart(uint8_t *data) {
+    DEBUGOUT((fprintf(stdout, "Creating DHPart packet from data\n")));
+
+    allocated = NULL;
     zrtpHeader = (zrtpPacketHeader_t *)&((DHPartPacket_t *)data)->hdr;	// the standard header
+    
+    int16_t len = getLength();
+    DEBUGOUT((fprintf(stdout, "DHPart length: %d\n", len)));
+    SupportedPubKeys pkt;
+    if (len == 108) {
+	pkt = Dh3072;
+    }
+    else if (len == 140) {
+	pkt = Dh4096;
+    }
+    else {
+	fprintf(stderr, "Wrong DHPart length: %d\n", len);
+	pv = NULL;
+	return;
+    }
     pv = data + sizeof(zrtpPacketHeader_t);
-    DHPartHeader = (DHPart_t *)(data + sizeof(zrtpPacketHeader_t) + ((pkt == DH3072) ? 384 : 512));
+    DHPartHeader = (DHPart_t *)(data + sizeof(zrtpPacketHeader_t) + ((pkt == Dh3072) ? 384 : 512));
 
     pktype = pkt;
 }
 
+ZrtpPacketDHPart::~ZrtpPacketDHPart() {
+    DEBUGOUT((fprintf(stdout, "Deleting DHPart packet: alloc: %x\n", allocated)));
+
+    if (allocated != NULL) {
+	free(allocated);
+    }
+}

Modified: trunk/libminisip/source/zrtp/ZrtpPacketError.cxx
===================================================================
--- trunk/libminisip/source/zrtp/ZrtpPacketError.cxx	2006-07-09 10:50:02 UTC (rev 2693)
+++ trunk/libminisip/source/zrtp/ZrtpPacketError.cxx	2006-07-09 13:18:35 UTC (rev 2694)
@@ -25,20 +25,31 @@
 #include <malloc.h>
 
 ZrtpPacketError::ZrtpPacketError() {
+    DEBUGOUT((fprintf(stdout, "Creating Error packet without data\n")));
 
-  void *p = malloc(sizeof (ErrorPacket_t));
-  if ( p == NULL) {
-  }
-    zrtpHeader = (zrtpPacketHeader_t *)&((ErrorPacket_t *)p)->hdr;	// the standard header
-    errorHeader = (Error_t *)&((ErrorPacket_t *)p)->error;
+    allocated = malloc(sizeof (ErrorPacket_t));
+    if (allocated == NULL) {
+    }
+    zrtpHeader = (zrtpPacketHeader_t *)&((ErrorPacket_t *)allocated)->hdr;	// the standard header
+    errorHeader = (Error_t *)&((ErrorPacket_t *)allocated)->error;
 
     setZrtpId();
     setLength(MESSAGE_LENGTH + ERROR_LENGTH);
-    setMessage(ErrorMsg);
+    setMessage((uint8_t*)ErrorMsg);
 }
 
 ZrtpPacketError::ZrtpPacketError(char *data) {
+    DEBUGOUT((fprintf(stdout, "Creating Error packet from data\n")));
+
+    allocated = NULL;
     zrtpHeader = (zrtpPacketHeader_t *)&((ErrorPacket_t *)data)->hdr;	// the standard header
     errorHeader = (Error_t *)&((ErrorPacket_t *)data)->error;
 }
 
+ZrtpPacketError::~ZrtpPacketError() {
+    DEBUGOUT((fprintf(stdout, "Deleting Error packet: alloc: %x\n", allocated)));
+
+    if (allocated != NULL) {
+	free(allocated);
+    }
+}

Modified: trunk/libminisip/source/zrtp/ZrtpPacketHello.cxx
===================================================================
--- trunk/libminisip/source/zrtp/ZrtpPacketHello.cxx	2006-07-09 10:50:02 UTC (rev 2693)
+++ trunk/libminisip/source/zrtp/ZrtpPacketHello.cxx	2006-07-09 13:18:35 UTC (rev 2694)
@@ -25,21 +25,22 @@
 
 
 ZrtpPacketHello::ZrtpPacketHello() {
+    DEBUGOUT((fprintf(stdout, "Creating Hello packet without data\n")));
 
-    void *p = malloc(sizeof (HelloPacket_t));
+    allocated = malloc(sizeof (HelloPacket_t));
 
-    if ( p == NULL) {
+    if (allocated == NULL) {
     }
 
-    zrtpHeader = (zrtpPacketHeader_t *)&((HelloPacket_t *)p)->hdr;	// the standard header
-    helloHeader = (Hello_t *)&((HelloPacket_t *)p)->hello;
+    zrtpHeader = (zrtpPacketHeader_t *)&((HelloPacket_t *)allocated)->hdr;	// the standard header
+    helloHeader = (Hello_t *)&((HelloPacket_t *)allocated)->hello;
 
     setZrtpId();
     setLength(HELLO_LENGTH + MESSAGE_LENGTH);
-    setMessage(HelloMsg);
+    setMessage((uint8_t*)HelloMsg);
 
-    setClientId(clientId);
-    setVersion(zrtpVersion);
+    setClientId((uint8_t*)clientId);
+    setVersion((uint8_t*)zrtpVersion);
 
     setHashType(0, supportedHashes[0]);
     setHashType(1, supportedHashes[1]);
@@ -66,8 +67,17 @@
     setSasType(4, supportedSASType[4]);
 }
 
-ZrtpPacketHello::ZrtpPacketHello(char *data) {
+ZrtpPacketHello::ZrtpPacketHello(uint8_t *data) {
+    DEBUGOUT((fprintf(stdout, "Creating Hello packet from data\n")));
+
+    allocated = NULL;
     zrtpHeader = (zrtpPacketHeader_t *)&((HelloPacket_t *)data)->hdr;	// the standard header
     helloHeader = (Hello_t *)&((HelloPacket_t *)data)->hello;
 }
 
+ZrtpPacketHello::~ZrtpPacketHello() {
+    DEBUGOUT((fprintf(stdout, "Deleting Hello packet: alloc: %x\n", allocated)));
+    if (allocated != NULL) {
+	free(allocated);
+    }
+}

Modified: trunk/libminisip/source/zrtp/ZrtpPacketHelloAck.cxx
===================================================================
--- trunk/libminisip/source/zrtp/ZrtpPacketHelloAck.cxx	2006-07-09 10:50:02 UTC (rev 2693)
+++ trunk/libminisip/source/zrtp/ZrtpPacketHelloAck.cxx	2006-07-09 13:18:35 UTC (rev 2694)
@@ -24,18 +24,29 @@
 #include <malloc.h>
 
 ZrtpPacketHelloAck::ZrtpPacketHelloAck() {
+    DEBUGOUT((fprintf(stdout, "Creating HelloAck packet without data\n")));
 
-  void *p = malloc(sizeof (HelloAck_t));
-  if ( p == NULL) {
-  }
-    zrtpHeader = (zrtpPacketHeader_t *)&((HelloAck_t *)p)->hdr;	// the standard header
+    allocated = malloc(sizeof (HelloAck_t));
+    if (allocated == NULL) {
+    }
+    zrtpHeader = (zrtpPacketHeader_t *)&((HelloAck_t *)allocated)->hdr;	// the standard header
 
     setZrtpId();
     setLength(MESSAGE_LENGTH);
-    setMessage(HelloAckMsg);
+    setMessage((uint8_t*)HelloAckMsg);
 }
 
 ZrtpPacketHelloAck::ZrtpPacketHelloAck(char *data) {
+    DEBUGOUT((fprintf(stdout, "Creating HelloAck packet from data\n")));
+
+    allocated = NULL;
     zrtpHeader = (zrtpPacketHeader_t *)&((HelloAck_t *)data)->hdr;	// the standard header
 }
 
+ZrtpPacketHelloAck::~ZrtpPacketHelloAck() {
+    DEBUGOUT((fprintf(stdout, "Deleting HelloAck packet: alloc: %x\n", allocated)));
+    if (allocated != NULL) {
+	free(allocated);
+    }
+}
+

Modified: trunk/libminisip/source/zrtp/ZrtpStateClass.cxx
===================================================================
--- trunk/libminisip/source/zrtp/ZrtpStateClass.cxx	2006-07-09 10:50:02 UTC (rev 2693)
+++ trunk/libminisip/source/zrtp/ZrtpStateClass.cxx	2006-07-09 13:18:35 UTC (rev 2694)
@@ -20,12 +20,14 @@
  * Authors: Werner Dittmann <Werner.Dittmann at t-online.de>
  */
 
-#include <iostream.h>
-#include <assert.h>
+#include <iostream>
+#include <cstdlib>
 #include <ctype.h>
 #include <libminisip/zrtp/ZRtp.h>
 #include <libminisip/zrtp/ZrtpStateClass.h>
 
+using namespace std;
+
 state_t states[numberOfStates] = {
     {Initial,      &ZrtpStateClass::evInitial },
     {Detect,       &ZrtpStateClass::evDetect },
@@ -39,6 +41,13 @@
     {SecureState,  &ZrtpStateClass::evSecureState }
 };
 
+static char* sendErrorText = "Cannot send data via RTP - connection or peer down?";
+static char* sendErrorTextSrtp = "Cannot send data via SRTP - connection or peer down?";
+static char* timerError = "Cannot start a timer - internal resources exhausted?";
+static char* resendError = "Too much retries during ZRTP negotiation - connection or peer down?";
+static char* internalProtocolError = "Internal protocol error occured!";
+static char* zrtpClosed = "No more security for this session";
+    
 ZrtpStateClass::ZrtpStateClass(ZRtp *p) {
     parent = p;
     engine = new ZrtpStates(states, numberOfStates, Initial);
@@ -59,10 +68,12 @@
     }
 }
 
-
 int32_t ZrtpStateClass::processEvent(Event_t *ev) {
 
-    if (inState(Initial)) {
+    /*
+     * Ignore any events if we are not really started yet.
+     */
+    if (inState(Initial) && ev->type != ZrtpInitial) {
 	return (Done);
     }
     event = ev;
@@ -71,32 +82,40 @@
 
 
 int32_t ZrtpStateClass::evInitial(void) {
-    cout << "Checking for match in Initial.\n";
+    DEBUGOUT((cout << "Checking for match in Initial.\n"));
 
     ZrtpPacketHello *hello = parent->prepareHello();
     if (!parent->sendPacketRTP(static_cast<ZrtpPacketBase *>(hello))) {
-	// Huston, we have a problem
+	nextState(Initial);
+	parent->sendInfo(Error, sendErrorText);
+	return(Fail);
     }
     nextState(Detect);
 
     // remember packet for easy resend in case timer triggers
     sentPacket = static_cast<ZrtpPacketBase *>(hello);
     if (startTimer(&T1) <= 0) {
-	// Yet another problem
+	nextState(Initial);
+	parent->sendInfo(Error, timerError);
+	return(Fail);
     }
-    return (Done);
+    return(Done);
 }
 
+/*
+ * When entering this transition function
+ * - sentPacket contains Hello, Hello timer active
+ */
 int32_t ZrtpStateClass::evDetect(void) {
 
-    cout << "Checking for match in Detect.\n";
+    DEBUGOUT((cout << "Checking for match in Detect.\n"));
 
     char *msg, first, last;
-    ZrtpPacketBase *pkt;
+    uint8_t *pkt;
 
     if (event->type == ZrtpPacket) {
 	pkt = event->data.packet;
-	msg = pkt->getMessage();
+	msg = (char *)pkt + 4;
 	  
 	first = tolower(*msg);
 	last = tolower(*(msg+7));
@@ -109,14 +128,24 @@
 	 * - don't start timer, we are responder
 	 */
 	if (first == 'c') {
-	    T1.stop = 1;	// stop Hello timer processing
-	    ZrtpPacketDHPart* dhPart1 = 
-		parent->prepareDHPart1(static_cast<ZrtpPacketCommit *>(pkt));
-
+	    cancelTimer();	// stop Hello timer processing, don't delete a Hello packet
+	    sentPacket = NULL;
+	    
+	    ZrtpPacketCommit *cpkt = new ZrtpPacketCommit(pkt);
+	    ZrtpPacketDHPart* dhPart1 = parent->prepareDHPart1(cpkt);
+	    delete cpkt;
+	    
+	    nextState(WaitDHPart2);
+	    
 	    if (!parent->sendPacketRTP(static_cast<ZrtpPacketBase *>(dhPart1))) {
-		// Huston, we have a problem
+		delete dhPart1;
+		sentPacket = NULL;
+		nextState(Initial);
+		parent->sendInfo(Error, sendErrorText);
+		return(Fail);
 	    }
-	    nextState(WaitDHPart2);
+	    // remember packet for easy resend in new state
+	    sentPacket = static_cast<ZrtpPacketBase *>(dhPart1);
 	    return (Done);
 	}
 	/*
@@ -125,95 +154,161 @@
 	 * - switch to state AckDetected, wait for peer's Hello
 	 */
 	if (first == 'h' && last =='k') {
-	    T1.stop = 1;	// stop Hello timer processing
+	    cancelTimer();	// stop Hello timer processing, don't delete this Hello packet
+	    sentPacket = NULL;
 	    nextState(AckDetected);
 	    return (Done);	  
 	}
 	/*
 	 * Hello:
-	 * - stop resending Hello
+	 * - stop Hello timer
 	 * - prepare and send my Commit, 
-	 * - switch state to CommitSent
-	 * - start timer - we are in Initiator role here
+	 * - switch state to CommitSent, start Commit timer
 	 */
 	if (first == 'h' && last ==' ') {
-	    T1.stop = 1;	// stop Hello timer processing
-	    ZrtpPacketCommit* commit = 
-		parent->prepareCommit(static_cast<ZrtpPacketHello *>(pkt));
+	    cancelTimer();
+	    sentPacket = NULL;
+	    
+	    ZrtpPacketHello *hpkt = new ZrtpPacketHello(pkt);
+	    ZrtpPacketCommit* commit = parent->prepareCommit(hpkt);
+	    delete hpkt;
+	    
+	    nextState(CommitSent);
 
 	    if (!parent->sendPacketRTP(static_cast<ZrtpPacketBase *>(commit))){
-		// Huston, we have a problem
+		delete commit;
+		sentPacket = NULL;
+		nextState(Initial);
+		parent->sendInfo(Error, sendErrorText);
+		return(Fail);
 	    }
-	    nextState(CommitSent);
 
 	    // remember packet for easy resend in case timer triggers
 	    sentPacket = static_cast<ZrtpPacketBase *>(commit);
 	    if (startTimer(&T2) <= 0) {
-		// Yet another problem
+		delete sentPacket;
+		sentPacket = NULL;
+		nextState(Initial);
+		parent->sendInfo(Error, timerError);
+		return(Fail);
 	    }
 	    return (Done);
 	}
     }
     // Timer event triggered
-    else {
-	// Timer triggered but we got a message during that time that
-	// stopped further timer processing. Ignore the trigger
-	if (T1.stop) {
+    else if (event->type == Timer) {
+	if (sentPacket == NULL) {      // probably a race condition - ignore
 	    return (Done);
 	}
-	if (nextTimer(&T1) > 0 && parent->sendPacketRTP(sentPacket)) {
-	    return (Done);
+	if (nextTimer(&T1) < 0) {
+	    parent->sendInfo(Error, resendError);
+	    sentPacket = NULL;
+	    nextState(Initial);
+	    return (Fail);
 	}
+	if (!parent->sendPacketRTP(sentPacket)) {
+	    parent->sendInfo(Error, sendErrorText);
+	    sentPacket = NULL;
+	    nextState(Initial);
+	    return (Fail);
+	}
     }
-    // Error packet ??
-    return (Fail);
+    else {      // unknown Event type for this state
+	parent->sendInfo(Error, internalProtocolError);
+	sentPacket = NULL;
+	nextState(Initial);
+        // TODO: Error packet ??
+	return (Fail);
+    }
 }
 
+/*
+ * When entering this transition function
+ * - sentPacket contains NULL, Hello timer stopped
+ */
 int32_t ZrtpStateClass::evAckDetected(void) {
 
-    cout << "Checking for match in AckDetected.\n";
+    DEBUGOUT((cout << "Checking for match in AckDetected.\n"));
 
     char *msg, first, last;
-    ZrtpPacketBase *pkt;
+    uint8_t *pkt;
 
     if (event->type == ZrtpPacket) {
 	pkt = event->data.packet;
-	msg = pkt->getMessage();
+	msg = (char *)pkt + 4;
 	  
 	first = tolower(*msg);
 	last = tolower(*(msg+7));
 	/*
 	 * Hello:
-	 * - stop resending Hello
 	 * - Acknowledge the Hello
 	 * - switch to state WaitCommit, wait for peer's Commit
 	 */
 	if (first == 'h') {
-	    T1.stop = 1;	// stop Hello timer processing
 	    ZrtpPacketHelloAck *helloAck = parent->prepareHelloAck();
+
+	    nextState(WaitCommit);
+
 	    if (!parent->sendPacketRTP(static_cast<ZrtpPacketBase *>(helloAck))) {
-		// Huston, we have a problem
+		nextState(Initial);
+		sentPacket = NULL;
+		parent->sendInfo(Error, sendErrorText);
+		return(Fail);
 	    }
-	    nextState(WaitCommit);
 	    // remember packet for easy resend
 	    sentPacket = static_cast<ZrtpPacketBase *>(helloAck);
 	    return (Done);
 	}
+       /* 
+        * Commit:  (Actually illegal here)
+        * - go the responder path
+        * - send our DHPart1
+        * - switch to state WaitDHPart2, wait for peer's DHPart2
+        * - don't start timer, we are responder
+                */
+        if (first == 'c') {
+	    
+            ZrtpPacketCommit *cpkt = new ZrtpPacketCommit(pkt);
+            ZrtpPacketDHPart* dhPart1 = parent->prepareDHPart1(cpkt);
+            delete cpkt;
+	    
+            nextState(WaitDHPart2);
+	    
+            if (!parent->sendPacketRTP(static_cast<ZrtpPacketBase *>(dhPart1))) {
+                delete dhPart1;
+                sentPacket = NULL;
+                nextState(Initial);
+                parent->sendInfo(Error, sendErrorText);
+                return(Fail);
+            }
+	    // remember packet for easy resend in new state
+            sentPacket = static_cast<ZrtpPacketBase *>(dhPart1);
+            return (Done);
+        }
     }
-    // TODO: Error packet ??
-    return (Fail);
+    else {
+	parent->sendInfo(Error, internalProtocolError);
+	sentPacket = NULL;
+	nextState(Initial);
+        // TODO: Error packet ??
+	return (Fail);
+    }
 }
 
+/*
+ * When entering this transition function
+ * - sentPacket contains a HelloAck packet
+ */
 int32_t ZrtpStateClass::evWaitCommit(void) {
 
-    cout << "Checking for match in WaitCommit.\n";
+    DEBUGOUT((cout << "Checking for match in WaitCommit.\n"));
 
     char *msg, first, last;
-    ZrtpPacketBase *pkt;
+    uint8_t *pkt;
 
     if (event->type == ZrtpPacket) {
 	pkt = event->data.packet;
-	msg = pkt->getMessage();
+	msg = (char *)pkt + 4;
 	  
 	first = tolower(*msg);
 	last = tolower(*(msg+7));
@@ -225,7 +320,10 @@
 	 */
 	if (first == 'h') {
 	    if (!parent->sendPacketRTP(sentPacket)) {
-		// Huston, we have a problem
+		nextState(Initial);
+		sentPacket = NULL;    // don't delete HelloAck, it's preconfigured
+		parent->sendInfo(Error, sendErrorText);
+		return(Fail);
 	    }
 	    return (Done);
 	}
@@ -237,60 +335,96 @@
 	 * - don't start timer, we are responder
 	 */
 	if (first == 'c') {
-	    ZrtpPacketDHPart* dhPart1 = 
-		parent->prepareDHPart1(static_cast<ZrtpPacketCommit *>(pkt));
+	    ZrtpPacketCommit *cpkt = new ZrtpPacketCommit(pkt);
+	    ZrtpPacketDHPart* dhPart1 = parent->prepareDHPart1(cpkt);
+	    delete cpkt;
 
+	    nextState(WaitDHPart2);
+
 	    if (!parent->sendPacketRTP(static_cast<ZrtpPacketBase *>(dhPart1))){
-		// Huston, we have a problem
+		delete dhPart1;
+		nextState(Initial);
+		parent->sendInfo(Error, sendErrorText);
+		return(Fail);
 	    }
-	    nextState(WaitDHPart2);
 	    sentPacket = static_cast<ZrtpPacketBase *>(dhPart1);
 	    return (Done);	  
 	}
     }
-    // TODO: Error packet ??
-    return (Fail);
+    else {
+	parent->sendInfo(Error, internalProtocolError);
+	sentPacket = NULL;
+	nextState(Initial);
+        // TODO: Error packet ??
+	return (Fail);
+    }
 }
 
+/*
+ * When entering this transition function
+ * - sentPacket contains Commit packet, Hello timer stopped, Commit timer active
+ */
+
 int32_t ZrtpStateClass::evCommitSent(void) {
 
-    cout << "Checking for match in CommitSend.\n";
+    DEBUGOUT((cout << "Checking for match in CommitSend.\n"));
 
     char *msg, first, last;
-    ZrtpPacketBase *pkt;
+    uint8_t *pkt;
 
     if (event->type == ZrtpPacket) {
 	pkt = event->data.packet;
-	msg = pkt->getMessage();
+	msg = (char *)pkt + 4;
 	  
 	first = tolower(*msg);
 	last = tolower(*(msg+7));
 
 	/*
 	 * Commit:
-	 * - switch off resending Commit?? probably not
+	 * - switch off resending Commit
 	 * - compare my hvi with peer's hvi
 	 * - if my hvi is greater
 	 *   - I'm Initiator, stay in state
 	 * - else 
-	 *   - stop timer
+	*    - stop timer, we will be triggered by peer (Initiator)
 	 *   - prepare and send DH1Packt, 
 	 *   - switch to state WaitDHPart2, implies Responder path
 	 */
 	if (first == 'c') {
-	    if (parent->compareHvi(static_cast<ZrtpPacketCommit *>(pkt))< 0) {
-		T2.stop = 1;
-		ZrtpPacketDHPart* dhPart1 = 
-		    parent->prepareDHPart1(static_cast<ZrtpPacketCommit *>(pkt));
+	    ZrtpPacketCommit *zpCo = new ZrtpPacketCommit(pkt);
+	    cancelTimer();         // this cancels the Commit timer T2
+	    
+	    // if our hvi is less  that peer's hvi - switch to Responder
+	    // path, send DHPart1. Peer (as Initiator) will retrigger if necessary
+	    if (parent->compareHvi(zpCo) < 0) {
+		cancelTimer();         // this cancels the Commit timer T2
+		delete sentPacket;     // delete the Commit packet
+		sentPacket = NULL;
+		ZrtpPacketDHPart* dhPart1 = parent->prepareDHPart1(zpCo);
 	
+		nextState(WaitDHPart2);
+
 		if (!parent->sendPacketRTP(static_cast<ZrtpPacketBase *>(dhPart1))){
-		    // Huston, we have a problem
+		    delete dhPart1;
+		    delete zpCo;
+		    nextState(Initial);
+		    parent->sendInfo(Error, sendErrorText);
+		    return(Fail);
 		}
-		nextState(WaitDHPart2);
 		sentPacket = static_cast<ZrtpPacketBase *>(dhPart1);
 	    }
-	    // TODO: what about Timer: we depend on that fact that
-	    // peer _will_ send a DHPart1 because it is Responder.
+	    // Stay in state, we are Initiator, resend Commit after timeout until
+	    // we get a DHPart1
+	    else {
+		if (startTimer(&T2) <= 0) { // restart the Commit timer, gives peer more time to react
+                    delete sentPacket;
+                    sentPacket = NULL;
+                    nextState(Initial);
+                    parent->sendInfo(Error, timerError);
+                    return(Fail);
+		}
+	    }
+	    delete zpCo;
 	    return (Done);
 	}
 
@@ -299,46 +433,81 @@
 	 * - switch off resending Commit
 	 * - Prepare and send DHPart2
 	 * - switch to WaitConfirm1
-	 * - start timer to resend DHPart2 if necessary
+	 * - start timer to resend DHPart2 if necessary, we are Initiator
+	 * - switch on Security for receiver, Confirm1 payload is encrypted
 	 */
 	if (first == 'd') {
-	    T2.stop = 1;
-	    ZrtpPacketDHPart* dhPart2 = 
-		parent->prepareDHPart2(static_cast<ZrtpPacketDHPart *>(pkt));
+	    cancelTimer();
+	    delete sentPacket;     // deletes the Commit packet
+	    sentPacket = NULL;
+	    
+	    ZrtpPacketDHPart* dpkt = new ZrtpPacketDHPart(pkt);
+	    ZrtpPacketDHPart* dhPart2 = parent->prepareDHPart2(dpkt);
+	    delete dpkt;
 
+	    nextState(WaitConfirm1);
+	    parent->srtpSecretsReady(ForReceiver);	// let's try
+
 	    if (!parent->sendPacketRTP(static_cast<ZrtpPacketBase *>(dhPart2))){
-		// Huston, we have a problem
+		delete dhPart2;
+		nextState(Initial);
+		parent->srtpSecretsOff(ForReceiver);
+		parent->sendInfo(Error, sendErrorText);
+		return(Fail);
 	    }
-	    nextState(WaitConfirm1);
 	    sentPacket = static_cast<ZrtpPacketBase *>(dhPart2);
-	    startTimer(&T2);
+	    if (startTimer(&T2) <= 0) {;
+	       delete sentPacket;
+	       sentPacket = NULL;
+	       nextState(Initial);
+	       parent->srtpSecretsOff(ForReceiver);
+	       parent->sendInfo(Error, timerError);
+	       return(Fail);
+	    }
 	    return (Done);
 	}
     }
-    else {
-	// Timer triggered but we got a message during that time
-	// that stopped further timer processing. Ignore the trigger
-	if (T2.stop) {
+    // Timer event triggered, resend the Commit packet
+    else if (event->type == Timer) {
+	if (sentPacket == NULL) {      // probably a race condition - ignore
 	    return (Done);
 	}
-	if (nextTimer(&T2) > 0 && parent->sendPacketRTP(sentPacket)) {
-	    return (Done);
+	if (nextTimer(&T2) <= 0) {
+	    parent->sendInfo(Error, resendError);
+	    sentPacket = NULL;
+	    nextState(Initial);
+	    return (Fail);
 	}
+	if (!parent->sendPacketRTP(sentPacket)) {
+	    parent->sendInfo(Error, sendErrorText);
+	    sentPacket = NULL;
+	    nextState(Initial);
+	    return (Fail);
+	}
     }
-    // Error packet ??
-    return (Fail);
+    else {      // unknown Event type for this state
+	parent->sendInfo(Error, internalProtocolError);
+	sentPacket = NULL;
+	nextState(Initial);
+        // TODO: Error packet ??
+	return (Fail);
+    }
 }
 
+/*
+ * When entering this transition function
+ * - sentPacket contains DHPart1 packet, no timer active
+ */
 int32_t ZrtpStateClass::evWaitDHPart2(void) {
 
-    cout << "Checking for match in DHPart2.\n";
+    DEBUGOUT((cout << "Checking for match in DHPart2.\n"));
 
     char *msg, first, last;
-    ZrtpPacketBase *pkt;
+    uint8_t *pkt;
 
     if (event->type == ZrtpPacket) {
 	pkt = event->data.packet;
-	msg = pkt->getMessage();
+	msg = (char *)pkt + 4;
 	  
 	first = tolower(*msg);
 	last = tolower(*(msg+7));
@@ -350,42 +519,67 @@
 	 */
 	if (first == 'c') {
 	    if (!parent->sendPacketRTP(sentPacket)) {
-		// Huston, we have a problem
+		delete sentPacket;
+		sentPacket = NULL;
+		nextState(Initial);
+		parent->sendInfo(Error, sendErrorText);
+		return(Fail);
 	    }
 	    return (Done);
 	}
 	/*
 	 * DHPart2:
 	 * - prepare Confirm1 packet
-	 * - send it via SRTP
 	 * - switch to WaitConfirm2
+	 * - switch on security for sender, send it via SRTP
 	 * - No timer, we are responder
 	 */
 	if (first == 'd') {
-	    ZrtpPacketConfirm* confirm = 
-		parent->prepareConfirm1(static_cast<ZrtpPacketDHPart *>(pkt));
+	    delete sentPacket;     // delete DHPart1 packet
+	    sentPacket = NULL;
+	    
+	    ZrtpPacketDHPart* dpkt = new ZrtpPacketDHPart(pkt);
+	    ZrtpPacketConfirm* confirm = parent->prepareConfirm1(dpkt);
+	    delete dpkt;
+	    
+	    nextState(WaitConfirm2);
+            parent->srtpSecretsReady((EnableSecurity)(ForSender + ForReceiver));
+
 	    if (!parent->sendPacketSRTP(static_cast<ZrtpPacketBase *>(confirm))){
-		// Huston, we have a problem
+		delete confirm;
+		nextState(Initial);
+		parent->srtpSecretsOff(ForSender);
+		parent->sendInfo(Error, sendErrorTextSrtp);
+		return(Fail);
 	    }
-	    nextState(WaitConfirm2);
 	    sentPacket = static_cast<ZrtpPacketBase *>(confirm);
 	    return (Done);
 	}
     }
-    // TODO: Error packet ??
+    else {      // unknown Event type for this state
+        parent->sendInfo(Error, internalProtocolError);
+        sentPacket = NULL;
+        nextState(Initial);
+        // TODO: Error packet ?
+    }
     return (Fail);
 }
 
+/*
+ * When entering this transition function
+ * - sentPacket contains DHPart2 packet, DHPart2 timer active
+ * - Receiver security switched on
+ */
 int32_t ZrtpStateClass::evWaitConfirm1(void) {
 
-    cout << "Checking for match in WaitConfirm1.\n";
+    DEBUGOUT((cout << "Checking for match in WaitConfirm1.\n"));
 
     char *msg, first, last;
-    ZrtpPacketBase *pkt;
+    uint8_t *pkt;
 
     if (event->type == ZrtpPacket) {
 	pkt = event->data.packet;
-	msg = pkt->getMessage();
+	msg = (char *)pkt + 4;
 	  
 	first = tolower(*msg);
 	last = tolower(*(msg+7));
@@ -394,56 +588,101 @@
 	 * Confirm1:
 	 * - Switch off resending DHPart2
 	 * - prepare a Confirm2 packet 
-	 * - send via SRTP, 
+	 * - switch on sender security and send via SRTP, 
 	 * - switch to state WaitConfAck
+	 * - set timer to monitor Confirm2 packet, we are initiator
 	 */
 	if (first == 'c' && last == '1') {
-	    ZrtpPacketConfirm* confirm = 
-		parent->prepareConfirm2(static_cast<ZrtpPacketConfirm *>(pkt));
+	    cancelTimer();
+	    delete sentPacket;             // delete DHPart2 packet
+	    sentPacket = NULL;
+	    
+	    ZrtpPacketConfirm* cpkt = new ZrtpPacketConfirm(pkt, event->content);
+	    ZrtpPacketConfirm* confirm = parent->prepareConfirm2(cpkt);
+	    delete cpkt;
+	    
+	    nextState(WaitConfAck);
+	    parent->srtpSecretsReady(ForSender);	// let's try
+
 	    if (!parent->sendPacketSRTP(static_cast<ZrtpPacketBase *>(confirm))){
-		// Huston, we have a problem
+		delete confirm;
+		nextState(Initial);
+		parent->srtpSecretsOff((EnableSecurity)(ForReceiver + ForSender));
+		parent->sendInfo(Error, sendErrorText);
+		return(Fail);
 	    }
-	    nextState(WaitConfAck);
 	    sentPacket = static_cast<ZrtpPacketBase *>(confirm);
-	    startTimer(&T2);
+	    if (startTimer(&T2) <= 0) {		
+		delete sentPacket;
+		sentPacket = NULL;
+		nextState(Initial);
+		parent->srtpSecretsOff((EnableSecurity)(ForReceiver + ForSender));
+		parent->sendInfo(Error, timerError);
+		return(Fail);
+	    }
 	    return (OkDismiss);
 	}
     }
-    else {
-	// Nothing received from peer, resend DHPart2 until counter exceeds
-	if (T2.stop) {
+    else if (event->type == Timer) {
+	if (sentPacket == NULL) {      // probably a race condition - ignore
 	    return (Done);
 	}
-	if (nextTimer(&T2) > 0 && parent->sendPacketRTP(sentPacket)) {
-	    return (Done);
+	if (nextTimer(&T2) <= 0) {
+	    parent->sendInfo(Error, resendError);
+	    sentPacket = NULL;
+	    nextState(Initial);
+	    parent->srtpSecretsOff(ForReceiver);
+	    return (Fail);
 	}
+	if (!parent->sendPacketRTP(sentPacket)) {
+	    parent->sendInfo(Error, sendErrorText);
+	    sentPacket = NULL;
+	    nextState(Initial);
+	    parent->srtpSecretsOff(ForReceiver);
+	    return (Fail);
+	}
     }
-    // TODO: Error packet ??
-    return (Fail);
+    else {      // unknown Event type for this state
+	parent->sendInfo(Error, internalProtocolError);
+	sentPacket = NULL;
+	nextState(Initial);
+	parent->srtpSecretsOff(ForReceiver);
+        // TODO: Error packet ??
+	return (Fail);
+    }
 }
 
+/*
+ * When entering this transition function
+ * - sentPacket contains Confirm1 packet, no timer active
+ * - Sender security switched on
+ */
 int32_t ZrtpStateClass::evWaitConfirm2(void) {
 
-    cout << "Checking for match in WaitConfirm2.\n";
+    DEBUGOUT((cout << "Checking for match in WaitConfirm2.\n"));
 
     char *msg, first, last;
-    ZrtpPacketBase *pkt;
+    uint8_t *pkt;
 
     if (event->type == ZrtpPacket) {
 	pkt = event->data.packet;
-	msg = pkt->getMessage();
+	msg = (char *)pkt + 4;
 	  
 	first = tolower(*msg);
 	last = tolower(*(msg+7));
 
 	/*
 	 * DHPart2:
-	 * - resend Confirm2 packet via SRTP
+	 * - resend Confirm1 packet via SRTP
 	 * - stay in state
 	 */
 	if (first == 'd') {
 	    if (!parent->sendPacketSRTP(sentPacket)) {
-		// Huston, we have a problem
+		delete sentPacket;
+		sentPacket = NULL;
+		nextState(Initial);
+		parent->sendInfo(Error, sendErrorText);
+		return(Fail);
 	    }
 	    return (Done);
 	}
@@ -451,33 +690,59 @@
 	 * Confirm2:
 	 * - prepare ConfAck 
 	 * - send via SRTP
-	 * - switch to SecureState
+	 * - switch on to receiver security
+	 * - SecureState
 	 */
 	if (first == 'c' && last == '2') {
+	    delete sentPacket;             // delete Confirm1 packet
+	    sentPacket = NULL;
+	    
 	    // send ConfAck via SRTP
-	    ZrtpPacketConf2Ack* confack = 
-		parent->prepareConf2Ack(static_cast<ZrtpPacketConfirm *>(pkt));
+	    ZrtpPacketConfirm* cpkt = new ZrtpPacketConfirm(pkt, event->content);
+	    ZrtpPacketConf2Ack* confack = parent->prepareConf2Ack(cpkt);
+	    delete cpkt;
+	    
+	    nextState(SecureState);
+//	    parent->srtpSecretsReady(ForReceiver);	// let's try
+
 	    if (!parent->sendPacketSRTP(static_cast<ZrtpPacketBase *>(confack))){
-		// Huston, we have a problem
+		sentPacket = NULL;        // don't delete confAck packet, it's preconfigured
+		nextState(Initial);
+		parent->srtpSecretsOff((EnableSecurity)(ForReceiver + ForSender));
+		parent->sendInfo(Error, sendErrorTextSrtp);
+		return(Fail);
 	    }
-	    nextState(SecureState);
+	    sentPacket = static_cast<ZrtpPacketBase *>(confack);
+	    parent->sendInfo(Info, "Switching to secure state");
+
 	    return (OkDismiss);
 	}
     }
-    // TODO: Error packet ??
-    return (Fail);
+    else {      // unknown Event type for this state
+        parent->sendInfo(Error, internalProtocolError);
+        sentPacket = NULL;
+	parent->srtpSecretsOff(ForSender);
+        nextState(Initial);
+        // TODO: Error packet ??
+	return (Fail);
+    }
 }
 
+/*
+ * When entering this transition function
+ * - sentPacket contains Confirm2 packet, Confirm2 timer active
+ * - sender and receiver security switched on
+ */
 int32_t ZrtpStateClass::evWaitConfAck(void) {
 
-    cout << "Checking for match in WaitConfAck.\n";
+    DEBUGOUT((cout << "Checking for match in WaitConfAck.\n"));
 
     char *msg, first, last;
-    ZrtpPacketBase *pkt;
+    uint8_t