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 [email protected] + * + * 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 [email protected] http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
