FFmpeg
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
tls_openssl.c
Go to the documentation of this file.
1 /*
2  * TLS/DTLS/SSL Protocol
3  * Copyright (c) 2011 Martin Storsjo
4  * Copyright (c) 2025 Jack Lau
5  *
6  * This file is part of FFmpeg.
7  *
8  * FFmpeg is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * FFmpeg is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with FFmpeg; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 
23 #include "libavutil/mem.h"
24 #include "network.h"
25 #include "os_support.h"
26 #include "libavutil/random_seed.h"
27 #include "url.h"
28 #include "tls.h"
29 #include "libavutil/opt.h"
30 
31 #include <openssl/bio.h>
32 #include <openssl/ssl.h>
33 #include <openssl/err.h>
34 
35 /**
36  * Returns a heap‐allocated null‐terminated string containing
37  * the PEM‐encoded public key. Caller must free.
38  */
39 static char *pkey_to_pem_string(EVP_PKEY *pkey) {
40  BIO *mem = NULL;
41  BUF_MEM *bptr = NULL;
42  char *pem_str = NULL;
43 
44  // Create a memory BIO
45  if (!(mem = BIO_new(BIO_s_mem())))
46  goto err;
47 
48  // Write public key in PEM form
49  if (!PEM_write_bio_PrivateKey(mem, pkey, NULL, NULL, 0, NULL, NULL))
50  goto err;
51 
52  // Extract pointer/length
53  BIO_get_mem_ptr(mem, &bptr);
54  if (!bptr || !bptr->length)
55  goto err;
56 
57  // Allocate string (+1 for NUL)
58  pem_str = av_malloc(bptr->length + 1);
59  if (!pem_str)
60  goto err;
61 
62  // Copy data & NUL‐terminate
63  memcpy(pem_str, bptr->data, bptr->length);
64  pem_str[bptr->length] = '\0';
65 
66 cleanup:
67  BIO_free(mem);
68  return pem_str;
69 
70 err:
71  // error path: free and return NULL
72  free(pem_str);
73  pem_str = NULL;
74  goto cleanup;
75 }
76 
77 /**
78  * Serialize an X509 certificate to a av_malloc’d PEM string.
79  * Caller must free the returned pointer.
80  */
81 static char *cert_to_pem_string(X509 *cert)
82 {
83  BIO *mem = BIO_new(BIO_s_mem());
84  BUF_MEM *bptr = NULL;
85  char *out = NULL;
86 
87  if (!mem) goto err;
88 
89  /* Write the PEM certificate */
90  if (!PEM_write_bio_X509(mem, cert))
91  goto err;
92 
93  BIO_get_mem_ptr(mem, &bptr);
94  if (!bptr || !bptr->length) goto err;
95 
96  out = av_malloc(bptr->length + 1);
97  if (!out) goto err;
98 
99  memcpy(out, bptr->data, bptr->length);
100  out[bptr->length] = '\0';
101 
102 cleanup:
103  BIO_free(mem);
104  return out;
105 
106 err:
107  free(out);
108  out = NULL;
109  goto cleanup;
110 }
111 
112 
113 /**
114  * Generate a SHA-256 fingerprint of an X.509 certificate.
115  *
116  * @param ctx AVFormatContext for logging (can be NULL)
117  * @param cert X509 certificate to fingerprint
118  * @return Newly allocated fingerprint string in "AA:BB:CC:…" format,
119  * or NULL on error (logs via av_log if ctx is not NULL).
120  * Caller must free() the returned string.
121  */
122 static char *generate_fingerprint(X509 *cert)
123 {
124  unsigned char md[EVP_MAX_MD_SIZE];
125  int n = 0;
126  AVBPrint fingerprint;
127  char *result = NULL;
128  int i;
129 
130  /* To prevent a crash during cleanup, always initialize it. */
131  av_bprint_init(&fingerprint, 0, AV_BPRINT_SIZE_UNLIMITED);
132 
133  if (X509_digest(cert, EVP_sha256(), md, &n) != 1) {
134  av_log(NULL, AV_LOG_ERROR, "TLS: Failed to generate fingerprint, %s\n", ERR_error_string(ERR_get_error(), NULL));
135  goto end;
136  }
137 
138  for (i = 0; i < n; i++) {
139  av_bprintf(&fingerprint, "%02X", md[i]);
140  if (i + 1 < n)
141  av_bprintf(&fingerprint, ":");
142  }
143 
144  if (!fingerprint.str || !strlen(fingerprint.str)) {
145  av_log(NULL, AV_LOG_ERROR, "TLS: Fingerprint is empty\n");
146  goto end;
147  }
148 
149  result = av_strdup(fingerprint.str);
150  if (!result) {
151  av_log(NULL, AV_LOG_ERROR, "TLS: Out of memory generating fingerprint\n");
152  }
153 
154 end:
155  av_bprint_finalize(&fingerprint, NULL);
156  return result;
157 }
158 
159 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)
160 {
161  int ret = 0;
162  BIO *key_b = NULL, *cert_b = NULL;
163  AVBPrint key_bp, cert_bp;
164  EVP_PKEY *pkey;
165  X509 *cert;
166  char *key_tem = NULL, *cert_tem = NULL;
167 
168  /* To prevent a crash during cleanup, always initialize it. */
170  av_bprint_init(&cert_bp, 1, MAX_CERTIFICATE_SIZE);
171 
172  /* Read key file. */
173  ret = ff_url_read_all(key_url, &key_bp);
174  if (ret < 0) {
175  av_log(NULL, AV_LOG_ERROR, "TLS: Failed to open key file %s\n", key_url);
176  goto end;
177  }
178 
179  if (!(key_b = BIO_new(BIO_s_mem()))) {
180  ret = AVERROR(ENOMEM);
181  goto end;
182  }
183 
184  BIO_write(key_b, key_bp.str, key_bp.len);
185  pkey = PEM_read_bio_PrivateKey(key_b, NULL, NULL, NULL);
186  if (!pkey) {
187  av_log(NULL, AV_LOG_ERROR, "TLS: Failed to read private key from %s\n", key_url);
188  ret = AVERROR(EIO);
189  goto end;
190  }
191 
192  /* Read certificate. */
193  ret = ff_url_read_all(cert_url, &cert_bp);
194  if (ret < 0) {
195  av_log(NULL, AV_LOG_ERROR, "TLS: Failed to open cert file %s\n", cert_url);
196  goto end;
197  }
198 
199  if (!(cert_b = BIO_new(BIO_s_mem()))) {
200  ret = AVERROR(ENOMEM);
201  goto end;
202  }
203 
204  BIO_write(cert_b, cert_bp.str, cert_bp.len);
205  cert = PEM_read_bio_X509(cert_b, NULL, NULL, NULL);
206  if (!cert) {
207  av_log(NULL, AV_LOG_ERROR, "TLS: Failed to read certificate from %s\n", cert_url);
208  ret = AVERROR(EIO);
209  goto end;
210  }
211 
212  key_tem = pkey_to_pem_string(pkey);
213  cert_tem = cert_to_pem_string(cert);
214 
215  snprintf(key_buf, key_sz, "%s", key_tem);
216  snprintf(cert_buf, cert_sz, "%s", cert_tem);
217 
218  /* Generate fingerprint. */
219  *fingerprint = generate_fingerprint(cert);
220  if (!*fingerprint) {
221  av_log(NULL, AV_LOG_ERROR, "TLS: Failed to generate fingerprint from %s\n", cert_url);
222  ret = AVERROR(EIO);
223  goto end;
224  }
225 
226 end:
227  BIO_free(key_b);
228  av_bprint_finalize(&key_bp, NULL);
229  BIO_free(cert_b);
230  av_bprint_finalize(&cert_bp, NULL);
231  if (key_tem) av_free(key_tem);
232  if (cert_tem) av_free(cert_tem);
233  return ret;
234 }
235 
236 static int openssl_gen_private_key(EVP_PKEY **pkey, EC_KEY **eckey)
237 {
238  int ret = 0;
239 
240  /**
241  * Note that secp256r1 in openssl is called NID_X9_62_prime256v1 or prime256v1 in string,
242  * not NID_secp256k1 or secp256k1 in string.
243  *
244  * TODO: Should choose the curves in ClientHello.supported_groups, for example:
245  * Supported Group: x25519 (0x001d)
246  * Supported Group: secp256r1 (0x0017)
247  * Supported Group: secp384r1 (0x0018)
248  */
249 #if OPENSSL_VERSION_NUMBER < 0x30000000L /* OpenSSL 3.0 */
250  EC_GROUP *ecgroup = NULL;
251  int curve = NID_X9_62_prime256v1;
252 #else
253  const char *curve = SN_X9_62_prime256v1;
254 #endif
255 
256 #if OPENSSL_VERSION_NUMBER < 0x30000000L /* OpenSSL 3.0 */
257  *pkey = EVP_PKEY_new();
258  *eckey = EC_KEY_new();
259  ecgroup = EC_GROUP_new_by_curve_name(curve);
260  if (!ecgroup) {
261  av_log(NULL, AV_LOG_ERROR, "TLS: Create EC group by curve=%d failed, %s", curve, ERR_error_string(ERR_get_error(), NULL));
262  goto einval_end;
263  }
264 
265 #if OPENSSL_VERSION_NUMBER < 0x10100000L // v1.1.x
266  /* For openssl 1.0, we must set the group parameters, so that cert is ok. */
267  EC_GROUP_set_asn1_flag(ecgroup, OPENSSL_EC_NAMED_CURVE);
268 #endif
269 
270  if (EC_KEY_set_group(*eckey, ecgroup) != 1) {
271  av_log(NULL, AV_LOG_ERROR, "TLS: Generate private key, EC_KEY_set_group failed, %s\n", ERR_error_string(ERR_get_error(), NULL));
272  goto einval_end;
273  }
274 
275  if (EC_KEY_generate_key(*eckey) != 1) {
276  av_log(NULL, AV_LOG_ERROR, "TLS: Generate private key, EC_KEY_generate_key failed, %s\n", ERR_error_string(ERR_get_error(), NULL));
277  goto einval_end;
278  }
279 
280  if (EVP_PKEY_set1_EC_KEY(*pkey, *eckey) != 1) {
281  av_log(NULL, AV_LOG_ERROR, "TLS: Generate private key, EVP_PKEY_set1_EC_KEY failed, %s\n", ERR_error_string(ERR_get_error(), NULL));
282  goto einval_end;
283  }
284 #else
285  *pkey = EVP_EC_gen(curve);
286  if (!*pkey) {
287  av_log(NULL, AV_LOG_ERROR, "TLS: Generate private key, EVP_EC_gen curve=%s failed, %s\n", curve, ERR_error_string(ERR_get_error(), NULL));
288  goto einval_end;
289  }
290 #endif
291  goto end;
292 
293 einval_end:
294  ret = AVERROR(EINVAL);
295 end:
296 #if OPENSSL_VERSION_NUMBER < 0x30000000L /* OpenSSL 3.0 */
297  EC_GROUP_free(ecgroup);
298 #endif
299  return ret;
300 }
301 
302 static int openssl_gen_certificate(EVP_PKEY *pkey, X509 **cert, char **fingerprint)
303 {
304  int ret = 0, serial, expire_day;
305  const char *aor = "lavf";
306  X509_NAME* subject = NULL;
307 
308  *cert= X509_new();
309  if (!*cert) {
310  goto enomem_end;
311  }
312 
313  // TODO: Support non-self-signed certificate, for example, load from a file.
314  subject = X509_NAME_new();
315  if (!subject) {
316  goto enomem_end;
317  }
318 
319  serial = (int)av_get_random_seed();
320  if (ASN1_INTEGER_set(X509_get_serialNumber(*cert), serial) != 1) {
321  av_log(NULL, AV_LOG_ERROR, "TLS: Failed to set serial, %s\n", ERR_error_string(ERR_get_error(), NULL));
322  goto einval_end;
323  }
324 
325  if (X509_NAME_add_entry_by_txt(subject, "CN", MBSTRING_ASC, aor, strlen(aor), -1, 0) != 1) {
326  av_log(NULL, AV_LOG_ERROR, "TLS: Failed to set CN, %s\n", ERR_error_string(ERR_get_error(), NULL));
327  goto einval_end;
328  }
329 
330  if (X509_set_issuer_name(*cert, subject) != 1) {
331  av_log(NULL, AV_LOG_ERROR, "TLS: Failed to set issuer, %s\n", ERR_error_string(ERR_get_error(), NULL));
332  goto einval_end;
333  }
334  if (X509_set_subject_name(*cert, subject) != 1) {
335  av_log(NULL, AV_LOG_ERROR, "TLS: Failed to set subject name, %s\n", ERR_error_string(ERR_get_error(), NULL));
336  goto einval_end;
337  }
338 
339  expire_day = 365;
340  if (!X509_gmtime_adj(X509_get_notBefore(*cert), 0)) {
341  av_log(NULL, AV_LOG_ERROR, "TLS: Failed to set notBefore, %s\n", ERR_error_string(ERR_get_error(), NULL));
342  goto einval_end;
343  }
344  if (!X509_gmtime_adj(X509_get_notAfter(*cert), 60*60*24*expire_day)) {
345  av_log(NULL, AV_LOG_ERROR, "TLS: Failed to set notAfter, %s\n", ERR_error_string(ERR_get_error(), NULL));
346  goto einval_end;
347  }
348 
349  if (X509_set_version(*cert, 2) != 1) {
350  av_log(NULL, AV_LOG_ERROR, "TLS: Failed to set version, %s\n", ERR_error_string(ERR_get_error(), NULL));
351  goto einval_end;
352  }
353 
354  if (X509_set_pubkey(*cert, pkey) != 1) {
355  av_log(NULL, AV_LOG_ERROR, "TLS: Failed to set public key, %s\n", ERR_error_string(ERR_get_error(), NULL));
356  goto einval_end;
357  }
358 
359  if (!X509_sign(*cert, pkey, EVP_sha1())) {
360  av_log(NULL, AV_LOG_ERROR, "TLS: Failed to sign certificate, %s\n", ERR_error_string(ERR_get_error(), NULL));
361  goto einval_end;
362  }
363 
364  *fingerprint = generate_fingerprint(*cert);
365  if (!*fingerprint) {
366  goto enomem_end;
367  }
368 
369  goto end;
370 enomem_end:
371  ret = AVERROR(ENOMEM);
372  goto end;
373 einval_end:
374  ret = AVERROR(EINVAL);
375 end:
376  X509_NAME_free(subject);
377  //av_bprint_finalize(&fingerprint, NULL);
378  return ret;
379 }
380 
381 int ff_ssl_gen_key_cert(char *key_buf, size_t key_sz, char *cert_buf, size_t cert_sz, char **fingerprint)
382 {
383  int ret = 0;
384  EVP_PKEY *pkey = NULL;
385  EC_KEY *ec_key = NULL;
386  X509 *cert = NULL;
387  char *key_tem = NULL, *cert_tem = NULL;
388 
389  ret = openssl_gen_private_key(&pkey, &ec_key);
390  if (ret < 0) goto error;
391 
392  ret = openssl_gen_certificate(pkey, &cert, fingerprint);
393  if (ret < 0) goto error;
394 
395  key_tem = pkey_to_pem_string(pkey);
396  cert_tem = cert_to_pem_string(cert);
397 
398  snprintf(key_buf, key_sz, "%s", key_tem);
399  snprintf(cert_buf, cert_sz, "%s", cert_tem);
400 
401  if (key_tem) av_free(key_tem);
402  if (cert_tem) av_free(cert_tem);
403 error:
404  return ret;
405 }
406 
407 
408 /**
409  * Deserialize a PEM‐encoded private or public key from a NUL-terminated C string.
410  *
411  * @param pem_str The PEM text, e.g.
412  * "-----BEGIN PRIVATE KEY-----\n…\n-----END PRIVATE KEY-----\n"
413  * @param is_priv If non-zero, parse as a PRIVATE key; otherwise, parse as a PUBLIC key.
414  * @return EVP_PKEY* on success (must EVP_PKEY_free()), or NULL on error.
415  */
416 static EVP_PKEY *pkey_from_pem_string(const char *pem_str, int is_priv)
417 {
418  BIO *mem = BIO_new_mem_buf(pem_str, -1);
419  if (!mem) {
420  av_log(NULL, AV_LOG_ERROR, "BIO_new_mem_buf failed\n");
421  return NULL;
422  }
423 
424  EVP_PKEY *pkey = NULL;
425  if (is_priv) {
426  pkey = PEM_read_bio_PrivateKey(mem, NULL, NULL, NULL);
427  } else {
428  pkey = PEM_read_bio_PUBKEY(mem, NULL, NULL, NULL);
429  }
430 
431  if (!pkey)
432  av_log(NULL, AV_LOG_ERROR, "Failed to parse %s key from string\n",
433  is_priv ? "private" : "public");
434 
435  BIO_free(mem);
436  return pkey;
437 }
438 
439 /**
440  * Deserialize a PEM‐encoded certificate from a NUL-terminated C string.
441  *
442  * @param pem_str The PEM text, e.g.
443  * "-----BEGIN CERTIFICATE-----\n…\n-----END CERTIFICATE-----\n"
444  * @return X509* on success (must X509_free()), or NULL on error.
445  */
446 static X509 *cert_from_pem_string(const char *pem_str)
447 {
448  BIO *mem = BIO_new_mem_buf(pem_str, -1);
449  if (!mem) {
450  av_log(NULL, AV_LOG_ERROR, "BIO_new_mem_buf failed\n");
451  return NULL;
452  }
453 
454  X509 *cert = PEM_read_bio_X509(mem, NULL, NULL, NULL);
455  if (!cert) {
456  av_log(NULL, AV_LOG_ERROR, "Failed to parse certificate from string\n");
457  return NULL;
458  }
459 
460  BIO_free(mem);
461  return cert;
462 }
463 
464 
465 typedef struct TLSContext {
466  const AVClass *class;
468  SSL_CTX *ctx;
469  SSL *ssl;
470 #if OPENSSL_VERSION_NUMBER >= 0x1010000fL
471  BIO_METHOD* url_bio_method;
472 #endif
473  int io_err;
474  char error_message[256];
475 } TLSContext;
476 
477 /**
478  * Retrieves the error message for the latest OpenSSL error.
479  *
480  * This function retrieves the error code from the thread's error queue, converts it
481  * to a human-readable string, and stores it in the TLSContext's error_message field.
482  * The error queue is then cleared using ERR_clear_error().
483  */
484 static const char* openssl_get_error(TLSContext *ctx)
485 {
486  int r2 = ERR_get_error();
487  if (r2) {
488  ERR_error_string_n(r2, ctx->error_message, sizeof(ctx->error_message));
489  } else
490  ctx->error_message[0] = '\0';
491 
492  ERR_clear_error();
493  return ctx->error_message;
494 }
495 
497 {
498  TLSContext *c = h->priv_data;
499  c->tls_shared.udp = udp;
500  return 0;
501 }
502 
503 int ff_dtls_export_materials(URLContext *h, char *dtls_srtp_materials, size_t materials_sz)
504 {
505  int ret = 0;
506  const char* dst = "EXTRACTOR-dtls_srtp";
507  TLSContext *c = h->priv_data;
508 
509  ret = SSL_export_keying_material(c->ssl, dtls_srtp_materials, materials_sz,
510  dst, strlen(dst), NULL, 0, 0);
511  if (!ret) {
512  av_log(c, AV_LOG_ERROR, "TLS: Failed to export SRTP material, %s\n", openssl_get_error(c));
513  return -1;
514  }
515  return 0;
516 }
517 
519 {
520  TLSContext *c = h->priv_data;
521  return c->tls_shared.state;
522 }
523 
524 /* OpenSSL 1.0.2 or below, then you would use SSL_library_init. If you are
525  * using OpenSSL 1.1.0 or above, then the library will initialize
526  * itself automatically.
527  * https://wiki.openssl.org/index.php/Library_Initialization
528  */
529 #if OPENSSL_VERSION_NUMBER < 0x10100000L
530 #include "libavutil/thread.h"
531 
533 
534 static int openssl_init;
535 
536 #if HAVE_THREADS
537 #include <openssl/crypto.h>
538 #include "libavutil/mem.h"
539 
540 pthread_mutex_t *openssl_mutexes;
541 static void openssl_lock(int mode, int type, const char *file, int line)
542 {
543  if (mode & CRYPTO_LOCK)
544  pthread_mutex_lock(&openssl_mutexes[type]);
545  else
546  pthread_mutex_unlock(&openssl_mutexes[type]);
547 }
548 #if !defined(WIN32) && OPENSSL_VERSION_NUMBER < 0x10000000
549 static unsigned long openssl_thread_id(void)
550 {
551  return (intptr_t) pthread_self();
552 }
553 #endif
554 #endif
555 
557 {
559  if (!openssl_init) {
560  SSL_library_init();
561  SSL_load_error_strings();
562 #if HAVE_THREADS
563  if (!CRYPTO_get_locking_callback()) {
564  int i;
565  openssl_mutexes = av_malloc_array(sizeof(pthread_mutex_t), CRYPTO_num_locks());
566  if (!openssl_mutexes) {
568  return AVERROR(ENOMEM);
569  }
570 
571  for (i = 0; i < CRYPTO_num_locks(); i++)
572  pthread_mutex_init(&openssl_mutexes[i], NULL);
573  CRYPTO_set_locking_callback(openssl_lock);
574 #if !defined(WIN32) && OPENSSL_VERSION_NUMBER < 0x10000000
575  CRYPTO_set_id_callback(openssl_thread_id);
576 #endif
577  }
578 #endif
579  }
580  openssl_init++;
582 
583  return 0;
584 }
585 
587 {
589  openssl_init--;
590  if (!openssl_init) {
591 #if HAVE_THREADS
592  if (CRYPTO_get_locking_callback() == openssl_lock) {
593  int i;
594  CRYPTO_set_locking_callback(NULL);
595  for (i = 0; i < CRYPTO_num_locks(); i++)
596  pthread_mutex_destroy(&openssl_mutexes[i]);
597  av_free(openssl_mutexes);
598  }
599 #endif
600  }
602 }
603 #endif
604 
605 static int print_ssl_error(URLContext *h, int ret)
606 {
607  TLSContext *c = h->priv_data;
608  int printed = 0, e, averr = AVERROR(EIO);
609  if (h->flags & AVIO_FLAG_NONBLOCK) {
610  int err = SSL_get_error(c->ssl, ret);
611  if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE)
612  return AVERROR(EAGAIN);
613  }
614  while ((e = ERR_get_error()) != 0) {
615  av_log(h, AV_LOG_ERROR, "%s\n", ERR_error_string(e, NULL));
616  printed = 1;
617  }
618  if (c->io_err) {
619  av_log(h, AV_LOG_ERROR, "IO error: %s\n", av_err2str(c->io_err));
620  printed = 1;
621  averr = c->io_err;
622  c->io_err = 0;
623  }
624  if (!printed)
625  av_log(h, AV_LOG_ERROR, "Unknown error\n");
626  return averr;
627 }
628 
629 static int tls_close(URLContext *h)
630 {
631  TLSContext *c = h->priv_data;
632  if (c->ssl) {
633  SSL_shutdown(c->ssl);
634  SSL_free(c->ssl);
635  }
636  if (c->ctx)
637  SSL_CTX_free(c->ctx);
638  ffurl_closep(&c->tls_shared.tcp);
639 #if OPENSSL_VERSION_NUMBER >= 0x1010000fL
640  if (c->url_bio_method)
641  BIO_meth_free(c->url_bio_method);
642 #endif
643 #if OPENSSL_VERSION_NUMBER < 0x10100000L
645 #endif
646  return 0;
647 }
648 
649 static int url_bio_create(BIO *b)
650 {
651 #if OPENSSL_VERSION_NUMBER >= 0x1010000fL
652  BIO_set_init(b, 1);
653  BIO_set_data(b, NULL);
654  BIO_set_flags(b, 0);
655 #else
656  b->init = 1;
657  b->ptr = NULL;
658  b->flags = 0;
659 #endif
660  return 1;
661 }
662 
663 static int url_bio_destroy(BIO *b)
664 {
665  return 1;
666 }
667 
668 #if OPENSSL_VERSION_NUMBER >= 0x1010000fL
669 #define GET_BIO_DATA(x) BIO_get_data(x)
670 #else
671 #define GET_BIO_DATA(x) (x)->ptr
672 #endif
673 
674 static int url_bio_bread(BIO *b, char *buf, int len)
675 {
677  int ret = ffurl_read(c->tls_shared.is_dtls ? c->tls_shared.udp : c->tls_shared.tcp, buf, len);
678  if (ret >= 0)
679  return ret;
680  BIO_clear_retry_flags(b);
681  if (ret == AVERROR_EXIT)
682  return 0;
683  if (ret == AVERROR(EAGAIN))
684  BIO_set_retry_read(b);
685  else
686  c->io_err = ret;
687  return -1;
688 }
689 
690 static int url_bio_bwrite(BIO *b, const char *buf, int len)
691 {
693  int ret = ffurl_write(c->tls_shared.is_dtls ? c->tls_shared.udp : c->tls_shared.tcp, buf, len);
694  if (ret >= 0)
695  return ret;
696  BIO_clear_retry_flags(b);
697  if (ret == AVERROR_EXIT)
698  return 0;
699  if (ret == AVERROR(EAGAIN))
700  BIO_set_retry_write(b);
701  else
702  c->io_err = ret;
703  return -1;
704 }
705 
706 static long url_bio_ctrl(BIO *b, int cmd, long num, void *ptr)
707 {
708  if (cmd == BIO_CTRL_FLUSH) {
709  BIO_clear_retry_flags(b);
710  return 1;
711  }
712  return 0;
713 }
714 
715 static int url_bio_bputs(BIO *b, const char *str)
716 {
717  return url_bio_bwrite(b, str, strlen(str));
718 }
719 
720 #if OPENSSL_VERSION_NUMBER < 0x1010000fL
721 static BIO_METHOD url_bio_method = {
722  .type = BIO_TYPE_SOURCE_SINK,
723  .name = "urlprotocol bio",
724  .bwrite = url_bio_bwrite,
725  .bread = url_bio_bread,
726  .bputs = url_bio_bputs,
727  .bgets = NULL,
728  .ctrl = url_bio_ctrl,
729  .create = url_bio_create,
730  .destroy = url_bio_destroy,
731 };
732 #endif
733 
735 {
736  TLSContext *p = h->priv_data;
737  BIO *bio;
738 #if OPENSSL_VERSION_NUMBER >= 0x1010000fL
739  p->url_bio_method = BIO_meth_new(BIO_TYPE_SOURCE_SINK, "urlprotocol bio");
740  BIO_meth_set_write(p->url_bio_method, url_bio_bwrite);
741  BIO_meth_set_read(p->url_bio_method, url_bio_bread);
742  BIO_meth_set_puts(p->url_bio_method, url_bio_bputs);
743  BIO_meth_set_ctrl(p->url_bio_method, url_bio_ctrl);
744  BIO_meth_set_create(p->url_bio_method, url_bio_create);
745  BIO_meth_set_destroy(p->url_bio_method, url_bio_destroy);
746  bio = BIO_new(p->url_bio_method);
747  BIO_set_data(bio, p);
748 #else
749  bio = BIO_new(&url_bio_method);
750  bio->ptr = p;
751 #endif
752  SSL_set_bio(p->ssl, bio, bio);
753 }
754 
755 static void openssl_info_callback(const SSL *ssl, int where, int ret) {
756  const char *method = "undefined";
757  TLSContext *ctx = (TLSContext*)SSL_get_ex_data(ssl, 0);
758 
759  if (where & SSL_ST_CONNECT) {
760  method = "SSL_connect";
761  } else if (where & SSL_ST_ACCEPT)
762  method = "SSL_accept";
763 
764  if (where & SSL_CB_LOOP) {
765  av_log(ctx, AV_LOG_DEBUG, "Info method=%s state=%s(%s), where=%d, ret=%d\n",
766  method, SSL_state_string(ssl), SSL_state_string_long(ssl), where, ret);
767  } else if (where & SSL_CB_ALERT) {
768  method = (where & SSL_CB_READ) ? "read":"write";
769  av_log(ctx, AV_LOG_DEBUG, "Alert method=%s state=%s(%s), where=%d, ret=%d\n",
770  method, SSL_state_string(ssl), SSL_state_string_long(ssl), where, ret);
771  }
772 }
773 
774 /**
775  * Always return 1 to accept any certificate. This is because we allow the peer to
776  * use a temporary self-signed certificate for DTLS.
777  */
778 static int openssl_dtls_verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
779 {
780  return 1;
781 }
782 
784 {
785  int ret = 0, r0, r1;
786  TLSContext *p = h->priv_data;
787 
788  r0 = SSL_do_handshake(p->ssl);
789  r1 = SSL_get_error(p->ssl, r0);
790  if (r0 <= 0) {
791  if (r1 != SSL_ERROR_WANT_READ && r1 != SSL_ERROR_WANT_WRITE && r1 != SSL_ERROR_ZERO_RETURN) {
792  av_log(p, AV_LOG_ERROR, "TLS: Read failed, r0=%d, r1=%d %s\n", r0, r1, openssl_get_error(p));
793  ret = AVERROR(EIO);
794  goto end;
795  }
796  } else {
797  av_log(p, AV_LOG_TRACE, "TLS: Read %d bytes, r0=%d, r1=%d\n", r0, r0, r1);
798  }
799 
800  /* Check whether the DTLS is completed. */
801  if (SSL_is_init_finished(p->ssl) != 1)
802  goto end;
803 
805 end:
806  return ret;
807 }
808 
810 {
811  int ret;
812  TLSContext *p = h->priv_data;
813  TLSShared *c = &p->tls_shared;
814  EVP_PKEY *pkey = NULL;
815  X509 *cert = NULL;
816  /* setup ca, private key, certificate */
817  if (c->ca_file) {
818  if (!SSL_CTX_load_verify_locations(p->ctx, c->ca_file, NULL))
819  av_log(h, AV_LOG_ERROR, "SSL_CTX_load_verify_locations %s\n", openssl_get_error(p));
820  }
821 
822  if (c->cert_file) {
823  ret = SSL_CTX_use_certificate_chain_file(p->ctx, c->cert_file);
824  if (ret <= 0) {
825  av_log(h, AV_LOG_ERROR, "Unable to load cert file %s: %s\n",
826  c->cert_file, openssl_get_error(p));
827  ret = AVERROR(EIO);
828  goto fail;
829  }
830  } else if (p->tls_shared.cert_buf) {
832  if (SSL_CTX_use_certificate(p->ctx, cert) != 1) {
833  av_log(p, AV_LOG_ERROR, "SSL: Init SSL_CTX_use_certificate failed, %s\n", openssl_get_error(p));
834  ret = AVERROR(EINVAL);
835  return ret;
836  }
837  } else if (p->tls_shared.is_dtls){
838  av_log(p, AV_LOG_ERROR, "TLS: Init cert failed, %s\n", openssl_get_error(p));
839  ret = AVERROR(EINVAL);
840  goto fail;
841  }
842 
843  if (c->key_file) {
844  ret = SSL_CTX_use_PrivateKey_file(p->ctx, c->key_file, SSL_FILETYPE_PEM);
845  if (ret <= 0) {
846  av_log(h, AV_LOG_ERROR, "Unable to load key file %s: %s\n",
847  c->key_file, openssl_get_error(p));
848  ret = AVERROR(EIO);
849  goto fail;
850  }
851  } else if (p->tls_shared.key_buf) {
853  if (SSL_CTX_use_PrivateKey(p->ctx, pkey) != 1) {
854  av_log(p, AV_LOG_ERROR, "TLS: Init SSL_CTX_use_PrivateKey failed, %s\n", openssl_get_error(p));
855  ret = AVERROR(EINVAL);
856  return ret;
857  }
858  } else if (p->tls_shared.is_dtls){
859  av_log(p, AV_LOG_ERROR, "TLS: Init pkey failed, %s\n", openssl_get_error(p));
860  ret = AVERROR(EINVAL);
861  goto fail;
862  }
863  ret = 0;
864 fail:
865  return ret;
866 }
867 
868 /**
869  * Once the DTLS role has been negotiated - active for the DTLS client or passive for the
870  * DTLS server - we proceed to set up the DTLS state and initiate the handshake.
871  */
872 static int dtls_start(URLContext *h, const char *url, int flags, AVDictionary **options)
873 {
874  TLSContext *p = h->priv_data;
875  TLSShared *c = &p->tls_shared;
876  int ret = 0;
877  c->is_dtls = 1;
878  const char* ciphers = "ALL";
879  /**
880  * The profile for OpenSSL's SRTP is SRTP_AES128_CM_SHA1_80, see ssl/d1_srtp.c.
881  * The profile for FFmpeg's SRTP is SRTP_AES128_CM_HMAC_SHA1_80, see libavformat/srtp.c.
882  */
883  const char* profiles = "SRTP_AES128_CM_SHA1_80";
884  /* Refer to the test cases regarding these curves in the WebRTC code. */
885 #if OPENSSL_VERSION_NUMBER >= 0x10100000L /* OpenSSL 1.1.0 */
886  const char* curves = "X25519:P-256:P-384:P-521";
887 #elif OPENSSL_VERSION_NUMBER >= 0x10002000L /* OpenSSL 1.0.2 */
888  const char* curves = "P-256:P-384:P-521";
889 #endif
890 
891 #if OPENSSL_VERSION_NUMBER < 0x10002000L /* OpenSSL v1.0.2 */
892  p->ctx = SSL_CTX_new(DTLSv1_method());
893 #else
894  p->ctx = SSL_CTX_new(DTLS_method());
895 #endif
896  if (!p->ctx) {
897  ret = AVERROR(ENOMEM);
898  goto fail;
899  }
900 
901 #if OPENSSL_VERSION_NUMBER >= 0x10002000L /* OpenSSL 1.0.2 */
902  /* For ECDSA, we could set the curves list. */
903  if (SSL_CTX_set1_curves_list(p->ctx, curves) != 1) {
904  av_log(p, AV_LOG_ERROR, "TLS: Init SSL_CTX_set1_curves_list failed, curves=%s, %s\n",
906  ret = AVERROR(EINVAL);
907  return ret;
908  }
909 #endif
910 
911 #if OPENSSL_VERSION_NUMBER < 0x10100000L // v1.1.x
912 #if OPENSSL_VERSION_NUMBER < 0x10002000L // v1.0.2
913  if (ctx->dtls_eckey)
914  SSL_CTX_set_tmp_ecdh(p->ctx, p->dtls_eckey);
915 #else
916  SSL_CTX_set_ecdh_auto(p->ctx, 1);
917 #endif
918 #endif
919 
920  /**
921  * We activate "ALL" cipher suites to align with the peer's capabilities,
922  * ensuring maximum compatibility.
923  */
924  if (SSL_CTX_set_cipher_list(p->ctx, ciphers) != 1) {
925  av_log(p, AV_LOG_ERROR, "TLS: Init SSL_CTX_set_cipher_list failed, ciphers=%s, %s\n",
926  ciphers, openssl_get_error(p));
927  ret = AVERROR(EINVAL);
928  return ret;
929  }
931  if (ret < 0) goto fail;
932 
933  /* Server will send Certificate Request. */
934  SSL_CTX_set_verify(p->ctx, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, openssl_dtls_verify_callback);
935  /* The depth count is "level 0:peer certificate", "level 1: CA certificate",
936  * "level 2: higher level CA certificate", and so on. */
937  SSL_CTX_set_verify_depth(p->ctx, 4);
938  /* Whether we should read as many input bytes as possible (for non-blocking reads) or not. */
939  SSL_CTX_set_read_ahead(p->ctx, 1);
940  /* Setup the SRTP context */
941  if (SSL_CTX_set_tlsext_use_srtp(p->ctx, profiles)) {
942  av_log(p, AV_LOG_ERROR, "TLS: Init SSL_CTX_set_tlsext_use_srtp failed, profiles=%s, %s\n",
944  ret = AVERROR(EINVAL);
945  return ret;
946  }
947 
948  /* The ssl should not be created unless the ctx has been initialized. */
949  p->ssl = SSL_new(p->ctx);
950  if (!p->ssl) {
951  ret = AVERROR(ENOMEM);
952  goto fail;
953  }
954 
955  /* Setup the callback for logging. */
956  SSL_set_ex_data(p->ssl, 0, p);
957  SSL_set_info_callback(p->ssl, openssl_info_callback);
958  /**
959  * We have set the MTU to fragment the DTLS packet. It is important to note that the
960  * packet is split to ensure that each handshake packet is smaller than the MTU.
961  */
962  SSL_set_options(p->ssl, SSL_OP_NO_QUERY_MTU);
963  SSL_set_mtu(p->ssl, p->tls_shared.mtu);
964 #if OPENSSL_VERSION_NUMBER >= 0x100010b0L /* OpenSSL 1.0.1k */
965  DTLS_set_link_mtu(p->ssl, p->tls_shared.mtu);
966 #endif
968 
969  if (p->tls_shared.use_external_udp != 1) {
970  if ((ret = ff_tls_open_underlying(&p->tls_shared, h, url, options)) < 0) {
971  av_log(p, AV_LOG_ERROR, "Failed to connect %s\n", url);
972  return ret;
973  }
974  }
975 
976  /* Setup DTLS as passive, which is server role. */
977  c->listen ? SSL_set_accept_state(p->ssl) : SSL_set_connect_state(p->ssl);
978 
979  /**
980  * During initialization, we only need to call SSL_do_handshake once because SSL_read consumes
981  * the handshake message if the handshake is incomplete.
982  * To simplify maintenance, we initiate the handshake for both the DTLS server and client after
983  * sending out the ICE response in the start_active_handshake function. It's worth noting that
984  * although the DTLS server may receive the ClientHello immediately after sending out the ICE
985  * response, this shouldn't be an issue as the handshake function is called before any DTLS
986  * packets are received.
987  *
988  * The SSL_do_handshake can't be called if DTLS hasn't prepare for udp.
989  */
990  if (p->tls_shared.use_external_udp != 1) {
991  ret = dtls_handshake(h);
992  // Fatal SSL error, for example, no available suite when peer is DTLS 1.0 while we are DTLS 1.2.
993  if (ret < 0) {
994  av_log(p, AV_LOG_ERROR, "TLS: Failed to drive SSL context, ret=%d\n", ret);
995  return AVERROR(EIO);
996  }
997  }
998 
999  av_log(p, AV_LOG_VERBOSE, "TLS: Setup ok, MTU=%d, fingerprint %s\n",
1001 
1002  ret = 0;
1003 fail:
1004  return ret;
1005 }
1006 
1007 /**
1008  * Cleanup the DTLS context.
1009  */
1011 {
1012  TLSContext *ctx = h->priv_data;
1013  SSL_free(ctx->ssl);
1014  SSL_CTX_free(ctx->ctx);
1015  av_freep(&ctx->tls_shared.fingerprint);
1016  av_freep(&ctx->tls_shared.cert_buf);
1017  av_freep(&ctx->tls_shared.key_buf);
1018 #if OPENSSL_VERSION_NUMBER < 0x30000000L /* OpenSSL 3.0 */
1019  EC_KEY_free(ctx->dtls_eckey);
1020 #endif
1021  return 0;
1022 }
1023 
1024 static int tls_open(URLContext *h, const char *uri, int flags, AVDictionary **options)
1025 {
1026  TLSContext *p = h->priv_data;
1027  TLSShared *c = &p->tls_shared;
1028  int ret;
1029 
1030 #if OPENSSL_VERSION_NUMBER < 0x10100000L
1031  if ((ret = ff_openssl_init()) < 0)
1032  return ret;
1033 #endif
1034 
1035  if ((ret = ff_tls_open_underlying(c, h, uri, options)) < 0)
1036  goto fail;
1037 
1038  // We want to support all versions of TLS >= 1.0, but not the deprecated
1039  // and insecure SSLv2 and SSLv3. Despite the name, SSLv23_*_method()
1040  // enables support for all versions of SSL and TLS, and we then disable
1041  // support for the old protocols immediately after creating the context.
1042  p->ctx = SSL_CTX_new(c->listen ? SSLv23_server_method() : SSLv23_client_method());
1043  if (!p->ctx) {
1044  av_log(h, AV_LOG_ERROR, "%s\n", openssl_get_error(p));
1045  ret = AVERROR(EIO);
1046  goto fail;
1047  }
1048  SSL_CTX_set_options(p->ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
1050  if (ret < 0) goto fail;
1051  // Note, this doesn't check that the peer certificate actually matches
1052  // the requested hostname.
1053  if (c->verify)
1054  SSL_CTX_set_verify(p->ctx, SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
1055  p->ssl = SSL_new(p->ctx);
1056  if (!p->ssl) {
1057  av_log(h, AV_LOG_ERROR, "%s\n", openssl_get_error(p));
1058  ret = AVERROR(EIO);
1059  goto fail;
1060  }
1061  SSL_set_ex_data(p->ssl, 0, p);
1062  SSL_CTX_set_info_callback(p->ctx, openssl_info_callback);
1063  init_bio_method(h);
1064  if (!c->listen && !c->numerichost)
1065  SSL_set_tlsext_host_name(p->ssl, c->host);
1066  ret = c->listen ? SSL_accept(p->ssl) : SSL_connect(p->ssl);
1067  if (ret == 0) {
1068  av_log(h, AV_LOG_ERROR, "Unable to negotiate TLS/SSL session\n");
1069  ret = AVERROR(EIO);
1070  goto fail;
1071  } else if (ret < 0) {
1072  ret = print_ssl_error(h, ret);
1073  goto fail;
1074  }
1075 
1076  return 0;
1077 fail:
1078  tls_close(h);
1079  return ret;
1080 }
1081 
1082 static int tls_read(URLContext *h, uint8_t *buf, int size)
1083 {
1084  TLSContext *c = h->priv_data;
1085  URLContext *uc = c->tls_shared.is_dtls ? c->tls_shared.udp
1086  : c->tls_shared.tcp;
1087  int ret;
1088  // Set or clear the AVIO_FLAG_NONBLOCK on c->tls_shared.tcp
1089  uc->flags &= ~AVIO_FLAG_NONBLOCK;
1090  uc->flags |= h->flags & AVIO_FLAG_NONBLOCK;
1091  ret = SSL_read(c->ssl, buf, size);
1092  if (ret > 0)
1093  return ret;
1094  if (ret == 0)
1095  return AVERROR_EOF;
1096  return print_ssl_error(h, ret);
1097 }
1098 
1099 static int tls_write(URLContext *h, const uint8_t *buf, int size)
1100 {
1101  TLSContext *c = h->priv_data;
1102  URLContext *uc = c->tls_shared.is_dtls ? c->tls_shared.udp
1103  : c->tls_shared.tcp;
1104  int ret;
1105  // Set or clear the AVIO_FLAG_NONBLOCK on c->tls_shared.tcp
1106  uc->flags &= ~AVIO_FLAG_NONBLOCK;
1107  uc->flags |= h->flags & AVIO_FLAG_NONBLOCK;
1108  ret = SSL_write(c->ssl, buf, size);
1109  if (ret > 0)
1110  return ret;
1111  if (ret == 0)
1112  return AVERROR_EOF;
1113  return print_ssl_error(h, ret);
1114 }
1115 
1117 {
1118  TLSContext *c = h->priv_data;
1119  return ffurl_get_file_handle(c->tls_shared.tcp);
1120 }
1121 
1123 {
1124  TLSContext *s = h->priv_data;
1125  return ffurl_get_short_seek(s->tls_shared.tcp);
1126 }
1127 
1128 static const AVOption options[] = {
1129  TLS_COMMON_OPTIONS(TLSContext, tls_shared),
1130  { NULL }
1131 };
1132 
1133 static const AVClass tls_class = {
1134  .class_name = "tls",
1135  .item_name = av_default_item_name,
1136  .option = options,
1137  .version = LIBAVUTIL_VERSION_INT,
1138 };
1139 
1141  .name = "tls",
1142  .url_open2 = tls_open,
1143  .url_read = tls_read,
1144  .url_write = tls_write,
1145  .url_close = tls_close,
1146  .url_get_file_handle = tls_get_file_handle,
1147  .url_get_short_seek = tls_get_short_seek,
1148  .priv_data_size = sizeof(TLSContext),
1150  .priv_data_class = &tls_class,
1151 };
1152 
1153 static const AVClass dtls_class = {
1154  .class_name = "dtls",
1155  .item_name = av_default_item_name,
1156  .option = options,
1157  .version = LIBAVUTIL_VERSION_INT,
1158 };
1159 
1161  .name = "dtls",
1162  .url_open2 = dtls_start,
1163  .url_handshake = dtls_handshake,
1164  .url_close = dtls_close,
1165  .url_read = tls_read,
1166  .url_write = tls_write,
1167  .priv_data_size = sizeof(TLSContext),
1169  .priv_data_class = &dtls_class,
1170 };
error
static void error(const char *err)
Definition: target_bsf_fuzzer.c:32
flags
const SwsFlags flags[]
Definition: swscale.c:61
pthread_mutex_t
_fmutex pthread_mutex_t
Definition: os2threads.h:53
cert_from_pem_string
static X509 * cert_from_pem_string(const char *pem_str)
Deserialize a PEM‐encoded certificate from a NUL-terminated C string.
Definition: tls_openssl.c:446
AV_BPRINT_SIZE_UNLIMITED
#define AV_BPRINT_SIZE_UNLIMITED
TLSContext
Definition: tls_gnutls.c:44
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
opt.h
URL_PROTOCOL_FLAG_NETWORK
#define URL_PROTOCOL_FLAG_NETWORK
Definition: url.h:33
out
FILE * out
Definition: movenc.c:55
curves
static const Curve curves[]
Definition: vf_pseudocolor.c:192
av_bprint_init
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
Definition: bprint.c:69
thread.h
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:57
pthread_mutex_init
static av_always_inline int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
Definition: os2threads.h:104
openssl_gen_private_key
static int openssl_gen_private_key(EVP_PKEY **pkey, EC_KEY **eckey)
Definition: tls_openssl.c:236
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
dtls_close
static av_cold int dtls_close(URLContext *h)
Cleanup the DTLS context.
Definition: tls_openssl.c:1010
mode
Definition: swscale.c:56
cleanup
static av_cold void cleanup(FlashSV2Context *s)
Definition: flashsv2enc.c:130
pthread_mutex_lock
static av_always_inline int pthread_mutex_lock(pthread_mutex_t *mutex)
Definition: os2threads.h:119
AVOption
AVOption.
Definition: opt.h:429
b
#define b
Definition: input.c:42
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:226
AVDictionary
Definition: dict.c:32
TLSShared::state
enum DTLSState state
Definition: tls.h:64
URLProtocol
Definition: url.h:51
os_support.h
ff_openssl_deinit
void ff_openssl_deinit(void)
Definition: tls_openssl.c:586
TLSShared::fingerprint
char * fingerprint
Definition: tls.h:70
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:31
av_get_random_seed
uint32_t av_get_random_seed(void)
Get a seed to use in conjunction with random functions.
Definition: random_seed.c:196
ff_mutex_unlock
static int ff_mutex_unlock(AVMutex *mutex)
Definition: thread.h:189
ff_dtls_export_materials
int ff_dtls_export_materials(URLContext *h, char *dtls_srtp_materials, size_t materials_sz)
Definition: tls_openssl.c:503
TLS_COMMON_OPTIONS
#define TLS_COMMON_OPTIONS(pstruct, options_field)
Definition: tls.h:83
tls_class
static const AVClass tls_class
Definition: tls_openssl.c:1133
fail
#define fail()
Definition: checkasm.h:196
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
url_bio_create
static int url_bio_create(BIO *b)
Definition: tls_openssl.c:649
type
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 type
Definition: writing_filters.txt:86
GET_BIO_DATA
#define GET_BIO_DATA(x)
Definition: tls_openssl.c:671
openssl_dtls_verify_callback
static int openssl_dtls_verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
Always return 1 to accept any certificate.
Definition: tls_openssl.c:778
openssl_init
static int openssl_init
Definition: tls_openssl.c:534
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_openssl.c:159
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
av_cold
#define av_cold
Definition: attributes.h:90
ff_dtls_state
int ff_dtls_state(URLContext *h)
Definition: tls_openssl.c:518
AVMutex
#define AVMutex
Definition: thread.h:184
s
#define s(width, name)
Definition: cbs_vp9.c:198
pthread_mutex_unlock
static av_always_inline int pthread_mutex_unlock(pthread_mutex_t *mutex)
Definition: os2threads.h:126
URLContext::flags
int flags
Definition: url.h:40
tls_write
static int tls_write(URLContext *h, const uint8_t *buf, int size)
Definition: tls_openssl.c:1099
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:231
ctx
AVFormatContext * ctx
Definition: movenc.c:49
ff_tls_protocol
const URLProtocol ff_tls_protocol
Definition: tls_openssl.c:1140
ff_dtls_set_udp
int ff_dtls_set_udp(URLContext *h, URLContext *udp)
Definition: tls_openssl.c:496
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
dtls_handshake
static int dtls_handshake(URLContext *h)
Definition: tls_openssl.c:783
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:76
result
and forward the result(frame or status change) to the corresponding input. If nothing is possible
NULL
#define NULL
Definition: coverity.c:32
openssl_mutex
static AVMutex openssl_mutex
Definition: tls_openssl.c:532
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:240
options
Definition: swscale.c:43
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_openssl.c:381
url_bio_ctrl
static long url_bio_ctrl(BIO *b, int cmd, long num, void *ptr)
Definition: tls_openssl.c:706
ff_openssl_init
int ff_openssl_init(void)
Definition: tls_openssl.c:556
url_bio_destroy
static int url_bio_destroy(BIO *b)
Definition: tls_openssl.c:663
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
url_bio_bwrite
static int url_bio_bwrite(BIO *b, const char *buf, int len)
Definition: tls_openssl.c:690
tls_open
static int tls_open(URLContext *h, const char *uri, int flags, AVDictionary **options)
Definition: tls_openssl.c:1024
TLSContext::error_message
char error_message[256]
Definition: tls_openssl.c:474
TLSShared::cert_buf
char * cert_buf
Definition: tls.h:73
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:153
av_bprint_finalize
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
Definition: bprint.c:240
url_bio_bread
static int url_bio_bread(BIO *b, char *buf, int len)
Definition: tls_openssl.c:674
dst
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition: dsp.h:87
av_err2str
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition: error.h:122
TLSContext::ctx
SSL_CTX * ctx
Definition: tls_openssl.c:468
AV_MUTEX_INITIALIZER
#define AV_MUTEX_INITIALIZER
Definition: thread.h:185
pkey_to_pem_string
static char * pkey_to_pem_string(EVP_PKEY *pkey)
Returns a heap‐allocated null‐terminated string containing the PEM‐encoded public key.
Definition: tls_openssl.c:39
size
int size
Definition: twinvq_data.h:10344
TLSContext::tls_shared
TLSShared tls_shared
Definition: tls_gnutls.c:46
URLProtocol::name
const char * name
Definition: url.h:52
options
static const AVOption options[]
Definition: tls_openssl.c:1128
TLSContext::io_err
int io_err
Definition: tls_gnutls.c:50
openssl_info_callback
static void openssl_info_callback(const SSL *ssl, int where, int ret)
Definition: tls_openssl.c:755
line
Definition: graph2dot.c:48
ff_mutex_lock
static int ff_mutex_lock(AVMutex *mutex)
Definition: thread.h:188
tls_get_file_handle
static int tls_get_file_handle(URLContext *h)
Definition: tls_openssl.c:1116
TLSShared::key_buf
char * key_buf
Definition: tls.h:74
TLSShared::use_external_udp
int use_external_udp
Definition: tls.h:66
init_bio_method
static av_cold void init_bio_method(URLContext *h)
Definition: tls_openssl.c:734
pthread_mutex_destroy
static av_always_inline int pthread_mutex_destroy(pthread_mutex_t *mutex)
Definition: os2threads.h:112
TLSContext::ssl
SSL * ssl
Definition: tls_openssl.c:469
URLContext
Definition: url.h:35
print_ssl_error
static int print_ssl_error(URLContext *h, int ret)
Definition: tls_openssl.c:605
openssl_get_error
static const char * openssl_get_error(TLSContext *ctx)
Retrieves the error message for the latest OpenSSL error.
Definition: tls_openssl.c:484
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
generate_fingerprint
static char * generate_fingerprint(X509 *cert)
Generate a SHA-256 fingerprint of an X.509 certificate.
Definition: tls_openssl.c:122
av_malloc_array
#define av_malloc_array(a, b)
Definition: tableprint_vlc.h:32
url.h
len
int len
Definition: vorbis_enc_data.h:426
cert_to_pem_string
static char * cert_to_pem_string(X509 *cert)
Serialize an X509 certificate to a av_malloc’d PEM string.
Definition: tls_openssl.c:81
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:69
ret
ret
Definition: filter_design.txt:187
TLSShared::is_dtls
int is_dtls
Definition: tls.h:62
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
averr
int averr
Definition: nvenc.c:126
av_bprintf
void av_bprintf(AVBPrint *buf, const char *fmt,...)
Definition: bprint.c:99
network.h
tls.h
random_seed.h
tls_get_short_seek
static int tls_get_short_seek(URLContext *h)
Definition: tls_openssl.c:1122
profiles
static const AVProfile profiles[]
Definition: libfdk-aacenc.c:557
tls_read
static int tls_read(URLContext *h, uint8_t *buf, int size)
Definition: tls_openssl.c:1082
av_strdup
char * av_strdup(const char *s)
Duplicate a string.
Definition: mem.c:272
mem.h
MAX_CERTIFICATE_SIZE
#define MAX_CERTIFICATE_SIZE
Maximum size limit of a certificate and private key size.
Definition: tls.h:34
TLSShared::mtu
int mtu
The size of RTP packet, should generally be set to MTU.
Definition: tls.h:79
url_bio_method
static BIO_METHOD url_bio_method
Definition: tls_openssl.c:721
TLSShared
Definition: tls.h:47
openssl_init_ca_key_cert
static av_cold int openssl_init_ca_key_cert(URLContext *h)
Definition: tls_openssl.c:809
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
dtls_start
static int dtls_start(URLContext *h, const char *url, int flags, AVDictionary **options)
Once the DTLS role has been negotiated - active for the DTLS client or passive for the DTLS server - ...
Definition: tls_openssl.c:872
AVIO_FLAG_NONBLOCK
#define AVIO_FLAG_NONBLOCK
Use non-blocking mode.
Definition: avio.h:636
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
TLSContext::ctx
struct tls * ctx
Definition: tls_libtls.c:37
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
pkey_from_pem_string
static EVP_PKEY * pkey_from_pem_string(const char *pem_str, int is_priv)
Deserialize a PEM‐encoded private or public key from a NUL-terminated C string.
Definition: tls_openssl.c:416
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
dtls_class
static const AVClass dtls_class
Definition: tls_openssl.c:1153
DTLS_STATE_FINISHED
@ DTLS_STATE_FINISHED
Definition: tls.h:40
tls_close
static int tls_close(URLContext *h)
Definition: tls_openssl.c:629
snprintf
#define snprintf
Definition: snprintf.h:34
ff_dtls_protocol
const URLProtocol ff_dtls_protocol
Definition: tls_openssl.c:1160
openssl_gen_certificate
static int openssl_gen_certificate(EVP_PKEY *pkey, X509 **cert, char **fingerprint)
Definition: tls_openssl.c:302
ffurl_get_file_handle
int ffurl_get_file_handle(URLContext *h)
Return the file descriptor associated with this URL.
Definition: avio.c:815
url_bio_bputs
static int url_bio_bputs(BIO *b, const char *str)
Definition: tls_openssl.c:715
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