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