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 samsam...@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, +};
01_wolfssl_backend.patch
Description: Binary data
_______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel