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