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