How to Get Up and Running Quickly with libZRTP

1. About


The libzrtp library is a cross-platform implementation of ZRTP, a VoIP encryption protocol developed by Phil Zimmermann. libzrtp is suitable for inclusion in software VoIP clients, firmware for hardware VoIP phones, VoIP PBX servers, mobile VoIP clients, and SIP border control servers, enabling a VoIP application to interoperate and make secure calls with the rest of the ZRTP community.

The libzrtp library consists of three main components: the protocol module responsible for the safe connection of a call, the encryption module, and a set of interfaces. ZRTP works by assuming control of the VoIP traffic and initiating an encrypted connection between two ZRTP endpoints after a safe mode is achieved. To integrate the library, please review our documentation on the ZRTP interfaces, connections management, and integration plan.

2. Quick Info


Building with GNU tools (Linux, *BSD, MacOS X, mingw, etc.)

Generally these should be all that are needed to build the libraries, applications, and samples:

  1. go to ./projects/gnu and run
    $ ./configure
    $ make clean && make
    

Building Win32 Target with Microsoft Visual Studio

Generally we can just do these steps:

  1. Visual Studio 8: open projects/win/libzrtp_vc8.sln solution,
  2. build the libzrtp_test application.

Building for Windows Mobile

Generally these are all that are needed:

  1. Visual Studio 8: open projects/win/libzrtp_wince_vc8.sln solution,
  2. build the libzrtp_test application.

Locating Output Binaries/Libraries

For GNU targets, library files will be placed to ./projects/gnu/build and ./third_party/bnlib.

Running the Applications

After successful build, you can try running libzrtp_test application on projects/gnu/build/test directory.

3. Getting the Source Distribution


3.1 Getting the Release tarball

Getting the released tarball is the best way to obtain stable version of libzrtp. The tarball may not contain the latest features or bug-fixes, but normally it is considered more stable, tested and well documented.

The latest released tarball can be downloaded from the http://zfoneproject.com/prod_sdk.html

3.2 Getting from Subversion trunk

At the moment, SVN repository is available for libzrtp developers only. It will be opened for public soon.

3.3 Source Directories Layout

The top-level directories (denoted as $TOP here) in the source distribution contains the following sub-directories:

$TOP/doc - documentation folder;

$TOP/include - header files:

$TOP/projects

$TOP/src - libzrtp source files;

$TOP/test - test suite for libZRTP kernel logic. Includes versions for Unix, Windows, Windows CE and Symbian.

$TOP/third_party

4. Build Preparation


4.1 zrtp_cinfig_user.h

Before building libzrtp, some adjustments may be performed according to developers needs. In order to do this, include/zrtp_cinfig_user.h should be used. Most of configuration parameters are optional and libzrtp can be build without any modifications.

Check Build Configuration for more information.

4.2 libzrtp platform-dependent interfaces

The library requires external implementation of some system-dependent functions to enable cross-platform operation. The libzrtp distribution contains almost all interface implementations for the following platforms: Windows, Linux, Mac OSX, Symbian, Windows CE. The Quick Start allows a fast integration of the library. Built-in implementations are used by default and developer don't need to anything more.

In order to start using libzrtp, developer should implement just few feedback interfaces. Libzrtp uses callbacks to notify application about some events in ZRTP protocol, such as:

Another callback which must be implemented - transport routine:

These only two callbacks which must be implemented to start using libzrtp. Example can be found at the end of this article.

For more detail information about libzrtp platform-dependent interfaces check XXX.

5. Building Linux, *nix, *BSD, and MacOS X Targets with GNU Build Systems


Supported Targets

The new, autoconf based GNU build system can be used to build the libraries/applications for the following targets:

5.1 Requirements

In order to use libzrtp's GNU build system, these typical GNU tools are needed:

In addition, the appropriate libraries must be installed for platform-dependent interfaces implementation. This could just be a libc and the appropriate system abstraction library such as Posix.

The build system is known to work on the following hosts:

5.2 Running configure and make

Run "./configure" without any options to let the script detect the appropriate settings for the host:
   $ cd libzrtp
   $ ./configure
   ...

Once the configure script completes successfully, libzrtp is ready to be built. Use following commands:

   $ cd libzrtp
   $ make clean
   $ make

Description of all make targets supported by the Makefile's:

6. Building MacOS X Targets with Xcode


6.1 Requirements

To build libzrtp on OS X using Xcode you need following:

6.2 Building the Projects

Follow the steps below to build libzrtp using Apple Xcode:
  1. For Apple Xcode: open projects/xcode/libzrtp.xcodeproj project file.
  2. Set "libzrtp" or "libzrtp_ec" as Active Target.
  3. Select Debug or Release build as appropriate.
  4. Build "configure" target.
  5. Build the project. This will build libzrtp with all dependencies.
  6. After successful build, libzrtp will be placed in projects/xcode/build/Debug or Release.

Use projects/xcode/libzrtp_test.xcodeproj by analogy to build the test application.

7. Building for Windows Targets with Microsoft Visual Studio


7.1 Requirements

The Microsoft Visual Studio based project files can be used with one of the following:

For the host platform, the following are required:

7.2 Building the Projects

Follow the steps below to build libzrtp using Visual Studio:
  1. For Visual Studio 8 (VS 2005): open libzrtp_vs8.sln solution file.
  2. Set "libzrtp" or "libzrtp_ec" as StartUp Project.
  3. Select Debug or Release build as appropriate.
  4. Build the project. This will build libzrtp and all dependencies.
  5. After successful build, libzrtp will be placed in projects/win/Debug or Release.

To build libzrtp test-cases use "libzrtp_test" as StartUp Project and perform steps listed above.

8. Building for Windows Mobile Targets (Windows CE/WinCE/PDA/SmartPhone)


8.1 Requirements

The Microsoft Visual Studio based project files can be used with one of the following:

For the host platform, the following are required:

8.2 Building the Projects

Follow the steps below to build libzrtp using Visual Studio:
  1. For Visual Studio 8 (VS 2005): open libzrtp_wince_vs8.sln solution file.
  2. Set "libzrtp" or "libzrtp_ec" as StartUp Project.
  3. Select Debug or Release build as appropriate.
  4. Build the project. This will build libzrtp and all dependencies.
  5. After successful build, libzrtp will be placed in projects/win/Debug or Release.

Note:
The Test Application is not available for Windows Mobile platform at the moment. We will fix this in next version of libzrtp.

9. Building for Symbian


10. Using libzrtp with Applications


Regardless of the build system being used, the following tasks are normally needed to be done in order to build application to use libzrtp:
  1. Add following include directories in the include search path:
    • libzrtp/include
    • libzrtp/include/enterprise (if you are using Enterprise version of libzrtp)
    • libzrtp/third_party/bgaes
    • libzrtp/third_party/bnlib
    • libzrtp/projects/gnu/config (for GNU Autoconf targets)
  2. Put these library directories in the library search path:
    • libzrtp/third_party/bnlib
    • libzrtp/projects/gnu/build (for GNU Autoconf targets)
    • libzrtp/projects/xcode/build/Release (when building with Xcode)
    • libzrtp/projects/win/Release (when building with Visual Studio)
  3. Include libzrtp.h header file to the application.
  4. Link with libzrtp and bnlib.
  5. Link with system spesific libraries:
    • Windows: Add (among other things): ws2_32.lib.
    • Linux, *nix, *BSD: Add (among other things): '-lpthread'.
    • MacOS X: Add (among other things): '-lpthread'.

11. Quick Start Example


An overview for creating an encrypted channel using libzrtp:

11.1 Initialization

The library supports profiling and dictating different channel parameters, though the initialization can be performed by one function call with default parameters.

typedef struct testcon_t
{
    zrtp_session_t  *zrtp_session;  // ZRTP Session structure
    zrtp_stream_t   *zrtp_audio;    // ZRTP stream for voice encryption
    zrtp_stream__t  *zrtp_video;    // ZRTP stream for video encryption
} testcon_t;

testcon_t safe_connection;          // Secure channel instance
zrtp_global_t zrtp_global;          // Persistent storage for libzrtp data

zrtp_status_t s = zrtp_status_ok;
zrtp_config_t zrtp_config;

// Initialize zrtp config with default values 
zrtp_config_defaults(&zrtp_config);

// Make some adjustments:
// - Set Client ID to identify ourself
// - Set appropriate license mode
// - We going to use  default zrtp cache implementation, so let's specify cache file path
strcpy(zrtp_config.client_id, TEST_CLIENT_ID);
zrtp_config.lic_mode = ZRTP_LICENSE_MODE_ACTIVE;
zrtp_zstrcpyc( ZSTR_GV(zrtp_config.def_cache_path), TEST_CACHE_PATH);

// Define interface callback functions
zrtp_config.cb.misc_cb.on_send_packet           = on_send_packet;
zrtp_config.cb.event_cb.on_zrtp_secure          = on_zrtp_secure;
zrtp_config.cb.event_cb.on_zrtp_security_event  = on_zrtp_event;

// Everything is ready - initialize libzrtp.        
s = zrtp_init(&zrtp_config, &zrtp_global);
if (zrtp_status_ok != s) {
    // Check error code and debug logs  
}

// The library has been initialized and is ready to use
. . .

11.2 Sessions/Streams

The library operates with the ZRTP streams concept, where each packet is encrypted within this stream. The streams are created before the start of the encryption process.

//
// Allocate zrtp session with default parameters
//
z = zrtp_session_init( zrtp_global,
                        NULL,
                        zid,                        
                        is_initator,
                        &safe_connection->zrtp_session);
if (zrtp_status_ok != s) {
    // Check error code and debug logs  
}

// Set call-back pointer to our parent structure
zrtp_session_set_userdata(safe_connection->zrtp_session, &safe_connection);

// 
// Attach Audio and Video Streams
//
s = zrtp_stream_attach(safe_connection->zrtp_session, &safe_connection->zrtp_audio);
if (zrtp_status_ok != s) {
    // Check error code and debug logs
}
zrtp_stream_set_userdata(safe_connection->zrtp_audio, &safe_connection);

s = zrtp_stream_attach(safe_connection->zrtp_session, &safe_connection->zrtp_video);
if (zrtp_status_ok != s) {
    // Check error code and debug logs
}
zrtp_stream_set_userdata(safe_connection->zrtp_video, &safe_connection);

11.3 Protocol Handling

To create an encrypted channel, run the ZRTP engine for each stream added to the session. In our case we have two streams. The library will notify when achieving safe mode through the feedback path interface.

//
// Streams are ready - initiate ZRTP protocol 
//
zrtp_stream_start(safe_connection->zrtp_audio, assrc);
zrtp_stream_start(safe_connection->zrtp_video, vssrc);

The three steps above create the encrypted channel. After entering the "Secure" state, you provide a plain packet to the library and receive an encrypted packet ready to be sent. Decryption works in the analogous way.

zrtp_status_t s = zrtp_status_fail;
char packet[MAX_RTP_SIZE];
int  size = 0;

// Some abstract function for packets receiving
size = get_packet(packet);

 //
 // Processing incoming packets. 
 // You must determine media type and choose corresponding ZRTP stream
 //
s = zrtp_process_srtp(safe_connection->zrtp_audio, packet, &size);
switch (s) {
    case zrtp_status_ok:
        //
        // Packet was successfully decrypted. Dont forget that packet
        // size was changed during decryption. New size now in size 
        //
    
    case zrtp_status_drop:
         //
         // This is a protocol ZRTP packet or masked RTP media.
         // In either case the packet must be dropped to protect your 
         // private data and media codec
    
    case zrtp_status_fail:
        //
        // This is some kind of error - see logs for more information.
        // Don't put such packet to the network. It is not secure.
        //
}

11.4 Callbacks

libzrtp informs the user application about all changes in protocol state through a system of callback functions. The developer's guide considers this question in detail in XXX. In most cases we need to display the SAS string and some other stream options after switching to the Secure state. An example of doing this is follow:

static void on_zrtp_secure(zrtp_stream_t *stream, unsigned event)
{
    test_options_t* info; // some user-defined stream options    

    switch (event) {
        case ZRTP_EVENT_IS_SECURE:
        {
            safe_connection_t* safe_connection = zrtp_stream_get_userdata(stream);
            zrtp_session_info_t zrtp_session_info;
            
            zrtp_session_get(safe_connection->zrtp_session, &zrtp_session_info);
            //
            // Print out SAS  there.
            //
        } break;
        
        // ...
        // handle other events there

        default: 
            break;
   }
}

An overview for closing an secure channel using libzrtp:

11.5 Utilization

The uninstall session permits libzrtp to dispose of all engaged resources and release memory for session context storage. ZRTP streams will be also released, so you don't need to call separate functions.

zrtp_session_down(safe_connection->zrtp_session);

When you no longer need the library, dispose of all resources allocated before the beginning of the operation.

zrtp_down(&zrtp_global);

12. Summary


Integration of libzrtp requires familiarity with the protocol and the library operation features. While the encryption of VoIP is not a trivial task, we have attempted to simplify as much as possible the work required to integrate libzrtp.

Generated on Wed Dec 9 17:31:06 2009 for libzrtp  zfone