r2777 - in trunk: . build.d libmcrypto/source libminisip libminisip/include libminisip/include/libminisip libminisip/include/libminisip/mediahandler libminisip/include/libminisip/zrtp libminisip/source libminisip/source/zrtp libzrtpcpp libzrtpcpp/m4 libzrtpcpp/src libzrtpcpp/src/libzrtpcpp libzrtpcpp/src/libzrtpcpp/crypto libzrtpcpp/src/libzrtpcpp/crypto/openssl

werner at minisip.org werner at minisip.org
Fri Sep 22 21:16:34 CEST 2006


Author: werner
Date: 2006-09-22 21:16:33 +0200 (Fri, 22 Sep 2006)
New Revision: 2777

Added:
   trunk/libminisip/include/libminisip/zrtp/
   trunk/libminisip/include/libminisip/zrtp/ZrtpHostBridgeMinisip.h
   trunk/libminisip/source/zrtp/
   trunk/libminisip/source/zrtp/ZrtpHostBridgeMinisip.cxx
   trunk/libzrtpcpp/
   trunk/libzrtpcpp/ChangeLog
   trunk/libzrtpcpp/INSTALL
   trunk/libzrtpcpp/NEWS
   trunk/libzrtpcpp/README
   trunk/libzrtpcpp/bootstrap
   trunk/libzrtpcpp/configure.ac
   trunk/libzrtpcpp/libzrtpcpp.pc.in
   trunk/libzrtpcpp/m4/
   trunk/libzrtpcpp/m4/Makefile.am
   trunk/libzrtpcpp/m4/libzrtpcpp.m4
   trunk/libzrtpcpp/src/
   trunk/libzrtpcpp/src/Base32.cxx
   trunk/libzrtpcpp/src/ZIDFile.cxx
   trunk/libzrtpcpp/src/ZIDRecord.cxx
   trunk/libzrtpcpp/src/ZRtp.cxx
   trunk/libzrtpcpp/src/ZrtpPacketClearAck.cxx
   trunk/libzrtpcpp/src/ZrtpPacketCommit.cxx
   trunk/libzrtpcpp/src/ZrtpPacketConf2Ack.cxx
   trunk/libzrtpcpp/src/ZrtpPacketConfirm.cxx
   trunk/libzrtpcpp/src/ZrtpPacketDHPart.cxx
   trunk/libzrtpcpp/src/ZrtpPacketError.cxx
   trunk/libzrtpcpp/src/ZrtpPacketGoClear.cxx
   trunk/libzrtpcpp/src/ZrtpPacketHello.cxx
   trunk/libzrtpcpp/src/ZrtpPacketHelloAck.cxx
   trunk/libzrtpcpp/src/ZrtpStateClass.cxx
   trunk/libzrtpcpp/src/ZrtpTextData.cxx
   trunk/libzrtpcpp/src/libzrtpcpp/
   trunk/libzrtpcpp/src/libzrtpcpp/Base32.h
   trunk/libzrtpcpp/src/libzrtpcpp/Makefile.am
   trunk/libzrtpcpp/src/libzrtpcpp/ZIDFile.h
   trunk/libzrtpcpp/src/libzrtpcpp/ZIDRecord.h
   trunk/libzrtpcpp/src/libzrtpcpp/ZRtp.h
   trunk/libzrtpcpp/src/libzrtpcpp/ZrtpCallback.h
   trunk/libzrtpcpp/src/libzrtpcpp/ZrtpPacketBase.h
   trunk/libzrtpcpp/src/libzrtpcpp/ZrtpPacketClearAck.h
   trunk/libzrtpcpp/src/libzrtpcpp/ZrtpPacketCommit.h
   trunk/libzrtpcpp/src/libzrtpcpp/ZrtpPacketConf2Ack.h
   trunk/libzrtpcpp/src/libzrtpcpp/ZrtpPacketConfirm.h
   trunk/libzrtpcpp/src/libzrtpcpp/ZrtpPacketDHPart.h
   trunk/libzrtpcpp/src/libzrtpcpp/ZrtpPacketError.h
   trunk/libzrtpcpp/src/libzrtpcpp/ZrtpPacketGoClear.h
   trunk/libzrtpcpp/src/libzrtpcpp/ZrtpPacketHello.h
   trunk/libzrtpcpp/src/libzrtpcpp/ZrtpPacketHelloAck.h
   trunk/libzrtpcpp/src/libzrtpcpp/ZrtpStateClass.h
   trunk/libzrtpcpp/src/libzrtpcpp/ZrtpStates.h
   trunk/libzrtpcpp/src/libzrtpcpp/ZrtpTextData.h
   trunk/libzrtpcpp/src/libzrtpcpp/crypto/
   trunk/libzrtpcpp/src/libzrtpcpp/crypto/Makefile.am
   trunk/libzrtpcpp/src/libzrtpcpp/crypto/ZrtpDH.h
   trunk/libzrtpcpp/src/libzrtpcpp/crypto/hmac256.h
   trunk/libzrtpcpp/src/libzrtpcpp/crypto/openssl/
   trunk/libzrtpcpp/src/libzrtpcpp/crypto/openssl/InitializeOpenSSL.cxx
   trunk/libzrtpcpp/src/libzrtpcpp/crypto/openssl/ZrtpDH.cxx
   trunk/libzrtpcpp/src/libzrtpcpp/crypto/openssl/hmac256.cxx
   trunk/libzrtpcpp/src/libzrtpcpp/crypto/openssl/sha256.cxx
   trunk/libzrtpcpp/src/libzrtpcpp/crypto/sha256.h
   trunk/libzrtpcpp/src/libzrtpcpp/zrtpPacket.h
Modified:
   trunk/build.d/build.conf
   trunk/libmcrypto/source/init.cxx
   trunk/libminisip/Makefile.am
   trunk/libminisip/configure.ac
   trunk/libminisip/include/Makefile.am
   trunk/libminisip/include/libminisip/mediahandler/MediaStream.h
Log:
Restructure ZRTP code into own library

Modified: trunk/build.d/build.conf
===================================================================
--- trunk/build.d/build.conf	2006-09-15 18:57:59 UTC (rev 2776)
+++ trunk/build.d/build.conf	2006-09-22 19:16:33 UTC (rev 2777)
@@ -1,23 +1,25 @@
 #!/usr/bin/perl
 #######
-# minisip build system definitions 
+# minisip build system definitions
 #
 # These structuers should only be updated when the corresponding packages,
-# dependecies, or configuration options have been changed.  If you want 
+# dependecies, or configuration options have been changed.  If you want
 # to customize tehse settings, look at build.local.example.
 #
 
 
- at packages = ( qw( 
-	 libmutil libmcrypto libmnetutil 
-	 libmstun libmikey libmsip 
-	 libminisip milbc 
-	 ministun minisip 
+ at packages = ( qw(
+	 libmutil libmcrypto libmnetutil
+	 libmstun libmikey libmsip
+	 libminisip milbc libzrtpcpp
+	 ministun minisip
 	) );
 %dependencies = (
 	# core portability and platform libraries
 	libmutil => [ ],
 	libmcrypto => [ 'libmutil' ],
+        libzrtpcpp => [ 'libmutil' ],
+
 	libmnetutil => [ qw( libmutil libmcrypto ) ],
 
 	# IETF RFC standard libraries
@@ -26,19 +28,19 @@
 	libmsip => [ qw( libmutil libmcrypto libmnetutil ) ],
 
 	# libminsip; thar be 'ar kitchen sink, mateys.
-	libminisip => [ qw( 
-		  libmutil libmcrypto libmnetutil 
-		  libmstun libmikey libmsip
+	libminisip => [ qw(
+		  libmutil libmcrypto libmnetutil
+		  libmstun libmikey libmsip libzrtpcpp
 		) ],
 	# sound codecs
 	milbc => [ qw(
-		  libmutil libmcrypto libmnetutil libmikey libmsip libminisip 
+		  libmutil libmcrypto libmnetutil libmikey libmsip libminisip
 		) ],
 
 	# applications
 	ministun => [ qw( libmutil libmcrypto libmnetutil libmstun ) ],
-	minisip => [ qw( 
-		  libmutil libmcrypto libmnetutil libmikey libmsip libminisip 
+	minisip => [ qw(
+		  libmutil libmcrypto libmnetutil libmikey libmsip libminisip
 		) ],
 );
 
@@ -61,6 +63,11 @@
 	openssl => undef,	# specifies location of openssl files
 	gnutls => undef,	# specifies location of gnutls files
 );
+
+my %libzrtp_params = (
+        %common_params,
+);
+
 my %libmnetutil_params = (
 	%common_params,
 	ipv6 => 1,	# enables IPV6 support
@@ -83,7 +90,7 @@
 	%common_minisip_params,
 	aec => 0,	# enables automatic echo cancellation features
 	alsa => 0,	# enables ALSA sound support
-	avcodec => undef,	# specifies location of avcodec 
+	avcodec => undef,	# specifies location of avcodec
 	'avcodec-fixes' => 0,	# enables support for new libavcodec abi
 	buzzer => 0, 	# enables buzzer support on iPAQ
 	dsound => 0,	# enables DirectSound support
@@ -116,6 +123,7 @@
 %configure_params = (
 	libmutil => \%libmutil_params,
 	libmcrypto => \%libmcrypto_params,
+        libzrtpcpp => \%libzrtp_params,
 	libmnetutil => \%libmnetutil_params,
 
 	libmstun => \%libmstun_params,

Modified: trunk/libmcrypto/source/init.cxx
===================================================================
--- trunk/libmcrypto/source/init.cxx	2006-09-15 18:57:59 UTC (rev 2776)
+++ trunk/libmcrypto/source/init.cxx	2006-09-22 19:16:33 UTC (rev 2777)
@@ -31,7 +31,7 @@
 
 #include <config.h>
 
-void libmcryptoInit() 
+void libmcryptoInit()
 {
 #ifdef HAVE_OPENSSL
 	OpensslThreadGuard::initialize();
@@ -45,16 +45,16 @@
 
 std::vector<Mutex*> CryptoThreadGuard::guards;
 
-CryptoThreadGuard::CryptoThreadGuard() 
+CryptoThreadGuard::CryptoThreadGuard()
 {
 	this->changeGuards(1);
 }
-CryptoThreadGuard::~CryptoThreadGuard() 
+CryptoThreadGuard::~CryptoThreadGuard()
 {
 	this->changeGuards(0);
 }
 
-void CryptoThreadGuard::changeGuards(bool onDuty) 
+void CryptoThreadGuard::changeGuards(bool onDuty)
 {
 	int num_locks = this->numLocks();
 	this->guards.reserve(num_locks);
@@ -66,7 +66,7 @@
 	}
 }
 
-void CryptoThreadGuard::setLock(int i, bool isSet) 
+void CryptoThreadGuard::setLock(int i, bool isSet)
 {
 	if (isSet) {
 		this->guards[i]->lock();

Modified: trunk/libminisip/Makefile.am
===================================================================
--- trunk/libminisip/Makefile.am	2006-09-15 18:57:59 UTC (rev 2776)
+++ trunk/libminisip/Makefile.am	2006-09-22 19:16:33 UTC (rev 2777)
@@ -102,6 +102,10 @@
 			source/p2t/P2T.cxx
 endif
 
+if ZRTP_SUPPORT
+libzrtp_src = source/zrtp/ZrtpHostBridgeMinisip.cxx
+endif
+
 librtp_src = source/rtp/RtpHeader.cxx \
 		source/rtp/RtpPacket.cxx \
 		source/rtp/CryptoContext.cxx \

Modified: trunk/libminisip/configure.ac
===================================================================
--- trunk/libminisip/configure.ac	2006-09-15 18:57:59 UTC (rev 2776)
+++ trunk/libminisip/configure.ac	2006-09-22 19:16:33 UTC (rev 2777)
@@ -49,7 +49,7 @@
 
 dnl debug flag
 AC_ARG_ENABLE(autocall,
-    AS_HELP_STRING([--enable-autocall], 
+    AS_HELP_STRING([--enable-autocall],
     	[enables automatic calling for debug purposes (default disabled)]),
     [ if test "${enable_autocall}" = "yes"
       then
@@ -67,8 +67,8 @@
 
 dnl debug flag
 AC_ARG_ENABLE(memdebug,
-    AS_HELP_STRING([--enable-memdebug], [enables memory debugging code. 
-    WARNING: This changes the MemObject API that is used by both libraries 
+    AS_HELP_STRING([--enable-memdebug], [enables memory debugging code.
+    WARNING: This changes the MemObject API that is used by both libraries
     and applications. Use with care (default disabled)]),
     [ if test "${enable_memdebug}" = "yes"
       then
@@ -80,7 +80,7 @@
 
 dnl ipaq buzzer
 AC_ARG_ENABLE(buzzer,
-    AS_HELP_STRING([--enable-buzzer], 
+    AS_HELP_STRING([--enable-buzzer],
     	[enables IPAQ buzzer (default disabled)]),
     [ if test "${enable_buzzer}" = "yes" -o "${enable_ipaq}" = "yes"
       then
@@ -91,7 +91,7 @@
 
 dnl OSS support
 AC_ARG_ENABLE(oss,
-    AS_HELP_STRING([--disable-oss], 
+    AS_HELP_STRING([--disable-oss],
     	[disables OSS sound IO support (default enabled)]),
 )
 if test "${enable_oss}" = "no"
@@ -116,7 +116,7 @@
 
 
 dnl Check for libsamplerate
-AC_CHECK_HEADER([samplerate.h], 
+AC_CHECK_HEADER([samplerate.h],
 	[
 		AC_CHECK_LIB([samplerate], [main],
 			[SAMPLERATE_LIBS="-lsamplerate"
@@ -130,7 +130,7 @@
 AC_SUBST(SAMPLERATE_LIBS)
 
 dnl Check for stack trace support
-AC_CHECK_HEADER([execinfo.h], 
+AC_CHECK_HEADER([execinfo.h],
 	[
 		AC_DEFINE(HAS_EXECINFO, [], [Stack trace functionality found])
 			HAS_EXECINFO="yes"
@@ -139,7 +139,7 @@
 AM_CONDITIONAL(HAS_EXECINFO, test "${HAS_EXECINFO}" = "yes")
 
 dnl Check for libspeex
-AC_CHECK_HEADER([speex/speex.h], 
+AC_CHECK_HEADER([speex/speex.h],
 	[
 		AC_CHECK_LIB([speex], [speex_encoder_init],
 			[SPEEX_LIBS="-lspeex"
@@ -151,7 +151,7 @@
 AC_SUBST(SPEEX_LIBS)
 
 dnl Check for libgsm
-AC_CHECK_HEADER([gsm.h], 
+AC_CHECK_HEADER([gsm.h],
 	[
 		AC_CHECK_LIB([gsm], [gsm_encode],
 			[GSM_LIBS="-lgsm"
@@ -223,7 +223,7 @@
 AM_CONDITIONAL(AEC_SUPPORT, test "${enable_aec}" = "yes")
 
 AC_ARG_ENABLE(gconf,
-    AS_HELP_STRING([--enable-gconf], 
+    AS_HELP_STRING([--enable-gconf],
     	[enables support for GConf (default disabled).])
    )
 
@@ -261,7 +261,7 @@
        fi ])
 
 AC_ARG_ENABLE(video,
-    AS_HELP_STRING([--enable-video], 
+    AS_HELP_STRING([--enable-video],
     	[enables video features (default disabled)]),
     [ if test "${enable_video}" = "yes"
       then
@@ -279,7 +279,7 @@
 	  FFMPEG_CFLAGS=
 	  FFMPEG_LIBS="-lavcodec -lz"
 	fi
-        
+
 	LIBS="${FFMPEG_LIBS} ${LIBS}"
 	CPPFLAGS="${CPPFLAGS} ${FFMPEG_CFLAGS} ${AVCODEC_CPPFLAGS}"
 	LDFLAGS="${LDFLAGS} ${AVCODEC_LDFLAGS}"
@@ -287,12 +287,12 @@
 	  AC_CHECK_HEADER([avcodec.h], [],
             [
               AC_MSG_ERROR(
-	      [Could not locate avcodec header files. Please install 
+	      [Could not locate avcodec header files. Please install
                the libavcodec-devel package.]
               )
             ]
           )
-            
+
 	  AC_CHECK_LIB([avcodec], [main], [], [AC_MSG_ERROR(
 	    [Could not locate libavcodec, required for video features.])])
 
@@ -302,7 +302,7 @@
 	CPPFLAGS="${CPPFLAGS_SAVE}"
 	LDFLAGS="${LDFLAGS_SAVE}"
 	LIBS="${LIBS_SAVE}"
-        
+
 dnl look for V4L headers
         AC_CHECK_HEADERS([linux/videodev.h],
           [VIDEO_GRABBER="${VIDEO_GRABBER} v4l"
@@ -313,7 +313,7 @@
 	   AC_CHECK_LIB([raw1394],[main], [
 	     AC_CHECK_LIB([dc1394_control],[main], [
 	       VIDEO_GRABBER="${VIDEO_GRABBER} dc1394}"
-	       DC1394_VIDEO_GRABBER="yes" 
+	       DC1394_VIDEO_GRABBER="yes"
 	       AC_DEFINE(DC1394_SUPPORT, [], [Compile DC1394 support])
 	       DC1394_LIBS="-ldc1394_control -lraw1394"
 	       ], [], [-lraw1394])
@@ -345,7 +345,7 @@
 	  XV_LIBS="-lXv"
 	  VIDEO_DISPLAY="${VIDEO_DISPLAY} xv"
 	  AC_DEFINE(XV_SUPPORT, [], [Compile Xvideo support])
-	  XV_VIDEO_DISPLAY="yes" 
+	  XV_VIDEO_DISPLAY="yes"
 	fi
 
 dnl check for SDL
@@ -355,7 +355,7 @@
                if test "x${enable_sdl}" != "xno"
                then
 	         VIDEO_DISPLAY="${VIDEO_DISPLAY} sdl"
-	         SDL_VIDEO_DISPLAY="yes" 
+	         SDL_VIDEO_DISPLAY="yes"
 	         AC_DEFINE(SDL_SUPPORT, [], [Compile SDL support])
                  X_EXTRA_LIBS="${X_EXTRA_LIBS} -lXext"
 		 SDL_LIBS="-lSDL -pthread"
@@ -365,15 +365,15 @@
                fi
 	     ], [], [${X_EXTRA_LIBS} -lXext ${XV_LIBS} ${X_LIBS} -lpthread] )
 	  ])
-	
+
 	CPPFLAGS="${CPPFLAGS_SAVE}"
 	LDFLAGS="${LDFLAGS_SAVE}"
 	LIBS="${LIBS_SAVE}"
-	
+
 	if test "x${VIDEO_DISPLAY}" != "x"
 	then
 	  AC_DEFINE(VIDEO_SUPPORT, [], [Compile video features])
-	  
+
 	  AC_SUBST(FFMPEG_LIBS)
 	  AC_SUBST(FFMPEG_CFLAGS)
 	  AC_SUBST(AVCODEC_LDFLAGS)
@@ -394,11 +394,11 @@
 
 
 
-      
 
+
 dnl ALSA sound interface
 AC_ARG_ENABLE(alsa,
-    AS_HELP_STRING([--enable-alsa], 
+    AS_HELP_STRING([--enable-alsa],
     	[enables ALSA sound support (default disabled)]),
     [ if test "${enable_alsa}" = "yes"
       then
@@ -414,11 +414,11 @@
 
 dnl DirectSound sound interface
 AC_ARG_ENABLE(dsound,
-    AS_HELP_STRING([--enable-dsound], 
+    AS_HELP_STRING([--enable-dsound],
     	[enables DirectSound sound support (default disabled)]),
     [ if test "${enable_dsound}" = "yes"
       then
-        AC_DEFINE(DSOUND, [], [Use DirectSound sound driver]) 
+        AC_DEFINE(DSOUND, [], [Use DirectSound sound driver])
       fi ])
 
 if test ! x$enable_dsound = xno; then
@@ -456,6 +456,7 @@
 AM_MINISIP_CHECK_LIBMSTUN([0.5.0])
 AM_MINISIP_CHECK_LIBMSIP([0.3.1])
 AM_MINISIP_CHECK_LIBMIKEY([0.4.1])
+AM_MINISIP_CHECK_LIBZRTPCPP([0.9.0])
 
 AM_MINISIP_CHECK_COMPLETE
 

Modified: trunk/libminisip/include/Makefile.am
===================================================================
--- trunk/libminisip/include/Makefile.am	2006-09-15 18:57:59 UTC (rev 2776)
+++ trunk/libminisip/include/Makefile.am	2006-09-22 19:16:33 UTC (rev 2777)
@@ -115,7 +115,8 @@
 			libminisip/ipprovider/StunIpProvider.h \
 			libminisip/ipprovider/IpProvider.h \
 			libminisip/Minisip.h \
-			libminisip/libminisip_config.h
+			libminisip/libminisip_config.h \
+			libminisip/zrtp/ZrtpHostBridgeMinisip.h
 
 
 noinst_HEADERS = 	config.h

Modified: trunk/libminisip/include/libminisip/mediahandler/MediaStream.h
===================================================================
--- trunk/libminisip/include/libminisip/mediahandler/MediaStream.h	2006-09-15 18:57:59 UTC (rev 2776)
+++ trunk/libminisip/include/libminisip/mediahandler/MediaStream.h	2006-09-22 19:16:33 UTC (rev 2777)
@@ -1,22 +1,22 @@
 /*
  Copyright (C) 2004-2006 the Minisip Team
- 
+
  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.
- 
+
  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.
- 
+
  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  */
 
-/* Copyright (C) 2004, 2005 
+/* Copyright (C) 2004, 2005
  *
  * Authors: Erik Eliasson <eliasson at it.kth.se>
  *          Johan Bilien <jobi at via.ecp.fr>
@@ -57,7 +57,7 @@
 		 * Starts the transmission or reception of a the stream.
 		 */
 		virtual void start() = 0;
-		
+
 		/**
 		 * Stops the transmission or reception of a the stream.
 		 */
@@ -66,7 +66,7 @@
 #ifdef DEBUG_OUTPUT
 		virtual std::string getDebugString();
 #endif
-		
+
 		/**
 		 * Returns the media type corresponding to this stream
 		 * (video, audio...) as it appears in the session
@@ -85,7 +85,7 @@
 
 		virtual std::string getMemObjectType(){return "MediaStream";}
 		bool disabled;
-		
+
 		/**
 		 * Used to query the port on which the media is received for
 		 * a receiver, respectively where it is sent to for a sender
@@ -104,7 +104,7 @@
 		 * @returns whether or not this media stream corresponds
 		 * to the description in the m: header.
 		 */
-		virtual bool matches( MRef<SdpHeaderM *> m, 
+		virtual bool matches( MRef<SdpHeaderM *> m,
 					uint32_t formatIndex );
 
 		/**
@@ -155,13 +155,13 @@
 		 */
 		void setKeyAgreementZrtp(MRef<CryptoContext *>cx);
 #endif
-		
+
 	protected:
 		MRef<CryptoContext *> getCryptoContext( uint32_t ssrc, uint16_t seq_no );
 		MediaStream( MRef<Media *> );
 		MRef<Media *> media;
 		uint32_t csbId;
-		
+
 		uint8_t localPayloadType;
 
 		MRef<CryptoContext *> initCrypto( uint32_t ssrc, uint16_t seq_no );
@@ -178,12 +178,12 @@
  * given session. It is responsible for decryption and replay protection
  * in the case of SRTP.
  */
-class LIBMINISIP_API MediaStreamReceiver : public MediaStream{ 
+class LIBMINISIP_API MediaStreamReceiver : public MediaStream{
 	public:
 		/**
 		 * Constructor, called by the MediaHandler when creating
 		 * a new media session.
-		 * @param media a reference to the Media object 
+		 * @param media a reference to the Media object
 		 * that will process
 		 * incoming data on this receiver.
 		 * @param rtpReceiver a reference to the RtpReceiver object
@@ -193,8 +193,8 @@
 		 * used to obtain contact IP address and port in NAT
 		 * traversal mechanism
 		 */
-		MediaStreamReceiver( MRef<Media *> media, 
-				MRef<RtpReceiver *> rtpReceiver, 
+		MediaStreamReceiver( MRef<Media *> media,
+				MRef<RtpReceiver *> rtpReceiver,
 				MRef<RtpReceiver *> rtp6Receiver = NULL );
 
 #ifdef DEBUG_OUTPUT
@@ -202,19 +202,19 @@
 #endif
 
 		virtual std::string getMemObjectType(){return "MediaStreamReceiver";}
-	
+
 		/**
 		 * Starts the reception of a the stream, by subscribing to
 		 * the RtpReceiver.
 		 */
 		virtual void start();
-		
+
 		/**
 		 * Stops the reception of a stream, by unsubscribing to
 		 * the RtpReceiver.
 		 */
 		virtual void stop();
-		
+
 		/**
 		 * Used to query which port should be advertised as
 		 * the contact port in the session description.
@@ -254,7 +254,7 @@
 		 * according to the user's preference, first being preferred
 		 */
 		std::list<MRef<Codec *> > getAvailableCodecs();
-		
+
 		std::list<uint32_t> getSsrcList() {
 			return ssrcList;
 		}
@@ -294,7 +294,7 @@
 		Mutex ssrcListLock;
 
 		bool running;
-		
+
 };
 
 /**
@@ -302,7 +302,7 @@
  * a specific media Session. It holds the CODEC instance selected for
  * this peer, and is responsible for encryption.
  */
-class LIBMINISIP_API MediaStreamSender : public MediaStream{ 
+class LIBMINISIP_API MediaStreamSender : public MediaStream{
 	public:
 		/**
 		 * Constructor, used by the MediaHandler during the
@@ -313,14 +313,14 @@
 		 * to which the data should be sent. If NULL a new one
 		 * is created
 		 */
-		MediaStreamSender( MRef<Media *> media, 
+		MediaStreamSender( MRef<Media *> media,
 				   MRef<UDPSocket *> senderSock=NULL,
 				   MRef<UDPSocket *> sender6Sock=NULL );
 
 #ifdef DEBUG_OUTPUT
 		virtual std::string getDebugString();
 #endif
-		
+
 		virtual std::string getMemObjectType(){return "MediaStreamSender";}
 
 		/**
@@ -329,13 +329,13 @@
 		 * @returns a reference to the CodecState object
 		 */
 		MRef<CodecState *> getSelectedCodec(){return selectedCodec;};
-		
+
 		/**
 		 * Starts the transmission of the stream, by
 		 * subscribing to the Media for data.
 		 */
 		virtual void start();
-		
+
 		/**
 		 * Stops the transmission, by unsubscribing to the
 		 * Media.
@@ -358,7 +358,7 @@
 		 * data, or 0 if it was not set
 		 */
 		virtual uint16_t getPort();
-		
+
 		/**
 		 * Used by the Media to send data, if the MediaStreamSender
 		 * has subscribed to the Media. The data will be encrypted
@@ -392,12 +392,12 @@
                  * @param payLen
                  *    Length of payload in bytes
 		 */
-		void sendZrtp(unsigned char* data, int length, 
+		void sendZrtp(unsigned char* data, int length,
                               unsigned char* payload, int payLen);
-		
+
 		/**
 		 * Get the current Seq number of this packet
-		 * 
+		 *
 		 * @return
 		 *     The sender current sequence number.
 		 */
@@ -413,7 +413,7 @@
 		 * which represents the peer's contact IP address
 		 */
 		void setRemoteAddress( MRef<IPAddress *> remoteAddress );
-		
+
 		/**
 		 * Used to mute or unmute this sender, resulting
 		 * in it sending or not sending the data it receives
@@ -437,7 +437,7 @@
 		 * keep alive packet should be sent
 		 */
 		bool muteKeepAlive( uint32_t max);
-		
+
 		/**
 		 * Used to check a m: header in a session description
 		 * against the media stream for compatibility. In
@@ -461,10 +461,10 @@
 		 * @returns the SSRC identifier used by this MediaStreamSender
 		 */
 		uint32_t getSsrc();
-		
+
 		void increaseLastTs( ) { lastTs += 160; };
 		uint32_t getLastTs() { return lastTs; };
-		
+
 	private:
 		uint32_t ssrc;
 		MRef<UDPSocket *> senderSock;
@@ -474,14 +474,14 @@
 		uint32_t lastTs;
 		MRef<IPAddress *> remoteAddress;
 		Mutex senderLock;
-		
+
 		uint8_t payloadType;
 		MRef<CodecState *> selectedCodec;
-		
+
 		//Cesc -- does it conflict with bool disabled???
 		bool muted;
 		uint32_t muteCounter;
-		
+
 };
 
 #endif

Added: trunk/libminisip/include/libminisip/zrtp/ZrtpHostBridgeMinisip.h
===================================================================
--- trunk/libminisip/include/libminisip/zrtp/ZrtpHostBridgeMinisip.h	2006-09-15 18:57:59 UTC (rev 2776)
+++ trunk/libminisip/include/libminisip/zrtp/ZrtpHostBridgeMinisip.h	2006-09-22 19:16:33 UTC (rev 2777)
@@ -0,0 +1,352 @@
+/*
+  Copyright (C) 2006 Werner Dittmann
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+
+/*
+ * Authors: Werner Dittmann <Werner.Dittmann at t-online.de>
+ */
+
+
+#ifndef _ZIDHOSTBRIDGEMINISIP_H_
+#define _ZIDHOSTBRIDGEMINISIP_H_
+
+#ifdef ZRTP_SUPPORT
+// #include<libminisip/libminisip_config.h>
+
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <libmutil/StateMachine.h>
+#include <libmutil/MessageRouter.h>
+#include <libmsip/SipSMCommand.h>
+
+#include <libminisip/mediahandler/MediaStream.h>
+#include <libminisip/rtp/SRtpPacket.h>
+#include <libminisip/rtp/CryptoContext.h>
+
+#include <libzrtpcpp/ZrtpCallback.h>
+#include <libzrtpcpp/ZRtp.h>
+
+/**
+ * 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 call functions of the
+ * hosting SIP client. In this case the host is Minisip.
+ *
+ * <p/>
+ *
+ * As required by ZRTP base implementation the bridge implements
+ * the ZrtpCallback interface.
+ *
+ * <p/>
+ *
+ * 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>
+ *
+ * ZrtpHostBridge::initialize(sip->getSipStack()->getTimeoutProvider(),
+filename?);
+ *
+ * <br/>
+ *
+ * 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 {
+
+ public:
+
+    virtual std::string getMemObjectType() { return "ZrtpHostBridgeMinisip";}
+
+    /**
+     * Initialize the host bridge.
+     *
+     * 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
+     *    same as defined for the SIP stack.
+     * @param zidFilename
+     *    Optional filename for the ZID file.
+     * @return
+     *    TODO
+     */
+    static int32_t initialize(MRef<TimeoutProvider<std::string,
+MRef<StateMachine<SipSMCommand,std::string>*> > *> tp,
+		     const char *zidFilename =NULL);
+
+    ZrtpHostBridgeMinisip(std::string id, MRef<CommandReceiver*> callback);
+    ~ZrtpHostBridgeMinisip();
+
+
+    void start();
+    void stop();
+
+    void setReceiver(MRef<MediaStreamReceiver *> r);
+    void setSsrcReceiver(uint32_t ssrc)             { receiverSsrc = ssrc; };
+    uint32_t getSsrcReceiver()                      { return receiverSsrc; };
+
+    void setSender(MRef<MediaStreamSender *> s);
+    void setSsrcSender(uint32_t ssrc)               { senderSsrc = ssrc; };
+    uint32_t getSsrcSender()                        { return senderSsrc; };
+
+    bool isSecureState();
+
+    void setCallId(std::string id)                  { callId = id; }
+    /**
+     * Set the IP address of our remote peer.
+     *
+     * 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.
+     *
+     * @param ra
+     *    The IP address of our remote peer
+     */
+    void setRemoteAddress(MRef<IPAddress *> ra) { remoteAddress = ra; };
+
+    /**
+     * Get the IP address of our remote peer.
+     *
+     * @return
+     *    The IP address of our remote peer.
+     */
+    MRef<IPAddress *> getRemoteAddress() { return remoteAddress; };
+
+    /**
+     * 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
+     * process it. Otherwise just return to the caller for further
+     * processing of the packet.
+     *
+     * <p/>
+     *
+     * Depending on the contents of the packet and the protocol state
+     * the method returns a indication to either dismiss the payload
+     * data or process it as usual.
+     *
+     * @param packet
+     *   A (S)Rtp packet to process
+     * @return
+     *    Returns 0 if the caller shall dismiss the payload, 1 otherwise.
+     */
+    int32_t processPacket(MRef<SRtpPacket *> packet);
+
+    /**
+     * Handle timeout event forwarded by Minisip's (SipStack)
+     * TimeoutProvider.
+     *
+     * Just call the ZRTP engine for further processing.
+     */
+    void handleTimeout(const std::string & /* c */ ) {
+        if (zrtpEngine != NULL) {
+            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,
+		         char *dataContent, int32_t lengthContent);
+
+    int32_t activateTimer(int32_t time) {
+	std::string s("ZRTP");
+	requestTimeout(time, s);
+	return 1;
+    };
+
+    int32_t cancelTimer() {
+	std::string s("ZRTP");
+	cancelTimeout(s);
+	return 1;
+    };
+
+    void sendInfo(MessageSeverity severity, char* msg) {
+	fprintf(stderr, "Severity: %d - %s\n", severity, msg);
+    }
+
+    /**
+     * This method shall handle GoClear requests.
+     *
+     * According to the ZRTP specification the user must be informed about
+     * this message because the ZRTP implementation switches off security
+     * if it could authenticate the GoClear packet.
+     *
+     */
+    void handleGoClear() {
+        fprintf(stderr, "Need to process a GoClear message!");
+    }
+
+    /**
+     * Switch on the security for the defined part.
+     *
+     * Create an CryproContext with the negotiated ZRTP data and
+     * register it with the respective part (sender or receiver) thus
+     * replacing the current active context (usually an empty
+     * context). This effectively enables SRTP.
+     *
+     * @param secrets
+     *    The secret keys and salt negotiated by ZRTP
+     * @param part
+     *    An enum that defines sender, receiver, or both.
+     */
+    void srtpSecretsReady(SrtpSecret_t* secrets, EnableSecurity part);
+
+    /**
+     * Switch off the security for the defined part.
+     *
+     * Create an empty CryproContext and register it with the
+     * repective part (sender or receiver) thus replacing the current
+     * active context. This effectively disables SRTP.
+     *
+     * @param part
+     *    An enum that defines sender, receiver, or both.
+     */
+    void srtpSecretsOff(EnableSecurity part);
+
+    /**
+     * ZRTP calls this if the negotiation failed.
+     *
+     * ZRTP calls this method in case ZRTP negotiation failed. The parameters
+     * show the severity as well as some explanatory text.
+     * Refer to the <code>MessageSeverity</code> enum above.
+     *
+     * @param severity
+     *     This defines the message's severity
+     * @param msg
+     *     The message string, terminated with a null byte.
+         */
+    void zrtpNegotiationFailed(MessageSeverity severity, char* msg);
+
+    /**
+     * ZRTP calls this methof if the other side does not support ZRTP.
+     *
+     * If the other side does not answer the ZRTP <em>Hello</em> packets then
+     * ZRTP calls this method,
+     *
+     */
+    void zrtpNotSuppOther();
+
+    /**
+     * This method switches off secure state because of a session
+     * error.
+     *
+     * The receiver detected a wrong SSRC during a session with our
+     * remote peer. This could indicate a security problem - just
+     * disable SRTP and alert the user.
+     */
+    void rtpSessionError();
+
+    /**
+     * Set the zfoneDeadBeef flag.
+     *
+     * This flag indicates the special Zfone maker SSRC 0xdeadbeef.
+     *
+     * @param onOff
+     *     A value of one indicates that we detected a marker SSRC.
+     */
+    void setZfoneDeadBeef(int8_t onOff)  { zfoneDeadBeef = onOff; }
+
+    /**
+     * Get the zfoneDeadBeef flag.
+     *
+     * This flag indicates the special Zfone maker SSRC 0xdeadbeef.
+     *
+     * @return the value of zfoneDeadBeef flag. One indicates that
+     *     we detected a marker SSRC
+     */
+    int8_t getZfoneDeadBeef()           {return zfoneDeadBeef; }
+
+    uint16_t getZrtpSendSeqNo()         { return senderZrtpSeqNo++; }
+
+    uint32_t getZrtpSendSsrc()          { return senderZrtpSsrc; }
+
+    MRef<CryptoContext *> newCryptoContextForRecvSSRC(uint32_t ssrc, int roc, uint16_t seq,
+                                                      int64_t keyDerivRate);
+
+    bool isZrtpPacket(MRef<SRtpPacket *> packet);
+
+ private:
+    ZRtp *zrtpEngine;
+    SrtpSecret_t secret;
+    int32_t secureParts;
+
+    MRef<IPAddress *> remoteAddress;
+
+    MRef<MediaStreamReceiver *> rStream;
+    uint32_t receiverSsrc;
+    uint32_t receiverSecure;
+    uint16_t receiverSeqNo;
+
+    MRef<MediaStreamSender *> sStream;
+    uint32_t senderSsrc;
+    uint32_t senderSecure;
+
+    bool enableZrtp;
+
+    uint32_t recvZrtpSsrc;
+    uint16_t recvZrtpSeqNo;
+    MRef<CryptoContext *> recvCryptoContext;
+
+    uint32_t senderZrtpSsrc;
+    uint16_t senderZrtpSeqNo;
+    MRef<CryptoContext *> senderCryptoContext;
+
+    /*
+     * The call id of our call
+     */
+    std::string callId;
+
+    MRef<CommandReceiver*> messageRouterCallback;
+
+    /**
+     * This flag is true if we saw the special <em>0xdeadbeef</em> marker
+     * SSRC. The Zfone implementation uses this in its ZRTP packets. Other
+     * ZRTP implementation may not require such a marker SSRC.
+     * (maybe even Zfone could live without it but ...)
+     */
+    int8_t zfoneDeadBeef;
+};
+
+#endif // ZRTP_SUPPORT
+
+#endif // _ZIDHOSTBRIDGEMINISIP_H_


Property changes on: trunk/libminisip/include/libminisip/zrtp/ZrtpHostBridgeMinisip.h
___________________________________________________________________
Name: svn:eol-style
   + native

Added: trunk/libminisip/source/zrtp/ZrtpHostBridgeMinisip.cxx
===================================================================
--- trunk/libminisip/source/zrtp/ZrtpHostBridgeMinisip.cxx	2006-09-15 18:57:59 UTC (rev 2776)
+++ trunk/libminisip/source/zrtp/ZrtpHostBridgeMinisip.cxx	2006-09-22 19:16:33 UTC (rev 2777)
@@ -0,0 +1,354 @@
+/*
+  Copyright (C) 2006 Werner Dittmann
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+/*
+ * Authors: Werner Dittmann <Werner.Dittmann at t-online.de>
+ */
+
+#include <config.h>
+
+#include <libminisip/zrtp/ZrtpHostBridgeMinisip.h>
+#include <libzrtpcpp/ZIDFile.h>
+#include <libzrtpcpp/ZrtpStateClass.h>
+
+#include <libmikey/MikeyPayloadSP.h>
+#include <libminisip/configbackend/UserConfig.h>
+#include <libmutil/CommandString.h>
+
+#ifdef ZRTP_SUPPORT
+
+static MRef<TimeoutProvider<std::string, MRef<StateMachine<SipSMCommand,std::string>*> > *>staticTimeoutProvider;
+
+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((char *)zidFilename);
+    return 1;
+}
+
+ZrtpHostBridgeMinisip::ZrtpHostBridgeMinisip(std::string id, MRef<CommandReceiver*> callback):
+        StateMachine<SipSMCommand, std::string>(staticTimeoutProvider),
+        callId(id),
+        messageRouterCallback(callback) {
+
+    secureParts = 0;
+    zrtpEngine = NULL;
+
+    senderSecure = 0;
+    receiverSecure = 0;
+
+    receiverSsrc = 0;
+    senderSsrc = 0;
+
+    rStream = NULL;
+    sStream = NULL;
+
+    senderCryptoContext = NULL;
+    senderZrtpSsrc = 0xdeadbeef;         // may be a different value (random) as well
+    senderZrtpSeqNo = 1;
+
+    recvCryptoContext = NULL;
+}
+
+ZrtpHostBridgeMinisip::~ZrtpHostBridgeMinisip() {
+
+    cancelTimer();
+    freeStateMachine();		// to clean up the TimeoutProvider
+    delete zrtpEngine;
+}
+
+void ZrtpHostBridgeMinisip::setReceiver(MRef<MediaStreamReceiver *> r) {
+	rStream = r;
+}
+
+void ZrtpHostBridgeMinisip::setSender(MRef<MediaStreamSender *> s) {
+	sStream = s;
+}
+
+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;
+}
+
+bool ZrtpHostBridgeMinisip::isZrtpPacket(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 true;
+    }
+    return false;
+}
+
+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 and no other
+     * content return zero to dismiss packet, otherwise return 1 for further
+     * actions. This can happen for "piggy-back" ZRTP packets.
+     */
+    if (zrtpEngine == NULL) {
+        if (packet->getContentLength() > 0) {
+            return  1;
+        }
+        else {
+            return 0;
+        }
+    }
+    recvZrtpSeqNo = packet->getHeader().getSeqNo();
+    recvZrtpSsrc = packet->getHeader().getSSRC();
+
+    if (zrtpEngine->handleGoClear(extHeader)) {
+        return 0;
+    }
+    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, e.g.
+    // in case of "piggy-back" ZRTP packets.
+    return ((ret == Fail || ret == Done) ? 1 : 0);
+}
+
+bool ZrtpHostBridgeMinisip::isSecureState()
+{
+    return zrtpEngine->checkState(SecureState);
+}
+
+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 *> pcc;
+
+    if (part == ForSender) {
+    // encrypting packets, intiator uses initiator keys, responder uses responders keys
+	if (secrets->role == Initiator) {
+            senderCryptoContext = new CryptoContext(
+		    0,
+                    0,
+                    0,
+                    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 {
+            senderCryptoContext = new CryptoContext(
+		    0,
+                    0,
+                    0,
+                    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
+        }
+        pcc = senderCryptoContext->newCryptoContextForSSRC(senderZrtpSsrc, 0, senderZrtpSeqNo, 0L);
+        pcc->derive_srtp_keys(senderZrtpSeqNo);
+        sStream->setKeyAgreementZrtp(pcc);
+
+        // create a crypto context for real SSRC sender stream. Note: this
+        // can be done at this point only if the key derivation rate is 0
+        // (disabled) or greater 2^16. For ZRTP this is the case: the key
+        // derivation is defined as 2^48 which is effectively 0.
+        pcc = senderCryptoContext->newCryptoContextForSSRC(senderSsrc, 0, sStream->getSeqNo(), 0L);
+        pcc->derive_srtp_keys(sStream->getSeqNo());
+        sStream->setKeyAgreementZrtp(pcc);
+
+        secureParts++;
+    }
+    if (part == ForReceiver) {
+    // decrypting packets, intiator uses responder keys, responder initiator keys
+	if (secrets->role == Initiator) {
+            recvCryptoContext = new CryptoContext(
+		    0,
+                    0,
+                    0,
+                    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 {
+            recvCryptoContext = new CryptoContext(
+		    0,
+                    0,
+                    0,
+                    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
+	}
+        pcc = recvCryptoContext->newCryptoContextForSSRC(recvZrtpSsrc, 0, recvZrtpSeqNo, 0L);
+        pcc->derive_srtp_keys(recvZrtpSeqNo);
+        rStream->setKeyAgreementZrtp(pcc);
+
+        secureParts++;
+    }
+    if (secureParts == 2) {
+        CommandString cmd(callId, "zrtp_security_change", "secure", secrets->sas);
+        messageRouterCallback->handleCommand("gui", cmd);
+    }
+}
+
+MRef<CryptoContext *>
+ZrtpHostBridgeMinisip::newCryptoContextForRecvSSRC(uint32_t ssrc, int roc,
+                                                   uint16_t seq,
+                                                   int64_t keyDerivRate)
+{
+    MRef<CryptoContext *> pcc;
+
+    pcc = recvCryptoContext->newCryptoContextForSSRC(ssrc, roc, seq, keyDerivRate);
+    pcc->derive_srtp_keys(seq);
+    rStream->setKeyAgreementZrtp(pcc);
+    return pcc;
+}
+
+void ZrtpHostBridgeMinisip::srtpSecretsOff(EnableSecurity part) {
+    MRef<CryptoContext *> cryptoContext;
+
+    if (part == ForSender) {
+	cryptoContext = new CryptoContext(senderSsrc);
+	sStream->setKeyAgreementZrtp(cryptoContext);
+
+        cryptoContext = new CryptoContext(senderZrtpSsrc);
+        sStream->setKeyAgreementZrtp(cryptoContext);
+        secureParts--;
+    }
+    if (part == ForReceiver) {
+	cryptoContext = new CryptoContext(receiverSsrc);
+	sStream->setKeyAgreementZrtp(cryptoContext);
+
+        cryptoContext = new CryptoContext(recvZrtpSsrc);
+        sStream->setKeyAgreementZrtp(cryptoContext);
+        secureParts--;
+    }
+
+    CommandString cmd(callId, "zrtp_security_change", "insecure");
+    messageRouterCallback->handleCommand("gui", cmd);
+
+}
+
+void ZrtpHostBridgeMinisip::rtpSessionError() {
+    MRef<CryptoContext *> cryptoContext;
+
+    cryptoContext = new CryptoContext(senderZrtpSsrc);
+    sStream->setKeyAgreementZrtp(cryptoContext);
+
+    cryptoContext = new CryptoContext(senderSsrc);
+    sStream->setKeyAgreementZrtp(cryptoContext);
+
+    cryptoContext = new CryptoContext(recvZrtpSsrc);
+    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);
+}
+
+void ZrtpHostBridgeMinisip::zrtpNegotiationFailed(MessageSeverity severity, char* msg)
+{
+    fprintf(stderr, "Severity: %d - %s\n", severity, msg);
+}
+
+void ZrtpHostBridgeMinisip::zrtpNotSuppOther() {
+
+    fprintf(stderr, "The other (remote) client does not support ZRTP\n");
+}
+
+#endif
+


Property changes on: trunk/libminisip/source/zrtp/ZrtpHostBridgeMinisip.cxx
___________________________________________________________________
Name: svn:eol-style
   + native

Added: trunk/libzrtpcpp/ChangeLog
===================================================================
--- trunk/libzrtpcpp/ChangeLog	2006-09-15 18:57:59 UTC (rev 2776)
+++ trunk/libzrtpcpp/ChangeLog	2006-09-22 19:16:33 UTC (rev 2777)
@@ -0,0 +1,3 @@
+Initial inplementation based on the draft ZRTP specification.
+This is ongoing as the protocol is being changed until the
+ZRTP specification reaches a stable state.

Added: trunk/libzrtpcpp/INSTALL
===================================================================
--- trunk/libzrtpcpp/INSTALL	2006-09-15 18:57:59 UTC (rev 2776)
+++ trunk/libzrtpcpp/INSTALL	2006-09-22 19:16:33 UTC (rev 2777)
@@ -0,0 +1,5 @@
+See generic installation instructions for minsip
+using the build.pl script.
+
+libzrtpcpp can be built using the build.pl script
+and specifying "libcrtpcpp" as target.
\ No newline at end of file

Added: trunk/libzrtpcpp/NEWS
===================================================================

Added: trunk/libzrtpcpp/README
===================================================================

Added: trunk/libzrtpcpp/bootstrap
===================================================================
--- trunk/libzrtpcpp/bootstrap	2006-09-15 18:57:59 UTC (rev 2776)
+++ trunk/libzrtpcpp/bootstrap	2006-09-22 19:16:33 UTC (rev 2777)
@@ -0,0 +1,58 @@
+#! /bin/sh
+
+##  bootstrap file - borrowed from VideoLAN's libdvdplay 
+##  original verion by Sam Hocevar <sam at zoy.org>
+
+set -x
+set -e
+
+# Get a sane environment, just in case
+LANG=C
+export LANG
+CYGWIN=binmode
+export CYGWIN
+
+# Check for automake
+amvers="no"
+if automake-1.9 --version >/dev/null 2>&1; then
+  amvers="-1.9"
+elif automake-1.8 --version >/dev/null 2>&1; then
+  amvers="-1.8"
+elif automake-1.7 --version >/dev/null 2>&1; then
+  amvers="-1.7"
+elif automake --version > /dev/null 2>&1; then
+  amvers="`automake --version | sed -e '1s/[^0-9]*//' -e q`"
+  if expr "$amvers" "<" "1.7" > /dev/null 2>&1; then
+    amvers="no"
+  else
+    amvers=""
+  fi
+fi
+
+if test "$amvers" = "no"; then
+  set +x
+  echo "$0: you need automake version 1.7 or later"
+  exit 1
+fi
+
+# Check for libtool
+libtoolize="no"
+if libtoolize --version >/dev/null 2>&1; then
+  libtoolize="libtoolize"
+elif glibtoolize --version >/dev/null 2>&1; then
+  libtoolize="glibtoolize"
+fi
+
+if test "$libtoolize" = "no"; then
+  set +x
+  echo "$0: you need libtool"
+  exit 1
+fi
+
+aclocal${amvers} -I m4 "$@" ${ACLOCAL_FLAGS}
+${libtoolize} --copy --force
+
+autoconf
+autoheader
+automake${amvers} --add-missing --copy
+


Property changes on: trunk/libzrtpcpp/bootstrap
___________________________________________________________________
Name: svn:executable
   + *

Added: trunk/libzrtpcpp/configure.ac
===================================================================
--- trunk/libzrtpcpp/configure.ac	2006-09-15 18:57:59 UTC (rev 2776)
+++ trunk/libzrtpcpp/configure.ac	2006-09-22 19:16:33 UTC (rev 2777)
@@ -0,0 +1,60 @@
+AC_PREREQ([2.50])
+AC_INIT([libzrtpcpp], [0.9.0])
+AC_CONFIG_HEADERS([config.h])
+AM_INIT_AUTOMAKE([libzrtpcpp], [0.9.0])
+AM_MINISIP_PACKAGE_INIT
+
+# checks for progs
+AC_PROG_CXX
+AM_MINISIP_LIBTOOL_EXTRAS
+AC_PROG_LIBTOOL
+
+# use "-no-undefined" on Cygwin to force (trigger) libtool to create
+# the shared lib. If this is not set this library
+# is not created. Be sure that the LIBS variable above contains _all_
+# libraries necessary to build ours, Cygwin does not allow undefined
+# symbols.
+case $host in
+#  *-*-msdos* | *-*-go32* | *-*-mingw32* | *-*-cygwin* | *-*-windows*)
+  *-*-cygwin*)
+	LDFLAGS="$LDFLAGS -no-undefined"
+    ;;
+  *)
+    ;;
+esac
+
+AC_CHECK_LIB([crypto],
+             [EVP_CipherInit_ex],
+             [
+              CRYPTOBACKEND="openSSL >= 0.9.8"
+              LIBS="-lcrypto $LIBS"
+                                ],
+             [AC_MSG_ERROR([Cannot find libgcrypt or OpenSSL crypto library.])]
+             )
+
+AM_CONDITIONAL(ZRTP_GCRYPT, test "${ac_cv_lib_gcrypt_gcry_cipher_open}" = "yes")
+AM_CONDITIONAL(ZRTP_OPENSSL, test "${ac_cv_lib_crypto_EVP_CipherInit_ex}" = "yes")
+
+if test $GCC = yes ; then
+        WARN_FLAGS="-Wall -ansi -pedantic"
+else
+        WARN_FLAGS=""
+fi
+AC_SUBST(WARN_FLAGS)
+
+AM_MINISIP_CHECK_LIBMUTIL([0.3.1])
+AM_MINISIP_CHECK_COMPLETE
+
+# Checks for header files.
+AC_HEADER_STDC
+AC_CHECK_HEADERS([stdlib.h string.h pthread.h])
+
+# Checks for typedefs, structures, and compiler characteristics.
+AC_C_CONST
+
+# Checks for library functions.
+AC_FUNC_MALLOC
+
+AC_SUBST(CRYPTOBACKEND)
+AC_CONFIG_FILES([Makefile m4/Makefile src/libzrtpcpp/Makefile src/libzrtpcpp/crypto/Makefile])
+AC_OUTPUT(libzrtpcpp.pc)

Added: trunk/libzrtpcpp/libzrtpcpp.pc.in
===================================================================
--- trunk/libzrtpcpp/libzrtpcpp.pc.in	2006-09-15 18:57:59 UTC (rev 2776)
+++ trunk/libzrtpcpp/libzrtpcpp.pc.in	2006-09-22 19:16:33 UTC (rev 2777)
@@ -0,0 +1,13 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: libccrtp1
+Description: GNU ZRTP core library
+Version: @VERSION@
+Requires: @CRYPTOBACKEND@
+Libs:  -lzrtpcpp
+
+
+

Added: trunk/libzrtpcpp/m4/Makefile.am
===================================================================
--- trunk/libzrtpcpp/m4/Makefile.am	2006-09-15 18:57:59 UTC (rev 2776)
+++ trunk/libzrtpcpp/m4/Makefile.am	2006-09-22 19:16:33 UTC (rev 2777)
@@ -0,0 +1,9 @@
+aclocaldir = $(datadir)/aclocal
+aclocal_DATA = @PACKAGE at .m4
+EXTRA_DIST = @PACKAGE at .m4
+
+MAINTAINERCLEANFILES = \
+		$(srcdir)/Makefile.in
+
+AUTOMAKE_OPTIONS = no-dependencies
+


Property changes on: trunk/libzrtpcpp/m4/Makefile.am
___________________________________________________________________
Name: svn:eol-style
   + native

Added: trunk/libzrtpcpp/m4/libzrtpcpp.m4
===================================================================
--- trunk/libzrtpcpp/m4/libzrtpcpp.m4	2006-09-15 18:57:59 UTC (rev 2776)
+++ trunk/libzrtpcpp/m4/libzrtpcpp.m4	2006-09-22 19:16:33 UTC (rev 2777)
@@ -0,0 +1,9 @@
+# AM_MINISIP_CHECK_LIBZRTP(VERSION)
+# ----------------------------------
+AC_DEFUN([AM_MINISIP_CHECK_LIBZRTPCPP],[
+    AC_REQUIRE([AM_MINISIP_CHECK_LIBMUTIL]) dnl
+    AC_MINISIP_WITH_ARG(ZRTP, zrtpcpp, libzrtpcpp, $1, [REQUIRED])
+    AC_MINISIP_CHECK_LIBRARY(ZRTP, libzrtpcpp, ZRtp.h, zrtpcpp)
+  ])
+# End of AM_MINISIP_CHECK_LIBZRTPCPP
+#

Added: trunk/libzrtpcpp/src/Base32.cxx
===================================================================
--- trunk/libzrtpcpp/src/Base32.cxx	2006-09-15 18:57:59 UTC (rev 2776)
+++ trunk/libzrtpcpp/src/Base32.cxx	2006-09-22 19:16:33 UTC (rev 2777)
@@ -0,0 +1,297 @@
+/**
+ *
+ * Copyright (c) 2002 Bryce "Zooko" Wilcox-O'Hearn Permission is hereby
+ * granted, free of charge, to any person obtaining a copy of this software to
+ * deal in this software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of this software, and to permit persons to whom this software
+ * is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of this software.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THIS SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THIS SOFTWARE.
+ *
+ * Converted to C++ by:
+ * @author Werner Dittmann <Werner.Dittmann at t-online.de>
+ */
+#include <libzrtpcpp/Base32.h>
+
+int divceil(int a, int b) {
+    int c;
+    if (a>0) {
+	if (b>0) c=a+b-1;
+	else c=a;
+    } else {
+	if (b>0) c=a;
+	else c=a+b+1;
+    }
+    return c/b;
+}
+
+//                                         1         2         3
+//                               01234567890123456789012345678901
+static const char* const chars= "ybndrfg8ejkmcpqxot1uwisza345h769";
+
+/*
+ * revchars: index into this table with the ASCII value of the char.
+ * The result is the value of that quintet.
+ */
+static const unsigned char revchars[]= {
+    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, 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,
+    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,
+    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, 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, 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, 255, 255, 255,
+    255, 255, 255, 255, 255, 255, 255, 255
+};
+
+
+Base32::Base32(const string encoded):
+    binaryResult(NULL), resultLength(0) {
+
+    a2b_l(encoded, encoded.size(), (encoded.size()*5/8)*8);
+}
+
+Base32::Base32(const string encoded, int noOfBits):
+    binaryResult(NULL), resultLength(0) {
+
+    a2b_l(encoded, divceil(noOfBits, 5), noOfBits);
+}
+
+Base32::Base32(const unsigned char* data, int noOfBits):
+    binaryResult(NULL), resultLength(0) {
+
+    b2a_l(data, (noOfBits+7)/8, noOfBits);
+}
+
+Base32::~Base32() {
+    if (binaryResult != NULL && binaryResult != smallBuffer) {
+	delete [] binaryResult;
+    }
+    binaryResult = NULL;
+}
+
+const unsigned char* Base32::getDecoded(int &length) {
+    length = resultLength;
+    return binaryResult;
+}
+
+void Base32::b2a_l(const unsigned char* os, int len,
+		   const size_t lengthinbits) {
+
+    /* if lengthinbits is not a multiple of 8 then this is allocating
+     * space for 0, 1, or 2 extra quintets that will be truncated at the
+     * end of this function if they are not needed
+     */
+    string result(divceil(len*8, 5), ' ');
+
+    /* pointer into the result buffer, initially pointing to the
+     * "one-past-the-end" quintet
+     */
+    int resp = result.size();
+
+    /* pointer into the os buffer, initially pointing to the
+     * "one-past-the-end" octet
+     */
+    const unsigned char* osp = os + len;
+
+    /* Now this is a real live Duff's device.  You gotta love it. */
+
+    unsigned long x = 0;	// to hold up to 32 bits worth of the input
+    switch ((osp - os) % 5) {
+
+	case 0:
+	    do {
+		x = *--osp;
+		result[--resp] = chars[x % 32]; /* The least sig 5 bits go into the final quintet. */
+		x /= 32;	/* ... now we have 3 bits worth in x... */
+		case 4:
+		    x |= ((unsigned long)(*--osp)) << 3; /* ... now we have 11 bits worth in x... */
+		    result[--resp] = chars[x % 32];
+		    x /= 32; /* ... now we have 6 bits worth in x... */
+		    result[--resp] = chars[x % 32];
+		    x /= 32; /* ... now we have 1 bits worth in x... */
+		case 3:
+		    x |= ((unsigned long)(*--osp)) << 1; /* The 8 bits from the 2-indexed octet.
+							    So now we have 9 bits worth in x... */
+		    result[--resp] = chars[x % 32];
+		    x /= 32; /* ... now we have 4 bits worth in x... */
+		case 2:
+		    x |= ((unsigned long)(*--osp)) << 4; /* The 8 bits from the 1-indexed octet.
+							    So now we have 12 bits worth in x... */
+		    result[--resp] = chars[x%32];
+		    x /= 32; /* ... now we have 7 bits worth in x... */
+		    result[--resp] = chars[x%32];
+		    x /= 32; /* ... now we have 2 bits worth in x... */
+		case 1:
+		    x |= ((unsigned long)(*--osp)) << 2; /* The 8 bits from the 0-indexed octet.
+							    So now we have 10 bits worth in x... */
+		    result[--resp] = chars[x%32];
+		    x /= 32; /* ... now we have 5 bits worth in x... */
+		    result[--resp] = chars[x];
+	    } while (osp > os);
+    } /* switch ((osp - os.buf) % 5) */
+
+    /* truncate any unused trailing zero quintets */
+    encoded = result.substr(0, divceil(lengthinbits, 5));
+    return;
+}
+
+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
+
+    int 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
+     */
+
+    if (len < 128) {
+        binaryResult = smallBuffer;
+    }
+    else {
+        binaryResult = new unsigned char[len];
+    }
+
+    /* pointer into the result buffer, initially pointing to
+     * the "one-past-the-end" octet
+     */
+    unsigned char* resp = binaryResult + len;
+
+    /* index into the input buffer, initially pointing to the
+     * "one-past-the-end" character
+     */
+    int csp = size;
+
+    /* Now this is a real live Duff's device.  You gotta love it. */
+    switch (csp % 8) {
+	case 0:
+	    do {
+		x = revchars[cs[--csp]]; /* 5 bits... */
+		case 7:
+		    x |= revchars[cs[--csp]] << 5; /* 10 bits... */
+		    *--resp = x % 256;
+		    x /= 256; /* 2 bits... */
+		case 6:
+		    x |= revchars[cs[--csp]] << 2; /* 7 bits... */
+		case 5:
+		    x |= revchars[cs[--csp]] << 7; /* 12 bits... */
+		    *--resp = x % 256;
+		    x /= 256; /* 4 bits... */
+		case 4:
+		    x |= revchars[cs[--csp]] << 4; /* 9 bits... */
+		    *--resp = x % 256;
+		    x /= 256; /* 1 bit... */
+		case 3:
+		    x |= revchars[cs[--csp]] << 1; /* 6 bits... */
+		case 2:
+		    x |= revchars[cs[--csp]] << 6; /* 11 bits... */
+		    *--resp = x % 256;
+		    x /= 256; /* 3 bits... */
+		case 1:
+		    x |= revchars[cs[--csp]] << 3; /* 8 bits... */
+		    *--resp = x % 256;
+	    } while (csp);
+    } /* switch ((csp - cs.buf) % 8) */
+
+    /* truncate any unused trailing zero octets */
+    resultLength = divceil(lengthinbits, 8);
+    return;
+}
+
+#ifdef UNIT_TEST
+#include <math.h>
+
+
+uint8* randz(const size_t len)
+{
+    uint8* result = (uint8*)malloc(len);
+    size_t i;
+    for (i=0; i<len; i++) {
+        result[i] = rand() % 256;
+    }
+    return result;
+}
+
+int main(int argc, char *argv[]) {
+
+    int32 resLen;
+    string a;
+    const uint8* zrecovered;
+    uint8 ones[] = {1, 1, 1, 1, 1};
+
+    // Encode all bits of the 5 one bytes (= 40 bits)
+    a = Base32(ones, 5*8).getEncoded();
+
+    // The string should be: "yryonyeb"
+    cout << "Encoded 5 ones: '" << a << "', Expected: 'yryonyeb'" << endl;
+
+    // Now decode all bits and check
+    Base32 *y = new Base32(a);
+    zrecovered = y->getDecoded(resLen);
+    if (resLen != 5 && memcmp(ones, zrecovered, 5)) {
+        printf("Failed basic 5 ones recovery test.\n");
+        return -1;
+    }
+    delete y;
+
+    a = Base32(ones, 15).getEncoded();
+    cout << "Encoded 5 ones, 15 bits only: '" << a << "', Expected: 'yry'" << endl;
+    // now decode 15 bits (out of 40 possible)
+    y = new Base32(a, 15);
+    zrecovered = y->getDecoded(resLen);
+    printf("Decoded 15 bits, result length: %d (should be 2)\n", resLen);
+    printf("Decoded bytes: %x %x (should be 1 0)\n", zrecovered[0], zrecovered[1]);
+    delete y;
+
+    for (int i = 0; i < 2; i++) {
+        uint8* z = randz(16);
+        a = Base32(z, 16*8).getEncoded();
+//        cout << "Result: " << a << endl;
+        assert (a.size() == Base32::b2alen(16*8));
+        Base32 *x = new Base32(a);
+        zrecovered = x->getDecoded(resLen);
+        if (resLen != 16 && memcmp(z, zrecovered, 16)) {
+            printf("Failed basic recovery test.\n");
+            return -1;
+        }
+        delete x;
+        free((void*)z);
+    }
+}
+#endif


Property changes on: trunk/libzrtpcpp/src/Base32.cxx
___________________________________________________________________
Name: svn:eol-style
   + native

Added: trunk/libzrtpcpp/src/ZIDFile.cxx
===================================================================
--- trunk/libzrtpcpp/src/ZIDFile.cxx	2006-09-15 18:57:59 UTC (rev 2776)
+++ trunk/libzrtpcpp/src/ZIDFile.cxx	2006-09-22 19:16:33 UTC (rev 2777)
@@ -0,0 +1,186 @@
+/*
+  Copyright (C) 2006 Werner Dittmann
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2, or (at your option)
+  any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Boston, MA 02111.
+*/
+
+/*
+ * Authors: Werner Dittmann <Werner.Dittmann at t-online.de>
+ */
+// #define UNIT_TEST
+
+#include <time.h>
+#include <stdlib.h>
+
+#include <libzrtpcpp/ZIDFile.h>
+
+static ZIDFile* instance;
+
+ZIDFile::~ZIDFile() {
+}
+
+ZIDFile* ZIDFile::getInstance() {
+
+    if (instance == NULL) {
+	instance = new ZIDFile();
+    }
+    return instance;
+}
+
+int ZIDFile::open(char *name) {
+    zidrecord_t rec;
+    unsigned int* 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, generate an associated randomw ZID and save
+        // it as first record
+	if (zidFile != NULL) {
+	    ip = (unsigned int*)associatedZid;
+	    memset(&rec, 0, sizeof(zidrecord_t));
+            srandom(time(NULL));
+	    *ip++ = random();
+	    *ip++ = random();
+	    *ip = random();
+	    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);
+}
+
+void ZIDFile::close() {
+
+    if (zidFile != NULL) {
+	fclose(zidFile);
+	zidFile = NULL;
+    }
+}
+
+unsigned int ZIDFile::getRecord(ZIDRecord *zidRecord) {
+    unsigned long pos;
+    zidrecord_t rec;
+    int numRead;
+
+    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.ownZid == 1 && rec.recValid == 0 && numRead == 1) {
+	    numRead = fread(&rec, sizeof(zidrecord_t), 1, zidFile);
+	}
+
+	// if we are at end of file, then no record found. Create new
+	// record and write its data at end of file.
+	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;
+}
+
+unsigned int ZIDFile::saveRecord(ZIDRecord *zidRecord) {
+
+    fseek(zidFile, zidRecord->position, SEEK_SET);
+    fwrite(&zidRecord->record, sizeof(zidrecord_t), 1, zidFile);
+    return 1;
+}
+
+#ifdef UNIT_TEST
+
+int main(int argc, char *argv[]) {
+
+    ZIDFile *zid = ZIDFile::getInstance();
+
+    zid->open("testzid");
+    ZIDRecord zr3("123456789012");
+    zid->getRecord(&zr3);
+    zid->saveRecord(&zr3);
+    ZIDRecord zr4("210987654321");
+    zid->getRecord(&zr4);
+    zid->saveRecord(&zr4);
+
+    zr3.setNewRs1("11122233344455566677788899900012");
+    zid->saveRecord(&zr3);
+    zr3.setNewRs1("00099988877766655544433322211121");
+    zid->saveRecord(&zr3);
+
+    zid->close();
+
+    // Reopen, manipulate 2nd record
+    zid->open("testzid");
+
+    ZIDRecord zr5("210987654321");
+    zid->getRecord(&zr5);
+
+    zr5.setNewRs1("aaa22233344455566677788899900012");
+    zid->saveRecord(&zr5);
+    zr5.setNewRs1("bbb99988877766655544433322211121");
+    zid->saveRecord(&zr5);
+
+    zid->close();
+
+    // reopen, manipulate 2nd record again
+    zid->open("testzid");
+
+    ZIDRecord zr6("210987654321");
+    zid->getRecord(&zr6);
+
+    zr6.setNewRs1("ccc22233344455566677788899900012");
+    zr6.setNewRs1("ddd99988877766655544433322211121");
+    zid->saveRecord(&zr6);
+
+    zid->close();
+
+}
+
+#endif
+
+/** EMACS **
+ * Local variables:
+ * mode: c++
+ * c-default-style: ellemtel
+ * c-basic-offset: 4
+ * End:
+ */


Property changes on: trunk/libzrtpcpp/src/ZIDFile.cxx
___________________________________________________________________
Name: svn:eol-style
   + native

Added: trunk/libzrtpcpp/src/ZIDRecord.cxx
===================================================================
--- trunk/libzrtpcpp/src/ZIDRecord.cxx	2006-09-15 18:57:59 UTC (rev 2776)
+++ trunk/libzrtpcpp/src/ZIDRecord.cxx	2006-09-22 19:16:33 UTC (rev 2777)
@@ -0,0 +1,42 @@
+/*
+  Copyright (C) 2006 Werner Dittmann
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2, or (at your option)
+  any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Boston, MA 02111.
+*/
+
+/*
+ * Authors: Werner Dittmann <Werner.Dittmann at t-online.de>
+ */
+
+#include <libzrtpcpp/ZIDRecord.h>
+
+void ZIDRecord::setNewRs1(const unsigned char *data) {
+
+  // shift RS1 data and flag into RS2
+  memcpy(record.rs2Data, record.rs1Data, RS_LENGTH);
+  record.rs2Valid = record.rs1Valid;
+
+  // set new RS1 data
+  memcpy(record.rs1Data, data, RS_LENGTH);
+  record.rs1Valid = 1;
+}
+
+/** EMACS **
+ * Local variables:
+ * mode: c++
+ * c-default-style: ellemtel
+ * c-basic-offset: 4
+ * End:
+ */


Property changes on: trunk/libzrtpcpp/src/ZIDRecord.cxx
___________________________________________________________________
Name: svn:eol-style
   + native

Added: trunk/libzrtpcpp/src/ZRtp.cxx
===================================================================
--- trunk/libzrtpcpp/src/ZRtp.cxx	2006-09-15 18:57:59 UTC (rev 2776)
+++ trunk/libzrtpcpp/src/ZRtp.cxx	2006-09-22 19:16:33 UTC (rev 2777)
@@ -0,0 +1,1160 @@
+/*
+  Copyright (C) 2006 Werner Dittmann
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2, or (at your option)
+  any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Boston, MA 02111.
+*/
+
+/*
+ * Authors: Werner Dittmann <Werner.Dittmann at t-online.de>
+ */
+
+#include <libzrtpcpp/crypto/ZrtpDH.h>
+#include <libzrtpcpp/crypto/hmac256.h>
+#include <libzrtpcpp/crypto/sha256.h>
+
+#include <libzrtpcpp/ZRtp.h>
+#include <libzrtpcpp/ZrtpStateClass.h>
+#include <libzrtpcpp/ZIDFile.h>
+#include <libzrtpcpp/ZIDRecord.h>
+#include <libzrtpcpp/Base32.h>
+
+static void hexdump(const char* title, const unsigned char *s, int l) {
+    int n=0;
+
+    if (s == NULL) return;
+
+    fprintf(stderr, "%s",title);
+    for( ; n < l ; ++n)
+    {
+        if((n%16) == 0)
+            fprintf(stderr, "\n%04x",n);
+        fprintf(stderr, " %02x",s[n]);
+    }
+    fprintf(stderr, "\n");
+}
+
+/*
+ * This method simplifies detection of libzrtpcpp inside configure
+ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+int ZrtpAvailable()
+{
+    return 1;
+}
+#ifdef __cplusplus
+}
+#endif
+
+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);
+}
+
+bool ZRtp::handleGoClear(uint8_t *extHeader)
+{
+    char *msg, first, last;
+
+    msg = (char *)extHeader + 4;
+    first = tolower(*msg);
+    last = tolower(*(msg+6));
+
+    if (first == 'g' && last == 'r') {
+        Event_t ev;
+
+        ev.type = ZrtpGoClear;
+        ev.data.packet = extHeader;
+        ev.content = NULL;
+        stateEngine->processEvent(&ev);
+        return true;
+    }
+    else {
+        return false;
+    }
+}
+
+void ZRtp::startZrtpEngine() {
+    Event_t ev;
+
+    ev.type = ZrtpInitial;
+    stateEngine->processEvent(&ev);
+}
+
+void ZRtp::stopZrtp() {
+    Event_t ev;
+
+    /*
+     * If we need to stop the state engine before we reached SecureState
+     * reset to initial state only. This state ignores any event except
+     * ZrtpInitial and effectively stops the engine.
+     */
+    if (!stateEngine->inState(SecureState)) {
+        stateEngine->nextState(Initial);
+        return;
+    }
+    ev.type = ZrtpClose;
+    stateEngine->processEvent(&ev);
+}
+
+int32_t ZRtp::checkState(int32_t state)
+{
+    return stateEngine->inState(state);
+}
+
+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;
+    }
+    authLength = findBestAuthLen(hello);
+    if (authLength >= NumSupportedAuthLenghts) {
+        sendInfo(Error, "Hello message does not contain a supported authentication length");
+        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->setAuthLen((uint8_t*)supportedAuthLen[authLength]);
+    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 Authentication length
+    cp = commit->getAuthLen();
+    for (i = 0; i < NumSupportedAuthLenghts; i++) {
+        if (!memcmp(cp, supportedAuthLen[i], 8)) {
+            break;
+        }
+    }
+    if (i >= NumSupportedAuthLenghts) { // no match - something went wrong
+        sendInfo(Alert, "Cannot find a supported authentication length in Commit message");
+        return NULL;
+    }
+    authLength = (SupportedAuthLengths)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, SHA256_DIGEST_LENGTH*5).getEncoded();
+    SAS = SAS.substr(SAS.length()-4, 4);
+
+    // 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);
+    /*
+     * 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, SHA256_DIGEST_LENGTH*5).getEncoded();
+    SAS = SAS.substr(SAS.length()-4, 4);
+
+    // 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);
+//    int sasFlag = zidRec.isSasVerified() ? 1 : 0;
+    int sasFlag = 0;
+
+    /*
+     * 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(sasFlag);
+    zpConf->setExpTime(0);
+
+    uint8_t confMac[SHA256_DIGEST_LENGTH];
+    unsigned int macLen;
+
+    // The HMAC with length 20 includes the SAS flag inside the Confirm packet
+    // TODO: Be aware of specific handling of stay secure flag !!!
+    hmac_sha256(hmacSrtp, SHA256_DIGEST_LENGTH, (unsigned char*)zpConf->getPlainText(),
+		20, 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) {
+    }
+
+    if (memcmp(knownPlain, confirm1->getPlainText(), 15) != 0) {
+        fprintf(stderr, "1: %s\n", confirm1->getPlainText());
+	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
+    // TODO: Be aware of specific handling of stay secure flag !!!
+    hmac_sha256(hmacSrtp, SHA256_DIGEST_LENGTH, (unsigned char*)confirm1->getPlainText(),
+		20, 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);
+    zpConf->setExpTime(0);
+
+    // The HMAC with length 16 includes the SAS flag inside the Confirm packet
+    // TODO: Be aware of specific handling of stay secure flag !!!
+    hmac_sha256(hmacSrtp, SHA256_DIGEST_LENGTH, (unsigned char*)zpConf->getPlainText(),
+		20, 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) {
+        fprintf(stderr, "2: %s\n", confirm2->getPlainText());
+	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
+    // TODO: Be aware of specific handling of stay secure flag !!!
+    hmac_sha256(hmacSrtp, SHA256_DIGEST_LENGTH, (unsigned char*)confirm2->getPlainText(),
+		20, confMac, &macLen);
+
+    if (memcmp(confMac, confirm2->getHmac(), 32) != 0) {
+	sendInfo(Error, "HMAC verification of Confirm2 message failed");
+	return NULL;
+    }
+    return zrtpConf2Ack;
+}
+
+// TODO Implement GoClear handling
+ZrtpPacketClearAck* ZRtp::prepareClearAck(ZrtpPacketGoClear* gpkt)
+{
+    sendInfo(Warning, "Received a GoClear message");
+    return NULL;
+}
+
+
+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;
+}
+
+SupportedAuthLengths ZRtp::findBestAuthLen(ZrtpPacketHello *hello) {
+
+    int  i;
+    int ii;
+
+    for (i = 0; i < NumSupportedAuthLenghts ; i++) {
+        for (ii = 0; ii < 5; ii++) {
+            if (!memcmp(hello->getAuthLen(ii), supportedAuthLen[i], 8)) {
+                break;
+            }
+        }
+        // if ii < 5 we found the cipher i in the packet, done
+        if (ii < 5) {
+            break;
+        }
+    }
+    return (SupportedAuthLengths)i;
+}
+
+void ZRtp::computeHvi(uint8_t *pv, uint32_t pvLength, ZrtpPacketHello *hello) {
+
+    unsigned char* data[3];
+    unsigned int length[3];
+    /*
+     * populate the vector to compute the HVI hash according to the
+     * ZRTP specification.
+     */
+    data[0] = pv;
+    length[0] = pvLength;
+
+    data[1] = (unsigned char*)hello->getHashType(0);
+    length[1] = 5*5*8;
+
+    data[2] = NULL;            // terminate data chunks
+    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];
+    int32_t rsFound = 0;
+
+#if 0
+    hexdump("rs1IDr (I)", rs1IDr, 8);
+    hexdump("rs1IDi (I)", rs1IDi, 8);
+    hexdump("rs2IDr (I)", rs2IDr, 8);
+    hexdump("rs2IDi (I)", rs2IDi, 8);
+    hexdump("rs1Id (recv)) (I)", dhPart->getRs1Id(), 8);
+    hexdump("rs2Id (recv)) (I)", dhPart->getRs2Id(), 8);
+#endif
+
+    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;
+
+    setD[0] = setE[0] = NULL;
+    setD[1] = setE[1] = NULL;
+    setD[2] = setE[2] = NULL;
+    setD[3] = setE[3] = NULL;
+    setD[4] = setE[4] = 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
+        rsFound = 0x1;
+    }
+
+    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
+        rsFound |= 0x2;
+    }
+
+    if (rsFound == 0) {
+        sendInfo(Warning, "No retained secret matches - verify SAS");
+    }
+    if ((rsFound & 0x1) && (rsFound & 0x2)) {
+        sendInfo(Info, "Both retained secrets match - security OK");
+    }
+    if ((rsFound & 0x1) && !(rsFound & 0x2)) {
+        sendInfo(Warning, "Only the first retained secret matches - verify SAS");
+    }
+    if (!(rsFound & 0x1) && (rsFound & 0x2)) {
+        sendInfo(Warning, "Only the second retained secret matches - verify SAS");
+    }
+
+    int32_t i;
+    const uint8_t* tmpP;
+    int32_t notDone = 1;
+    if (matchingSecrets) {
+	/*
+	 * 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;
+	       }
+	   }
+        }
+    }
+
+#if 0
+    hexdump("setD0 (I)", setD[0], 32);
+    hexdump("setD1 (I)", setD[1], 32);
+#endif
+    /*
+     * 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);
+    // hexdump("S0 (I)", s0, 32);
+
+    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
+    int32_t rsFound = 0;
+
+#if 0
+    hexdump("rs1IDr (R)", rs1IDr, 8);
+    hexdump("rs1IDi (R)", rs1IDi, 8);
+    hexdump("rs2IDr (R)", rs2IDr, 8);
+    hexdump("rs2IDi (R)", rs2IDi, 8);
+    hexdump("rs1Id (recv)) (R)", dhPart->getRs1Id(), 8);
+    hexdump("rs2Id (recv)) (R)", dhPart->getRs2Id(), 8);
+#endif
+
+    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;
+
+    setD[0] = setE[0] = NULL;
+    setD[1] = setE[1] = NULL;
+    setD[2] = setE[2] = NULL;
+    setD[3] = setE[3] = NULL;
+    setD[4] = setE[4] = 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;
+        rsFound = 0x1;
+    }
+
+    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
+        rsFound |= 0x2;
+    }
+    if (rsFound == 0) {
+        sendInfo(Warning, "No retained secret matches - verify SAS");
+    }
+    if ((rsFound & 0x1) && (rsFound & 0x2)) {
+        sendInfo(Info, "Both retained secrets match - security OK");
+    }
+    if ((rsFound & 0x1) && !(rsFound & 0x2)) {
+        sendInfo(Warning, "Only the first retained secret matches - verify SAS");
+    }
+    if (!(rsFound & 0x1) && (rsFound & 0x2)) {
+        sendInfo(Warning, "Only the second retained secret matches - verify SAS");
+    }
+
+    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;
+		}
+	    }
+        }
+    }
+#if 0
+    hexdump("setD0 (R)", setD[0], 32);
+    hexdump("setD1 (R)", setD[1], 32);
+#endif
+
+    /*
+     * 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);
+
+    // hexdump("S0 (R)", s0, 32);
+    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 = (authLength == AuthLen32) ? 32 : 80;
+    sec.sas = SAS;
+    sec.role = myRole;
+
+    callback->srtpSecretsReady(&sec, part);
+}
+
+void ZRtp::srtpSecretsOff(EnableSecurity part) {
+    callback->srtpSecretsOff(part);
+}
+
+void ZRtp::SASVerified()
+{
+    // Initialize a ZID record to get peer's retained secrets
+    ZIDRecord zidRec(peerZid);
+    ZIDFile *zid = ZIDFile::getInstance();
+
+    zid->getRecord(&zidRec);
+    zidRec.setSasVerified();
+    zid->saveRecord(&zidRec);
+}
+
+int32_t ZRtp::sendPacketRTP(ZrtpPacketBase *packet) {
+    return ((packet == NULL) ? 0 :
+            callback->sendDataRTP(packet->getHeaderBase(), (packet->getLength() * 4) + 4));
+}
+
+int32_t ZRtp::sendPacketSRTP(ZrtpPacketBase *packet) {
+    return ((packet == NULL) ? 0 :
+            callback->sendDataSRTP(packet->getHeaderBase(),
+                                   (packet->getLength() * 4) + 4,
+                                   ((char *)(packet->getHeaderBase()) + (packet->getLength() * 4) + 4),
+                                   52));
+}
+
+void ZRtp::setSigsSecret(uint8_t* data)
+{
+}
+
+void ZRtp::setSrtpsSecret(uint8_t* data)
+{
+}
+
+void ZRtp::setOtherSecret(uint8_t* data, int32_t length)
+{
+}
+
+void ZRtp::setClientId(std::string id) {
+    const char* tmp = "                ";
+    if (id.size() < 15) {
+        zrtpHello->setClientId((unsigned char*)tmp);
+    }
+    zrtpHello->setClientId((unsigned char*)id.c_str());
+}


Property changes on: trunk/libzrtpcpp/src/ZRtp.cxx
___________________________________________________________________
Name: svn:eol-style
   + native

Added: trunk/libzrtpcpp/src/ZrtpPacketClearAck.cxx
===================================================================
--- trunk/libzrtpcpp/src/ZrtpPacketClearAck.cxx	2006-09-15 18:57:59 UTC (rev 2776)
+++ trunk/libzrtpcpp/src/ZrtpPacketClearAck.cxx	2006-09-22 19:16:33 UTC (rev 2777)
@@ -0,0 +1,50 @@
+/*
+  Copyright (C) 2006 Werner Dittmann
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2, or (at your option)
+  any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Boston, MA 02111.
+*/
+
+/*
+ * @author: Werner Dittmann <Werner.Dittmann at t-online.de>
+ */
+
+#include <libzrtpcpp/ZrtpPacketClearAck.h>
+
+ZrtpPacketClearAck::ZrtpPacketClearAck() {
+    DEBUGOUT((fprintf(stdout, "Creating ClearAck packet without data\n")));
+
+    allocated = malloc(sizeof (ClearAck_t));
+    if (allocated == NULL) {
+    }
+    zrtpHeader = (zrtpPacketHeader_t *)&((ClearAck_t *)allocated)->hdr;	// the standard header
+
+    setZrtpId();
+    setLength(MESSAGE_LENGTH);
+    setMessage((uint8_t*)ClearAckMsg);
+}
+
+ZrtpPacketClearAck::ZrtpPacketClearAck(uint8_t *data) {
+    DEBUGOUT((fprintf(stdout, "Creating Conf2Ack packet from data\n")));
+
+    allocated = NULL;
+    zrtpHeader = (zrtpPacketHeader_t *)&((ClearAck_t *)data)->hdr;	// the standard header
+}
+
+ZrtpPacketClearAck::~ZrtpPacketClearAck() {
+    DEBUGOUT((fprintf(stdout, "Deleting ClearAck packet: alloc: %x\n", allocated)));
+    if (allocated != NULL) {
+	free(allocated);
+    }
+}


Property changes on: trunk/libzrtpcpp/src/ZrtpPacketClearAck.cxx
___________________________________________________________________
Name: svn:eol-style
   + native

Added: trunk/libzrtpcpp/src/ZrtpPacketCommit.cxx
===================================================================
--- trunk/libzrtpcpp/src/ZrtpPacketCommit.cxx	2006-09-15 18:57:59 UTC (rev 2776)
+++ trunk/libzrtpcpp/src/ZrtpPacketCommit.cxx	2006-09-22 19:16:33 UTC (rev 2777)
@@ -0,0 +1,53 @@
+/*
+  Copyright (C) 2006 Werner Dittmann
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2, or (at your option)
+  any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Boston, MA 02111.
+*/
+
+/*
+ * @author: Werner Dittmann <Werner.Dittmann at t-online.de>
+ */
+
+#include <libzrtpcpp/ZrtpPacketCommit.h>
+
+ZrtpPacketCommit::ZrtpPacketCommit() {
+    DEBUGOUT((fprintf(stdout, "Creating commit packet without data\n")));
+
+    allocated = malloc(sizeof (CommitPacket_t));
+
+    if (allocated == NULL) {
+    }
+
+    zrtpHeader = (zrtpPacketHeader_t *)&((CommitPacket_t *)allocated)->hdr;	// the standard header
+    commitHeader = (Commit_t *)&((CommitPacket_t *)allocated)->commit;
+
+    setZrtpId();
+    setLength(COMMIT_LENGTH + MESSAGE_LENGTH);
+    setMessage((uint8_t*)CommitMsg);
+}
+
+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);
+    }
+}


Property changes on: trunk/libzrtpcpp/src/ZrtpPacketCommit.cxx
___________________________________________________________________
Name: svn:eol-style
   + native

Added: trunk/libzrtpcpp/src/ZrtpPacketConf2Ack.cxx
===================================================================
--- trunk/libzrtpcpp/src/ZrtpPacketConf2Ack.cxx	2006-09-15 18:57:59 UTC (rev 2776)
+++ trunk/libzrtpcpp/src/ZrtpPacketConf2Ack.cxx	2006-09-22 19:16:33 UTC (rev 2777)
@@ -0,0 +1,50 @@
+/*
+  Copyright (C) 2006 Werner Dittmann
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2, or (at your option)
+  any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Boston, MA 02111.
+*/
+
+/*
+ * Authors: Werner Dittmann <Werner.Dittmann at t-online.de>
+ */
+
+#include <libzrtpcpp/ZrtpPacketConf2Ack.h>
+
+ZrtpPacketConf2Ack::ZrtpPacketConf2Ack() {
+    DEBUGOUT((fprintf(stdout, "Creating Conf2Ack packet without data\n")));
+
+    allocated = malloc(sizeof (Conf2Ack_t));
+    if (allocated == NULL) {
+    }
+    zrtpHeader = (zrtpPacketHeader_t *)&((Conf2Ack_t *)allocated)->hdr;	// the standard header
+
+    setZrtpId();
+    setLength(MESSAGE_LENGTH);
+    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);
+    }
+}


Property changes on: trunk/libzrtpcpp/src/ZrtpPacketConf2Ack.cxx
___________________________________________________________________
Name: svn:eol-style
   + native

Added: trunk/libzrtpcpp/src/ZrtpPacketConfirm.cxx
===================================================================
--- trunk/libzrtpcpp/src/ZrtpPacketConfirm.cxx	2006-09-15 18:57:59 UTC (rev 2776)
+++ trunk/libzrtpcpp/src/ZrtpPacketConfirm.cxx	2006-09-22 19:16:33 UTC (rev 2777)
@@ -0,0 +1,51 @@
+/*
+  Copyright (C) 2006 Werner Dittmann
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2, or (at your option)
+  any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Boston, MA 02111.
+*/
+
+/*
+ * Authors: Werner Dittmann <Werner.Dittmann at t-online.de>
+ */
+
+#include <libzrtpcpp/ZrtpPacketConfirm.h>
+
+ZrtpPacketConfirm::ZrtpPacketConfirm() {
+    DEBUGOUT((fprintf(stdout, "Creating Confirm packet without data\n")));
+
+    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(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);
+    }
+}


Property changes on: trunk/libzrtpcpp/src/ZrtpPacketConfirm.cxx
___________________________________________________________________
Name: svn:eol-style
   + native

Added: trunk/libzrtpcpp/src/ZrtpPacketDHPart.cxx
===================================================================
--- trunk/libzrtpcpp/src/ZrtpPacketDHPart.cxx	2006-09-15 18:57:59 UTC (rev 2776)
+++ trunk/libzrtpcpp/src/ZrtpPacketDHPart.cxx	2006-09-22 19:16:33 UTC (rev 2777)
@@ -0,0 +1,81 @@
+/*
+  Copyright (C) 2006 Werner Dittmann
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2, or (at your option)
+  any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Boston, MA 02111.
+*/
+
+/*
+ * Authors: Werner Dittmann <Werner.Dittmann at t-online.de>
+ */
+
+#include <libzrtpcpp/ZrtpPacketDHPart.h>
+
+
+ZrtpPacketDHPart::ZrtpPacketDHPart(SupportedPubKeys pkt) {
+    DEBUGOUT((fprintf(stdout, "Creating DHPart packet without data\n")));
+
+    int length = sizeof(zrtpPacketHeader_t) + sizeof(DHPart_t);
+
+    length += ((pkt == Dh3072) ? 384 : 512); // length according to DH type
+    allocated = malloc(length);
+    memset(allocated, 0, length);
+
+    if (allocated == NULL) {
+	// TODO error handling
+    }
+
+    pktype = pkt;
+
+    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));
+}
+
+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));
+
+    pktype = pkt;
+}
+
+ZrtpPacketDHPart::~ZrtpPacketDHPart() {
+    DEBUGOUT((fprintf(stdout, "Deleting DHPart packet: alloc: %x\n", allocated)));
+
+    if (allocated != NULL) {
+	free(allocated);
+    }
+}


Property changes on: trunk/libzrtpcpp/src/ZrtpPacketDHPart.cxx
___________________________________________________________________
Name: svn:eol-style
   + native

Added: trunk/libzrtpcpp/src/ZrtpPacketError.cxx
===================================================================
--- trunk/libzrtpcpp/src/ZrtpPacketError.cxx	2006-09-15 18:57:59 UTC (rev 2776)
+++ trunk/libzrtpcpp/src/ZrtpPacketError.cxx	2006-09-22 19:16:33 UTC (rev 2777)
@@ -0,0 +1,54 @@
+/*
+  Copyright (C) 2006 Werner Dittmann
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2, or (at your option)
+  any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Boston, MA 02111.
+*/
+
+/* Copyright (C) 2006
+ *
+ * Authors: Werner Dittmann <Werner.Dittmann at t-online.de>
+ */
+
+#include <libzrtpcpp/ZrtpPacketError.h>
+
+ZrtpPacketError::ZrtpPacketError() {
+    DEBUGOUT((fprintf(stdout, "Creating Error packet without data\n")));
+
+    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((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);
+    }
+}


Property changes on: trunk/libzrtpcpp/src/ZrtpPacketError.cxx
___________________________________________________________________
Name: svn:eol-style
   + native

Added: trunk/libzrtpcpp/src/ZrtpPacketGoClear.cxx
===================================================================
--- trunk/libzrtpcpp/src/ZrtpPacketGoClear.cxx	2006-09-15 18:57:59 UTC (rev 2776)
+++ trunk/libzrtpcpp/src/ZrtpPacketGoClear.cxx	2006-09-22 19:16:33 UTC (rev 2777)
@@ -0,0 +1,54 @@
+/*
+  Copyright (C) 2006 Werner Dittmann
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2, or (at your option)
+  any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Boston, MA 02111.
+*/
+
+/* Copyright (C) 2006
+ *
+ * Authors: Werner Dittmann <Werner.Dittmann at t-online.de>
+ */
+
+#include <libzrtpcpp/ZrtpPacketGoClear.h>
+
+ZrtpPacketGoClear::ZrtpPacketGoClear() {
+    DEBUGOUT((fprintf(stdout, "Creating GoClear packet without data\n")));
+
+    allocated = malloc(sizeof (GoClearPacket_t));
+    if (allocat