summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Dröge <sebastian@centricular.com>2014-02-09 18:09:36 +0100
committerSebastian Dröge <sebastian@centricular.com>2014-02-09 18:09:36 +0100
commite8befb7ce3c32622289ee21193dfab07505e78fd (patch)
tree42cd4c7b4febe7a736e8f77dde2be62e82fb7af2
parent35e0ffa227dd2a3cc071ddf48f4e16d90befc302 (diff)
downloadgstreamer-plugins-bad-e8befb7ce3c32622289ee21193dfab07505e78fd.tar.gz
hlsdemux: Use libgcrypt directly instead of going through gnutls
gnutls is also just wrapping gcrypt, but we don't need any of the TLS related functionality. We just need to be able to decrypt AES128-CBC.
-rw-r--r--configure.ac2
-rw-r--r--ext/hls/Makefile.am4
-rw-r--r--ext/hls/gsthlsdemux.c49
-rw-r--r--m4/libgcrypt.m4122
4 files changed, 161 insertions, 16 deletions
diff --git a/configure.ac b/configure.ac
index 2f7e1e80c..23992fcc4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2211,7 +2211,7 @@ AG_GST_CHECK_FEATURE(SNDIO, [sndio audio], sndio, [
dnl *** hls ***
translit(dnm, m, l) AM_CONDITIONAL(USE_HLS, true)
AG_GST_CHECK_FEATURE(HLS, [http live streaming plugin], hls, [
- PKG_CHECK_MODULES(GNUTLS, gnutls >= 2.11.3, [ HAVE_HLS="yes" ], [ HAVE_HLS="no" ])
+ AM_PATH_LIBGCRYPT([1.2.0], [ HAVE_HLS="yes" ], [ HAVE_HLS="no" ])
])
else
diff --git a/ext/hls/Makefile.am b/ext/hls/Makefile.am
index 508c77551..853944b32 100644
--- a/ext/hls/Makefile.am
+++ b/ext/hls/Makefile.am
@@ -8,11 +8,11 @@ libgstfragmented_la_SOURCES = \
gsthlssink.c \
gstm3u8playlist.c
-libgstfragmented_la_CFLAGS = $(GST_PLUGINS_BAD_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(GST_CFLAGS) $(GIO_CFLAGS) $(GNUTLS_CFLAGS)
+libgstfragmented_la_CFLAGS = $(GST_PLUGINS_BAD_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(GST_CFLAGS) $(GIO_CFLAGS) $(LIBGCRYPT_CFLAGS)
libgstfragmented_la_LIBADD = \
$(top_builddir)/gst-libs/gst/uridownloader/libgsturidownloader-@GST_API_VERSION@.la \
$(GST_PLUGINS_BASE_LIBS) -lgstpbutils-$(GST_API_VERSION) -lgstvideo-$(GST_API_VERSION) \
- $(GST_BASE_LIBS) $(GST_LIBS) $(GIO_LIBS) $(LIBM) $(GNUTLS_LIBS)
+ $(GST_BASE_LIBS) $(GST_LIBS) $(GIO_LIBS) $(LIBM) $(LIBGCRYPT_LIBS)
libgstfragmented_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) -no-undefined
libgstfragmented_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
diff --git a/ext/hls/gsthlsdemux.c b/ext/hls/gsthlsdemux.c
index 6854263bb..32e1b7b69 100644
--- a/ext/hls/gsthlsdemux.c
+++ b/ext/hls/gsthlsdemux.c
@@ -47,8 +47,7 @@
#include <string.h>
#include <gst/glib-compat-private.h>
-#include <gnutls/gnutls.h>
-#include <gnutls/crypto.h>
+#include <gcrypt.h>
#include "gsthlsdemux.h"
static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src_%u",
@@ -1247,8 +1246,8 @@ gst_hls_demux_decrypt_fragment (GstHLSDemux * demux,
GstFragment *key_fragment, *ret = NULL;
GstBuffer *key_buffer, *encrypted_buffer, *decrypted_buffer;
GstMapInfo key_info, encrypted_info, decrypted_info;
- gnutls_cipher_hd_t aes_ctx;
- gnutls_datum_t key_d, iv_d;
+ gcry_cipher_hd_t aes_ctx = NULL;
+ gcry_error_t err = 0;
gsize unpadded_size;
GST_INFO_OBJECT (demux, "Fetching key %s", key);
@@ -1266,15 +1265,21 @@ gst_hls_demux_decrypt_fragment (GstHLSDemux * demux,
gst_buffer_map (encrypted_buffer, &encrypted_info, GST_MAP_READ);
gst_buffer_map (decrypted_buffer, &decrypted_info, GST_MAP_WRITE);
- key_d.data = key_info.data;
- key_d.size = 16;
- iv_d.data = (unsigned char *) iv;
- iv_d.size = 16;
- gnutls_cipher_init (&aes_ctx, gnutls_cipher_get_id ("AES-128-CBC"), &key_d,
- &iv_d);
- gnutls_cipher_decrypt2 (aes_ctx, encrypted_info.data, encrypted_info.size,
- decrypted_info.data, decrypted_info.size);
- gnutls_cipher_deinit (aes_ctx);
+ err =
+ gcry_cipher_open (&aes_ctx, GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC, 0);
+ if (err)
+ goto gcry_error;
+ err = gcry_cipher_setkey (aes_ctx, key_info.data, 16);
+ if (err)
+ goto gcry_error;
+ err = gcry_cipher_setiv (aes_ctx, iv, 16);
+ if (err)
+ goto gcry_error;
+ err = gcry_cipher_decrypt (aes_ctx, decrypted_info.data, decrypted_info.size,
+ encrypted_info.data, encrypted_info.size);
+ if (err)
+ goto gcry_error;
+ gcry_cipher_close (aes_ctx);
/* Handle pkcs7 unpadding here */
unpadded_size =
@@ -1296,6 +1301,24 @@ gst_hls_demux_decrypt_fragment (GstHLSDemux * demux,
key_failed:
g_object_unref (encrypted_fragment);
return ret;
+
+gcry_error:
+ GST_ERROR_OBJECT (demux, "Failed to decrypt fragment: %s",
+ gpg_strerror (err));
+
+ if (aes_ctx)
+ gcry_cipher_close (aes_ctx);
+
+ gst_buffer_unref (key_buffer);
+ gst_buffer_unref (encrypted_buffer);
+ gst_buffer_unref (decrypted_buffer);
+
+ gst_buffer_unmap (decrypted_buffer, &decrypted_info);
+ gst_buffer_unmap (encrypted_buffer, &encrypted_info);
+ gst_buffer_unmap (key_buffer, &key_info);
+
+ g_object_unref (encrypted_fragment);
+ return ret;
}
static gboolean
diff --git a/m4/libgcrypt.m4 b/m4/libgcrypt.m4
new file mode 100644
index 000000000..6cf482fcb
--- /dev/null
+++ b/m4/libgcrypt.m4
@@ -0,0 +1,122 @@
+dnl Autoconf macros for libgcrypt
+dnl Copyright (C) 2002, 2004, 2011 Free Software Foundation, Inc.
+dnl
+dnl This file is free software; as a special exception the author gives
+dnl unlimited permission to copy and/or distribute it, with or without
+dnl modifications, as long as this notice is preserved.
+dnl
+dnl This file is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+dnl implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+
+dnl AM_PATH_LIBGCRYPT([MINIMUM-VERSION,
+dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]])
+dnl Test for libgcrypt and define LIBGCRYPT_CFLAGS and LIBGCRYPT_LIBS.
+dnl MINIMUN-VERSION is a string with the version number optionalliy prefixed
+dnl with the API version to also check the API compatibility. Example:
+dnl a MINIMUN-VERSION of 1:1.2.5 won't pass the test unless the installed
+dnl version of libgcrypt is at least 1.2.5 *and* the API number is 1. Using
+dnl this features allows to prevent build against newer versions of libgcrypt
+dnl with a changed API.
+dnl
+AC_DEFUN([AM_PATH_LIBGCRYPT],
+[ AC_REQUIRE([AC_CANONICAL_HOST])
+ AC_ARG_WITH(libgcrypt-prefix,
+ AC_HELP_STRING([--with-libgcrypt-prefix=PFX],
+ [prefix where LIBGCRYPT is installed (optional)]),
+ libgcrypt_config_prefix="$withval", libgcrypt_config_prefix="")
+ if test x$libgcrypt_config_prefix != x ; then
+ if test x${LIBGCRYPT_CONFIG+set} != xset ; then
+ LIBGCRYPT_CONFIG=$libgcrypt_config_prefix/bin/libgcrypt-config
+ fi
+ fi
+
+ AC_PATH_TOOL(LIBGCRYPT_CONFIG, libgcrypt-config, no)
+ tmp=ifelse([$1], ,1:1.2.0,$1)
+ if echo "$tmp" | grep ':' >/dev/null 2>/dev/null ; then
+ req_libgcrypt_api=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\1/'`
+ min_libgcrypt_version=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\2/'`
+ else
+ req_libgcrypt_api=0
+ min_libgcrypt_version="$tmp"
+ fi
+
+ AC_MSG_CHECKING(for LIBGCRYPT - version >= $min_libgcrypt_version)
+ ok=no
+ if test "$LIBGCRYPT_CONFIG" != "no" ; then
+ req_major=`echo $min_libgcrypt_version | \
+ sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\1/'`
+ req_minor=`echo $min_libgcrypt_version | \
+ sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\2/'`
+ req_micro=`echo $min_libgcrypt_version | \
+ sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\3/'`
+ libgcrypt_config_version=`$LIBGCRYPT_CONFIG --version`
+ major=`echo $libgcrypt_config_version | \
+ sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\1/'`
+ minor=`echo $libgcrypt_config_version | \
+ sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\2/'`
+ micro=`echo $libgcrypt_config_version | \
+ sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\3/'`
+ if test "$major" -gt "$req_major"; then
+ ok=yes
+ else
+ if test "$major" -eq "$req_major"; then
+ if test "$minor" -gt "$req_minor"; then
+ ok=yes
+ else
+ if test "$minor" -eq "$req_minor"; then
+ if test "$micro" -ge "$req_micro"; then
+ ok=yes
+ fi
+ fi
+ fi
+ fi
+ fi
+ fi
+ if test $ok = yes; then
+ AC_MSG_RESULT([yes ($libgcrypt_config_version)])
+ else
+ AC_MSG_RESULT(no)
+ fi
+ if test $ok = yes; then
+ # If we have a recent libgcrypt, we should also check that the
+ # API is compatible
+ if test "$req_libgcrypt_api" -gt 0 ; then
+ tmp=`$LIBGCRYPT_CONFIG --api-version 2>/dev/null || echo 0`
+ if test "$tmp" -gt 0 ; then
+ AC_MSG_CHECKING([LIBGCRYPT API version])
+ if test "$req_libgcrypt_api" -eq "$tmp" ; then
+ AC_MSG_RESULT([okay])
+ else
+ ok=no
+ AC_MSG_RESULT([does not match. want=$req_libgcrypt_api got=$tmp])
+ fi
+ fi
+ fi
+ fi
+ if test $ok = yes; then
+ LIBGCRYPT_CFLAGS=`$LIBGCRYPT_CONFIG --cflags`
+ LIBGCRYPT_LIBS=`$LIBGCRYPT_CONFIG --libs`
+ ifelse([$2], , :, [$2])
+ libgcrypt_config_host=`$LIBGCRYPT_CONFIG --host 2>/dev/null || echo none`
+ if test x"$libgcrypt_config_host" != xnone ; then
+ if test x"$libgcrypt_config_host" != x"$host" ; then
+ AC_MSG_WARN([[
+***
+*** The config script $LIBGCRYPT_CONFIG was
+*** built for $libgcrypt_config_host and thus may not match the
+*** used host $host.
+*** You may want to use the configure option --with-libgcrypt-prefix
+*** to specify a matching config script.
+***]])
+ fi
+ fi
+ else
+ LIBGCRYPT_CFLAGS=""
+ LIBGCRYPT_LIBS=""
+ ifelse([$3], , :, [$3])
+ fi
+ AC_SUBST(LIBGCRYPT_CFLAGS)
+ AC_SUBST(LIBGCRYPT_LIBS)
+])