From: "David Fletcher" <David@megapico.co.uk> To: "FFmpeg development discussions and patches" <ffmpeg-devel@ffmpeg.org> Subject: Re: [FFmpeg-devel] PATCH - wolfSSL TLS support Date: Tue, 03 May 2022 18:37:35 +0000 Message-ID: <TkZB9Jkk.1651603055.5850040.dif@localhost> (raw) In-Reply-To: <xXK2lu6V.1651514736.5879990.dif@localhost> [-- Attachment #1: Type: text/plain, Size: 335 bytes --] Following today's posts about help with submitting patches I realised I sent the patch yesterday to add wolfSSL as a TLS backend in the wrong format. Apologies, I was not familiar with the git format patches. Hopefully the attached version is now in the correct format against the current master branch. Best regards, David. [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: wolfSSL-git-master.patch --] [-- Type: text/x-patch; name="wolfSSL-git-master.patch", Size: 13433 bytes --] From 3fc91e85b31ce0e5422f6ffe39d7d2287bce5939 Mon Sep 17 00:00:00 2001 From: David Fletcher <david@megapico.co.uk> Date: Tue, 3 May 2022 19:23:50 +0100 Subject: [PATCH] Patched to work with wolfSSL as a new TLS backend Signed-off-by: David Fletcher <david@megapico.co.uk> --- configure | 12 +- libavformat/Makefile | 1 + libavformat/network.c | 6 + libavformat/tls.h | 3 + libavformat/tls_wolfssl.c | 241 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 259 insertions(+), 4 deletions(-) create mode 100644 libavformat/tls_wolfssl.c diff --git a/configure b/configure index 196873c4aa..b20d94bfbd 100755 --- a/configure +++ b/configure @@ -211,7 +211,7 @@ External library support: --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, libtls or mbedtls is not used [no] + if openssl, libtls, wolfssl or mbedtls is not used [no] --disable-iconv disable iconv [autodetect] --enable-jni enable JNI support [no] --enable-ladspa enable LADSPA audio filtering [no] @@ -278,7 +278,7 @@ External library support: --enable-libtesseract enable Tesseract, needed for ocr filter [no] --enable-libtheora enable Theora encoding via libtheora [no] --enable-libtls enable LibreSSL (via libtls), needed for https support - if openssl, gnutls or mbedtls is not used [no] + if openssl, gnutls, wolfssl or mbedtls is not used [no] --enable-libtwolame enable MP2 encoding via libtwolame [no] --enable-libuavs3d enable AVS3 decoding via libuavs3d [no] --enable-libv4l2 enable libv4l2/v4l-utils [no] @@ -289,6 +289,8 @@ External library support: native implementation exists [no] --enable-libvpx enable VP8 and VP9 de/encoding via libvpx [no] --enable-libwebp enable WebP encoding via libwebp [no] + --enable-wolfssl enable WolfSSL), needed for https support + if openssl, gnutls, libtls or mbedtls 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] @@ -317,7 +319,7 @@ External library support: --enable-opencl enable OpenCL processing [no] --enable-opengl enable OpenGL rendering [no] --enable-openssl enable openssl, needed for https support - if gnutls, libtls or mbedtls is not used [no] + if gnutls, libtls, wolfssl or mbedtls is not used [no] --enable-pocketsphinx enable PocketSphinx, needed for asr filter [no] --disable-sndio disable sndio support [autodetect] --disable-schannel disable SChannel SSP, needed for TLS support on @@ -1885,6 +1887,7 @@ EXTERNAL_LIBRARY_LIST=" openssl pocketsphinx vapoursynth + wolfssl " HWACCEL_AUTODETECT_LIBRARY_LIST=" @@ -3581,7 +3584,7 @@ sctp_protocol_select="network" securetransport_conflict="openssl gnutls libtls mbedtls" srtp_protocol_select="rtp_protocol srtp" tcp_protocol_select="network" -tls_protocol_deps_any="gnutls openssl schannel securetransport libtls mbedtls" +tls_protocol_deps_any="gnutls openssl schannel securetransport libtls mbedtls wolfssl" tls_protocol_select="tcp_protocol" udp_protocol_select="network" udplite_protocol_select="network" @@ -6512,6 +6515,7 @@ enabled decklink && { require_headers DeckLinkAPI.h && enabled frei0r && require_headers "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_headers jni.h && enabled pthreads || die "ERROR: jni not found"; } enabled ladspa && require_headers "ladspa.h dlfcn.h" enabled lcms2 && require_pkg_config lcms2 "lcms2 >= 2.13" lcms2.h cmsCreateContext diff --git a/libavformat/Makefile b/libavformat/Makefile index f16634a418..6e95bb1eee 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -667,6 +667,7 @@ TLS-OBJS-$(CONFIG_GNUTLS) += tls_gnutls.o TLS-OBJS-$(CONFIG_LIBTLS) += tls_libtls.o TLS-OBJS-$(CONFIG_MBEDTLS) += tls_mbedtls.o TLS-OBJS-$(CONFIG_OPENSSL) += tls_openssl.o +TLS-OBJS-$(CONFIG_WOLFSSL) += tls_wolfssl.o TLS-OBJS-$(CONFIG_SECURETRANSPORT) += tls_securetransport.o TLS-OBJS-$(CONFIG_SCHANNEL) += tls_schannel.o OBJS-$(CONFIG_TLS_PROTOCOL) += tls.o $(TLS-OBJS-yes) diff --git a/libavformat/network.c b/libavformat/network.c index 21e20b3e9a..b25f8edf3c 100644 --- a/libavformat/network.c +++ b/libavformat/network.c @@ -39,6 +39,9 @@ int ff_tls_init(void) #if CONFIG_GNUTLS ff_gnutls_init(); #endif +#if CONFIG_WOLFSSL + ff_wolfssl_init(); +#endif #endif return 0; } @@ -52,6 +55,9 @@ void ff_tls_deinit(void) #if CONFIG_GNUTLS ff_gnutls_deinit(); #endif +#if CONFIG_WOLFSSL + ff_wolfssl_deinit(); +#endif #endif } diff --git a/libavformat/tls.h b/libavformat/tls.h index 6c6aa01a9a..0cfad1c82b 100644 --- a/libavformat/tls.h +++ b/libavformat/tls.h @@ -55,6 +55,9 @@ typedef struct TLSShared { int ff_tls_open_underlying(TLSShared *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 --git a/libavformat/tls_wolfssl.c b/libavformat/tls_wolfssl.c new file mode 100644 index 0000000000..f0c50088b0 --- /dev/null +++ b/libavformat/tls_wolfssl.c @@ -0,0 +1,241 @@ +/* + * TLS/SSL Protocol + * Copyright (c) 2011 Martin Storsjo + * Copyright (c) 2018 samsamsam@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) +{ + ff_lock_avformat(); + if (!wolfssl_init) { + wolfSSL_Init(); + } + wolfssl_init++; + ff_unlock_avformat(); +} + +void ff_wolfssl_deinit(void) +{ + ff_lock_avformat(); + wolfssl_init--; + if (!wolfssl_init) { + wolfSSL_Cleanup(); + } + ff_unlock_avformat(); +} + +static int print_tls_error(URLContext *h, int ret, WOLFSSL *ssl) +{ + char error_buffer[WOLFSSL_MAX_ERROR_SZ]; + av_log(h, AV_LOG_ERROR, "%i -> %s\n", wolfSSL_get_error(ssl,0), wolfSSL_ERR_error_string(wolfSSL_get_error(ssl,0), 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); + return 0; +} + +static int 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 int 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_SZ]; + 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()); +#ifndef NO_FILESYSTEM + if (!p->ctx) { + av_log(h, AV_LOG_ERROR, "%s\n", wolfSSL_ERR_error_string(wolfSSL_get_error(p->ssl,0), error_buffer)); + ret = AVERROR(EIO); + goto fail; + } + if (c->ca_file) { + if (!wolfSSL_CTX_load_verify_locations(p->ctx, c->ca_file, NULL)) + av_log(h, AV_LOG_ERROR, "wolfSSL_CTX_load_verify_locations %s\n", wolfSSL_ERR_error_string(wolfSSL_get_error(p->ssl,0), error_buffer)); + } + if (c->cert_file && !wolfSSL_CTX_use_certificate_chain_file(p->ctx, c->cert_file)) { + av_log(h, AV_LOG_ERROR, "Unable to load cert file %s: %s\n", + c->cert_file, wolfSSL_ERR_error_string(wolfSSL_get_error(p->ssl,0), error_buffer)); + ret = AVERROR(EIO); + goto fail; + } + if (c->key_file && !wolfSSL_CTX_use_PrivateKey_file(p->ctx, 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(wolfSSL_get_error(p->ssl,0), 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_CERT : + 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_get_error(p->ssl,0), wolfSSL_ERR_error_string(wolfSSL_get_error(p->ssl,0), 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(wolfSSL_get_error(p->ssl,0), 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, p->ssl); + 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, c->ssl); +} + +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, c->ssl); +} + +static int tls_get_file_handle(URLContext *h) +{ + TLSContext *c = h->priv_data; + return ffurl_get_file_handle(c->tls_shared.tcp); +} + +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_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, +}; -- 2.17.6 [-- Attachment #3: Type: text/plain, Size: 251 bytes --] _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
prev parent reply other threads:[~2022-05-03 18:38 UTC|newest] Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top 2022-05-01 23:04 David Fletcher 2022-05-02 11:05 ` Timo Rothenpieler 2022-05-02 18:05 ` David Fletcher 2022-05-03 18:37 ` David Fletcher [this message]
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=TkZB9Jkk.1651603055.5850040.dif@localhost \ --to=david@megapico.co.uk \ --cc=ffmpeg-devel@ffmpeg.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel This inbox may be cloned and mirrored by anyone: git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git # If you have public-inbox 1.1+ installed, you may # initialize and index your mirror using the following commands: public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \ ffmpegdev@gitmailbox.com public-inbox-index ffmpegdev Example config snippet for mirrors. AGPL code for this site: git clone https://public-inbox.org/public-inbox.git