FFmpeg
tls_mbedtls.c
Go to the documentation of this file.
1 /*
2  * TLS/SSL Protocol
3  * Copyright (c) 2018 Thomas Volkert
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #include <mbedtls/version.h>
23 #include <mbedtls/ctr_drbg.h>
24 #include <mbedtls/entropy.h>
25 #include <mbedtls/net_sockets.h>
26 #include <mbedtls/platform.h>
27 #include <mbedtls/ssl.h>
28 #include <mbedtls/x509_crt.h>
29 #include <mbedtls/debug.h>
30 #include <mbedtls/timing.h>
31 #ifdef MBEDTLS_PSA_CRYPTO_C
32 #include <psa/crypto.h>
33 #endif
34 
35 #include "avformat.h"
36 #include "internal.h"
37 #include "network.h"
38 #include "url.h"
39 #include "tls.h"
40 #include "libavutil/mem.h"
41 #include "libavutil/parseutils.h"
42 #include "libavutil/avstring.h"
43 #include "libavutil/random_seed.h"
44 
45 static int mbedtls_x509_fingerprint(char *cert_buf, size_t cert_sz, char **fingerprint)
46 {
47  unsigned char md[32];
48  size_t n = sizeof(md);
49  AVBPrint buf;
50  int ret;
51  mbedtls_x509_crt crt;
52 
53  mbedtls_x509_crt_init(&crt);
54 
55  if ((ret = mbedtls_x509_crt_parse(&crt, cert_buf, cert_sz)) != 0) {
56  mbedtls_x509_crt_free(&crt);
57  return AVERROR(EINVAL);
58  }
59 
60  if ((ret = mbedtls_sha256(crt.raw.p, crt.raw.len, md, 0)) != 0) {
61  mbedtls_x509_crt_free(&crt);
62  return AVERROR(EINVAL);
63  }
64 
65  av_bprint_init(&buf, n*3, n*3);
66 
67  for (int i = 0; i < n - 1; i++)
68  av_bprintf(&buf, "%02X:", md[i]);
69  av_bprintf(&buf, "%02X", md[n - 1]);
70 
71  return av_bprint_finalize(&buf, fingerprint);
72 }
73 
74 int ff_ssl_read_key_cert(char *key_url, char *cert_url, char *key_buf, size_t key_sz, char *cert_buf, size_t cert_sz, char **fingerprint)
75 {
76  int ret = 0;
77  AVBPrint key_bp, cert_bp;
80 
81  ret = ff_url_read_all(key_url, &key_bp);
82  if (ret < 0) {
83  av_log(NULL, AV_LOG_ERROR, "TLS: Failed to open key file %s\n", key_url);
84  goto end;
85  }
86 
87  ret = ff_url_read_all(cert_url, &cert_bp);
88  if (ret < 0) {
89  av_log(NULL, AV_LOG_ERROR, "TLS: Failed to open cert file %s\n", cert_url);
90  goto end;
91  }
92 
93  if (key_sz < key_bp.size || cert_sz < cert_bp.size) {
94  av_log(NULL, AV_LOG_ERROR, "TLS: Key or Cert buffer is too samall\n");
96  goto end;
97  }
98 
99  key_buf = key_bp.str;
100  cert_buf = cert_bp.str;
101 
102  ret = mbedtls_x509_fingerprint(cert_buf, cert_sz, fingerprint);
103  if (ret < 0)
104  av_log(NULL, AV_LOG_ERROR, "TLS: Failed to generate fingerprint\n");
105 end:
106  av_bprint_finalize(&key_bp, NULL);
107  av_bprint_finalize(&cert_bp, NULL);
108  return ret;
109 }
110 
111 static int mbedtls_gen_pkey(mbedtls_pk_context *key)
112 {
113  int ret = 0;
114  mbedtls_entropy_context entropy;
115  mbedtls_ctr_drbg_context ctr_drbg;
116 
117  mbedtls_entropy_init(&entropy);
118  mbedtls_ctr_drbg_init(&ctr_drbg);
119 
120  if ((ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func,
121  &entropy, NULL, 0)) != 0) {
122  av_log(NULL, AV_LOG_ERROR, "mbedtls_ctr_drbg_seed returned %d\n", ret);
123  goto end;
124  }
125 
126  if ((ret = mbedtls_pk_setup(key,
127  mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY))) != 0) {
128  av_log(NULL, AV_LOG_ERROR, "mbedtls_pk_setup returned %d\n", ret);
129  goto end;
130  }
131  /**
132  * See RFC 8827 section 6.5,
133  * All implementations MUST support DTLS 1.2 with the
134  * TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 cipher suite
135  * and the P-256 curve.
136  */
137  if ((ret = mbedtls_ecp_gen_key(MBEDTLS_ECP_DP_SECP256R1,
138  mbedtls_pk_ec(*key),
139  mbedtls_ctr_drbg_random, &ctr_drbg)) != 0) {
140  av_log(NULL, AV_LOG_ERROR, "mbedtls_ecp_gen_key returned %d\n", ret);
141  goto end;
142  }
143 end:
144  mbedtls_entropy_free(&entropy);
145  mbedtls_ctr_drbg_free(&ctr_drbg);
146  return ret;
147 }
148 
149 static int mbedtls_gen_x509_cert(mbedtls_pk_context *key, char *cert_buf, size_t cert_sz)
150 {
151  int ret = 0;
152  const char *name = "CN=lavf";
153  time_t now;
154  struct tm tm;
155  char not_before[16], not_after[16];
156  unsigned char serial[20];
157  mbedtls_entropy_context entropy;
158  mbedtls_ctr_drbg_context ctr_drbg;
159  mbedtls_x509write_cert crt;
160 
161  mbedtls_entropy_init(&entropy);
162  mbedtls_ctr_drbg_init(&ctr_drbg);
163  mbedtls_x509write_crt_init(&crt);
164 
165  if ((ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, NULL, 0)) != 0) {
166  av_log(NULL, AV_LOG_ERROR, "mbedtls_ctr_drbg_seed returned %d\n", ret);
167  goto end;
168  }
169 
170  mbedtls_x509write_crt_set_subject_key(&crt, key);
171  mbedtls_x509write_crt_set_issuer_key(&crt, key);
172  if ((ret = mbedtls_x509write_crt_set_subject_name(&crt, name)) != 0) {
173  av_log(NULL, AV_LOG_ERROR, "mbedtls_x509write_crt_set_subject_name returned %d\n", ret);
174  goto end;
175  }
176 
177  if ((ret = mbedtls_x509write_crt_set_issuer_name(&crt, name)) != 0) {
178  av_log(NULL, AV_LOG_ERROR, "mbedtls_x509write_crt_set_issuer_name returned %d\n", ret);
179  goto end;
180  }
181  mbedtls_x509write_crt_set_version(&crt, MBEDTLS_X509_CRT_VERSION_3);
182  mbedtls_x509write_crt_set_md_alg(&crt, MBEDTLS_MD_SHA256);
183 
184  ret = av_random_bytes((uint8_t *)serial, sizeof(serial));
185  if (ret < 0) {
186  av_log(NULL, AV_LOG_ERROR, "Failed to generate random serial number!\n");
187  return ret;
188  }
189 
190  if ((ret = mbedtls_x509write_crt_set_serial_raw(&crt, serial, sizeof(serial))) != 0) {
191  av_log(NULL, AV_LOG_ERROR, "mbedtls_x509write_crt_set_serial_raw returned %d\n", ret);
192  goto end;
193  }
194 
195  time(&now);
196  gmtime_r(&now, &tm);
197  strftime(not_before, sizeof(not_before), "%Y%m%d%H%M%S", &tm);
198  tm.tm_year += 1;
199  strftime(not_after, sizeof(not_after), "%Y%m%d%H%M%S", &tm);
200 
201  if ((ret = mbedtls_x509write_crt_set_validity(&crt, not_before, not_after)) != 0) {
202  av_log(NULL, AV_LOG_ERROR, "mbedtls_x509write_crt_set_validity returned %d\n", ret);
203  goto end;
204  }
205 
206  if ((ret = mbedtls_x509write_crt_pem(&crt, cert_buf, cert_sz,
207  mbedtls_ctr_drbg_random, &ctr_drbg)) != 0) {
208  av_log(NULL, AV_LOG_ERROR, "mbedtls_x509write_crt_pem returned %d\n", ret);
209  return ret;
210  }
211 
212 end:
213  mbedtls_entropy_free(&entropy);
214  mbedtls_ctr_drbg_free(&ctr_drbg);
215  mbedtls_x509write_crt_free(&crt);
216  return ret;
217 }
218 
219 int ff_ssl_gen_key_cert(char *key_buf, size_t key_sz, char *cert_buf, size_t cert_sz, char **fingerprint)
220 {
221  int ret = 0;
222  mbedtls_pk_context key;
223 
224  mbedtls_pk_init(&key);
225 
226  if ((ret = mbedtls_gen_pkey(&key)) != 0)
227  goto end;
228 
229  if ((ret = mbedtls_pk_write_key_pem(&key, key_buf, key_sz)) != 0)
230  goto end;
231 
232  if ((ret = mbedtls_gen_x509_cert(&key, cert_buf, cert_sz)) != 0)
233  goto end;
234 
235  ret = mbedtls_x509_fingerprint(cert_buf, cert_sz, fingerprint);
236  if (ret < 0)
237  av_log(NULL, AV_LOG_ERROR, "TLS: Failed to generate fingerprint\n");
238 
239 end:
240  mbedtls_pk_free(&key);
241  return ret;
242 }
243 
244 typedef struct dtls_srtp_keys {
245  unsigned char master_secret[48];
246  unsigned char randbytes[64];
247  mbedtls_tls_prf_types tls_prf_type;
249 
250 typedef struct TLSContext {
252  mbedtls_ssl_context ssl_context;
253  mbedtls_ssl_config ssl_config;
254  mbedtls_entropy_context entropy_context;
255  mbedtls_ctr_drbg_context ctr_drbg_context;
256  mbedtls_timing_delay_context timer;
257  mbedtls_x509_crt ca_cert;
258  mbedtls_x509_crt own_cert;
259  mbedtls_pk_context priv_key;
260  char *priv_key_pw;
263  socklen_t dest_addr_len;
264 } TLSContext;
265 
267 {
268  TLSContext *tls_ctx = h->priv_data;
269  TLSShared *shr = &tls_ctx->tls_shared;
270 
271  if (shr->is_dtls)
272  shr->udp = sock;
273  else
274  shr->tcp = sock;
275 
276  return 0;
277 }
278 
279 #if defined(MBEDTLS_SSL_DTLS_SRTP)
280 static void dtls_srtp_key_derivation(void *p_expkey,
281  mbedtls_ssl_key_export_type secret_type,
282  const unsigned char *secret,
283  size_t secret_len,
284  const unsigned char client_random[32],
285  const unsigned char server_random[32],
286  mbedtls_tls_prf_types tls_prf_type)
287 {
288  dtls_srtp_keys *keys = (dtls_srtp_keys *) p_expkey;
289 
290  if (secret_len != sizeof(keys->master_secret))
291  return;
292 
293  memcpy(keys->master_secret, secret, secret_len);
294  memcpy(keys->randbytes, client_random, 32);
295  memcpy(keys->randbytes + 32, server_random, 32);
296  keys->tls_prf_type = tls_prf_type;
297 }
298 #endif
299 
300 int ff_dtls_export_materials(URLContext *h, char *dtls_srtp_materials, size_t materials_sz)
301 {
302  int ret = 0;
303  TLSContext *tls_ctx = h->priv_data;
304 #if defined(MBEDTLS_SSL_DTLS_SRTP)
305  const char* dst = "EXTRACTOR-dtls_srtp";
306  mbedtls_dtls_srtp_info dtls_srtp_negotiation_result;
307  mbedtls_ssl_get_dtls_srtp_negotiation_result(&tls_ctx->ssl_context, &dtls_srtp_negotiation_result);
308 
309  if ((ret = mbedtls_ssl_tls_prf(tls_ctx->srtp_key.tls_prf_type,
310  tls_ctx->srtp_key.master_secret,
311  sizeof(tls_ctx->srtp_key.master_secret),
312  dst,
313  tls_ctx->srtp_key.randbytes,
314  sizeof(tls_ctx->srtp_key.randbytes),
315  dtls_srtp_materials,
316  materials_sz)) != 0) {
317  av_log(h, AV_LOG_ERROR,"mbedtls_ssl_tls_prf returned %d\n", ret);
318  ret = AVERROR(EINVAL);
319  }
320 #else
321  av_log(h, AV_LOG_ERROR, "DTLS-SRTP is not supported in this mbedtls build\n");
322  ret = AVERROR(ENOSYS);
323 #endif
324  return ret;
325 }
326 
327 #define OFFSET(x) offsetof(TLSContext, x)
328 
329 static int tls_close(URLContext *h)
330 {
331  TLSContext *tls_ctx = h->priv_data;
332  TLSShared *shr = &tls_ctx->tls_shared;
333 
334  mbedtls_ssl_close_notify(&tls_ctx->ssl_context);
335  mbedtls_pk_free(&tls_ctx->priv_key);
336  mbedtls_x509_crt_free(&tls_ctx->ca_cert);
337  mbedtls_x509_crt_free(&tls_ctx->own_cert);
338  mbedtls_ssl_free(&tls_ctx->ssl_context);
339  mbedtls_ssl_config_free(&tls_ctx->ssl_config);
340  mbedtls_ctr_drbg_free(&tls_ctx->ctr_drbg_context);
341  mbedtls_entropy_free(&tls_ctx->entropy_context);
342  if (!shr->external_sock)
343  ffurl_closep(shr->is_dtls ? &shr->udp : &shr->tcp);
344  return 0;
345 }
346 
347 static int handle_transport_error(URLContext *h, const char* func_name, int react_on_eagain, int ret)
348 {
349  switch (ret) {
350  case AVERROR(EAGAIN):
351  return react_on_eagain;
352  case AVERROR_EXIT:
353  return 0;
354  case AVERROR(EPIPE):
355  case AVERROR(ECONNRESET):
356  return MBEDTLS_ERR_NET_CONN_RESET;
357  default:
358  av_log(h, AV_LOG_ERROR, "%s returned 0x%x\n", func_name, ret);
359  errno = EIO;
360  return MBEDTLS_ERR_NET_SEND_FAILED;
361  }
362 }
363 
364 static int mbedtls_send(void *ctx, const unsigned char *buf, size_t len)
365 {
366  TLSContext *tls_ctx = (TLSContext*) ctx;
367  TLSShared *shr = &tls_ctx->tls_shared;
368  URLContext *h = shr->is_dtls ? shr->udp : shr->tcp;
369  int ret = ffurl_write(h, buf, len);
370  if (ret >= 0)
371  return ret;
372 
373  if (h->max_packet_size && len > h->max_packet_size)
374  return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
375 
376  return handle_transport_error(h, "ffurl_write", MBEDTLS_ERR_SSL_WANT_WRITE, ret);
377 }
378 
379 static int mbedtls_recv(void *ctx, unsigned char *buf, size_t len)
380 {
381  TLSContext *tls_ctx = (TLSContext*) ctx;
382  TLSShared *shr = &tls_ctx->tls_shared;
383  URLContext *h = shr->is_dtls ? shr->udp : shr->tcp;
384  int ret = ffurl_read(h, buf, len);
385  if (ret >= 0) {
386  if (shr->is_dtls && shr->listen && !tls_ctx->dest_addr_len) {
387  int err_ret;
388 
389  ff_udp_get_last_recv_addr(shr->udp, &tls_ctx->dest_addr, &tls_ctx->dest_addr_len);
390  err_ret = ff_udp_set_remote_addr(shr->udp, (struct sockaddr *)&tls_ctx->dest_addr, tls_ctx->dest_addr_len, 1);
391  if (err_ret < 0) {
392  av_log(tls_ctx, AV_LOG_ERROR, "Failed connecting udp context\n");
393  return err_ret;
394  }
395  av_log(tls_ctx, AV_LOG_TRACE, "Set UDP remote addr on UDP socket, now 'connected'\n");
396  }
397  return ret;
398  }
399  if (h->max_packet_size && len > h->max_packet_size)
400  return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
401 
402  return handle_transport_error(h, "ffurl_read", MBEDTLS_ERR_SSL_WANT_READ, ret);
403 }
404 
405 static void mbedtls_debug(void *ctx, int lvl, const char *file, int line, const char *msg)
406 {
407  URLContext *h = (URLContext*) ctx;
408  int av_lvl = lvl >= 4 ? AV_LOG_TRACE : AV_LOG_DEBUG;
409  av_log(h, av_lvl, "%s:%d: %s", av_basename(file), line, msg);
410 }
411 
413 {
414  switch (ret) {
415  case MBEDTLS_ERR_PK_FILE_IO_ERROR:
416  av_log(h, AV_LOG_ERROR, "Read of key file failed. Is it actually there, are the access permissions correct?\n");
417  break;
418  case MBEDTLS_ERR_PK_PASSWORD_REQUIRED:
419  av_log(h, AV_LOG_ERROR, "A password for the private key is missing.\n");
420  break;
421  case MBEDTLS_ERR_PK_PASSWORD_MISMATCH:
422  av_log(h, AV_LOG_ERROR, "The given password for the private key is wrong.\n");
423  break;
424  default:
425  av_log(h, AV_LOG_ERROR, "mbedtls_pk_parse_key returned -0x%x\n", -ret);
426  break;
427  }
428 }
429 
431 {
432  switch (ret) {
433 #if MBEDTLS_VERSION_MAJOR < 3
434  case MBEDTLS_ERR_SSL_NO_USABLE_CIPHERSUITE:
435  av_log(h, AV_LOG_ERROR, "None of the common ciphersuites is usable. Was the local certificate correctly set?\n");
436  break;
437 #else
438  case MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE:
439  av_log(h, AV_LOG_ERROR, "TLS handshake failed.\n");
440  break;
441  case MBEDTLS_ERR_SSL_BAD_PROTOCOL_VERSION:
442  av_log(h, AV_LOG_ERROR, "TLS protocol version mismatch.\n");
443  break;
444 #endif
445  case MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE:
446  av_log(h, AV_LOG_ERROR, "A fatal alert message was received from the peer, has the peer a correct certificate?\n");
447  break;
448  case MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED:
449  av_log(h, AV_LOG_ERROR, "No CA chain is set, but required to operate. Was the CA correctly set?\n");
450  break;
451  case MBEDTLS_ERR_SSL_INTERNAL_ERROR:
452  av_log(h, AV_LOG_ERROR, "Internal error encountered.\n");
453  break;
454  case MBEDTLS_ERR_NET_CONN_RESET:
455  av_log(h, AV_LOG_ERROR, "TLS handshake was aborted by peer.\n");
456  break;
457  case MBEDTLS_ERR_X509_CERT_VERIFY_FAILED:
458  av_log(h, AV_LOG_ERROR, "Certificate verification failed.\n");
459  break;
460  default:
461  av_log(h, AV_LOG_ERROR, "mbedtls_ssl_handshake returned -0x%x\n", -ret);
462  break;
463  }
464 }
465 
467 {
468  TLSContext *tls_ctx = h->priv_data;
469  TLSShared *shr = &tls_ctx->tls_shared;
470  URLContext *uc = shr->is_dtls ? shr->udp : shr->tcp;
471  int ret;
472 
473  uc->flags &= ~AVIO_FLAG_NONBLOCK;
474 
475  while (1) {
476  ret = mbedtls_ssl_handshake(&tls_ctx->ssl_context);
477 
478  if (!ret)
479  break;
480  if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
482  return ret;
483  }
484  }
485 
486  return ret;
487 }
488 
489 static int tls_open(URLContext *h, const char *uri, int flags, AVDictionary **options)
490 {
491  TLSContext *tls_ctx = h->priv_data;
492  TLSShared *shr = &tls_ctx->tls_shared;
493  uint32_t verify_res_flags;
494  int ret;
495 #if defined(MBEDTLS_SSL_DTLS_SRTP)
496  const mbedtls_ssl_srtp_profile profiles[] = {
497  MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_80,
498  MBEDTLS_TLS_SRTP_UNSET
499  };
500 #endif
501 
502  if (!shr->external_sock) {
503  if ((ret = ff_tls_open_underlying(shr, h, uri, options)) < 0)
504  goto fail;
505  }
506 
507 #ifdef MBEDTLS_PSA_CRYPTO_C
508  if ((ret = psa_crypto_init()) != PSA_SUCCESS) {
509  av_log(h, AV_LOG_ERROR, "psa_crypto_init returned %d\n", ret);
510  goto fail;
511  }
512 #endif
513 
514  mbedtls_ssl_init(&tls_ctx->ssl_context);
515  mbedtls_ssl_config_init(&tls_ctx->ssl_config);
516  mbedtls_entropy_init(&tls_ctx->entropy_context);
517  mbedtls_ctr_drbg_init(&tls_ctx->ctr_drbg_context);
518  mbedtls_x509_crt_init(&tls_ctx->ca_cert);
519  mbedtls_pk_init(&tls_ctx->priv_key);
520 
521  if (av_log_get_level() >= AV_LOG_DEBUG) {
522  mbedtls_ssl_conf_dbg(&tls_ctx->ssl_config, mbedtls_debug, shr->is_dtls ? shr->udp : shr->tcp);
523  /*
524  * Note: we can't call mbedtls_debug_set_threshold() here because
525  * it's global state. The user is thus expected to manage this.
526  */
527  }
528 
529  // load trusted CA
530  if (shr->ca_file) {
531  if ((ret = mbedtls_x509_crt_parse_file(&tls_ctx->ca_cert, shr->ca_file)) != 0) {
532  av_log(h, AV_LOG_ERROR, "mbedtls_x509_crt_parse_file for CA cert returned %d\n", ret);
533  goto fail;
534  }
535  }
536 
537  // load own certificate
538  if (shr->cert_file) {
539  if ((ret = mbedtls_x509_crt_parse_file(&tls_ctx->own_cert, shr->cert_file)) != 0) {
540  av_log(h, AV_LOG_ERROR, "mbedtls_x509_crt_parse_file for own cert returned %d\n", ret);
541  goto fail;
542  }
543  } else if (shr->cert_buf) {
544  if ((ret = mbedtls_x509_crt_parse(&tls_ctx->own_cert, shr->cert_buf, strlen(shr->cert_buf) + 1)) != 0) {
545  av_log(h, AV_LOG_ERROR, "mbedtls_x509_crt_parse for own cert returned %d\n", ret);
546  goto fail;
547  }
548  }
549 
550  // seed the random number generator
551  if ((ret = mbedtls_ctr_drbg_seed(&tls_ctx->ctr_drbg_context,
552  mbedtls_entropy_func,
553  &tls_ctx->entropy_context,
554  NULL, 0)) != 0) {
555  av_log(h, AV_LOG_ERROR, "mbedtls_ctr_drbg_seed returned %d\n", ret);
556  goto fail;
557  }
558 
559  // load key file
560  if (shr->key_file) {
561  if ((ret = mbedtls_pk_parse_keyfile(&tls_ctx->priv_key,
562  shr->key_file,
563  tls_ctx->priv_key_pw
564 #if MBEDTLS_VERSION_MAJOR >= 3
565  , mbedtls_ctr_drbg_random,
566  &tls_ctx->ctr_drbg_context
567 #endif
568  )) != 0) {
570  goto fail;
571  }
572  } else if (shr->key_buf) {
573  if ((ret = mbedtls_pk_parse_key(&tls_ctx->priv_key,
574  shr->key_buf,
575  strlen(shr->key_buf) + 1,
576  NULL,
577  0
578 #if MBEDTLS_VERSION_MAJOR >= 3
579  , mbedtls_ctr_drbg_random,
580  &tls_ctx->ctr_drbg_context
581 #endif
582  )) != 0) {
584  goto fail;
585  }
586  }
587 
588  if (shr->listen && !shr->cert_file && !shr->cert_buf && !shr->key_file && !shr->key_buf) {
589  char buf[4096];
590  if ((ret = mbedtls_gen_pkey(&tls_ctx->priv_key)) != 0) {
591  av_log(h, AV_LOG_ERROR, "failed to generate priv_key, returned %d\n", ret);
592  goto fail;
593  }
594  if ((ret = mbedtls_gen_x509_cert(&tls_ctx->priv_key, buf, sizeof(buf))) != 0) {
595  av_log(h, AV_LOG_ERROR, "failed to generate cert, returned %d\n", ret);
596  goto fail;
597  }
598  if ((ret = mbedtls_x509_crt_parse(&tls_ctx->own_cert, buf, sizeof(buf))) != 0) {
599  av_log(h, AV_LOG_ERROR, "failed to parse generated cert, returned %d\n", ret);
600  goto fail;
601  }
602  }
603 
604  if ((ret = mbedtls_ssl_config_defaults(&tls_ctx->ssl_config,
605  shr->listen ? MBEDTLS_SSL_IS_SERVER : MBEDTLS_SSL_IS_CLIENT,
606  shr->is_dtls ? MBEDTLS_SSL_TRANSPORT_DATAGRAM : MBEDTLS_SSL_TRANSPORT_STREAM,
607  MBEDTLS_SSL_PRESET_DEFAULT)) != 0) {
608  av_log(h, AV_LOG_ERROR, "mbedtls_ssl_config_defaults returned %d\n", ret);
609  goto fail;
610  }
611 
612 #ifdef MBEDTLS_SSL_PROTO_TLS1_3
613  // this version does not allow disabling certificate verification with TLSv1.3 (yes, really).
614  if (mbedtls_version_get_number() == 0x03060000 && !shr->verify) {
615  av_log(h, AV_LOG_INFO, "Forcing TLSv1.2 because certificate verification is disabled\n");
616  mbedtls_ssl_conf_max_tls_version(&tls_ctx->ssl_config, MBEDTLS_SSL_VERSION_TLS1_2);
617  }
618 #endif
619 
620  // not VERIFY_REQUIRED because we manually check after handshake
621  mbedtls_ssl_conf_authmode(&tls_ctx->ssl_config,
622  shr->verify ? MBEDTLS_SSL_VERIFY_OPTIONAL : MBEDTLS_SSL_VERIFY_NONE);
623  mbedtls_ssl_conf_rng(&tls_ctx->ssl_config, mbedtls_ctr_drbg_random, &tls_ctx->ctr_drbg_context);
624  mbedtls_ssl_conf_ca_chain(&tls_ctx->ssl_config, &tls_ctx->ca_cert, NULL);
625 
626  // set own certificate and private key
627  if ((ret = mbedtls_ssl_conf_own_cert(&tls_ctx->ssl_config, &tls_ctx->own_cert, &tls_ctx->priv_key)) != 0) {
628  av_log(h, AV_LOG_ERROR, "mbedtls_ssl_conf_own_cert returned %d\n", ret);
629  goto fail;
630  }
631  if (shr->is_dtls) {
632  mbedtls_ssl_conf_dtls_cookies(&tls_ctx->ssl_config, NULL, NULL, NULL);
633  if (shr->use_srtp) {
634 #if defined(MBEDTLS_SSL_DTLS_SRTP)
635  if ((ret = mbedtls_ssl_conf_dtls_srtp_protection_profiles(&tls_ctx->ssl_config, profiles)) != 0) {
636  av_log(h, AV_LOG_ERROR, "mbedtls_ssl_conf_dtls_srtp_protection_profiles returned %d\n", ret);
637  goto fail;
638  }
639  mbedtls_ssl_set_export_keys_cb(&tls_ctx->ssl_context, dtls_srtp_key_derivation, &tls_ctx->srtp_key);
640 #else
641  av_log(h, AV_LOG_ERROR, "DTLS-SRTP is not supported in this mbedtls build\n");
642  ret = AVERROR(ENOSYS);
643  goto fail;
644 #endif
645  }
646 
647  }
648  if ((ret = mbedtls_ssl_setup(&tls_ctx->ssl_context, &tls_ctx->ssl_config)) != 0) {
649  av_log(h, AV_LOG_ERROR, "mbedtls_ssl_setup returned %d\n", ret);
650  goto fail;
651  }
652 
653  if (!shr->listen && !shr->numerichost) {
654  if ((ret = mbedtls_ssl_set_hostname(&tls_ctx->ssl_context, shr->host)) != 0) {
655  av_log(h, AV_LOG_ERROR, "mbedtls_ssl_set_hostname returned %d\n", ret);
656  goto fail;
657  }
658  }
659 
660  // set I/O functions to use FFmpeg internal code for transport layer
661  mbedtls_ssl_set_bio(&tls_ctx->ssl_context, tls_ctx, mbedtls_send, mbedtls_recv, NULL);
662 
663  if (shr->is_dtls) {
664  mbedtls_ssl_set_timer_cb(&tls_ctx->ssl_context, &tls_ctx->timer, mbedtls_timing_set_delay, mbedtls_timing_get_delay);
665  if (shr->mtu)
666  mbedtls_ssl_set_mtu(&tls_ctx->ssl_context, shr->mtu);
667  }
668  if (!shr->external_sock) {
669  ret = tls_handshake(h);
670  if (ret < 0)
671  goto fail;
672  }
673 
674  if (shr->verify) {
675  // check the result of the certificate verification
676  if ((verify_res_flags = mbedtls_ssl_get_verify_result(&tls_ctx->ssl_context)) != 0) {
677  av_log(h, AV_LOG_ERROR, "mbedtls_ssl_get_verify_result reported problems "\
678  "with the certificate verification, returned flags: %"PRIu32"\n",
679  verify_res_flags);
680  if (verify_res_flags & MBEDTLS_X509_BADCERT_NOT_TRUSTED)
681  av_log(h, AV_LOG_ERROR, "The certificate is not correctly signed by the trusted CA.\n");
682  goto fail;
683  }
684  }
685 
686  return 0;
687 
688 fail:
689  tls_close(h);
690  return AVERROR(EIO);
691 }
692 
693 static int dtls_open(URLContext *h, const char *uri, int flags, AVDictionary **options)
694 {
695  TLSContext *tls_ctx = h->priv_data;
696  TLSShared *shr = &tls_ctx->tls_shared;
697  shr->is_dtls = 1;
698  return tls_open(h, uri, flags, options);
699 }
700 
701 static int handle_tls_error(URLContext *h, const char* func_name, int ret)
702 {
703  switch (ret) {
704  case MBEDTLS_ERR_SSL_WANT_READ:
705  case MBEDTLS_ERR_SSL_WANT_WRITE:
706 #ifdef MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET
707  case MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET:
708 #endif
709  return AVERROR(EAGAIN);
710  case MBEDTLS_ERR_NET_SEND_FAILED:
711  case MBEDTLS_ERR_NET_RECV_FAILED:
712  return AVERROR(EIO);
713  case MBEDTLS_ERR_NET_CONN_RESET:
714  case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY:
715  av_log(h, AV_LOG_WARNING, "%s reported connection reset by peer\n", func_name);
716  return AVERROR_EOF;
717  default:
718  av_log(h, AV_LOG_ERROR, "%s returned -0x%x\n", func_name, -ret);
719  return AVERROR(EIO);
720  }
721 }
722 
723 static int tls_read(URLContext *h, uint8_t *buf, int size)
724 {
725  TLSContext *tls_ctx = h->priv_data;
726  TLSShared *shr = &tls_ctx->tls_shared;
727  URLContext *uc = shr->is_dtls ? shr->udp : shr->tcp;
728  int ret;
729 
730  uc->flags &= ~AVIO_FLAG_NONBLOCK;
731  uc->flags |= h->flags & AVIO_FLAG_NONBLOCK;
732  if ((ret = mbedtls_ssl_read(&tls_ctx->ssl_context, buf, size)) > 0) {
733  // return read length
734  return ret;
735  }
736 
737  return handle_tls_error(h, "mbedtls_ssl_read", ret);
738 }
739 
740 static int tls_write(URLContext *h, const uint8_t *buf, int size)
741 {
742  TLSContext *tls_ctx = h->priv_data;
743  TLSShared *shr = &tls_ctx->tls_shared;
744  URLContext *uc = shr->is_dtls ? shr->udp : shr->tcp;
745  int ret;
746 
747  uc->flags &= ~AVIO_FLAG_NONBLOCK;
748  uc->flags |= h->flags & AVIO_FLAG_NONBLOCK;
749  if ((ret = mbedtls_ssl_write(&tls_ctx->ssl_context, buf, size)) > 0) {
750  // return written length
751  return ret;
752  }
753 
754  return handle_tls_error(h, "mbedtls_ssl_write", ret);
755 }
756 
758 {
759  TLSContext *c = h->priv_data;
760  return ffurl_get_file_handle(c->tls_shared.tcp);
761 }
762 
764 {
765  TLSContext *s = h->priv_data;
766  return ffurl_get_short_seek(s->tls_shared.tcp);
767 }
768 
769 static const AVOption options[] = {
770  TLS_COMMON_OPTIONS(TLSContext, tls_shared), \
771  {"key_password", "Password for the private key file", OFFSET(priv_key_pw), AV_OPT_TYPE_STRING, .flags = TLS_OPTFL }, \
772  { NULL }
773 };
774 
775 static const AVClass tls_class = {
776  .class_name = "tls",
777  .item_name = av_default_item_name,
778  .option = options,
779  .version = LIBAVUTIL_VERSION_INT,
780 };
781 
783  .name = "tls",
784  .url_open2 = tls_open,
785  .url_read = tls_read,
786  .url_write = tls_write,
787  .url_close = tls_close,
788  .url_get_file_handle = tls_get_file_handle,
789  .url_get_short_seek = tls_get_short_seek,
790  .priv_data_size = sizeof(TLSContext),
792  .priv_data_class = &tls_class,
793 };
794 
795 static const AVClass dtls_class = {
796  .class_name = "dtls",
797  .item_name = av_default_item_name,
798  .option = options,
799  .version = LIBAVUTIL_VERSION_INT,
800 };
801 
803  .name = "dtls",
804  .url_open2 = dtls_open,
805  .url_handshake = tls_handshake,
806  .url_read = tls_read,
807  .url_write = tls_write,
808  .url_close = tls_close,
809  .url_get_file_handle = tls_get_file_handle,
810  .url_get_short_seek = tls_get_short_seek,
811  .priv_data_size = sizeof(TLSContext),
813  .priv_data_class = &dtls_class,
814 };
flags
const SwsFlags flags[]
Definition: swscale.c:62
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:216
TLSContext
Definition: tls_gnutls.c:333
name
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default minimum maximum flags name is the option name
Definition: writing_filters.txt:88
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
URL_PROTOCOL_FLAG_NETWORK
#define URL_PROTOCOL_FLAG_NETWORK
Definition: url.h:33
av_bprint_init
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
Definition: bprint.c:69
TLSContext::entropy_context
mbedtls_entropy_context entropy_context
Definition: tls_mbedtls.c:254
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:57
handle_pk_parse_error
static void handle_pk_parse_error(URLContext *h, int ret)
Definition: tls_mbedtls.c:412
ffurl_write
static int ffurl_write(URLContext *h, const uint8_t *buf, int size)
Write size bytes from buf to the resource accessed by h.
Definition: url.h:202
md
#define md
Definition: vf_colormatrix.c:101
AVOption
AVOption.
Definition: opt.h:429
mbedtls_x509_fingerprint
static int mbedtls_x509_fingerprint(char *cert_buf, size_t cert_sz, char **fingerprint)
Definition: tls_mbedtls.c:45
dtls_srtp_keys::randbytes
unsigned char randbytes[64]
Definition: tls_mbedtls.c:246
AVDictionary
Definition: dict.c:32
URLProtocol
Definition: url.h:51
av_basename
const char * av_basename(const char *path)
Thread safe basename.
Definition: avstring.c:253
sockaddr_storage
Definition: network.h:111
TLSShared::verify
int verify
Definition: tls.h:40
TLSShared::listen
int listen
Definition: tls.h:43
TLSContext::ctr_drbg_context
mbedtls_ctr_drbg_context ctr_drbg_context
Definition: tls_mbedtls.c:255
TLS_COMMON_OPTIONS
#define TLS_COMMON_OPTIONS(pstruct, options_field)
Definition: tls.h:88
ff_tls_set_external_socket
int ff_tls_set_external_socket(URLContext *h, URLContext *sock)
Definition: tls_mbedtls.c:266
fail
#define fail()
Definition: checkasm.h:220
ffurl_get_short_seek
int ffurl_get_short_seek(void *urlcontext)
Return the current short seek threshold value for this URL.
Definition: avio.c:839
gmtime_r
#define gmtime_r
Definition: time_internal.h:34
AVERROR_BUFFER_TOO_SMALL
#define AVERROR_BUFFER_TOO_SMALL
Buffer too small.
Definition: error.h:53
TLSContext::ca_cert
mbedtls_x509_crt ca_cert
Definition: tls_mbedtls.c:257
tls_close
static int tls_close(URLContext *h)
Definition: tls_mbedtls.c:329
AV_LOG_TRACE
#define AV_LOG_TRACE
Extremely verbose debugging, useful for libav* development.
Definition: log.h:236
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:210
mbedtls_recv
static int mbedtls_recv(void *ctx, unsigned char *buf, size_t len)
Definition: tls_mbedtls.c:379
s
#define s(width, name)
Definition: cbs_vp9.c:198
dtls_srtp_keys::tls_prf_type
mbedtls_tls_prf_types tls_prf_type
Definition: tls_mbedtls.c:247
TLS_OPTFL
#define TLS_OPTFL
Definition: tls.h:69
URLContext::flags
int flags
Definition: url.h:40
TLSContext::priv_key
mbedtls_pk_context priv_key
Definition: tls_mbedtls.c:259
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:231
ctx
static AVFormatContext * ctx
Definition: movenc.c:49
TLSContext::ssl_context
mbedtls_ssl_context ssl_context
Definition: tls_mbedtls.c:252
tls_handshake
static int tls_handshake(URLContext *h)
Definition: tls_mbedtls.c:466
key
const char * key
Definition: hwcontext_opencl.c:189
TLSContext::timer
mbedtls_timing_delay_context timer
Definition: tls_mbedtls.c:256
av_log_get_level
int av_log_get_level(void)
Get the current log level.
Definition: log.c:472
ff_udp_set_remote_addr
int ff_udp_set_remote_addr(URLContext *h, const struct sockaddr *dest_addr, socklen_t dest_addr_len, int do_connect)
This function is identical to ff_udp_set_remote_url, except that it takes a sockaddr directly.
Definition: udp.c:472
internal.h
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:76
NULL
#define NULL
Definition: coverity.c:32
mbedtls_gen_x509_cert
static int mbedtls_gen_x509_cert(mbedtls_pk_context *key, char *cert_buf, size_t cert_sz)
Definition: tls_mbedtls.c:149
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:242
ff_udp_get_last_recv_addr
void ff_udp_get_last_recv_addr(URLContext *h, struct sockaddr_storage *addr, socklen_t *addr_len)
Definition: udp.c:510
parseutils.h
options
Definition: swscale.c:44
dtls_srtp_keys::master_secret
unsigned char master_secret[48]
Definition: tls_mbedtls.c:245
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
TLSShared::host
char * host
Definition: tls.h:45
OFFSET
#define OFFSET(x)
Definition: tls_mbedtls.c:327
TLSShared::cert_buf
char * cert_buf
Definition: tls.h:59
ff_tls_protocol
const URLProtocol ff_tls_protocol
Definition: tls_mbedtls.c:782
ff_dtls_export_materials
int ff_dtls_export_materials(URLContext *h, char *dtls_srtp_materials, size_t materials_sz)
Definition: tls_mbedtls.c:300
ff_url_read_all
int ff_url_read_all(const char *url, AVBPrint *bp)
Read all data from the given URL url and store it in the given buffer bp.
Definition: tls.c:116
av_bprint_finalize
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
Definition: bprint.c:235
dst
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition: dsp.h:87
TLSContext::ssl_config
mbedtls_ssl_config ssl_config
Definition: tls_mbedtls.c:253
TLSShared::external_sock
int external_sock
Definition: tls.h:51
i
#define i(width, name, range_min, range_max)
Definition: cbs_h264.c:63
mbedtls_send
static int mbedtls_send(void *ctx, const unsigned char *buf, size_t len)
Definition: tls_mbedtls.c:364
dtls_srtp_keys
Definition: tls_mbedtls.c:244
ff_ssl_gen_key_cert
int ff_ssl_gen_key_cert(char *key_buf, size_t key_sz, char *cert_buf, size_t cert_sz, char **fingerprint)
Definition: tls_mbedtls.c:219
size
int size
Definition: twinvq_data.h:10344
ff_ssl_read_key_cert
int ff_ssl_read_key_cert(char *key_url, char *cert_url, char *key_buf, size_t key_sz, char *cert_buf, size_t cert_sz, char **fingerprint)
Definition: tls_mbedtls.c:74
handle_handshake_error
static void handle_handshake_error(URLContext *h, int ret)
Definition: tls_mbedtls.c:430
TLSContext::tls_shared
TLSShared tls_shared
Definition: tls_gnutls.c:334
URLProtocol::name
const char * name
Definition: url.h:52
tls_read
static int tls_read(URLContext *h, uint8_t *buf, int size)
Definition: tls_mbedtls.c:723
line
Definition: graph2dot.c:48
handle_transport_error
static int handle_transport_error(URLContext *h, const char *func_name, int react_on_eagain, int ret)
Definition: tls_mbedtls.c:347
TLSShared::key_buf
char * key_buf
Definition: tls.h:60
dtls_class
static const AVClass dtls_class
Definition: tls_mbedtls.c:795
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:221
options
static const AVOption options[]
Definition: tls_mbedtls.c:769
TLSContext::dest_addr
struct sockaddr_storage dest_addr
Definition: tls_gnutls.c:339
URLContext
Definition: url.h:35
TLSContext::dest_addr_len
socklen_t dest_addr_len
Definition: tls_gnutls.c:340
url.h
av_random_bytes
int av_random_bytes(uint8_t *buf, size_t len)
Generate cryptographically secure random data, i.e.
Definition: random_seed.c:159
len
int len
Definition: vorbis_enc_data.h:426
TLSShared::cert_file
char * cert_file
Definition: tls.h:41
ffurl_closep
int ffurl_closep(URLContext **hh)
Close the resource accessed by the URLContext h, and free the memory used by it.
Definition: avio.c:589
ff_tls_open_underlying
int ff_tls_open_underlying(TLSShared *c, URLContext *parent, const char *uri, AVDictionary **options)
Definition: tls.c:34
ret
ret
Definition: filter_design.txt:187
TLSShared::is_dtls
int is_dtls
Definition: tls.h:55
AVClass::class_name
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:81
TLSShared::ca_file
char * ca_file
Definition: tls.h:39
ff_dtls_protocol
const URLProtocol ff_dtls_protocol
Definition: tls_mbedtls.c:802
avformat.h
av_bprintf
void av_bprintf(AVBPrint *buf, const char *fmt,...)
Definition: bprint.c:122
network.h
tls_class
static const AVClass tls_class
Definition: tls_mbedtls.c:775
tls.h
dtls_open
static int dtls_open(URLContext *h, const char *uri, int flags, AVDictionary **options)
Definition: tls_mbedtls.c:693
random_seed.h
TLSContext::own_cert
mbedtls_x509_crt own_cert
Definition: tls_mbedtls.c:258
TLSShared::key_file
char * key_file
Definition: tls.h:42
tls_get_short_seek
static int tls_get_short_seek(URLContext *h)
Definition: tls_mbedtls.c:763
profiles
static const AVProfile profiles[]
Definition: libfdk-aacenc.c:557
tls_open
static int tls_open(URLContext *h, const char *uri, int flags, AVDictionary **options)
Definition: tls_mbedtls.c:489
TLSShared::use_srtp
int use_srtp
Definition: tls.h:56
mbedtls_debug
static void mbedtls_debug(void *ctx, int lvl, const char *file, int line, const char *msg)
Definition: tls_mbedtls.c:405
mem.h
MAX_CERTIFICATE_SIZE
#define MAX_CERTIFICATE_SIZE
Maximum size limit of a certificate and private key size.
Definition: tls.h:35
TLSShared::mtu
int mtu
The size of RTP packet, should generally be set to MTU.
Definition: tls.h:66
tls_write
static int tls_write(URLContext *h, const uint8_t *buf, int size)
Definition: tls_mbedtls.c:740
TLSShared
Definition: tls.h:37
AVIO_FLAG_NONBLOCK
#define AVIO_FLAG_NONBLOCK
Use non-blocking mode.
Definition: avio.h:636
TLSShared::udp
URLContext * udp
Definition: tls.h:52
handle_tls_error
static int handle_tls_error(URLContext *h, const char *func_name, int ret)
Definition: tls_mbedtls.c:701
tls_get_file_handle
static int tls_get_file_handle(URLContext *h)
Definition: tls_mbedtls.c:757
TLSContext::priv_key_pw
char * priv_key_pw
Definition: tls_mbedtls.c:260
TLSShared::numerichost
int numerichost
Definition: tls.h:49
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
h
h
Definition: vp9dsp_template.c:2070
AVERROR_EXIT
#define AVERROR_EXIT
Immediate exit was requested; the called function should not be restarted.
Definition: error.h:58
avstring.h
AV_OPT_TYPE_STRING
@ AV_OPT_TYPE_STRING
Underlying C type is a uint8_t* that is either NULL or points to a C string allocated with the av_mal...
Definition: opt.h:276
ffurl_get_file_handle
int ffurl_get_file_handle(URLContext *h)
Return the file descriptor associated with this URL.
Definition: avio.c:815
mbedtls_gen_pkey
static int mbedtls_gen_pkey(mbedtls_pk_context *key)
Definition: tls_mbedtls.c:111
TLSShared::tcp
URLContext * tcp
Definition: tls.h:53
ffurl_read
static int ffurl_read(URLContext *h, uint8_t *buf, int size)
Read up to size bytes from the resource accessed by h, and store the read bytes in buf.
Definition: url.h:181
TLSContext::srtp_key
dtls_srtp_keys srtp_key
Definition: tls_mbedtls.c:261