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