LibreSSL is a drop in replacement for OpenSSL 1.0, with goals of modernizing the codebase, improving security and applying best practice development processes. The main issue is that LibreSSL reports it's version as 2.0 and above, which causes checks for a OpenSSL version number >= 1.1 to use incompatible functions. The traditional way of handling this is to also check if LIBRESSL_VERSION_NUMBER is defined, however on projects with several of these checks it can quickly get out of hand. Instead, this patch takes the Apache approach to handling LibreSSL, which does the following: - Add a new file called ssl_private.h that has the following: - Add 4 definitions from OpenSSL 1.0.2 that are missing from LibreSSL. - Add 3 macros from OpenSSL 1.0.2 that are missing from LibreSSL. - Add a wrapper for SSL_is_server for LibreSSL to prevent an implicit declaration error when compiling. - Defines PJ_USE_OPENSSL_PRE_1_1_API if LIBRESSL_VERSION_NUMBER or OPENSSL_VERSION_NUMBER < 0x10100000L are true. - Add the header file to the other 5 files that have checks for OPENSSL_VERSION_NUMBER - Change the following OPENSSL_VERSION_NUMBER checks to PJ_USE_OPENSSL_PRE_1_1_API: < 0x009080ffL < 0x10100000L >= 0x1000200fL >= 0x10000000L - Change OPENSSL_VERSION_NUMBER >= 0x10100000L to !PJ_USE_OPENSSL_PRE_1_1_API - Add a check in aconfigure.ac and aconfigure to check for the function tls_config_set_ca_mem. This function does not exist in OpenSSL and is a clear way to check to see if LibreSSL is being compiled against. This is the same method used in openntpd. Depending on if it's found or not, the variable $libssl_library is set to either OpenSSL or LibreSSL. - Change the string OpenSSL to $libssl_library in aconfigure.ac and aconfigure where it's appropriate. Signed-off-by: Adam Duskett <aduskett@xxxxxxxxx> --- aconfigure | 80 ++++++++++++++++++++++++++----- aconfigure.ac | 13 ++--- pjlib/include/pj/ssl_private.h | 60 +++++++++++++++++++++++ pjlib/src/pj/ssl_sock_ossl.c | 27 ++++++----- pjmedia/src/pjmedia/transport_srtp_dtls.c | 3 +- pjmedia/src/pjmedia/transport_srtp_sdes.c | 3 +- third_party/srtp/crypto/hash/hmac_ossl.c | 5 +- third_party/srtp/crypto/include/sha1.h | 3 +- 8 files changed, 159 insertions(+), 35 deletions(-) create mode 100644 pjlib/include/pj/ssl_private.h diff --git a/aconfigure b/aconfigure index aec2a284..b021835d 100755 --- a/aconfigure +++ b/aconfigure @@ -7877,8 +7877,8 @@ $as_echo "Checking if SSL support is disabled... yes" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: checking for OpenSSL installations.." >&5 -$as_echo "checking for OpenSSL installations.." >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: checking for SSL library installations.." >&5 +$as_echo "checking for SSL library installations.." >&6; } if test "x$with_ssl" != "xno" -a "x$with_ssl" != "x"; then CFLAGS="$CFLAGS -I$with_ssl/include" LDFLAGS="$LDFLAGS -L$with_ssl/lib" @@ -7974,11 +7974,69 @@ if test "x$ac_cv_lib_ssl_SSL_CTX_new" = xyes; then : libssl_present=1 && LIBS="-lssl $LIBS" fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing tls_config_set_ca_mem" >&5 +$as_echo_n "checking for library containing tls_config_set_ca_mem... " >&6; } +if ${ac_cv_search_tls_config_set_ca_mem+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char tls_config_set_ca_mem (); +int +main () +{ +return tls_config_set_ca_mem (); + ; + return 0; +} +_ACEOF +for ac_lib in '' tls; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_tls_config_set_ca_mem=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_tls_config_set_ca_mem+:} false; then : + break +fi +done +if ${ac_cv_search_tls_config_set_ca_mem+:} false; then : + +else + ac_cv_search_tls_config_set_ca_mem=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_tls_config_set_ca_mem" >&5 +$as_echo "$ac_cv_search_tls_config_set_ca_mem" >&6; } +ac_res=$ac_cv_search_tls_config_set_ca_mem +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + libssl_library=LibreSSL +else + libssl_library=OpenSSL +fi + if test "x$openssl_h_present" = "x1" -a "x$libssl_present" = "x1" -a "x$libcrypto_present" = "x1"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: OpenSSL library found, SSL support enabled" >&5 -$as_echo "OpenSSL library found, SSL support enabled" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $libssl_library library found, SSL support enabled" >&5 +$as_echo "$libssl_library library found, SSL support enabled" >&6; } - # Check if SRTP should be compiled with OpenSSL + # Check if SRTP should be compiled with SSL # support, to enable cryptos such as AES GCM. # EVP_CIPHER_CTX is now opaque in OpenSSL 1.1.0, libsrtp 1.5.4 uses it as a transparent type. @@ -8039,11 +8097,11 @@ fi fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test "x$ac_ssl_has_aes_gcm" = "x1"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: OpenSSL has AES GCM support, SRTP will use OpenSSL" >&5 -$as_echo "OpenSSL has AES GCM support, SRTP will use OpenSSL" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $libssl_library has AES GCM support, SRTP will use $libssl_library" >&5 +$as_echo "$libssl_library has AES GCM support, SRTP will use $libssl_library" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: OpenSSL AES GCM support not found, SRTP will only support AES CM cryptos" >&5 -$as_echo "OpenSSL AES GCM support not found, SRTP will only support AES CM cryptos" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $libssl_library AES GCM support not found, SRTP will only support AES CM cryptos" >&5 +$as_echo "$libssl_library AES GCM support not found, SRTP will only support AES CM cryptos" >&6; } fi # PJSIP_HAS_TLS_TRANSPORT setting follows PJ_HAS_SSL_SOCK @@ -8051,8 +8109,8 @@ $as_echo "OpenSSL AES GCM support not found, SRTP will only support AES CM crypt $as_echo "#define PJ_HAS_SSL_SOCK 1" >>confdefs.h else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: ** OpenSSL libraries not found, disabling SSL support **" >&5 -$as_echo "** OpenSSL libraries not found, disabling SSL support **" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ** SSL libraries not found, disabling SSL support **" >&5 +$as_echo "** SSL libraries not found, disabling SSL support **" >&6; } fi fi diff --git a/aconfigure.ac b/aconfigure.ac index e9770b72..99705092 100644 --- a/aconfigure.ac +++ b/aconfigure.ac @@ -1565,7 +1565,7 @@ AC_ARG_ENABLE(ssl, fi ], [ - AC_MSG_RESULT([checking for OpenSSL installations..]) + AC_MSG_RESULT([checking for SSL library installations..]) if test "x$with_ssl" != "xno" -a "x$with_ssl" != "x"; then CFLAGS="$CFLAGS -I$with_ssl/include" LDFLAGS="$LDFLAGS -L$with_ssl/lib" @@ -1577,10 +1577,11 @@ AC_ARG_ENABLE(ssl, AC_CHECK_HEADER(openssl/ssl.h,[openssl_h_present=1]) AC_CHECK_LIB(crypto,ERR_load_BIO_strings,[libcrypto_present=1 && LIBS="-lcrypto $LIBS"]) AC_CHECK_LIB(ssl,SSL_CTX_new,[libssl_present=1 && LIBS="-lssl $LIBS"]) + AC_SEARCH_LIBS(tls_config_set_ca_mem,tls,[libssl_library=LibreSSL],[libssl_library=OpenSSL]) if test "x$openssl_h_present" = "x1" -a "x$libssl_present" = "x1" -a "x$libcrypto_present" = "x1"; then - AC_MSG_RESULT([OpenSSL library found, SSL support enabled]) + AC_MSG_RESULT([$libssl_library found, SSL support enabled]) - # Check if SRTP should be compiled with OpenSSL + # Check if SRTP should be compiled with SSL # support, to enable cryptos such as AES GCM. # EVP_CIPHER_CTX is now opaque in OpenSSL 1.1.0, libsrtp 1.5.4 uses it as a transparent type. @@ -1590,16 +1591,16 @@ AC_ARG_ENABLE(ssl, [EVP_CIPHER_CTX *ctx;EVP_aes_128_gcm();])], [AC_CHECK_LIB(crypto,EVP_aes_128_gcm,[ac_ssl_has_aes_gcm=1])]) if test "x$ac_ssl_has_aes_gcm" = "x1"; then - AC_MSG_RESULT([OpenSSL has AES GCM support, SRTP will use OpenSSL]) + AC_MSG_RESULT([$libssl_library has AES GCM support, SRTP will use SSL]) else - AC_MSG_RESULT([OpenSSL AES GCM support not found, SRTP will only support AES CM cryptos]) + AC_MSG_RESULT([$libssl_library AES GCM support not found, SRTP will only support AES CM cryptos]) fi # PJSIP_HAS_TLS_TRANSPORT setting follows PJ_HAS_SSL_SOCK #AC_DEFINE(PJSIP_HAS_TLS_TRANSPORT, 1) AC_DEFINE(PJ_HAS_SSL_SOCK, 1) else - AC_MSG_RESULT([** OpenSSL libraries not found, disabling SSL support **]) + AC_MSG_RESULT([** SSL libraries not found, disabling SSL support **]) fi ]) diff --git a/pjlib/include/pj/ssl_private.h b/pjlib/include/pj/ssl_private.h new file mode 100644 index 00000000..adfc73ec --- /dev/null +++ b/pjlib/include/pj/ssl_private.h @@ -0,0 +1,60 @@ +/* $Id$ */ +/* + * Copyright (C) 2017 Teluu Inc. (http://www.teluu.com) + * + * 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 of the License, 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, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef __PJ_SSL_PRIVATE_H__ +#define __PJ_SSL_PRIVATE_H__ + +/** + * @file ssl_private.h + * @brief Internal SSL handling. + */ + +#include <openssl/opensslv.h> +#include <pj/types.h> + +PJ_BEGIN_DECL + +#if defined(LIBRESSL_VERSION_NUMBER) +/** Missing from LibreSSL but present in OpenSSL 1.0.2 */ +# define TLSEXT_nid_unknown 0x1000000 +# define SSL_CTRL_GET_SHARED_CURVE 93 +# define SSL_CTRL_SET_SIGALGS_LIST 98 +# define SSL_CTRL_SET_CLIENT_SIGALGS_LIST 102 + +# define SSL_get_shared_curve(s, n) \ + SSL_ctrl(s,SSL_CTRL_GET_SHARED_CURVE,n,NULL) + +# define SSL_set1_sigalgs_list(ctx, s) \ + SSL_ctrl(ctx,SSL_CTRL_SET_SIGALGS_LIST,0,(char *)s) + +# define SSL_set1_client_sigalgs_list(ctx, s) \ + SSL_ctrl(ctx,SSL_CTRL_SET_CLIENT_SIGALGS_LIST,0,(char *)s) + +#define SSL_is_server(ssl) ((ssl)->server) + +/** LibreSSL declares OPENSSL_VERSION_NUMBER == 2.0 but is not compatible with + * OpenSSL >= 1.1 + */ +#define PJ_USE_OPENSSL_PRE_1_1_API (1) +#else +#define PJ_USE_OPENSSL_PRE_1_1_API (OPENSSL_VERSION_NUMBER < 0x10100000L) +#endif + +PJ_END_DECL + +#endif /* __PJ_SSL_PRIVATE_H__ */ diff --git a/pjlib/src/pj/ssl_sock_ossl.c b/pjlib/src/pj/ssl_sock_ossl.c index 6550f002..a0e10ff4 100644 --- a/pjlib/src/pj/ssl_sock_ossl.c +++ b/pjlib/src/pj/ssl_sock_ossl.c @@ -16,6 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include <pj/ssl_private.h> #include <pj/ssl_sock.h> #include <pj/activesock.h> #include <pj/compat/socket.h> @@ -53,7 +54,7 @@ #include <openssl/rand.h> #include <openssl/opensslconf.h> -#if !defined(OPENSSL_NO_EC) && OPENSSL_VERSION_NUMBER >= 0x1000200fL +#if !defined(OPENSSL_NO_EC) && PJ_USE_OPENSSL_PRE_1_1_API # include <openssl/obj_mac.h> @@ -111,7 +112,7 @@ static unsigned get_nid_from_cid(unsigned cid) #endif -#if OPENSSL_VERSION_NUMBER >= 0x10100000L +#if !PJ_USE_OPENSSL_PRE_1_1_API # define OPENSSL_NO_SSL2 /* seems to be removed in 1.1.0 */ # define M_ASN1_STRING_data(x) ASN1_STRING_get0_data(x) # define M_ASN1_STRING_length(x) ASN1_STRING_length(x) @@ -126,7 +127,7 @@ static unsigned get_nid_from_cid(unsigned cid) #ifdef _MSC_VER -# if OPENSSL_VERSION_NUMBER >= 0x10100000L +# if !PJ_USE_OPENSSL_PRE_1_1_API # pragma comment(lib, "libcrypto") # pragma comment(lib, "libssl") # pragma comment(lib, "crypt32") @@ -535,13 +536,13 @@ static pj_status_t init_openssl(void) pj_assert(status == PJ_SUCCESS); /* Init OpenSSL lib */ -#if OPENSSL_VERSION_NUMBER < 0x10100000L +#if PJ_USE_OPENSSL_PRE_1_1_API SSL_library_init(); SSL_load_error_strings(); #else OPENSSL_init_ssl(0, NULL); #endif -#if OPENSSL_VERSION_NUMBER < 0x009080ffL +#if PJ_USE_OPENSSL_PRE_1_1_API /* This is now synonym of SSL_library_init() */ OpenSSL_add_all_algorithms(); #endif @@ -556,7 +557,7 @@ static pj_status_t init_openssl(void) int nid; const char *cname; -#if OPENSSL_VERSION_NUMBER < 0x10100000L +#if PJ_USE_OPENSSL_PRE_1_1_API meth = (SSL_METHOD*)SSLv23_server_method(); if (!meth) meth = (SSL_METHOD*)TLSv1_server_method(); @@ -599,7 +600,7 @@ static pj_status_t init_openssl(void) SSL_set_session(ssl, SSL_SESSION_new()); -#if !defined(OPENSSL_NO_EC) && OPENSSL_VERSION_NUMBER >= 0x1000200fL +#if !defined(OPENSSL_NO_EC) && PJ_USE_OPENSSL_PRE_1_1_API openssl_curves_num = SSL_get_shared_curve(ssl,-1); if (openssl_curves_num > PJ_ARRAY_SIZE(openssl_curves)) openssl_curves_num = PJ_ARRAY_SIZE(openssl_curves); @@ -768,7 +769,7 @@ static pj_status_t create_ssl(pj_ssl_sock_t *ssock) BIO *bio; DH *dh; long options; -#if !defined(OPENSSL_NO_ECDH) && OPENSSL_VERSION_NUMBER >= 0x10000000L +#if !defined(OPENSSL_NO_ECDH) && PJ_USE_OPENSSL_PRE_1_1_API EC_KEY *ecdh; #endif SSL_METHOD *ssl_method = NULL; @@ -791,7 +792,7 @@ static pj_status_t create_ssl(pj_ssl_sock_t *ssock) ssock->param.proto = PJ_SSL_SOCK_PROTO_SSL23; /* Determine SSL method to use */ -#if OPENSSL_VERSION_NUMBER < 0x10100000L +#if PJ_USE_OPENSSL_PRE_1_1_API switch (ssock->param.proto) { case PJ_SSL_SOCK_PROTO_TLS1: ssl_method = (SSL_METHOD*)TLSv1_method(); @@ -927,7 +928,7 @@ static pj_status_t create_ssl(pj_ssl_sock_t *ssock) if (dh != NULL) { if (SSL_CTX_set_tmp_dh(ctx, dh)) { options = SSL_OP_CIPHER_SERVER_PREFERENCE | - #if !defined(OPENSSL_NO_ECDH) && OPENSSL_VERSION_NUMBER >= 0x10000000L + #if !defined(OPENSSL_NO_ECDH) && PJ_USE_OPENSSL_PRE_1_1_API SSL_OP_SINGLE_ECDH_USE | #endif SSL_OP_SINGLE_DH_USE; @@ -995,7 +996,7 @@ static pj_status_t create_ssl(pj_ssl_sock_t *ssock) if (SSL_CTX_ctrl(ctx, SSL_CTRL_SET_ECDH_AUTO, 1, NULL)) { PJ_LOG(4,(ssock->pool->obj_name, "SSL ECDH initialized " "(automatic), faster PFS ciphers enabled")); - #if !defined(OPENSSL_NO_ECDH) && OPENSSL_VERSION_NUMBER >= 0x10000000L + #if !defined(OPENSSL_NO_ECDH) && PJ_USE_OPENSSL_PRE_1_1_API } else { /* enables AES-128 ciphers, to get AES-256 use NID_secp384r1 */ ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); @@ -1228,7 +1229,7 @@ static pj_status_t set_cipher_list(pj_ssl_sock_t *ssock) static pj_status_t set_curves_list(pj_ssl_sock_t *ssock) { -#if !defined(OPENSSL_NO_EC) && OPENSSL_VERSION_NUMBER >= 0x1000200fL +#if !defined(OPENSSL_NO_EC) && PJ_USE_OPENSSL_PRE_1_1_API int ret; int curves[PJ_SSL_SOCK_MAX_CURVES]; unsigned cnt; @@ -1259,7 +1260,7 @@ static pj_status_t set_curves_list(pj_ssl_sock_t *ssock) static pj_status_t set_sigalgs(pj_ssl_sock_t *ssock) { -#if OPENSSL_VERSION_NUMBER >= 0x1000200fL +#if PJ_USE_OPENSSL_PRE_1_1_API int ret; if (ssock->param.sigalgs.ptr && ssock->param.sigalgs.slen) { diff --git a/pjmedia/src/pjmedia/transport_srtp_dtls.c b/pjmedia/src/pjmedia/transport_srtp_dtls.c index 6dfa4083..28103678 100644 --- a/pjmedia/src/pjmedia/transport_srtp_dtls.c +++ b/pjmedia/src/pjmedia/transport_srtp_dtls.c @@ -23,6 +23,7 @@ #include <pj/errno.h> #include <pj/rand.h> #include <pj/ssl_sock.h> +#include <pj/ssl_private.h> /* * Include OpenSSL headers @@ -32,7 +33,7 @@ #include <openssl/rsa.h> #include <openssl/ssl.h> -#if OPENSSL_VERSION_NUMBER >= 0x10100000L && \ +#if !PJ_USE_OPENSSL_PRE_1_1_API && \ defined(OPENSSL_API_COMPAT) && OPENSSL_API_COMPAT >= 0x10100000L # define X509_get_notBefore(x) X509_getm_notBefore(x) # define X509_get_notAfter(x) X509_getm_notAfter(x) diff --git a/pjmedia/src/pjmedia/transport_srtp_sdes.c b/pjmedia/src/pjmedia/transport_srtp_sdes.c index effe17c2..010443e7 100644 --- a/pjmedia/src/pjmedia/transport_srtp_sdes.c +++ b/pjmedia/src/pjmedia/transport_srtp_sdes.c @@ -17,11 +17,12 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include <pj/ssl_private.h> #if defined(PJ_HAS_SSL_SOCK) && (PJ_HAS_SSL_SOCK != 0) /* Include OpenSSL libraries for MSVC */ # ifdef _MSC_VER -# if OPENSSL_VERSION_NUMBER >= 0x10100000L +# if !PJ_USE_OPENSSL_PRE_1_1_API # pragma comment(lib, "libcrypto") # else # pragma comment(lib, "libeay32") diff --git a/third_party/srtp/crypto/hash/hmac_ossl.c b/third_party/srtp/crypto/hash/hmac_ossl.c index f99646b5..8c389d6c 100644 --- a/third_party/srtp/crypto/hash/hmac_ossl.c +++ b/third_party/srtp/crypto/hash/hmac_ossl.c @@ -51,6 +51,7 @@ #include "err.h" /* for srtp_debug */ #include <openssl/evp.h> #include <openssl/hmac.h> +#include <pj/ssl_private.h> #define SHA1_DIGEST_SIZE 20 @@ -76,7 +77,7 @@ static srtp_err_status_t srtp_hmac_alloc (srtp_auth_t **a, int key_len, int out_ /* OpenSSL 1.1.0 made HMAC_CTX an opaque structure, which must be allocated using HMAC_CTX_new. But this function doesn't exist in OpenSSL 1.0.x. */ -#if OPENSSL_VERSION_NUMBER < 0x10100000L +#if PJ_USE_OPENSSL_PRE_1_1_API { /* allocate memory for auth and HMAC_CTX structures */ uint8_t* pointer; @@ -121,7 +122,7 @@ static srtp_err_status_t srtp_hmac_dealloc (srtp_auth_t *a) hmac_ctx = (HMAC_CTX*)a->state; -#if OPENSSL_VERSION_NUMBER < 0x10100000L +#if PJ_USE_OPENSSL_PRE_1_1_API HMAC_CTX_cleanup(hmac_ctx); /* zeroize entire state*/ diff --git a/third_party/srtp/crypto/include/sha1.h b/third_party/srtp/crypto/include/sha1.h index 3dc8d910..b2e3353a 100644 --- a/third_party/srtp/crypto/include/sha1.h +++ b/third_party/srtp/crypto/include/sha1.h @@ -53,6 +53,7 @@ #include "err.h" #ifdef OPENSSL +#include <pj/ssl_private.h> #include <openssl/evp.h> #include <stdint.h> #else @@ -81,7 +82,7 @@ extern "C" { /* OpenSSL 1.1.0 made EVP_MD_CTX an opaque structure, which must be allocated using EVP_MD_CTX_new. But this function doesn't exist in OpenSSL 1.0.x. */ -#if OPENSSL_VERSION_NUMBER < 0x10100000L +#if PJ_USE_OPENSSL_PRE_1_1_API typedef EVP_MD_CTX srtp_sha1_ctx_t; -- 2.13.6 _______________________________________________ Visit our blog: http://blog.pjsip.org pjsip mailing list pjsip@xxxxxxxxxxxxxxx http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org