[FFmpeg-devel] wolfSSL - new TLS backend patch
samsamsam
samsamsam at o2.pl
Tue Aug 28 13:02:32 EEST 2018
This patch was prepared and tested for version 3.4.2, but I think that it can be used as base to discuss to add wolfSSL support. How do you think? diff -Nur ffmpeg-3.4.2/configure ffmpeg-3.4.2_wolfssl_patch/con --- ffmpeg-3.4.2/configure 2018-02 01:29:18.000000000 +0100 +++ ffmpeg-3.4.2_wolfssl_patch/con 17:38:46.000000000 +0200 @@ -215,7 +215,7 @@   --enable-gmp         enable gmp, needed for rtmp(t)e support                if openssl or librtmp is not used [no]   --enable-gnutls        enable gnutls, needed for https support -               if openssl is not used [no] +               if openssl or wolfssl is not used [no]   --disable-iconv        disable iconv [autodetect]   --disable-jack        disable libjack support [autodetect]   --enable-jni         enable JNI support [no] @@ -270,6 +270,8 @@   --enable-libvpx        enable VP8 and VP9 de/encoding via libvpx [no]   --enable-libwavpack     enable wavpack encoding via libwavpack [no]   --enable-libwebp       enable WebP encoding via libwebp [no] + --enable-wolfssl       enable WolfSSL), needed for https support +               if openssl or gnutls is not used [no]   --enable-libx264       enable H.264 encoding via x264 [no]   --enable-libx265       enable HEVC encoding via x265 [no]   --enable-libxavs       enable AVS encoding via xavs [no] @@ -292,7 +294,7 @@   --enable-opencl        enable OpenCL code   --enable-opengl        enable OpenGL rendering [no]   --enable-openssl       enable openssl, needed for https support -               if gnutls is not used [no] +               if gnutls or wolfssl is not used [no]   --disable-sndio        disable sndio support [autodetect]   --disable-schannel      disable SChannel SSP, needed for TLS support on                Windows if openssl and gnutls are not used [autodetect] @@ -1563,6 +1565,7 @@     libndi_newtek     libfdk_aac     openssl +   wolfssl " EXTERNAL_LIBRARY_VERSION3_LIST @@ -3164,14 +3167,17 @@ tls_gnutls_protocol_conflict=" tls_securetransport_protocol" tls_gnutls_protocol_deps="gnut tls_gnutls_protocol_select="tc -tls_openssl_protocol_conflict tls_securetransport_protocol tls_gnutls_protocol" +tls_openssl_protocol_conflict tls_securetransport_protocol tls_gnutls_protocol tls_wolfssl_protocol" tls_openssl_protocol_deps="ope tls_openssl_protocol_select="t +tls_wolfssl_protocol_conflict tls_securetransport_protocol tls_gnutls_protocol" +tls_wolfssl_protocol_deps="wo +tls_wolfssl_protocol_select=" tls_schannel_protocol_deps="sc tls_schannel_protocol_select=" tls_securetransport_protocol_d tls_securetransport_protocol_s -tls_protocol_deps_any="tls_sc tls_securetransport_protocol tls_gnutls_protocol tls_openssl_protocol" +tls_protocol_deps_any="tls_sc tls_securetransport_protocol tls_gnutls_protocol tls_openssl_protocol tls_wolfssl_protocol" udp_protocol_select="network" udplite_protocol_select="netwo unix_protocol_deps="sys_un_h" @@ -5907,6 +5913,7 @@ enabled frei0r           && require_header frei0r.h enabled gmp              && require gmp gmp.h mpz_export -lgmp enabled gnutls           && require_pkg_config gnutls gnutls gnutls/gnutls.h gnutls_global_init +enabled wolfssl          && require_pkg_config wolfssl wolfssl wolfssl/ssl.h wolfSSL_library_init enabled jni              && { [ $target_os = "android" ] && check_header jni.h && enabled pthreads || die "ERROR: jni not found"; } enabled ladspa           && require_header ladspa.h enabled libiec61883      && require libiec61883 libiec61883/iec61883.h iec61883_cmp_connect -lraw1394 -lavc1394 -lrom1394 -liec61883 diff -Nur ffmpeg-3.4.2/libavformat/Makef ffmpeg-3.4.2_wolfssl_patch/lib --- ffmpeg-3.4.2/libavformat/Makef 01:29:06.000000000 +0100 +++ ffmpeg-3.4.2_wolfssl_patch/lib 17:38:47.000000000 +0200 @@ -589,6 +589,7 @@ OBJS-$(CONFIG_TCP_PROTOCOL)  += tcp.o OBJS-$(CONFIG_TLS_GNUTLS_PROTO += tls_gnutls.o tls.o OBJS-$(CONFIG_TLS_OPENSSL_PROT += tls_openssl.o tls.o +OBJS-$(CONFIG_TLS_WOLFSSL_PRO += tls_wolfssl.o tls.o OBJS-$(CONFIG_TLS_SCHANNEL_PRO += tls_schannel.o tls.o OBJS-$(CONFIG_TLS_SECURETRANSP += tls_securetransport.o tls.o OBJS-$(CONFIG_UDP_PROTOCOL)  += udp.o diff -Nur ffmpeg-3.4.2/libavformat/netwo ffmpeg-3.4.2_wolfssl_patch/lib --- ffmpeg-3.4.2/libavformat/netwo 01:29:06.000000000 +0100 +++ ffmpeg-3.4.2_wolfssl_patch/lib 17:38:47.000000000 +0200 @@ -37,6 +37,9 @@ #if CONFIG_TLS_GNUTLS_PROTOCOL     ff_gnutls_init(); #endif +#if CONFIG_TLS_WOLFSSL_PROTOCOL +   ff_wolfssl_init(); +#endif     return 0; } @@ -48,6 +51,9 @@ #if CONFIG_TLS_GNUTLS_PROTOCOL     ff_gnutls_deinit(); #endif +#if CONFIG_TLS_WOLFSSL_PROTOCOL +   ff_wolfssl_deinit(); +#endif } int ff_network_inited_globally; diff -Nur ffmpeg-3.4.2/libavformat/proto ffmpeg-3.4.2_wolfssl_patch/lib --- ffmpeg-3.4.2/libavformat/proto 01:29:06.000000000 +0100 +++ ffmpeg-3.4.2_wolfssl_patch/lib 17:38:47.000000000 +0200 @@ -57,6 +57,7 @@ extern const URLProtocol ff_tee_protocol; extern const URLProtocol ff_tcp_protocol; extern const URLProtocol ff_tls_gnutls_protocol; +extern const URLProtocol ff_tls_wolfssl_protocol; extern const URLProtocol ff_tls_schannel_protocol; extern const URLProtocol ff_tls_securetransport_protoco extern const URLProtocol ff_tls_openssl_protocol; diff -Nur ffmpeg-3.4.2/libavformat/tls.h ffmpeg-3.4.2_wolfssl_patch/lib --- ffmpeg-3.4.2/libavformat/tls.h 23:35:49.000000000 +0100 +++ ffmpeg-3.4.2_wolfssl_patch/lib 17:38:47.000000000 +0200 @@ -55,6 +55,9 @@ int ff_tls_open_underlying(TLSShar *c, URLContext *parent, const char *uri, AVDictionary **options); +void ff_wolfssl_init(void); +void ff_wolfssl_deinit(void); + void ff_gnutls_init(void); void ff_gnutls_deinit(void); diff -Nur ffmpeg-3.4.2/libavformat/tls_w ffmpeg-3.4.2_wolfssl_patch/lib --- ffmpeg-3.4.2/libavformat/tls_w 01:00:00.000000000 +0100 +++ ffmpeg-3.4.2_wolfssl_patch/lib 17:41:39.000000000 +0200 @@ -0,0 +1,243 @@ +/* + * TLS/SSL Protocol + * Copyright (c) 2011 Martin Storsjo + * Copyright (c) 2018 samsamsam at o2.pl + * + * This file is part of FFmpeg. + * + * FFmpeg 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. + * + * FFmpeg 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 FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <errno.h> + +#include "avformat.h" +#include "internal.h" +#include "network.h" +#include "os_support.h" +#include "url.h" +#include "tls.h" +#include "libavcodec/internal.h" +#include "libavutil/avstring.h" +#include "libavutil/opt.h" +#include "libavutil/parseutils.h" + +#include <wolfssl/options.h> +#include <wolfssl/ssl.h> + +typedef struct TLSContext { +   const AVClass *class; +   TLSShared tls_shared; +   WOLFSSL_CTX *ctx; +   WOLFSSL *ssl; +} TLSContext; + +static int wolfssl_init; + +void ff_wolfssl_init(void) +{ +   avpriv_lock_avformat(); +   if (!wolfssl_init) { +       wolfSSL_Init(); +   } +   wolfssl_init++; +   avpriv_unlock_avformat(); +} + +void ff_wolfssl_deinit(void) +{ +   avpriv_lock_avformat(); +   wolfssl_init--; +   if (!wolfssl_init) { +       wolfSSL_Cleanup(); +   } +   avpriv_unlock_avformat(); +} + +static int print_tls_error(URLContext *h, int ret) +{ +   char error_buffer[WOLFSSL_MAX_ERROR +   av_log(h, AV_LOG_ERROR, "%ld -> %s\n", wolfSSL_ERR_get_error(), wolfSSL_ERR_error_string(wolfS error_buffer)); +   return AVERROR(EIO); +} + +static int tls_close(URLContext *h) +{ +   TLSContext *c = h->priv_data; +   if (c->ssl) { +       wolfSSL_shutdown(c->ssl); +       wolfSSL_free(c->ssl); +   } +   if (c->ctx) +       wolfSSL_CTX_free(c->ctx); +   if (c->tls_shared.tcp) +       ffurl_close(c->tls_shared.tcp) +   //ff_wolfssl_deinit(); +   return 0; +} + +static ssize_t wolfssl_recv_callback(WOLFSSL* ssl, char* buf, int sz, void* ctx) +{ +   URLContext *h = (URLContext*) ctx; +   int ret = ffurl_read(h, buf, sz); +   if (ret >= 0) +       return ret; +   if (ret == AVERROR_EXIT) +       return WOLFSSL_CBIO_ERR_GENERAL; +   errno = EIO; +   return WOLFSSL_CBIO_ERR_GENERAL; +} + +static ssize_t wolfssl_send_callback(WOLFSSL* ssl, char* buf, int sz, void* ctx) +{ +   URLContext *h = (URLContext*) ctx; +   int ret = ffurl_write(h, buf, sz); +   if (ret >= 0) +       return ret; +   if (ret == AVERROR_EXIT) +       return WOLFSSL_CBIO_ERR_GENERAL; +   errno = EIO; +   return WOLFSSL_CBIO_ERR_GENERAL; +} + +static int tls_open(URLContext *h, const char *uri, int flags, AVDictionary **options) +{ +   char error_buffer[WOLFSSL_MAX_ERROR +   TLSContext *p = h->priv_data; +   TLSShared *c = &p->tls_shared; +   int ret; + +   //ff_wolfssl_init(); + +   if ((ret = ff_tls_open_underlying(c, h, uri, options)) < 0) +       goto fail; + +    p->ctx = wolfSSL_CTX_new(c->listen ? wolfSSLv23_server_method() : wolfSSLv23_client_method()); // wolfTLSv1_1_client_method +#ifndef NO_FILESYSTEM +   if (!p->ctx) { +       av_log(h, AV_LOG_ERROR, "%s\n", wolfSSL_ERR_error_string(wolfS error_buffer)); +       ret = AVERROR(EIO); +       goto fail; +   } +   if (c->ca_file) { +       if (!wolfSSL_CTX_load_verify_loca c->ca_file, NULL)) +           av_log(h, AV_LOG_ERROR, "wolfSSL_CTX_load_verify_locat %s\n", wolfSSL_ERR_error_string(wolfS error_buffer)); +   } +   if (c->cert_file && !wolfSSL_CTX_use_certificate_c c->cert_file)) { +       av_log(h, AV_LOG_ERROR, "Unable to load cert file %s: %s\n", +              c->cert_file, wolfSSL_ERR_error_string(wolfS error_buffer)); +       ret = AVERROR(EIO); +       goto fail; +   } +   if (c->key_file && !wolfSSL_CTX_use_PrivateKey_fi c->key_file, WOLFSSL_FILETYPE_PEM)) { +       av_log(h, AV_LOG_ERROR, "Unable to load key file %s: %s\n", +              c->key_file, wolfSSL_ERR_error_string(wolfS error_buffer)); +       ret = AVERROR(EIO); +       goto fail; +   } +#endif +   +   wolfSSL_CTX_set_verify(p->ctx, +               c->verify ? WOLFSSL_VERIFY_PEER | WOLFSSL_VERIFY_FAIL_IF_NO_PEER : +               WOLFSSL_VERIFY_NONE, +               NULL); +   +#ifdef HAVE_SNI +   if (!c->listen && !c->numerichost && !wolfSSL_CTX_UseSNI(p->ctx, WOLFSSL_SNI_HOST_NAME, c->host, +               (unsigned short)strlen(c->host))) { +       av_log(h, AV_LOG_ERROR, "failed to configure server name indication (SNI) %s: %ld -> %s\n", +               c->host, wolfSSL_ERR_get_error(), wolfSSL_ERR_error_string(wolfS error_buffer)); +   } +#endif + +   wolfSSL_CTX_SetIORecv(p->ctx, wolfssl_recv_callback); +   wolfSSL_CTX_SetIOSend(p->ctx, wolfssl_send_callback); +   +   p->ssl = wolfSSL_new(p->ctx); +   if (!p->ssl) { +       av_log(h, AV_LOG_ERROR, "%s\n", wolfSSL_ERR_error_string(wolfS error_buffer)); +       ret = AVERROR(EIO); +       goto fail; +   } +   +   wolfSSL_SetIOReadCtx(p->ssl, c->tcp); +   wolfSSL_SetIOWriteCtx(p->ssl, c->tcp); +   +   ret = c->listen ? wolfSSL_accept(p->ssl) : wolfSSL_connect(p->ssl); +   if (ret == 0) { +       av_log(h, AV_LOG_ERROR, "Unable to negotiate TLS/SSL session\n"); +       ret = AVERROR(EIO); +       goto fail; +   } else if (ret < 0) { +       ret = print_tls_error(h, ret); +       goto fail; +   } +   +   return 0; +fail: +   tls_close(h); +   return ret; +} + +static int tls_read(URLContext *h, uint8_t *buf, int size) +{ +   TLSContext *c = h->priv_data; +   int ret = wolfSSL_read(c->ssl, buf, size); +   if (ret > 0) +       return ret; +   if (ret == 0) +       return AVERROR_EOF; +   return print_tls_error(h, ret); +} + +static int tls_write(URLContext *h, const uint8_t *buf, int size) +{ +   TLSContext *c = h->priv_data; +   int ret = wolfSSL_write(c->ssl, buf, size); +   if (ret > 0) +       return ret; +   if (ret == 0) +       return AVERROR_EOF; +   return print_tls_error(h, ret); +} + +static int tls_get_file_handle(URLContext *h) +{ +   TLSContext *c = h->priv_data; +   return ffurl_get_file_handle(c->tls_s +} + +static const AVOption options[] = { +   TLS_COMMON_OPTIONS(TLSContext, tls_shared), +   { NULL } +}; + +static const AVClass tls_class = { +   .class_name = "tls", +   .item_name = av_default_item_name, +   .option    = options, +   .version   = LIBAVUTIL_VERSION_INT, +}; + +const URLProtocol ff_tls_wolfssl_protocol = { +   .name          = "tls", +   .url_open2     = tls_open, +   .url_read      = tls_read, +   .url_write     = tls_write, +   .url_close     = tls_close, +   .url_get_file_handle = tls_get_file_handle, +   .priv_data_size = sizeof(TLSContext), +   .flags         = URL_PROTOCOL_FLAG_NETWORK, +   .priv_data_class = &tls_class, +};
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 01_wolfssl_backend.patch
Type: application/octet-stream
Size: 14028 bytes
Desc: not available
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20180828/e76d1d48/attachment.obj>
More information about the ffmpeg-devel
mailing list