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 #if OPENSSL_VERSION_NUMBER < 0x10002000L /* OpenSSL 1.0.2 */
419  BIO *mem = BIO_new_mem_buf((void *)pem_str, -1);
420 #else
421  BIO *mem = BIO_new_mem_buf(pem_str, -1);
422 #endif
423  if (!mem) {
424  av_log(NULL, AV_LOG_ERROR, "BIO_new_mem_buf failed\n");
425  return NULL;
426  }
427 
428  EVP_PKEY *pkey = NULL;
429  if (is_priv) {
430  pkey = PEM_read_bio_PrivateKey(mem, NULL, NULL, NULL);
431  } else {
432  pkey = PEM_read_bio_PUBKEY(mem, NULL, NULL, NULL);
433  }
434 
435  if (!pkey)
436  av_log(NULL, AV_LOG_ERROR, "Failed to parse %s key from string\n",
437  is_priv ? "private" : "public");
438 
439  BIO_free(mem);
440  return pkey;
441 }
442 
443 /**
444  * Deserialize a PEM‐encoded certificate from a NUL-terminated C string.
445  *
446  * @param pem_str The PEM text, e.g.
447  * "-----BEGIN CERTIFICATE-----\n…\n-----END CERTIFICATE-----\n"
448  * @return X509* on success (must X509_free()), or NULL on error.
449  */
450 static X509 *cert_from_pem_string(const char *pem_str)
451 {
452 #if OPENSSL_VERSION_NUMBER < 0x10002000L /* OpenSSL 1.0.2 */
453  BIO *mem = BIO_new_mem_buf((void *)pem_str, -1);
454 #else
455  BIO *mem = BIO_new_mem_buf(pem_str, -1);
456 #endif
457  if (!mem) {
458  av_log(NULL, AV_LOG_ERROR, "BIO_new_mem_buf failed\n");
459  return NULL;
460  }
461 
462  X509 *cert = PEM_read_bio_X509(mem, NULL, NULL, NULL);
463  if (!cert) {
464  av_log(NULL, AV_LOG_ERROR, "Failed to parse certificate from string\n");
465  return NULL;
466  }
467 
468  BIO_free(mem);
469  return cert;
470 }
471 
472 
473 typedef struct TLSContext {
474  const AVClass *class;
476  SSL_CTX *ctx;
477  SSL *ssl;
478  EVP_PKEY *pkey;
479 #if OPENSSL_VERSION_NUMBER >= 0x1010000fL
480  BIO_METHOD* url_bio_method;
481 #endif
482  int io_err;
483  char error_message[256];
484 } TLSContext;
485 
486 /**
487  * Retrieves the error message for the latest OpenSSL error.
488  *
489  * This function retrieves the error code from the thread's error queue, converts it
490  * to a human-readable string, and stores it in the TLSContext's error_message field.
491  * The error queue is then cleared using ERR_clear_error().
492  */
493 static const char* openssl_get_error(TLSContext *ctx)
494 {
495  int r2 = ERR_get_error();
496  if (r2) {
497  ERR_error_string_n(r2, ctx->error_message, sizeof(ctx->error_message));
498  } else
499  ctx->error_message[0] = '\0';
500 
501  ERR_clear_error();
502  return ctx->error_message;
503 }
504 
506 {
507  TLSContext *c = h->priv_data;
508  c->tls_shared.udp = udp;
509  return 0;
510 }
511 
512 int ff_dtls_export_materials(URLContext *h, char *dtls_srtp_materials, size_t materials_sz)
513 {
514  int ret = 0;
515  const char* dst = "EXTRACTOR-dtls_srtp";
516  TLSContext *c = h->priv_data;
517 
518  ret = SSL_export_keying_material(c->ssl, dtls_srtp_materials, materials_sz,
519  dst, strlen(dst), NULL, 0, 0);
520  if (!ret) {
521  av_log(c, AV_LOG_ERROR, "TLS: Failed to export SRTP material, %s\n", openssl_get_error(c));
522  return -1;
523  }
524  return 0;
525 }
526 
528 {
529  TLSContext *c = h->priv_data;
530  return c->tls_shared.state;
531 }
532 
533 /* OpenSSL 1.0.2 or below, then you would use SSL_library_init. If you are
534  * using OpenSSL 1.1.0 or above, then the library will initialize
535  * itself automatically.
536  * https://wiki.openssl.org/index.php/Library_Initialization
537  */
538 #if OPENSSL_VERSION_NUMBER < 0x10100000L
539 #include "libavutil/thread.h"
540 
542 
543 static int openssl_init;
544 
545 #if HAVE_THREADS
546 #include <openssl/crypto.h>
547 #include "libavutil/mem.h"
548 
549 pthread_mutex_t *openssl_mutexes;
550 static void openssl_lock(int mode, int type, const char *file, int line)
551 {
552  if (mode & CRYPTO_LOCK)
553  pthread_mutex_lock(&openssl_mutexes[type]);
554  else
555  pthread_mutex_unlock(&openssl_mutexes[type]);
556 }
557 #if !defined(WIN32) && OPENSSL_VERSION_NUMBER < 0x10000000
558 static unsigned long openssl_thread_id(void)
559 {
560  return (intptr_t) pthread_self();
561 }
562 #endif
563 #endif
564 
566 {
568  if (!openssl_init) {
569  SSL_library_init();
570  SSL_load_error_strings();
571 #if HAVE_THREADS
572  if (!CRYPTO_get_locking_callback()) {
573  int i;
574  openssl_mutexes = av_malloc_array(sizeof(pthread_mutex_t), CRYPTO_num_locks());
575  if (!openssl_mutexes) {
577  return AVERROR(ENOMEM);
578  }
579 
580  for (i = 0; i < CRYPTO_num_locks(); i++)
581  pthread_mutex_init(&openssl_mutexes[i], NULL);
582  CRYPTO_set_locking_callback(openssl_lock);
583 #if !defined(WIN32) && OPENSSL_VERSION_NUMBER < 0x10000000
584  CRYPTO_set_id_callback(openssl_thread_id);
585 #endif
586  }
587 #endif
588  }
589  openssl_init++;
591 
592  return 0;
593 }
594 
596 {
598  openssl_init--;
599  if (!openssl_init) {
600 #if HAVE_THREADS
601  if (CRYPTO_get_locking_callback() == openssl_lock) {
602  int i;
603  CRYPTO_set_locking_callback(NULL);
604  for (i = 0; i < CRYPTO_num_locks(); i++)
605  pthread_mutex_destroy(&openssl_mutexes[i]);
606  av_free(openssl_mutexes);
607  }
608 #endif
609  }
611 }
612 #endif
613 
614 static int print_ssl_error(URLContext *h, int ret)
615 {
616  TLSContext *c = h->priv_data;
617  int printed = 0, e, averr = AVERROR(EIO);
618  if (h->flags & AVIO_FLAG_NONBLOCK) {
619  int err = SSL_get_error(c->ssl, ret);
620  if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE)
621  return AVERROR(EAGAIN);
622  }
623  while ((e = ERR_get_error()) != 0) {
624  av_log(h, AV_LOG_ERROR, "%s\n", ERR_error_string(e, NULL));
625  printed = 1;
626  }
627  if (c->io_err) {
628  av_log(h, AV_LOG_ERROR, "IO error: %s\n", av_err2str(c->io_err));
629  printed = 1;
630  averr = c->io_err;
631  c->io_err = 0;
632  }
633  if (!printed)
634  av_log(h, AV_LOG_ERROR, "Unknown error\n");
635  return averr;
636 }
637 
638 static int tls_close(URLContext *h)
639 {
640  TLSContext *c = h->priv_data;
641  if (c->ssl) {
642  SSL_shutdown(c->ssl);
643  SSL_free(c->ssl);
644  }
645  if (c->ctx)
646  SSL_CTX_free(c->ctx);
647  ffurl_closep(&c->tls_shared.tcp);
648 #if OPENSSL_VERSION_NUMBER >= 0x1010000fL
649  if (c->url_bio_method)
650  BIO_meth_free(c->url_bio_method);
651 #endif
652 #if OPENSSL_VERSION_NUMBER < 0x10100000L
654 #endif
655  return 0;
656 }
657 
658 static int url_bio_create(BIO *b)
659 {
660 #if OPENSSL_VERSION_NUMBER >= 0x1010000fL
661  BIO_set_init(b, 1);
662  BIO_set_data(b, NULL);
663  BIO_set_flags(b, 0);
664 #else
665  b->init = 1;
666  b->ptr = NULL;
667  b->flags = 0;
668 #endif
669  return 1;
670 }
671 
672 static int url_bio_destroy(BIO *b)
673 {
674  return 1;
675 }
676 
677 #if OPENSSL_VERSION_NUMBER >= 0x1010000fL
678 #define GET_BIO_DATA(x) BIO_get_data(x)
679 #else
680 #define GET_BIO_DATA(x) (x)->ptr
681 #endif
682 
683 static int url_bio_bread(BIO *b, char *buf, int len)
684 {
686  int ret = ffurl_read(c->tls_shared.is_dtls ? c->tls_shared.udp : c->tls_shared.tcp, buf, len);
687  if (ret >= 0)
688  return ret;
689  BIO_clear_retry_flags(b);
690  if (ret == AVERROR_EXIT)
691  return 0;
692  if (ret == AVERROR(EAGAIN))
693  BIO_set_retry_read(b);
694  else
695  c->io_err = ret;
696  return -1;
697 }
698 
699 static int url_bio_bwrite(BIO *b, const char *buf, int len)
700 {
702  int ret = ffurl_write(c->tls_shared.is_dtls ? c->tls_shared.udp : c->tls_shared.tcp, buf, len);
703  if (ret >= 0)
704  return ret;
705  BIO_clear_retry_flags(b);
706  if (ret == AVERROR_EXIT)
707  return 0;
708  if (ret == AVERROR(EAGAIN))
709  BIO_set_retry_write(b);
710  else
711  c->io_err = ret;
712  return -1;
713 }
714 
715 static long url_bio_ctrl(BIO *b, int cmd, long num, void *ptr)
716 {
717  if (cmd == BIO_CTRL_FLUSH) {
718  BIO_clear_retry_flags(b);
719  return 1;
720  }
721  return 0;
722 }
723 
724 static int url_bio_bputs(BIO *b, const char *str)
725 {
726  return url_bio_bwrite(b, str, strlen(str));
727 }
728 
729 #if OPENSSL_VERSION_NUMBER < 0x1010000fL
730 static BIO_METHOD url_bio_method = {
731  .type = BIO_TYPE_SOURCE_SINK,
732  .name = "urlprotocol bio",
733  .bwrite = url_bio_bwrite,
734  .bread = url_bio_bread,
735  .bputs = url_bio_bputs,
736  .bgets = NULL,
737  .ctrl = url_bio_ctrl,
738  .create = url_bio_create,
739  .destroy = url_bio_destroy,
740 };
741 #endif
742 
744 {
745  TLSContext *p = h->priv_data;
746  BIO *bio;
747 #if OPENSSL_VERSION_NUMBER >= 0x1010000fL
748  p->url_bio_method = BIO_meth_new(BIO_TYPE_SOURCE_SINK, "urlprotocol bio");
749  BIO_meth_set_write(p->url_bio_method, url_bio_bwrite);
750  BIO_meth_set_read(p->url_bio_method, url_bio_bread);
751  BIO_meth_set_puts(p->url_bio_method, url_bio_bputs);
752  BIO_meth_set_ctrl(p->url_bio_method, url_bio_ctrl);
753  BIO_meth_set_create(p->url_bio_method, url_bio_create);
754  BIO_meth_set_destroy(p->url_bio_method, url_bio_destroy);
755  bio = BIO_new(p->url_bio_method);
756  BIO_set_data(bio, p);
757 #else
758  bio = BIO_new(&url_bio_method);
759  bio->ptr = p;
760 #endif
761  SSL_set_bio(p->ssl, bio, bio);
762 }
763 
764 static void openssl_info_callback(const SSL *ssl, int where, int ret) {
765  const char *method = "undefined";
766  TLSContext *ctx = (TLSContext*)SSL_get_ex_data(ssl, 0);
767 
768  if (where & SSL_ST_CONNECT) {
769  method = "SSL_connect";
770  } else if (where & SSL_ST_ACCEPT)
771  method = "SSL_accept";
772 
773  if (where & SSL_CB_LOOP) {
774  av_log(ctx, AV_LOG_DEBUG, "Info method=%s state=%s(%s), where=%d, ret=%d\n",
775  method, SSL_state_string(ssl), SSL_state_string_long(ssl), where, ret);
776  } else if (where & SSL_CB_ALERT) {
777  method = (where & SSL_CB_READ) ? "read":"write";
778  av_log(ctx, AV_LOG_DEBUG, "Alert method=%s state=%s(%s), where=%d, ret=%d\n",
779  method, SSL_state_string(ssl), SSL_state_string_long(ssl), where, ret);
780  }
781 }
782 
783 /**
784  * Always return 1 to accept any certificate. This is because we allow the peer to
785  * use a temporary self-signed certificate for DTLS.
786  */
787 static int openssl_dtls_verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
788 {
789  return 1;
790 }
791 
793 {
794  int ret = 0, r0, r1;
795  TLSContext *p = h->priv_data;
796 
797  r0 = SSL_do_handshake(p->ssl);
798  r1 = SSL_get_error(p->ssl, r0);
799  if (r0 <= 0) {
800  if (r1 != SSL_ERROR_WANT_READ && r1 != SSL_ERROR_WANT_WRITE && r1 != SSL_ERROR_ZERO_RETURN) {
801  av_log(p, AV_LOG_ERROR, "TLS: Read failed, r0=%d, r1=%d %s\n", r0, r1, openssl_get_error(p));
802  ret = AVERROR(EIO);
803  goto end;
804  }
805  } else {
806  av_log(p, AV_LOG_TRACE, "TLS: Read %d bytes, r0=%d, r1=%d\n", r0, r0, r1);
807  }
808 
809  /* Check whether the DTLS is completed. */
810  if (SSL_is_init_finished(p->ssl) != 1)
811  goto end;
812 
814 end:
815  return ret;
816 }
817 
819 {
820  int ret;
821  TLSContext *p = h->priv_data;
822  TLSShared *c = &p->tls_shared;
823  EVP_PKEY *pkey = NULL;
824  X509 *cert = NULL;
825  /* setup ca, private key, certificate */
826  if (c->ca_file) {
827  if (!SSL_CTX_load_verify_locations(p->ctx, c->ca_file, NULL))
828  av_log(h, AV_LOG_ERROR, "SSL_CTX_load_verify_locations %s\n", openssl_get_error(p));
829  }
830 
831  if (c->cert_file) {
832  ret = SSL_CTX_use_certificate_chain_file(p->ctx, c->cert_file);
833  if (ret <= 0) {
834  av_log(h, AV_LOG_ERROR, "Unable to load cert file %s: %s\n",
835  c->cert_file, openssl_get_error(p));
836  ret = AVERROR(EIO);
837  goto fail;
838  }
839  } else if (p->tls_shared.cert_buf) {
841  if (SSL_CTX_use_certificate(p->ctx, cert) != 1) {
842  av_log(p, AV_LOG_ERROR, "SSL: Init SSL_CTX_use_certificate failed, %s\n", openssl_get_error(p));
843  ret = AVERROR(EINVAL);
844  return ret;
845  }
846  } else if (p->tls_shared.is_dtls){
847  av_log(p, AV_LOG_ERROR, "TLS: Init cert failed, %s\n", openssl_get_error(p));
848  ret = AVERROR(EINVAL);
849  goto fail;
850  }
851 
852  if (c->key_file) {
853  ret = SSL_CTX_use_PrivateKey_file(p->ctx, c->key_file, SSL_FILETYPE_PEM);
854  if (ret <= 0) {
855  av_log(h, AV_LOG_ERROR, "Unable to load key file %s: %s\n",
856  c->key_file, openssl_get_error(p));
857  ret = AVERROR(EIO);
858  goto fail;
859  }
860  } else if (p->tls_shared.key_buf) {
861  p->pkey = pkey = pkey_from_pem_string(p->tls_shared.key_buf, 1);
862  if (SSL_CTX_use_PrivateKey(p->ctx, pkey) != 1) {
863  av_log(p, AV_LOG_ERROR, "TLS: Init SSL_CTX_use_PrivateKey failed, %s\n", openssl_get_error(p));
864  ret = AVERROR(EINVAL);
865  return ret;
866  }
867  } else if (p->tls_shared.is_dtls){
868  av_log(p, AV_LOG_ERROR, "TLS: Init pkey failed, %s\n", openssl_get_error(p));
869  ret = AVERROR(EINVAL);
870  goto fail;
871  }
872  ret = 0;
873 fail:
874  return ret;
875 }
876 
877 /**
878  * Once the DTLS role has been negotiated - active for the DTLS client or passive for the
879  * DTLS server - we proceed to set up the DTLS state and initiate the handshake.
880  */
881 static int dtls_start(URLContext *h, const char *url, int flags, AVDictionary **options)
882 {
883  TLSContext *p = h->priv_data;
884  TLSShared *c = &p->tls_shared;
885  int ret = 0;
886  c->is_dtls = 1;
887  const char* ciphers = "ALL";
888 #if OPENSSL_VERSION_NUMBER < 0x10002000L // v1.0.2
889  EC_KEY *ec_key = NULL;
890 #endif
891  /**
892  * The profile for OpenSSL's SRTP is SRTP_AES128_CM_SHA1_80, see ssl/d1_srtp.c.
893  * The profile for FFmpeg's SRTP is SRTP_AES128_CM_HMAC_SHA1_80, see libavformat/srtp.c.
894  */
895  const char* profiles = "SRTP_AES128_CM_SHA1_80";
896  /* Refer to the test cases regarding these curves in the WebRTC code. */
897 #if OPENSSL_VERSION_NUMBER >= 0x10100000L /* OpenSSL 1.1.0 */
898  const char* curves = "X25519:P-256:P-384:P-521";
899 #elif OPENSSL_VERSION_NUMBER >= 0x10002000L /* OpenSSL 1.0.2 */
900  const char* curves = "P-256:P-384:P-521";
901 #endif
902 
903 #if OPENSSL_VERSION_NUMBER < 0x10002000L /* OpenSSL v1.0.2 */
904  p->ctx = SSL_CTX_new(DTLSv1_method());
905 #else
906  p->ctx = SSL_CTX_new(DTLS_method());
907 #endif
908  if (!p->ctx) {
909  ret = AVERROR(ENOMEM);
910  goto fail;
911  }
912 
913 #if OPENSSL_VERSION_NUMBER >= 0x10002000L /* OpenSSL 1.0.2 */
914  /* For ECDSA, we could set the curves list. */
915  if (SSL_CTX_set1_curves_list(p->ctx, curves) != 1) {
916  av_log(p, AV_LOG_ERROR, "TLS: Init SSL_CTX_set1_curves_list failed, curves=%s, %s\n",
918  ret = AVERROR(EINVAL);
919  return ret;
920  }
921 #endif
922 
923  /**
924  * We activate "ALL" cipher suites to align with the peer's capabilities,
925  * ensuring maximum compatibility.
926  */
927  if (SSL_CTX_set_cipher_list(p->ctx, ciphers) != 1) {
928  av_log(p, AV_LOG_ERROR, "TLS: Init SSL_CTX_set_cipher_list failed, ciphers=%s, %s\n",
929  ciphers, openssl_get_error(p));
930  ret = AVERROR(EINVAL);
931  return ret;
932  }
934  if (ret < 0) goto fail;
935 
936 #if OPENSSL_VERSION_NUMBER < 0x10100000L // v1.1.x
937 #if OPENSSL_VERSION_NUMBER < 0x10002000L // v1.0.2
938  if (p->pkey)
939  ec_key = EVP_PKEY_get1_EC_KEY(p->pkey);
940  if (ec_key)
941  SSL_CTX_set_tmp_ecdh(p->ctx, ec_key);
942 #else
943  SSL_CTX_set_ecdh_auto(p->ctx, 1);
944 #endif
945 #endif
946 
947  /* Server will send Certificate Request. */
948  SSL_CTX_set_verify(p->ctx, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, openssl_dtls_verify_callback);
949  /* The depth count is "level 0:peer certificate", "level 1: CA certificate",
950  * "level 2: higher level CA certificate", and so on. */
951  SSL_CTX_set_verify_depth(p->ctx, 4);
952  /* Whether we should read as many input bytes as possible (for non-blocking reads) or not. */
953  SSL_CTX_set_read_ahead(p->ctx, 1);
954  /* Setup the SRTP context */
955  if (SSL_CTX_set_tlsext_use_srtp(p->ctx, profiles)) {
956  av_log(p, AV_LOG_ERROR, "TLS: Init SSL_CTX_set_tlsext_use_srtp failed, profiles=%s, %s\n",
958  ret = AVERROR(EINVAL);
959  return ret;
960  }
961 
962  /* The ssl should not be created unless the ctx has been initialized. */
963  p->ssl = SSL_new(p->ctx);
964  if (!p->ssl) {
965  ret = AVERROR(ENOMEM);
966  goto fail;
967  }
968 
969  /* Setup the callback for logging. */
970  SSL_set_ex_data(p->ssl, 0, p);
971  SSL_set_info_callback(p->ssl, openssl_info_callback);
972  /**
973  * We have set the MTU to fragment the DTLS packet. It is important to note that the
974  * packet is split to ensure that each handshake packet is smaller than the MTU.
975  */
976  SSL_set_options(p->ssl, SSL_OP_NO_QUERY_MTU);
977  SSL_set_mtu(p->ssl, p->tls_shared.mtu);
978 #if OPENSSL_VERSION_NUMBER >= 0x100010b0L /* OpenSSL 1.0.1k */
979  DTLS_set_link_mtu(p->ssl, p->tls_shared.mtu);
980 #endif
982 
983  if (p->tls_shared.use_external_udp != 1) {
984  if ((ret = ff_tls_open_underlying(&p->tls_shared, h, url, options)) < 0) {
985  av_log(p, AV_LOG_ERROR, "Failed to connect %s\n", url);
986  return ret;
987  }
988  }
989 
990  /* Setup DTLS as passive, which is server role. */
991  c->listen ? SSL_set_accept_state(p->ssl) : SSL_set_connect_state(p->ssl);
992 
993  /**
994  * During initialization, we only need to call SSL_do_handshake once because SSL_read consumes
995  * the handshake message if the handshake is incomplete.
996  * To simplify maintenance, we initiate the handshake for both the DTLS server and client after
997  * sending out the ICE response in the start_active_handshake function. It's worth noting that
998  * although the DTLS server may receive the ClientHello immediately after sending out the ICE
999  * response, this shouldn't be an issue as the handshake function is called before any DTLS
1000  * packets are received.
1001  *
1002  * The SSL_do_handshake can't be called if DTLS hasn't prepare for udp.
1003  */
1004  if (p->tls_shared.use_external_udp != 1) {
1005  ret = dtls_handshake(h);
1006  // Fatal SSL error, for example, no available suite when peer is DTLS 1.0 while we are DTLS 1.2.
1007  if (ret < 0) {
1008  av_log(p, AV_LOG_ERROR, "TLS: Failed to drive SSL context, ret=%d\n", ret);
1009  return AVERROR(EIO);
1010  }
1011  }
1012 
1013  av_log(p, AV_LOG_VERBOSE, "TLS: Setup ok, MTU=%d, fingerprint %s\n",
1015 
1016  ret = 0;
1017 fail:
1018 #if OPENSSL_VERSION_NUMBER < 0x10002000L // v1.0.2
1019  EC_KEY_free(ec_key);
1020 #endif
1021  return ret;
1022 }
1023 
1024 /**
1025  * Cleanup the DTLS context.
1026  */
1028 {
1029  TLSContext *ctx = h->priv_data;
1030  SSL_free(ctx->ssl);
1031  SSL_CTX_free(ctx->ctx);
1032  av_freep(&ctx->tls_shared.fingerprint);
1033  av_freep(&ctx->tls_shared.cert_buf);
1034  av_freep(&ctx->tls_shared.key_buf);
1035  EVP_PKEY_free(ctx->pkey);
1036  return 0;
1037 }
1038 
1039 static int tls_open(URLContext *h, const char *uri, int flags, AVDictionary **options)
1040 {
1041  TLSContext *p = h->priv_data;
1042  TLSShared *c = &p->tls_shared;
1043  int ret;
1044 
1045 #if OPENSSL_VERSION_NUMBER < 0x10100000L
1046  if ((ret = ff_openssl_init()) < 0)
1047  return ret;
1048 #endif
1049 
1050  if ((ret = ff_tls_open_underlying(c, h, uri, options)) < 0)
1051  goto fail;
1052 
1053  // We want to support all versions of TLS >= 1.0, but not the deprecated
1054  // and insecure SSLv2 and SSLv3. Despite the name, SSLv23_*_method()
1055  // enables support for all versions of SSL and TLS, and we then disable
1056  // support for the old protocols immediately after creating the context.
1057  p->ctx = SSL_CTX_new(c->listen ? SSLv23_server_method() : SSLv23_client_method());
1058  if (!p->ctx) {
1059  av_log(h, AV_LOG_ERROR, "%s\n", openssl_get_error(p));
1060  ret = AVERROR(EIO);
1061  goto fail;
1062  }
1063  SSL_CTX_set_options(p->ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
1065  if (ret < 0) goto fail;
1066  // Note, this doesn't check that the peer certificate actually matches
1067  // the requested hostname.
1068  if (c->verify)
1069  SSL_CTX_set_verify(p->ctx, SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
1070  p->ssl = SSL_new(p->ctx);
1071  if (!p->ssl) {
1072  av_log(h, AV_LOG_ERROR, "%s\n", openssl_get_error(p));
1073  ret = AVERROR(EIO);
1074  goto fail;
1075  }
1076  SSL_set_ex_data(p->ssl, 0, p);
1077  SSL_CTX_set_info_callback(p->ctx, openssl_info_callback);
1078  init_bio_method(h);
1079  if (!c->listen && !c->numerichost)
1080  SSL_set_tlsext_host_name(p->ssl, c->host);
1081  ret = c->listen ? SSL_accept(p->ssl) : SSL_connect(p->ssl);
1082  if (ret == 0) {
1083  av_log(h, AV_LOG_ERROR, "Unable to negotiate TLS/SSL session\n");
1084  ret = AVERROR(EIO);
1085  goto fail;
1086  } else if (ret < 0) {
1087  ret = print_ssl_error(h, ret);
1088  goto fail;
1089  }
1090 
1091  return 0;
1092 fail:
1093  tls_close(h);
1094  return ret;
1095 }
1096 
1097 static int tls_read(URLContext *h, uint8_t *buf, int size)
1098 {
1099  TLSContext *c = h->priv_data;
1100  URLContext *uc = c->tls_shared.is_dtls ? c->tls_shared.udp
1101  : c->tls_shared.tcp;
1102  int ret;
1103  // Set or clear the AVIO_FLAG_NONBLOCK on c->tls_shared.tcp
1104  uc->flags &= ~AVIO_FLAG_NONBLOCK;
1105  uc->flags |= h->flags & AVIO_FLAG_NONBLOCK;
1106  ret = SSL_read(c->ssl, buf, size);
1107  if (ret > 0)
1108  return ret;
1109  if (ret == 0)
1110  return AVERROR_EOF;
1111  return print_ssl_error(h, ret);
1112 }
1113 
1114 static int tls_write(URLContext *h, const uint8_t *buf, int size)
1115 {
1116  TLSContext *c = h->priv_data;
1117  URLContext *uc = c->tls_shared.is_dtls ? c->tls_shared.udp
1118  : c->tls_shared.tcp;
1119  int ret;
1120  // Set or clear the AVIO_FLAG_NONBLOCK on c->tls_shared.tcp
1121  uc->flags &= ~AVIO_FLAG_NONBLOCK;
1122  uc->flags |= h->flags & AVIO_FLAG_NONBLOCK;
1123  ret = SSL_write(c->ssl, buf, size);
1124  if (ret > 0)
1125  return ret;
1126  if (ret == 0)
1127  return AVERROR_EOF;
1128  return print_ssl_error(h, ret);
1129 }
1130 
1132 {
1133  TLSContext *c = h->priv_data;
1134  return ffurl_get_file_handle(c->tls_shared.tcp);
1135 }
1136 
1138 {
1139  TLSContext *s = h->priv_data;
1140  return ffurl_get_short_seek(s->tls_shared.tcp);
1141 }
1142 
1143 static const AVOption options[] = {
1144  TLS_COMMON_OPTIONS(TLSContext, tls_shared),
1145  { NULL }
1146 };
1147 
1148 static const AVClass tls_class = {
1149  .class_name = "tls",
1150  .item_name = av_default_item_name,
1151  .option = options,
1152  .version = LIBAVUTIL_VERSION_INT,
1153 };
1154 
1156  .name = "tls",
1157  .url_open2 = tls_open,
1158  .url_read = tls_read,
1159  .url_write = tls_write,
1160  .url_close = tls_close,
1161  .url_get_file_handle = tls_get_file_handle,
1162  .url_get_short_seek = tls_get_short_seek,
1163  .priv_data_size = sizeof(TLSContext),
1165  .priv_data_class = &tls_class,
1166 };
1167 
1168 static const AVClass dtls_class = {
1169  .class_name = "dtls",
1170  .item_name = av_default_item_name,
1171  .option = options,
1172  .version = LIBAVUTIL_VERSION_INT,
1173 };
1174 
1176  .name = "dtls",
1177  .url_open2 = dtls_start,
1178  .url_handshake = dtls_handshake,
1179  .url_close = dtls_close,
1180  .url_read = tls_read,
1181  .url_write = tls_write,
1182  .priv_data_size = sizeof(TLSContext),
1184  .priv_data_class = &dtls_class,
1185 };
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:450
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:1027
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:595
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:512
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:1148
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:658
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:680
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:787
openssl_init
static int openssl_init
Definition: tls_openssl.c:543
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:527
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:1114
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:1155
ff_dtls_set_udp
int ff_dtls_set_udp(URLContext *h, URLContext *udp)
Definition: tls_openssl.c:505
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
dtls_handshake
static int dtls_handshake(URLContext *h)
Definition: tls_openssl.c:792
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:541
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:715
ff_openssl_init
int ff_openssl_init(void)
Definition: tls_openssl.c:565
url_bio_destroy
static int url_bio_destroy(BIO *b)
Definition: tls_openssl.c:672
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:699
tls_open
static int tls_open(URLContext *h, const char *uri, int flags, AVDictionary **options)
Definition: tls_openssl.c:1039
TLSContext::error_message
char error_message[256]
Definition: tls_openssl.c:483
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:683
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:476
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:1143
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:764
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:1131
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:743
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:477
URLContext
Definition: url.h:35
print_ssl_error
static int print_ssl_error(URLContext *h, int ret)
Definition: tls_openssl.c:614
openssl_get_error
static const char * openssl_get_error(TLSContext *ctx)
Retrieves the error message for the latest OpenSSL error.
Definition: tls_openssl.c:493
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:1137
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:1097
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:730
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:818
TLSContext::pkey
EVP_PKEY * pkey
Definition: tls_openssl.c:478
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:881
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:1168
DTLS_STATE_FINISHED
@ DTLS_STATE_FINISHED
Definition: tls.h:40
tls_close
static int tls_close(URLContext *h)
Definition: tls_openssl.c:638
snprintf
#define snprintf
Definition: snprintf.h:34
ff_dtls_protocol
const URLProtocol ff_dtls_protocol
Definition: tls_openssl.c:1175
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:724
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