aboutsummaryrefslogtreecommitdiffhomepage
path: root/subprojects/packagefiles/ffmpeg-mbedtls-default-ca-certs.patch
blob: a22d4ae0d5135fbf2dafcce6989348074a2893e5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
--- a/libavformat/tls_mbedtls.c
+++ b/libavformat/tls_mbedtls.c
@@ -42,6 +42,66 @@
 #include "libavutil/avstring.h"
 #include "libavutil/random_seed.h"
 #include "libavutil/intreadwrite.h"
+#include "libavutil/getenv_utf8.h"
+
+/*
+ * mbedtls has no built-in default certificate location, unlike openssl which
+ * falls back to the location it was compiled with. Without this the peer
+ * certificate can only be verified when the caller passes a ca_file, so look
+ * for the certificate store of the system instead, honoring the same
+ * environment variables as openssl does.
+ */
+static const char * const default_ca_files[] = {
+    "/etc/ssl/ca-bundle.pem",             // opensuse
+    "/etc/ssl/cert.pem",                  // openbsd, freebsd, macos
+    "/usr/local/etc/ssl/cert.pem",        // freebsd ports
+};
+
+static const char * const default_ca_dirs[] = {
+    "/etc/ssl/certs",
+    "/etc/pki/tls/certs",
+};
+
+/* A positive return value from mbedtls means that only some of the certificates failed to parse, which is not fatal */
+static int mbedtls_load_default_ca_certs(URLContext *h, mbedtls_x509_crt *ca_cert)
+{
+    char *env_ca_file = getenv_utf8("SSL_CERT_FILE");
+    char *env_ca_dir = getenv_utf8("SSL_CERT_DIR");
+    int loaded = 0;
+
+    if (env_ca_file && mbedtls_x509_crt_parse_file(ca_cert, env_ca_file) >= 0)
+        loaded = 1;
+
+    if (!loaded && env_ca_dir && mbedtls_x509_crt_parse_path(ca_cert, env_ca_dir) >= 0)
+        loaded = 1;
+
+    freeenv_utf8(env_ca_file);
+    freeenv_utf8(env_ca_dir);
+
+    for (size_t i = 0; !loaded && i < FF_ARRAY_ELEMS(default_ca_files); i++) {
+        if (mbedtls_x509_crt_parse_file(ca_cert, default_ca_files[i]) >= 0) {
+            av_log(h, AV_LOG_VERBOSE, "loaded CA certificates from %s\n", default_ca_files[i]);
+            loaded = 1;
+        }
+    }
+
+    for (size_t i = 0; !loaded && i < FF_ARRAY_ELEMS(default_ca_dirs); i++) {
+        if (mbedtls_x509_crt_parse_path(ca_cert, default_ca_dirs[i]) >= 0) {
+            av_log(h, AV_LOG_VERBOSE, "loaded CA certificates from %s\n", default_ca_dirs[i]);
+            loaded = 1;
+        }
+    }
+
+    if (!loaded) {
+        av_log(h, AV_LOG_WARNING, "unable to find the CA certificates of the system, "
+                                  "certificate verification is going to fail\n");
+        return AVERROR(ENOENT);
+    }
+
+    return 0;
+}
 
 static int mbedtls_x509_fingerprint(char *cert_buf, size_t cert_sz, char **fingerprint)
 {
@@ -557,6 +617,9 @@
             av_log(h, AV_LOG_ERROR, "mbedtls_x509_crt_parse_file for CA cert returned %d\n", ret);
             goto fail;
         }
+    } else if (shr->verify) {
+        // Only a warning is logged when this fails, matching what the openssl backend does
+        mbedtls_load_default_ca_certs(h, &tls_ctx->ca_cert);
     }
 
     // load own certificate