PR #24591 opened by ffmpeg-devel
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24591
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24591.patch

**Backport:** https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/22709

Without setting this flag, apparently gnutls will only send the client
certificate according some logic based on what it thinks the server
accepts.
This is not the case a lot of times.
Just force it to send the client cert the user supplied, if one was
supplied, no matter what.

Fixes #22707


>From 1041abdc962f4cc4f394aa8de9dc5236c0c3b9e7 Mon Sep 17 00:00:00 2001
From: Timo Rothenpieler <[email protected]>
Date: Sat, 4 Apr 2026 17:58:30 +0200
Subject: [PATCH] avformat/tls_gnutls: actually send client cert if one is
 provided

Without setting this flag, apparently gnutls will only send the client
certificate according some logic based on what it thinks the server
accepts.
This is not the case a lot of times.
Just force it to send the client cert the user supplied, if one was
supplied, no matter what.

Fixes #22707

(cherry picked from commit 5c35d0b880156bef542d7221a6d96fe46f6d22aa)
---
 libavformat/tls_gnutls.c | 33 +++++++++++++++++++++++----------
 1 file changed, 23 insertions(+), 10 deletions(-)

diff --git a/libavformat/tls_gnutls.c b/libavformat/tls_gnutls.c
index 9bb272a308..4550a2724d 100644
--- a/libavformat/tls_gnutls.c
+++ b/libavformat/tls_gnutls.c
@@ -532,6 +532,7 @@ static int tls_open(URLContext *h, const char *uri, int 
flags, AVDictionary **op
     uint16_t gnutls_flags = 0;
     gnutls_x509_crt_t cert = NULL;
     gnutls_x509_privkey_t pkey = NULL;
+    int have_cert_pkey = 0;
     int ret;
 
     ff_gnutls_init();
@@ -556,16 +557,6 @@ static int tls_open(URLContext *h, const char *uri, int 
flags, AVDictionary **op
         }
     }
 
-    if (s->is_dtls)
-        gnutls_flags |= GNUTLS_DATAGRAM;
-
-    if (s->listen)
-        gnutls_flags |= GNUTLS_SERVER;
-    else
-        gnutls_flags |= GNUTLS_CLIENT;
-    gnutls_init(&c->session, gnutls_flags);
-    if (!s->listen && !s->numerichost)
-        gnutls_server_name_set(c->session, GNUTLS_NAME_DNS, s->host, 
strlen(s->host));
     gnutls_certificate_allocate_credentials(&c->cred);
     if (s->ca_file) {
         ret = gnutls_certificate_set_x509_trust_file(c->cred, s->ca_file, 
GNUTLS_X509_FMT_PEM);
@@ -589,6 +580,7 @@ static int tls_open(URLContext *h, const char *uri, int 
flags, AVDictionary **op
             ret = AVERROR(EIO);
             goto fail;
         }
+        have_cert_pkey = 1;
     } else if (s->cert_file || s->key_file) {
         av_log(h, AV_LOG_ERROR, "cert and key required\n");
     } else if (s->cert_buf && s->key_buf) {
@@ -600,6 +592,7 @@ static int tls_open(URLContext *h, const char *uri, int 
flags, AVDictionary **op
             ret = AVERROR(EINVAL);
             goto fail;
         }
+        have_cert_pkey = 1;
     } else if (s->cert_buf || s->key_buf) {
         av_log(h, AV_LOG_ERROR, "cert and key required\n");
     }
@@ -621,7 +614,27 @@ static int tls_open(URLContext *h, const char *uri, int 
flags, AVDictionary **op
             ret = AVERROR(EINVAL);
             goto fail;
         }
+
+        have_cert_pkey = 1;
     }
+
+    if (s->is_dtls)
+        gnutls_flags |= GNUTLS_DATAGRAM;
+
+    if (s->listen)
+        gnutls_flags |= GNUTLS_SERVER;
+    else {
+        gnutls_flags |= GNUTLS_CLIENT;
+#if GNUTLS_VERSION_NUMBER >= 0x030500
+        if (have_cert_pkey)
+            gnutls_flags |= GNUTLS_FORCE_CLIENT_CERT;
+#endif
+    }
+
+    gnutls_init(&c->session, gnutls_flags);
+
+    if (!s->listen && !s->numerichost)
+        gnutls_server_name_set(c->session, GNUTLS_NAME_DNS, s->host, 
strlen(s->host));
     gnutls_credentials_set(c->session, GNUTLS_CRD_CERTIFICATE, c->cred);
     gnutls_transport_set_pull_function(c->session, gnutls_url_pull);
     gnutls_transport_set_push_function(c->session, gnutls_url_push);
-- 
2.52.0

_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to