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