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 #include <openssl/x509v3.h>
35 
36 /**
37  * Returns a heap‐allocated null‐terminated string containing
38  * the PEM‐encoded public key. Caller must free.
39  */
40 static char *pkey_to_pem_string(EVP_PKEY *pkey) {
41  BIO *mem = NULL;
42  BUF_MEM *bptr = NULL;
43  char *pem_str = NULL;
44 
45  // Create a memory BIO
46  if (!(mem = BIO_new(BIO_s_mem())))
47  goto err;
48 
49  // Write public key in PEM form
50  if (!PEM_write_bio_PrivateKey(mem, pkey, NULL, NULL, 0, NULL, NULL))
51  goto err;
52 
53  // Extract pointer/length
54  BIO_get_mem_ptr(mem, &bptr);
55  if (!bptr || !bptr->length)
56  goto err;
57 
58  // Allocate string (+1 for NUL)
59  pem_str = av_malloc(bptr->length + 1);
60  if (!pem_str)
61  goto err;
62 
63  // Copy data & NUL‐terminate
64  memcpy(pem_str, bptr->data, bptr->length);
65  pem_str[bptr->length] = '\0';
66 
67 cleanup:
68  BIO_free(mem);
69  return pem_str;
70 
71 err:
72  // error path: free and return NULL
73  free(pem_str);
74  pem_str = NULL;
75  goto cleanup;
76 }
77 
78 /**
79  * Serialize an X509 certificate to a av_malloc’d PEM string.
80  * Caller must free the returned pointer.
81  */
82 static char *cert_to_pem_string(X509 *cert)
83 {
84  BIO *mem = BIO_new(BIO_s_mem());
85  BUF_MEM *bptr = NULL;
86  char *out = NULL;
87 
88  if (!mem) goto err;
89 
90  /* Write the PEM certificate */
91  if (!PEM_write_bio_X509(mem, cert))
92  goto err;
93 
94  BIO_get_mem_ptr(mem, &bptr);
95  if (!bptr || !bptr->length) goto err;
96 
97  out = av_malloc(bptr->length + 1);
98  if (!out) goto err;
99 
100  memcpy(out, bptr->data, bptr->length);
101  out[bptr->length] = '\0';
102 
103 cleanup:
104  BIO_free(mem);
105  return out;
106 
107 err:
108  free(out);
109  out = NULL;
110  goto cleanup;
111 }
112 
113 
114 /**
115  * Generate a SHA-256 fingerprint of an X.509 certificate.
116  *
117  * @param ctx AVFormatContext for logging (can be NULL)
118  * @param cert X509 certificate to fingerprint
119  * @return Newly allocated fingerprint string in "AA:BB:CC:…" format,
120  * or NULL on error (logs via av_log if ctx is not NULL).
121  * Caller must free() the returned string.
122  */
123 static char *generate_fingerprint(X509 *cert)
124 {
125  unsigned char md[EVP_MAX_MD_SIZE];
126  int n = 0;
127  AVBPrint fingerprint;
128  char *result = NULL;
129  int i;
130 
131  /* To prevent a crash during cleanup, always initialize it. */
132  av_bprint_init(&fingerprint, 0, AV_BPRINT_SIZE_UNLIMITED);
133 
134  if (X509_digest(cert, EVP_sha256(), md, &n) != 1) {
135  av_log(NULL, AV_LOG_ERROR, "TLS: Failed to generate fingerprint, %s\n", ERR_error_string(ERR_get_error(), NULL));
136  goto end;
137  }
138 
139  for (i = 0; i < n; i++) {
140  av_bprintf(&fingerprint, "%02X", md[i]);
141  if (i + 1 < n)
142  av_bprintf(&fingerprint, ":");
143  }
144 
145  if (!fingerprint.str || !strlen(fingerprint.str)) {
146  av_log(NULL, AV_LOG_ERROR, "TLS: Fingerprint is empty\n");
147  goto end;
148  }
149 
150  result = av_strdup(fingerprint.str);
151  if (!result) {
152  av_log(NULL, AV_LOG_ERROR, "TLS: Out of memory generating fingerprint\n");
153  }
154 
155 end:
156  av_bprint_finalize(&fingerprint, NULL);
157  return result;
158 }
159 
160 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)
161 {
162  int ret = 0;
163  BIO *key_b = NULL, *cert_b = NULL;
164  AVBPrint key_bp, cert_bp;
165  EVP_PKEY *pkey = NULL;
166  X509 *cert = NULL;
167  char *key_tem = NULL, *cert_tem = NULL;
168 
169  /* To prevent a crash during cleanup, always initialize it. */
171  av_bprint_init(&cert_bp, 1, MAX_CERTIFICATE_SIZE);
172 
173  /* Read key file. */
174  ret = ff_url_read_all(key_url, &key_bp);
175  if (ret < 0) {
176  av_log(NULL, AV_LOG_ERROR, "TLS: Failed to open key file %s\n", key_url);
177  goto end;
178  }
179 
180  if (!(key_b = BIO_new(BIO_s_mem()))) {
181  ret = AVERROR(ENOMEM);
182  goto end;
183  }
184 
185  BIO_write(key_b, key_bp.str, key_bp.len);
186  pkey = PEM_read_bio_PrivateKey(key_b, NULL, NULL, NULL);
187  if (!pkey) {
188  av_log(NULL, AV_LOG_ERROR, "TLS: Failed to read private key from %s\n", key_url);
189  ret = AVERROR(EIO);
190  goto end;
191  }
192 
193  /* Read certificate. */
194  ret = ff_url_read_all(cert_url, &cert_bp);
195  if (ret < 0) {
196  av_log(NULL, AV_LOG_ERROR, "TLS: Failed to open cert file %s\n", cert_url);
197  goto end;
198  }
199 
200  if (!(cert_b = BIO_new(BIO_s_mem()))) {
201  ret = AVERROR(ENOMEM);
202  goto end;
203  }
204 
205  BIO_write(cert_b, cert_bp.str, cert_bp.len);
206  cert = PEM_read_bio_X509(cert_b, NULL, NULL, NULL);
207  if (!cert) {
208  av_log(NULL, AV_LOG_ERROR, "TLS: Failed to read certificate from %s\n", cert_url);
209  ret = AVERROR(EIO);
210  goto end;
211  }
212 
213  key_tem = pkey_to_pem_string(pkey);
214  cert_tem = cert_to_pem_string(cert);
215 
216  snprintf(key_buf, key_sz, "%s", key_tem);
217  snprintf(cert_buf, cert_sz, "%s", cert_tem);
218 
219  /* Generate fingerprint. */
220  if (fingerprint) {
221  *fingerprint = generate_fingerprint(cert);
222  if (!*fingerprint) {
223  av_log(NULL, AV_LOG_ERROR, "TLS: Failed to generate fingerprint from %s\n", cert_url);
224  ret = AVERROR(EIO);
225  goto end;
226  }
227  }
228 
229 end:
230  BIO_free(key_b);
231  av_bprint_finalize(&key_bp, NULL);
232  BIO_free(cert_b);
233  av_bprint_finalize(&cert_bp, NULL);
234  av_free(key_tem);
235  av_free(cert_tem);
236  EVP_PKEY_free(pkey);
237  X509_free(cert);
238  return ret;
239 }
240 
241 static int openssl_gen_private_key(EVP_PKEY **pkey)
242 {
243  int ret = 0;
244 
245  /**
246  * Note that secp256r1 in openssl is called NID_X9_62_prime256v1 or prime256v1 in string,
247  * not NID_secp256k1 or secp256k1 in string.
248  *
249  * TODO: Should choose the curves in ClientHello.supported_groups, for example:
250  * Supported Group: x25519 (0x001d)
251  * Supported Group: secp256r1 (0x0017)
252  * Supported Group: secp384r1 (0x0018)
253  */
254 #if OPENSSL_VERSION_NUMBER < 0x30000000L /* OpenSSL 3.0 */
255  EC_GROUP *ecgroup = NULL;
256  EC_KEY *eckey = NULL;
257  int curve = NID_X9_62_prime256v1;
258 #else
259  const char *curve = SN_X9_62_prime256v1;
260 #endif
261 
262 #if OPENSSL_VERSION_NUMBER < 0x30000000L /* OpenSSL 3.0 */
263  *pkey = EVP_PKEY_new();
264  if (!*pkey)
265  return AVERROR(ENOMEM);
266 
267  eckey = EC_KEY_new();
268  if (!eckey) {
269  EVP_PKEY_free(*pkey);
270  *pkey = NULL;
271  return AVERROR(ENOMEM);
272  }
273 
274  ecgroup = EC_GROUP_new_by_curve_name(curve);
275  if (!ecgroup) {
276  av_log(NULL, AV_LOG_ERROR, "TLS: Create EC group by curve=%d failed, %s", curve, ERR_error_string(ERR_get_error(), NULL));
277  goto einval_end;
278  }
279 
280  if (EC_KEY_set_group(eckey, ecgroup) != 1) {
281  av_log(NULL, AV_LOG_ERROR, "TLS: Generate private key, EC_KEY_set_group failed, %s\n", ERR_error_string(ERR_get_error(), NULL));
282  goto einval_end;
283  }
284 
285  if (EC_KEY_generate_key(eckey) != 1) {
286  av_log(NULL, AV_LOG_ERROR, "TLS: Generate private key, EC_KEY_generate_key failed, %s\n", ERR_error_string(ERR_get_error(), NULL));
287  goto einval_end;
288  }
289 
290  if (EVP_PKEY_set1_EC_KEY(*pkey, eckey) != 1) {
291  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));
292  goto einval_end;
293  }
294 #else
295  *pkey = EVP_EC_gen(curve);
296  if (!*pkey) {
297  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));
298  goto einval_end;
299  }
300 #endif
301  goto end;
302 
303 einval_end:
304  ret = AVERROR(EINVAL);
305  EVP_PKEY_free(*pkey);
306  *pkey = NULL;
307 end:
308 #if OPENSSL_VERSION_NUMBER < 0x30000000L /* OpenSSL 3.0 */
309  EC_GROUP_free(ecgroup);
310  EC_KEY_free(eckey);
311 #endif
312  return ret;
313 }
314 
315 static int openssl_gen_certificate(EVP_PKEY *pkey, X509 **cert, char **fingerprint)
316 {
317  int ret = 0, serial, expire_day;
318  const char *aor = "lavf";
319  X509_NAME* subject = NULL;
320 
321  *cert= X509_new();
322  if (!*cert) {
323  goto enomem_end;
324  }
325 
326  // TODO: Support non-self-signed certificate, for example, load from a file.
327  subject = X509_NAME_new();
328  if (!subject) {
329  goto enomem_end;
330  }
331 
332  serial = (int)av_get_random_seed();
333  if (ASN1_INTEGER_set(X509_get_serialNumber(*cert), serial) != 1) {
334  av_log(NULL, AV_LOG_ERROR, "TLS: Failed to set serial, %s\n", ERR_error_string(ERR_get_error(), NULL));
335  goto einval_end;
336  }
337 
338  if (X509_NAME_add_entry_by_txt(subject, "CN", MBSTRING_ASC, aor, strlen(aor), -1, 0) != 1) {
339  av_log(NULL, AV_LOG_ERROR, "TLS: Failed to set CN, %s\n", ERR_error_string(ERR_get_error(), NULL));
340  goto einval_end;
341  }
342 
343  if (X509_set_issuer_name(*cert, subject) != 1) {
344  av_log(NULL, AV_LOG_ERROR, "TLS: Failed to set issuer, %s\n", ERR_error_string(ERR_get_error(), NULL));
345  goto einval_end;
346  }
347  if (X509_set_subject_name(*cert, subject) != 1) {
348  av_log(NULL, AV_LOG_ERROR, "TLS: Failed to set subject name, %s\n", ERR_error_string(ERR_get_error(), NULL));
349  goto einval_end;
350  }
351 
352  expire_day = 365;
353  if (!X509_gmtime_adj(X509_get_notBefore(*cert), 0)) {
354  av_log(NULL, AV_LOG_ERROR, "TLS: Failed to set notBefore, %s\n", ERR_error_string(ERR_get_error(), NULL));
355  goto einval_end;
356  }
357  if (!X509_gmtime_adj(X509_get_notAfter(*cert), 60*60*24*expire_day)) {
358  av_log(NULL, AV_LOG_ERROR, "TLS: Failed to set notAfter, %s\n", ERR_error_string(ERR_get_error(), NULL));
359  goto einval_end;
360  }
361 
362  if (X509_set_version(*cert, 2) != 1) {
363  av_log(NULL, AV_LOG_ERROR, "TLS: Failed to set version, %s\n", ERR_error_string(ERR_get_error(), NULL));
364  goto einval_end;
365  }
366 
367  if (X509_set_pubkey(*cert, pkey) != 1) {
368  av_log(NULL, AV_LOG_ERROR, "TLS: Failed to set public key, %s\n", ERR_error_string(ERR_get_error(), NULL));
369  goto einval_end;
370  }
371 
372  if (!X509_sign(*cert, pkey, EVP_sha1())) {
373  av_log(NULL, AV_LOG_ERROR, "TLS: Failed to sign certificate, %s\n", ERR_error_string(ERR_get_error(), NULL));
374  goto einval_end;
375  }
376 
377  if (fingerprint) {
378  *fingerprint = generate_fingerprint(*cert);
379  if (!*fingerprint) {
380  goto enomem_end;
381  }
382  }
383 
384  goto end;
385 enomem_end:
386  ret = AVERROR(ENOMEM);
387  goto end;
388 einval_end:
389  ret = AVERROR(EINVAL);
390 end:
391  if (ret) {
392  X509_free(*cert);
393  *cert = NULL;
394  }
395  X509_NAME_free(subject);
396  return ret;
397 }
398 
399 int ff_ssl_gen_key_cert(char *key_buf, size_t key_sz, char *cert_buf, size_t cert_sz, char **fingerprint)
400 {
401  int ret = 0;
402  EVP_PKEY *pkey = NULL;
403  X509 *cert = NULL;
404  char *key_tem = NULL, *cert_tem = NULL;
405 
406  ret = openssl_gen_private_key(&pkey);
407  if (ret < 0) goto error;
408 
409  ret = openssl_gen_certificate(pkey, &cert, fingerprint);
410  if (ret < 0) goto error;
411 
412  key_tem = pkey_to_pem_string(pkey);
413  cert_tem = cert_to_pem_string(cert);
414 
415  snprintf(key_buf, key_sz, "%s", key_tem);
416  snprintf(cert_buf, cert_sz, "%s", cert_tem);
417 
418  av_free(key_tem);
419  av_free(cert_tem);
420 error:
421  X509_free(cert);
422  EVP_PKEY_free(pkey);
423  return ret;
424 }
425 
426 
427 /**
428  * Deserialize a PEM‐encoded private or public key from a NUL-terminated C string.
429  *
430  * @param pem_str The PEM text, e.g.
431  * "-----BEGIN PRIVATE KEY-----\n…\n-----END PRIVATE KEY-----\n"
432  * @param is_priv If non-zero, parse as a PRIVATE key; otherwise, parse as a PUBLIC key.
433  * @return EVP_PKEY* on success (must EVP_PKEY_free()), or NULL on error.
434  */
435 static EVP_PKEY *pkey_from_pem_string(const char *pem_str, int is_priv)
436 {
437  BIO *mem = BIO_new_mem_buf(pem_str, -1);
438  if (!mem) {
439  av_log(NULL, AV_LOG_ERROR, "BIO_new_mem_buf failed\n");
440  return NULL;
441  }
442 
443  EVP_PKEY *pkey = NULL;
444  if (is_priv) {
445  pkey = PEM_read_bio_PrivateKey(mem, NULL, NULL, NULL);
446  } else {
447  pkey = PEM_read_bio_PUBKEY(mem, NULL, NULL, NULL);
448  }
449 
450  if (!pkey)
451  av_log(NULL, AV_LOG_ERROR, "Failed to parse %s key from string\n",
452  is_priv ? "private" : "public");
453 
454  BIO_free(mem);
455  return pkey;
456 }
457 
458 /**
459  * Deserialize a PEM‐encoded certificate from a NUL-terminated C string.
460  *
461  * @param pem_str The PEM text, e.g.
462  * "-----BEGIN CERTIFICATE-----\n…\n-----END CERTIFICATE-----\n"
463  * @return X509* on success (must X509_free()), or NULL on error.
464  */
465 static X509 *cert_from_pem_string(const char *pem_str)
466 {
467  BIO *mem = BIO_new_mem_buf(pem_str, -1);
468  if (!mem) {
469  av_log(NULL, AV_LOG_ERROR, "BIO_new_mem_buf failed\n");
470  return NULL;
471  }
472 
473  X509 *cert = PEM_read_bio_X509(mem, NULL, NULL, NULL);
474  if (!cert) {
475  av_log(NULL, AV_LOG_ERROR, "Failed to parse certificate from string\n");
476  return NULL;
477  }
478 
479  BIO_free(mem);
480  return cert;
481 }
482 
483 
484 typedef struct TLSContext {
485  const AVClass *class;
487  SSL_CTX *ctx;
488  SSL *ssl;
489  BIO_METHOD* url_bio_method;
490  int io_err;
491  char error_message[256];
493  socklen_t dest_addr_len;
494 } TLSContext;
495 
496 /**
497  * Retrieves the error message for the latest OpenSSL error.
498  *
499  * This function retrieves the error code from the thread's error queue, converts it
500  * to a human-readable string, and stores it in the TLSContext's error_message field.
501  * The error queue is then cleared using ERR_clear_error().
502  */
503 static const char* openssl_get_error(TLSContext *ctx)
504 {
505  int r2 = ERR_get_error();
506  if (r2) {
507  ERR_error_string_n(r2, ctx->error_message, sizeof(ctx->error_message));
508  } else
509  ctx->error_message[0] = '\0';
510 
511  ERR_clear_error();
512  return ctx->error_message;
513 }
514 
516 {
517  TLSContext *c = h->priv_data;
518  TLSShared *s = &c->tls_shared;
519 
520  if (s->is_dtls)
521  c->tls_shared.udp = sock;
522  else
523  c->tls_shared.tcp = sock;
524 
525  return 0;
526 }
527 
528 int ff_dtls_export_materials(URLContext *h, char *dtls_srtp_materials, size_t materials_sz)
529 {
530  int ret = 0;
531  const char* dst = "EXTRACTOR-dtls_srtp";
532  TLSContext *c = h->priv_data;
533 
534  ret = SSL_export_keying_material(c->ssl, dtls_srtp_materials, materials_sz,
535  dst, strlen(dst), NULL, 0, 0);
536  if (!ret) {
537  av_log(c, AV_LOG_ERROR, "Failed to export SRTP material, %s\n", openssl_get_error(c));
538  return -1;
539  }
540  return 0;
541 }
542 
544 {
545  TLSContext *c = h->priv_data;
546  return c->tls_shared.state;
547 }
548 
549 static int print_ssl_error(URLContext *h, int ret)
550 {
551  TLSContext *c = h->priv_data;
552  int printed = 0, e, averr = AVERROR(EIO);
553  if (h->flags & AVIO_FLAG_NONBLOCK) {
554  int err = SSL_get_error(c->ssl, ret);
555  if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE)
556  return AVERROR(EAGAIN);
557  }
558  while ((e = ERR_get_error()) != 0) {
559  av_log(h, AV_LOG_ERROR, "%s\n", ERR_error_string(e, NULL));
560  printed = 1;
561  }
562  if (c->io_err) {
563  av_log(h, AV_LOG_ERROR, "IO error: %s\n", av_err2str(c->io_err));
564  printed = 1;
565  averr = c->io_err;
566  c->io_err = 0;
567  }
568  if (!printed)
569  av_log(h, AV_LOG_ERROR, "Unknown error\n");
570  return averr;
571 }
572 
573 static int tls_close(URLContext *h)
574 {
575  TLSContext *c = h->priv_data;
576  if (c->ssl) {
577  SSL_shutdown(c->ssl);
578  SSL_free(c->ssl);
579  }
580  if (c->ctx)
581  SSL_CTX_free(c->ctx);
582  if (!c->tls_shared.external_sock)
583  ffurl_closep(c->tls_shared.is_dtls ? &c->tls_shared.udp : &c->tls_shared.tcp);
584  if (c->url_bio_method)
585  BIO_meth_free(c->url_bio_method);
586  return 0;
587 }
588 
589 static int url_bio_create(BIO *b)
590 {
591  BIO_set_init(b, 1);
592  BIO_set_data(b, NULL);
593  BIO_set_flags(b, 0);
594  return 1;
595 }
596 
597 static int url_bio_destroy(BIO *b)
598 {
599  return 1;
600 }
601 
602 static int url_bio_bread(BIO *b, char *buf, int len)
603 {
604  TLSContext *c = BIO_get_data(b);
605  TLSShared *s = &c->tls_shared;
606  int ret = ffurl_read(c->tls_shared.is_dtls ? c->tls_shared.udp : c->tls_shared.tcp, buf, len);
607  if (ret >= 0) {
608  if (s->is_dtls && s->listen && !c->dest_addr_len) {
609  int err_ret;
610 
611  ff_udp_get_last_recv_addr(s->udp, &c->dest_addr, &c->dest_addr_len);
612  err_ret = ff_udp_set_remote_addr(s->udp, (struct sockaddr *)&c->dest_addr, c->dest_addr_len, 1);
613  if (err_ret < 0) {
614  av_log(c, AV_LOG_ERROR, "Failed connecting udp context\n");
615  return err_ret;
616  }
617  av_log(c, AV_LOG_TRACE, "Set UDP remote addr on UDP socket, now 'connected'\n");
618  }
619 
620  return ret;
621  }
622  BIO_clear_retry_flags(b);
623  if (ret == AVERROR_EXIT)
624  return 0;
625  if (ret == AVERROR(EAGAIN))
626  BIO_set_retry_read(b);
627  else
628  c->io_err = ret;
629  return -1;
630 }
631 
632 static int url_bio_bwrite(BIO *b, const char *buf, int len)
633 {
634  TLSContext *c = BIO_get_data(b);
635  int ret = ffurl_write(c->tls_shared.is_dtls ? c->tls_shared.udp : c->tls_shared.tcp, buf, len);
636  if (ret >= 0)
637  return ret;
638  BIO_clear_retry_flags(b);
639  if (ret == AVERROR_EXIT)
640  return 0;
641  if (ret == AVERROR(EAGAIN))
642  BIO_set_retry_write(b);
643  else
644  c->io_err = ret;
645  return -1;
646 }
647 
648 static long url_bio_ctrl(BIO *b, int cmd, long num, void *ptr)
649 {
650  if (cmd == BIO_CTRL_FLUSH) {
651  BIO_clear_retry_flags(b);
652  return 1;
653  }
654  return 0;
655 }
656 
657 static int url_bio_bputs(BIO *b, const char *str)
658 {
659  return url_bio_bwrite(b, str, strlen(str));
660 }
661 
663 {
664  TLSContext *p = h->priv_data;
665  BIO *bio;
666  int bio_idx = BIO_get_new_index();
667  if (bio_idx == -1)
668  return AVERROR_EXTERNAL;
669  p->url_bio_method = BIO_meth_new(bio_idx | BIO_TYPE_SOURCE_SINK, "urlprotocol bio");
670  BIO_meth_set_write(p->url_bio_method, url_bio_bwrite);
671  BIO_meth_set_read(p->url_bio_method, url_bio_bread);
672  BIO_meth_set_puts(p->url_bio_method, url_bio_bputs);
673  BIO_meth_set_ctrl(p->url_bio_method, url_bio_ctrl);
674  BIO_meth_set_create(p->url_bio_method, url_bio_create);
675  BIO_meth_set_destroy(p->url_bio_method, url_bio_destroy);
676  bio = BIO_new(p->url_bio_method);
677  BIO_set_data(bio, p);
678 
679  SSL_set_bio(p->ssl, bio, bio);
680  return 0;
681 }
682 
683 static void openssl_info_callback(const SSL *ssl, int where, int ret) {
684  const char *method = "undefined";
685  TLSContext *ctx = (TLSContext*)SSL_get_ex_data(ssl, 0);
686 
687  if (where & SSL_ST_CONNECT) {
688  method = "SSL_connect";
689  } else if (where & SSL_ST_ACCEPT)
690  method = "SSL_accept";
691 
692  if (where & SSL_CB_LOOP) {
693  av_log(ctx, AV_LOG_DEBUG, "Info method=%s state=%s(%s), where=%d, ret=%d\n",
694  method, SSL_state_string(ssl), SSL_state_string_long(ssl), where, ret);
695  } else if (where & SSL_CB_ALERT) {
696  method = (where & SSL_CB_READ) ? "read":"write";
697  av_log(ctx, AV_LOG_DEBUG, "Alert method=%s state=%s(%s), where=%d, ret=%d\n",
698  method, SSL_state_string(ssl), SSL_state_string_long(ssl), where, ret);
699  }
700 }
701 
703 {
704  int ret = 1, r0, r1;
705  TLSContext *p = h->priv_data;
706 
708 
709  r0 = SSL_do_handshake(p->ssl);
710  if (r0 <= 0) {
711  r1 = SSL_get_error(p->ssl, r0);
712 
713  if (r1 != SSL_ERROR_WANT_READ && r1 != SSL_ERROR_WANT_WRITE && r1 != SSL_ERROR_ZERO_RETURN) {
714  av_log(p, AV_LOG_ERROR, "Handshake failed, r0=%d, r1=%d\n", r0, r1);
715  ret = print_ssl_error(h, r0);
716  goto end;
717  }
718  } else {
719  av_log(p, AV_LOG_TRACE, "Handshake success, r0=%d\n", r0);
720  }
721 
722  /* Check whether the handshake is completed. */
723  if (SSL_is_init_finished(p->ssl) != TLS_ST_OK)
724  goto end;
725 
726  ret = 0;
728 end:
729  return ret;
730 }
731 
733 {
734  int ret;
735  TLSContext *p = h->priv_data;
736  TLSShared *c = &p->tls_shared;
737  EVP_PKEY *pkey = NULL;
738  X509 *cert = NULL;
739  /* setup ca, private key, certificate */
740  if (c->ca_file) {
741  if (!SSL_CTX_load_verify_locations(p->ctx, c->ca_file, NULL))
742  av_log(h, AV_LOG_ERROR, "SSL_CTX_load_verify_locations %s\n", openssl_get_error(p));
743  } else {
744  if (!SSL_CTX_set_default_verify_paths(p->ctx)) {
745  // Only log the failure but do not error out, as this is not fatal
746  av_log(h, AV_LOG_WARNING, "Failure setting default verify locations: %s\n",
747  openssl_get_error(p));
748  }
749  }
750 
751  if (c->cert_file) {
752  ret = SSL_CTX_use_certificate_chain_file(p->ctx, c->cert_file);
753  if (ret <= 0) {
754  av_log(h, AV_LOG_ERROR, "Unable to load cert file %s: %s\n",
755  c->cert_file, openssl_get_error(p));
756  ret = AVERROR(EIO);
757  goto fail;
758  }
759  } else if (c->cert_buf) {
760  cert = cert_from_pem_string(c->cert_buf);
761  if (SSL_CTX_use_certificate(p->ctx, cert) != 1) {
762  av_log(p, AV_LOG_ERROR, "SSL: Init SSL_CTX_use_certificate failed, %s\n", openssl_get_error(p));
763  ret = AVERROR(EINVAL);
764  goto fail;
765  }
766  }
767 
768  if (c->key_file) {
769  ret = SSL_CTX_use_PrivateKey_file(p->ctx, c->key_file, SSL_FILETYPE_PEM);
770  if (ret <= 0) {
771  av_log(h, AV_LOG_ERROR, "Unable to load key file %s: %s\n",
772  c->key_file, openssl_get_error(p));
773  ret = AVERROR(EIO);
774  goto fail;
775  }
776  } else if (c->key_buf) {
777  pkey = pkey_from_pem_string(c->key_buf, 1);
778  if (SSL_CTX_use_PrivateKey(p->ctx, pkey) != 1) {
779  av_log(p, AV_LOG_ERROR, "Init SSL_CTX_use_PrivateKey failed, %s\n", openssl_get_error(p));
780  ret = AVERROR(EINVAL);
781  goto fail;
782  }
783  }
784 
785  if (c->listen && !c->cert_file && !c->cert_buf && !c->key_file && !c->key_buf) {
786  av_log(h, AV_LOG_VERBOSE, "No server certificate provided, using self-signed\n");
787 
788  ret = openssl_gen_private_key(&pkey);
789  if (ret < 0)
790  goto fail;
791 
792  ret = openssl_gen_certificate(pkey, &cert, NULL);
793  if (ret < 0)
794  goto fail;
795 
796  if (SSL_CTX_use_certificate(p->ctx, cert) != 1) {
797  av_log(p, AV_LOG_ERROR, "SSL_CTX_use_certificate failed for self-signed cert, %s\n", openssl_get_error(p));
798  ret = AVERROR(EINVAL);
799  goto fail;
800  }
801 
802  if (SSL_CTX_use_PrivateKey(p->ctx, pkey) != 1) {
803  av_log(p, AV_LOG_ERROR, "SSL_CTX_use_PrivateKey failed for self-signed cert, %s\n", openssl_get_error(p));
804  ret = AVERROR(EINVAL);
805  goto fail;
806  }
807  }
808 
809  ret = 0;
810 fail:
811  X509_free(cert);
812  EVP_PKEY_free(pkey);
813  return ret;
814 }
815 
816 /**
817  * Once the DTLS role has been negotiated - active for the DTLS client or passive for the
818  * DTLS server - we proceed to set up the DTLS state and initiate the handshake.
819  */
820 static int dtls_start(URLContext *h, const char *url, int flags, AVDictionary **options)
821 {
822  TLSContext *p = h->priv_data;
823  TLSShared *c = &p->tls_shared;
824  int ret = 0;
825  c->is_dtls = 1;
826 
827  /**
828  * The profile for OpenSSL's SRTP is SRTP_AES128_CM_SHA1_80, see ssl/d1_srtp.c.
829  * The profile for FFmpeg's SRTP is SRTP_AES128_CM_HMAC_SHA1_80, see libavformat/srtp.c.
830  */
831  const char* profiles = "SRTP_AES128_CM_SHA1_80";
832 
833  p->ctx = SSL_CTX_new(c->listen ? DTLS_server_method() : DTLS_client_method());
834  if (!p->ctx) {
835  ret = AVERROR(ENOMEM);
836  goto fail;
837  }
838 
840  if (ret < 0) goto fail;
841 
842  /* Note, this doesn't check that the peer certificate actually matches the requested hostname. */
843  if (c->verify)
844  SSL_CTX_set_verify(p->ctx, SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
845 
846  /* Setup the SRTP context */
847  if (SSL_CTX_set_tlsext_use_srtp(p->ctx, profiles)) {
848  av_log(p, AV_LOG_ERROR, "Init SSL_CTX_set_tlsext_use_srtp failed, profiles=%s, %s\n",
850  ret = AVERROR(EINVAL);
851  return ret;
852  }
853 
854  /* The ssl should not be created unless the ctx has been initialized. */
855  p->ssl = SSL_new(p->ctx);
856  if (!p->ssl) {
857  ret = AVERROR(ENOMEM);
858  goto fail;
859  }
860 
861  if (!c->listen && !c->numerichost)
862  SSL_set_tlsext_host_name(p->ssl, c->host);
863 
864  /* Setup the callback for logging. */
865  SSL_set_ex_data(p->ssl, 0, p);
866  SSL_CTX_set_info_callback(p->ctx, openssl_info_callback);
867 
868  /**
869  * We have set the MTU to fragment the DTLS packet. It is important to note that the
870  * packet is split to ensure that each handshake packet is smaller than the MTU.
871  */
872  if (c->mtu <= 0)
873  c->mtu = 1096;
874  SSL_set_options(p->ssl, SSL_OP_NO_QUERY_MTU);
875  SSL_set_mtu(p->ssl, c->mtu);
876  DTLS_set_link_mtu(p->ssl, c->mtu);
877 
878  ret = init_bio_method(h);
879  if (ret < 0)
880  goto fail;
881 
882  if (p->tls_shared.external_sock != 1) {
883  if ((ret = ff_tls_open_underlying(&p->tls_shared, h, url, options)) < 0) {
884  av_log(p, AV_LOG_ERROR, "Failed to connect %s\n", url);
885  return ret;
886  }
887  }
888 
889  /* This seems to be neccesary despite explicitly setting client/server method above. */
890  if (c->listen)
891  SSL_set_accept_state(p->ssl);
892  else
893  SSL_set_connect_state(p->ssl);
894 
895  /**
896  * During initialization, we only need to call SSL_do_handshake once because SSL_read consumes
897  * the handshake message if the handshake is incomplete.
898  * To simplify maintenance, we initiate the handshake for both the DTLS server and client after
899  * sending out the ICE response in the start_active_handshake function. It's worth noting that
900  * although the DTLS server may receive the ClientHello immediately after sending out the ICE
901  * response, this shouldn't be an issue as the handshake function is called before any DTLS
902  * packets are received.
903  *
904  * The SSL_do_handshake can't be called if DTLS hasn't prepare for udp.
905  */
906  if (p->tls_shared.external_sock != 1) {
907  ret = dtls_handshake(h);
908  // Fatal SSL error, for example, no available suite when peer is DTLS 1.0 while we are DTLS 1.2.
909  if (ret < 0) {
910  av_log(p, AV_LOG_ERROR, "Failed to drive SSL context, ret=%d\n", ret);
911  return AVERROR(EIO);
912  }
913  }
914 
915  av_log(p, AV_LOG_VERBOSE, "Setup ok, MTU=%d\n", p->tls_shared.mtu);
916 
917  ret = 0;
918 fail:
919  return ret;
920 }
921 
922 static int tls_open(URLContext *h, const char *uri, int flags, AVDictionary **options)
923 {
924  TLSContext *p = h->priv_data;
925  TLSShared *c = &p->tls_shared;
926  int ret;
927 
928  if ((ret = ff_tls_open_underlying(c, h, uri, options)) < 0)
929  goto fail;
930 
931  // We want to support all versions of TLS >= 1.0, but not the deprecated
932  // and insecure SSLv2 and SSLv3. Despite the name, TLS_*_method()
933  // enables support for all versions of SSL and TLS, and we then disable
934  // support for the old protocols immediately after creating the context.
935  p->ctx = SSL_CTX_new(c->listen ? TLS_server_method() : TLS_client_method());
936  if (!p->ctx) {
937  av_log(h, AV_LOG_ERROR, "%s\n", openssl_get_error(p));
938  ret = AVERROR(EIO);
939  goto fail;
940  }
941  if (!SSL_CTX_set_min_proto_version(p->ctx, TLS1_VERSION)) {
942  av_log(h, AV_LOG_ERROR, "Failed to set minimum TLS version to TLSv1\n");
944  goto fail;
945  }
947  if (ret < 0) goto fail;
948 
949  if (c->verify)
950  SSL_CTX_set_verify(p->ctx, SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
951  p->ssl = SSL_new(p->ctx);
952  if (!p->ssl) {
953  av_log(h, AV_LOG_ERROR, "%s\n", openssl_get_error(p));
954  ret = AVERROR(EIO);
955  goto fail;
956  }
957  SSL_set_ex_data(p->ssl, 0, p);
958  SSL_CTX_set_info_callback(p->ctx, openssl_info_callback);
959  ret = init_bio_method(h);
960  if (ret < 0)
961  goto fail;
962  if (!c->listen && !c->numerichost) {
963  // By default OpenSSL does too lax wildcard matching
964  SSL_set_hostflags(p->ssl, X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS);
965  if (!SSL_set1_host(p->ssl, c->host)) {
966  av_log(h, AV_LOG_ERROR, "Failed to set hostname for TLS/SSL verification: %s\n",
967  openssl_get_error(p));
969  goto fail;
970  }
971  if (!SSL_set_tlsext_host_name(p->ssl, c->host)) {
972  av_log(h, AV_LOG_ERROR, "Failed to set hostname for SNI: %s\n", openssl_get_error(p));
974  goto fail;
975  }
976  }
977  ret = c->listen ? SSL_accept(p->ssl) : SSL_connect(p->ssl);
978  if (ret == 0) {
979  av_log(h, AV_LOG_ERROR, "Unable to negotiate TLS/SSL session\n");
980  ret = AVERROR(EIO);
981  goto fail;
982  } else if (ret < 0) {
983  ret = print_ssl_error(h, ret);
984  goto fail;
985  }
986 
987  return 0;
988 fail:
989  tls_close(h);
990  return ret;
991 }
992 
993 static int tls_read(URLContext *h, uint8_t *buf, int size)
994 {
995  TLSContext *c = h->priv_data;
996  URLContext *uc = c->tls_shared.is_dtls ? c->tls_shared.udp
997  : c->tls_shared.tcp;
998  int ret;
999  // Set or clear the AVIO_FLAG_NONBLOCK on c->tls_shared.tcp
1000  uc->flags &= ~AVIO_FLAG_NONBLOCK;
1001  uc->flags |= h->flags & AVIO_FLAG_NONBLOCK;
1002  ret = SSL_read(c->ssl, buf, size);
1003  if (ret > 0)
1004  return ret;
1005  if (ret == 0)
1006  return AVERROR_EOF;
1007  return print_ssl_error(h, ret);
1008 }
1009 
1010 static int tls_write(URLContext *h, const uint8_t *buf, int size)
1011 {
1012  TLSContext *c = h->priv_data;
1013  URLContext *uc = c->tls_shared.is_dtls ? c->tls_shared.udp
1014  : c->tls_shared.tcp;
1015  int ret;
1016 
1017  // Set or clear the AVIO_FLAG_NONBLOCK on c->tls_shared.tcp
1018  uc->flags &= ~AVIO_FLAG_NONBLOCK;
1019  uc->flags |= h->flags & AVIO_FLAG_NONBLOCK;
1020 
1021  if (c->tls_shared.is_dtls)
1022  size = FFMIN(size, DTLS_get_data_mtu(c->ssl));
1023 
1024  ret = SSL_write(c->ssl, buf, size);
1025  if (ret > 0)
1026  return ret;
1027  if (ret == 0)
1028  return AVERROR_EOF;
1029  return print_ssl_error(h, ret);
1030 }
1031 
1033 {
1034  TLSContext *p = h->priv_data;
1035  TLSShared *c = &p->tls_shared;
1036  return ffurl_get_file_handle(c->is_dtls ? c->udp : c->tcp);
1037 }
1038 
1040 {
1041  TLSContext *p = h->priv_data;
1042  TLSShared *c = &p->tls_shared;
1043  return ffurl_get_short_seek(c->is_dtls ? c->udp : c->tcp);
1044 }
1045 
1046 static const AVOption options[] = {
1047  TLS_COMMON_OPTIONS(TLSContext, tls_shared),
1048  { NULL }
1049 };
1050 
1051 static const AVClass tls_class = {
1052  .class_name = "tls",
1053  .item_name = av_default_item_name,
1054  .option = options,
1055  .version = LIBAVUTIL_VERSION_INT,
1056 };
1057 
1059  .name = "tls",
1060  .url_open2 = tls_open,
1061  .url_read = tls_read,
1062  .url_write = tls_write,
1063  .url_close = tls_close,
1064  .url_get_file_handle = tls_get_file_handle,
1065  .url_get_short_seek = tls_get_short_seek,
1066  .priv_data_size = sizeof(TLSContext),
1068  .priv_data_class = &tls_class,
1069 };
1070 
1071 static const AVClass dtls_class = {
1072  .class_name = "dtls",
1073  .item_name = av_default_item_name,
1074  .option = options,
1075  .version = LIBAVUTIL_VERSION_INT,
1076 };
1077 
1079  .name = "dtls",
1080  .url_open2 = dtls_start,
1081  .url_handshake = dtls_handshake,
1082  .url_close = tls_close,
1083  .url_read = tls_read,
1084  .url_write = tls_write,
1085  .url_get_file_handle = tls_get_file_handle,
1086  .url_get_short_seek = tls_get_short_seek,
1087  .priv_data_size = sizeof(TLSContext),
1089  .priv_data_class = &dtls_class,
1090 };
error
static void error(const char *err)
Definition: target_bsf_fuzzer.c:32
flags
const SwsFlags flags[]
Definition: swscale.c:61
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:465
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:216
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
av_bprint_init
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
Definition: bprint.c:69
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:57
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
cleanup
static av_cold void cleanup(FlashSV2Context *s)
Definition: flashsv2enc.c:130
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:66
URLProtocol
Definition: url.h:51
os_support.h
sockaddr_storage
Definition: network.h:111
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_dtls_export_materials
int ff_dtls_export_materials(URLContext *h, char *dtls_srtp_materials, size_t materials_sz)
Definition: tls_openssl.c:528
TLS_COMMON_OPTIONS
#define TLS_COMMON_OPTIONS(pstruct, options_field)
Definition: tls.h:89
tls_class
static const AVClass tls_class
Definition: tls_openssl.c:1051
fail
#define fail()
Definition: checkasm.h:199
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:589
openssl_gen_private_key
static int openssl_gen_private_key(EVP_PKEY **pkey)
Definition: tls_openssl.c:241
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:160
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:543
s
#define s(width, name)
Definition: cbs_vp9.c:198
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:1010
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:1058
ff_udp_set_remote_addr
int ff_udp_set_remote_addr(URLContext *h, const struct sockaddr *dest_addr, socklen_t dest_addr_len, int do_connect)
This function is identical to ff_udp_set_remote_url, except that it takes a sockaddr directly.
Definition: udp.c:471
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
dtls_handshake
static int dtls_handshake(URLContext *h)
Definition: tls_openssl.c:702
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
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:240
ff_udp_get_last_recv_addr
void ff_udp_get_last_recv_addr(URLContext *h, struct sockaddr_storage *addr, socklen_t *addr_len)
Definition: udp.c:509
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:399
url_bio_ctrl
static long url_bio_ctrl(BIO *b, int cmd, long num, void *ptr)
Definition: tls_openssl.c:648
url_bio_destroy
static int url_bio_destroy(BIO *b)
Definition: tls_openssl.c:597
ff_tls_set_external_socket
int ff_tls_set_external_socket(URLContext *h, URLContext *sock)
Definition: tls_openssl.c:515
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:632
tls_open
static int tls_open(URLContext *h, const char *uri, int flags, AVDictionary **options)
Definition: tls_openssl.c:922
TLSContext::error_message
char error_message[256]
Definition: tls_openssl.c:491
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:150
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:602
init_bio_method
static av_cold int init_bio_method(URLContext *h)
Definition: tls_openssl.c:662
dst
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition: dsp.h:87
TLSShared::external_sock
int external_sock
Definition: tls.h:60
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:487
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:40
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:1046
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:683
AVERROR_EXTERNAL
#define AVERROR_EXTERNAL
Generic error in an external library.
Definition: error.h:59
tls_get_file_handle
static int tls_get_file_handle(URLContext *h)
Definition: tls_openssl.c:1032
TLSContext::ssl
SSL * ssl
Definition: tls_openssl.c:488
TLSContext::dest_addr
struct sockaddr_storage dest_addr
Definition: tls_openssl.c:492
URLContext
Definition: url.h:35
print_ssl_error
static int print_ssl_error(URLContext *h, int ret)
Definition: tls_openssl.c:549
openssl_get_error
static const char * openssl_get_error(TLSContext *ctx)
Retrieves the error message for the latest OpenSSL error.
Definition: tls_openssl.c:503
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:123
TLSContext::dest_addr_len
socklen_t dest_addr_len
Definition: tls_openssl.c:493
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
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:82
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
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:135
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:1039
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:993
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:76
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:732
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:820
AVIO_FLAG_NONBLOCK
#define AVIO_FLAG_NONBLOCK
Use non-blocking mode.
Definition: avio.h:636
TLSShared::udp
URLContext * udp
Definition: tls.h:61
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:435
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:1071
DTLS_STATE_FINISHED
@ DTLS_STATE_FINISHED
Definition: tls.h:40
tls_close
static int tls_close(URLContext *h)
Definition: tls_openssl.c:573
snprintf
#define snprintf
Definition: snprintf.h:34
ff_dtls_protocol
const URLProtocol ff_dtls_protocol
Definition: tls_openssl.c:1078
openssl_gen_certificate
static int openssl_gen_certificate(EVP_PKEY *pkey, X509 **cert, char **fingerprint)
Definition: tls_openssl.c:315
TLSContext::url_bio_method
BIO_METHOD * url_bio_method
Definition: tls_openssl.c:489
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:657
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