Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
 help / color / mirror / Atom feed
* [FFmpeg-devel] PATCH - wolfSSL TLS support
@ 2022-05-01 23:04 David Fletcher
  2022-05-02 11:05 ` Timo Rothenpieler
  0 siblings, 1 reply; 4+ messages in thread
From: David Fletcher @ 2022-05-01 23:04 UTC (permalink / raw)
  To: ffmpeg-devel

[-- Attachment #1: Type: text/plain, Size: 778 bytes --]

Please find attached a patch adding support for wolfSSL as a TLS backend.
This is against release ffmpeg-5.0.1, and is working well with wolfSSL
5.1.1 (January 2022 release).

This is based on a patch previously submitted in 2018 which never made it
into the mail codebase, but now updated for ffmpeg-5.0.1. The previous
version by samsamsam is at
https://lists.ffmpeg.org/pipermail/ffmpeg-devel/2018-August/233802.html.

Does this look useful? I developed this after identifying wolfSSL as most
suitable for adding TLS capability to very resource limited hardware
(Reciva internet radios, based around an ARMv4 CPU and just 32MB RAM,
for context more info about this application here:
http://www.megapico.co.uk/sharpfin/mediaserver.html).

Best regards, David.

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: wolfssl.patch --]
[-- Type: text/x-patch; name="wolfssl.patch", Size: 13454 bytes --]

diff -Nur ./ffmpeg-5.0.1/configure ./ffmpeg-5.0.1-wolfssl/configure
--- ./ffmpeg-5.0.1/configure	2022-04-04 15:40:22.000000000 +0100
+++ ./ffmpeg-5.0.1-wolfssl/configure	2022-05-01 22:58:55.672449527 +0100
@@ -212,7 +212,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, 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]
@@ -276,7 +276,7 @@
   --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]
@@ -287,6 +287,8 @@
                            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]
@@ -315,7 +317,7 @@
   --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
@@ -1880,6 +1882,7 @@
     openssl
     pocketsphinx
     vapoursynth
+    wolfssl
 "
 
 HWACCEL_AUTODETECT_LIBRARY_LIST="
@@ -3576,7 +3579,7 @@
 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 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 libaom            && require_pkg_config libaom "aom >= 1.0.0" aom/aom_codec.h aom_codec_version
diff -Nur ./ffmpeg-5.0.1/libavformat/Makefile ./ffmpeg-5.0.1-wolfssl/libavformat/Makefile
--- ./ffmpeg-5.0.1/libavformat/Makefile	2022-01-14 18:45:40.000000000 +0000
+++ ./ffmpeg-5.0.1-wolfssl/libavformat/Makefile	2022-04-05 21:53:03.000000000 +0100
@@ -660,6 +660,7 @@
 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 -Nur ./ffmpeg-5.0.1/libavformat/network.c ./ffmpeg-5.0.1-wolfssl/libavformat/network.c
--- ./ffmpeg-5.0.1/libavformat/network.c	2021-10-21 18:06:35.000000000 +0100
+++ ./ffmpeg-5.0.1-wolfssl/libavformat/network.c	2022-04-05 21:50:42.000000000 +0100
@@ -39,6 +39,9 @@
 #if CONFIG_GNUTLS
     ff_gnutls_init();
 #endif
+#if CONFIG_WOLFSSL
+    ff_wolfssl_init();
+#endif
 #endif
     return 0;
 }
@@ -52,6 +55,9 @@
 #if CONFIG_GNUTLS
     ff_gnutls_deinit();
 #endif
+#if CONFIG_WOLFSSL
+    ff_wolfssl_deinit();
+#endif
 #endif
 }
 
diff -Nur ./ffmpeg-5.0.1/libavformat/tls.h ./ffmpeg-5.0.1-wolfssl/libavformat/tls.h
--- ./ffmpeg-5.0.1/libavformat/tls.h	2021-10-24 21:47:07.000000000 +0100
+++ ./ffmpeg-5.0.1-wolfssl/libavformat/tls.h	2022-04-05 21:46:32.000000000 +0100
@@ -55,6 +55,9 @@
 
 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 -Nur ./ffmpeg-5.0.1/libavformat/tls_wolfssl.c ./ffmpeg-5.0.1-wolfssl/libavformat/tls_wolfssl.c
--- ./ffmpeg-5.0.1/libavformat/tls_wolfssl.c	1970-01-01 01:00:00.000000000 +0100
+++ ./ffmpeg-5.0.1-wolfssl/libavformat/tls_wolfssl.c	2022-04-12 15:56:38.000000000 +0100
@@ -0,0 +1,248 @@
+/*
+ * 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);
+    //ff_wolfssl_deinit();
+    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;
+     // Modified to compile with minimal wolfSSL library which only has client methods
+     //p->ctx = wolfSSL_CTX_new(c->listen ? wolfSSLv23_server_method() : wolfSSLv23_client_method()); // wolfTLSv1_1_client_method
+     p->ctx = wolfSSL_CTX_new(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); 
+    
+    // Modified to compile with minimal wolfSSL library which only has client methods
+    //ret = c->listen ? wolfSSL_accept(p->ssl) : wolfSSL_connect(p->ssl);
+    ret = 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,
+};

[-- 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".

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [FFmpeg-devel] PATCH - wolfSSL TLS support
  2022-05-01 23:04 [FFmpeg-devel] PATCH - wolfSSL TLS support David Fletcher
@ 2022-05-02 11:05 ` Timo Rothenpieler
  2022-05-02 18:05   ` David Fletcher
  0 siblings, 1 reply; 4+ messages in thread
From: Timo Rothenpieler @ 2022-05-02 11:05 UTC (permalink / raw)
  To: ffmpeg-devel

On 02.05.2022 01:04, David Fletcher wrote:
> Please find attached a patch adding support for wolfSSL as a TLS backend.
> This is against release ffmpeg-5.0.1, and is working well with wolfSSL
> 5.1.1 (January 2022 release).

Only patches against master can be accepted.
New stuff like this does not get backported either. Only fixes for 
existing features.
_______________________________________________
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".

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [FFmpeg-devel] PATCH - wolfSSL TLS support
  2022-05-02 11:05 ` Timo Rothenpieler
@ 2022-05-02 18:05   ` David Fletcher
  2022-05-03 18:37     ` David Fletcher
  0 siblings, 1 reply; 4+ messages in thread
From: David Fletcher @ 2022-05-02 18:05 UTC (permalink / raw)
  To: FFmpeg development discussions and patches

[-- Attachment #1: Type: text/plain, Size: 350 bytes --]

On 2/5/2022, "Timo Rothenpieler" <timo@rothenpieler.org> wrote:
>Only patches against master can be accepted.
>New stuff like this does not get backported either. Only fixes for
>existing features.

Hi Timo,

Thanks for the comments. Please find attached an updated patch against
the master
(ffmpeg-master-b67572c).

Best regards, David.

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: wolfssl-b67572c.patch --]
[-- Type: text/x-patch; name="wolfssl-b67572c.patch", Size: 13177 bytes --]

diff -Nur ./ffmpeg-master-b67572c/configure ./ffmpeg-master-b67572c-wolfssl/configure
--- ./ffmpeg-master-b67572c/configure	2022-05-02 16:10:22.000000000 +0100
+++ ./ffmpeg-master-b67572c-wolfssl/configure	2022-05-02 17:52:25.646019060 +0100
@@ -211,7 +211,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, 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 @@
   --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 @@
                            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 @@
   --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 @@
     openssl
     pocketsphinx
     vapoursynth
+    wolfssl
 "
 
 HWACCEL_AUTODETECT_LIBRARY_LIST="
@@ -3581,7 +3584,7 @@
 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 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 -Nur ./ffmpeg-master-b67572c/libavformat/Makefile ./ffmpeg-master-b67572c-wolfssl/libavformat/Makefile
--- ./ffmpeg-master-b67572c/libavformat/Makefile	2022-05-02 16:10:22.000000000 +0100
+++ ./ffmpeg-master-b67572c-wolfssl/libavformat/Makefile	2022-05-02 17:52:25.647019060 +0100
@@ -667,6 +667,7 @@
 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 -Nur ./ffmpeg-master-b67572c/libavformat/network.c ./ffmpeg-master-b67572c-wolfssl/libavformat/network.c
--- ./ffmpeg-master-b67572c/libavformat/network.c	2022-05-02 16:10:22.000000000 +0100
+++ ./ffmpeg-master-b67572c-wolfssl/libavformat/network.c	2022-05-02 17:52:25.648019060 +0100
@@ -39,6 +39,9 @@
 #if CONFIG_GNUTLS
     ff_gnutls_init();
 #endif
+#if CONFIG_WOLFSSL
+    ff_wolfssl_init();
+#endif
 #endif
     return 0;
 }
@@ -52,6 +55,9 @@
 #if CONFIG_GNUTLS
     ff_gnutls_deinit();
 #endif
+#if CONFIG_WOLFSSL
+    ff_wolfssl_deinit();
+#endif
 #endif
 }
 
diff -Nur ./ffmpeg-master-b67572c/libavformat/tls.h ./ffmpeg-master-b67572c-wolfssl/libavformat/tls.h
--- ./ffmpeg-master-b67572c/libavformat/tls.h	2022-05-02 16:10:22.000000000 +0100
+++ ./ffmpeg-master-b67572c-wolfssl/libavformat/tls.h	2022-05-02 17:52:25.648019060 +0100
@@ -55,6 +55,9 @@
 
 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 -Nur ./ffmpeg-master-b67572c/libavformat/tls_wolfssl.c ./ffmpeg-master-b67572c-wolfssl/libavformat/tls_wolfssl.c
--- ./ffmpeg-master-b67572c/libavformat/tls_wolfssl.c	1970-01-01 01:00:00.000000000 +0100
+++ ./ffmpeg-master-b67572c-wolfssl/libavformat/tls_wolfssl.c	2022-05-02 18:21:16.839074459 +0100
@@ -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,
+};

[-- 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".

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [FFmpeg-devel] PATCH - wolfSSL TLS support
  2022-05-02 18:05   ` David Fletcher
@ 2022-05-03 18:37     ` David Fletcher
  0 siblings, 0 replies; 4+ messages in thread
From: David Fletcher @ 2022-05-03 18:37 UTC (permalink / raw)
  To: FFmpeg development discussions and patches

[-- 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".

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2022-05-03 18:38 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-05-01 23:04 [FFmpeg-devel] PATCH - wolfSSL TLS support David Fletcher
2022-05-02 11:05 ` Timo Rothenpieler
2022-05-02 18:05   ` David Fletcher
2022-05-03 18:37     ` David Fletcher

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