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 CONFIG_UDP_PROTOCOL
540  if (s->is_dtls && s->listen && !c->dest_addr_len) {
541  int err_ret;
542 
543  ff_udp_get_last_recv_addr(s->udp, &c->dest_addr, &c->dest_addr_len);
544  err_ret = ff_udp_set_remote_addr(s->udp, (struct sockaddr *)&c->dest_addr, c->dest_addr_len, 1);
545  if (err_ret < 0) {
546  av_log(c, AV_LOG_ERROR, "Failed connecting udp context\n");
547  return err_ret;
548  }
549  av_log(c, AV_LOG_TRACE, "Set UDP remote addr on UDP socket, now 'connected'\n");
550  }
551 #endif
552 
553  return ret;
554  }
555  BIO_clear_retry_flags(b);
556  if (ret == AVERROR_EXIT)
557  return 0;
558  if (ret == AVERROR(EAGAIN))
559  BIO_set_retry_read(b);
560  else
561  c->io_err = ret;
562  return -1;
563 }
564 
565 static int url_bio_bwrite(BIO *b, const char *buf, int len)
566 {
567  TLSContext *c = BIO_get_data(b);
568  int ret = ffurl_write(c->tls_shared.is_dtls ? c->tls_shared.udp : c->tls_shared.tcp, buf, len);
569  if (ret >= 0)
570  return ret;
571  BIO_clear_retry_flags(b);
572  if (ret == AVERROR_EXIT)
573  return 0;
574  if (ret == AVERROR(EAGAIN))
575  BIO_set_retry_write(b);
576  else
577  c->io_err = ret;
578  return -1;
579 }
580 
581 static long url_bio_ctrl(BIO *b, int cmd, long num, void *ptr)
582 {
583  if (cmd == BIO_CTRL_FLUSH) {
584  BIO_clear_retry_flags(b);
585  return 1;
586  }
587  return 0;
588 }
589 
590 static int url_bio_bputs(BIO *b, const char *str)
591 {
592  return url_bio_bwrite(b, str, strlen(str));
593 }
594 
596 {
597  TLSContext *c = h->priv_data;
598  BIO *bio;
599  c->url_bio_method = BIO_meth_new(BIO_TYPE_SOURCE_SINK, "urlprotocol bio");
600  BIO_meth_set_write(c->url_bio_method, url_bio_bwrite);
601  BIO_meth_set_read(c->url_bio_method, url_bio_bread);
602  BIO_meth_set_puts(c->url_bio_method, url_bio_bputs);
603  BIO_meth_set_ctrl(c->url_bio_method, url_bio_ctrl);
604  BIO_meth_set_create(c->url_bio_method, url_bio_create);
605  BIO_meth_set_destroy(c->url_bio_method, url_bio_destroy);
606  bio = BIO_new(c->url_bio_method);
607  BIO_set_data(bio, c);
608 
609  SSL_set_bio(c->ssl, bio, bio);
610 }
611 
612 static void openssl_info_callback(const SSL *ssl, int where, int ret) {
613  const char *method = "undefined";
614  TLSContext *c = (TLSContext*)SSL_get_ex_data(ssl, 0);
615 
616  if (where & SSL_ST_CONNECT) {
617  method = "SSL_connect";
618  } else if (where & SSL_ST_ACCEPT)
619  method = "SSL_accept";
620 
621  if (where & SSL_CB_LOOP) {
622  av_log(c, AV_LOG_DEBUG, "Info method=%s state=%s(%s), where=%d, ret=%d\n",
623  method, SSL_state_string(ssl), SSL_state_string_long(ssl), where, ret);
624  } else if (where & SSL_CB_ALERT) {
625  method = (where & SSL_CB_READ) ? "read":"write";
626  av_log(c, AV_LOG_DEBUG, "Alert method=%s state=%s(%s), where=%d, ret=%d\n",
627  method, SSL_state_string(ssl), SSL_state_string_long(ssl), where, ret);
628  }
629 }
630 
632 {
633  TLSContext *c = h->priv_data;
634  int ret, err;
635  int timeout_ms;
636  struct timeval timeout;
637  int64_t timeout_start = av_gettime_relative();
638  int sockfd = ffurl_get_file_handle(c->tls_shared.udp);
639  struct pollfd pfd = { .fd = sockfd, .events = POLLIN, .revents = 0 };
640 
641  /* Force NONBLOCK mode to handle DTLS retransmissions */
642  c->tls_shared.udp->flags |= AVIO_FLAG_NONBLOCK;
643 
644  for (;;) {
645  if (av_gettime_relative() - timeout_start > DTLS_HANDSHAKE_TIMEOUT_US) {
646  ret = AVERROR(ETIMEDOUT);
647  goto end;
648  }
649 
650  ret = SSL_do_handshake(c->ssl);
651  if (ret == 1) {
652  av_log(c, AV_LOG_TRACE, "Handshake success\n");
653  break;
654  }
655  err = SSL_get_error(c->ssl, ret);
656  if (err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE && err != SSL_ERROR_ZERO_RETURN) {
657  av_log(c, AV_LOG_ERROR, "Handshake failed, ret=%d, err=%d\n", ret, err);
658  ret = print_ssl_error(h, ret);
659  goto end;
660  }
661 
662  timeout_ms = 1000;
663  if (DTLSv1_get_timeout(c->ssl, &timeout))
664  timeout_ms = timeout.tv_sec * 1000 + timeout.tv_usec / 1000;
665 
666  ret = poll(&pfd, 1, timeout_ms);
667  if (ret > 0 && (pfd.revents & POLLIN))
668  continue;
669  if (!ret) {
670  if (DTLSv1_handle_timeout(c->ssl) < 0) {
671  ret = AVERROR(EIO);
672  goto end;
673  }
674  continue;
675  }
676  if (ret < 0) {
677  ret = ff_neterrno();
678  goto end;
679  }
680  }
681  /* Check whether the handshake is completed. */
682  if (SSL_is_init_finished(c->ssl) != TLS_ST_OK)
683  goto end;
684 
685  ret = 0;
686 end:
687  if (!(h->flags & AVIO_FLAG_NONBLOCK))
688  c->tls_shared.udp->flags &= ~AVIO_FLAG_NONBLOCK;
689  return ret;
690 }
691 
693 {
694  int ret;
695  TLSContext *c = h->priv_data;
696  TLSShared *s = &c->tls_shared;
697  EVP_PKEY *pkey = NULL;
698  X509 *cert = NULL;
699  /* setup ca, private key, certificate */
700  if (s->ca_file) {
701  if (!SSL_CTX_load_verify_locations(c->ctx, s->ca_file, NULL))
702  av_log(h, AV_LOG_ERROR, "SSL_CTX_load_verify_locations %s\n", openssl_get_error(c));
703  } else {
704  if (!SSL_CTX_set_default_verify_paths(c->ctx)) {
705  // Only log the failure but do not error out, as this is not fatal
706  av_log(h, AV_LOG_WARNING, "Failure setting default verify locations: %s\n",
708  }
709  }
710 
711  if (s->cert_file) {
712  ret = SSL_CTX_use_certificate_chain_file(c->ctx, s->cert_file);
713  if (ret <= 0) {
714  av_log(h, AV_LOG_ERROR, "Unable to load cert file %s: %s\n",
715  s->cert_file, openssl_get_error(c));
716  ret = AVERROR(EIO);
717  goto fail;
718  }
719  } else if (s->cert_buf) {
720  cert = cert_from_pem_string(s->cert_buf);
721  if (SSL_CTX_use_certificate(c->ctx, cert) != 1) {
722  av_log(c, AV_LOG_ERROR, "SSL: Init SSL_CTX_use_certificate failed, %s\n", openssl_get_error(c));
723  ret = AVERROR(EINVAL);
724  goto fail;
725  }
726  }
727 
728  if (s->key_file) {
729  ret = SSL_CTX_use_PrivateKey_file(c->ctx, s->key_file, SSL_FILETYPE_PEM);
730  if (ret <= 0) {
731  av_log(h, AV_LOG_ERROR, "Unable to load key file %s: %s\n",
732  s->key_file, openssl_get_error(c));
733  ret = AVERROR(EIO);
734  goto fail;
735  }
736  } else if (s->key_buf) {
737  pkey = pkey_from_pem_string(s->key_buf, 1);
738  if (SSL_CTX_use_PrivateKey(c->ctx, pkey) != 1) {
739  av_log(c, AV_LOG_ERROR, "Init SSL_CTX_use_PrivateKey failed, %s\n", openssl_get_error(c));
740  ret = AVERROR(EINVAL);
741  goto fail;
742  }
743  }
744 
745  if (s->listen && !s->cert_file && !s->cert_buf && !s->key_file && !s->key_buf) {
746  av_log(h, AV_LOG_VERBOSE, "No server certificate provided, using self-signed\n");
747 
748  ret = openssl_gen_private_key(&pkey);
749  if (ret < 0)
750  goto fail;
751 
752  ret = openssl_gen_certificate(pkey, &cert, NULL);
753  if (ret < 0)
754  goto fail;
755 
756  if (SSL_CTX_use_certificate(c->ctx, cert) != 1) {
757  av_log(c, AV_LOG_ERROR, "SSL_CTX_use_certificate failed for self-signed cert, %s\n", openssl_get_error(c));
758  ret = AVERROR(EINVAL);
759  goto fail;
760  }
761 
762  if (SSL_CTX_use_PrivateKey(c->ctx, pkey) != 1) {
763  av_log(c, AV_LOG_ERROR, "SSL_CTX_use_PrivateKey failed for self-signed cert, %s\n", openssl_get_error(c));
764  ret = AVERROR(EINVAL);
765  goto fail;
766  }
767  }
768 
769  ret = 0;
770 fail:
771  X509_free(cert);
772  EVP_PKEY_free(pkey);
773  return ret;
774 }
775 
776 /**
777  * Once the DTLS role has been negotiated - active for the DTLS client or passive for the
778  * DTLS server - we proceed to set up the DTLS state and initiate the handshake.
779  */
780 static int dtls_start(URLContext *h, const char *url, int flags, AVDictionary **options)
781 {
782  TLSContext *c = h->priv_data;
783  TLSShared *s = &c->tls_shared;
784  int ret = 0;
785  s->is_dtls = 1;
786 
787  if (!c->tls_shared.external_sock) {
788  if ((ret = ff_tls_open_underlying(&c->tls_shared, h, url, options)) < 0) {
789  av_log(c, AV_LOG_ERROR, "Failed to connect %s\n", url);
790  return ret;
791  }
792  }
793 
794  c->ctx = SSL_CTX_new(s->listen ? DTLS_server_method() : DTLS_client_method());
795  if (!c->ctx) {
796  ret = AVERROR(ENOMEM);
797  goto fail;
798  }
799 
801  if (ret < 0) goto fail;
802 
803  /* Note, this doesn't check that the peer certificate actually matches the requested hostname. */
804  if (s->verify)
805  SSL_CTX_set_verify(c->ctx, SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
806 
807  if (s->use_srtp) {
808  /**
809  * The profile for OpenSSL's SRTP is SRTP_AES128_CM_SHA1_80, see ssl/d1_srtp.c.
810  * The profile for FFmpeg's SRTP is SRTP_AES128_CM_HMAC_SHA1_80, see libavformat/srtp.c.
811  */
812  const char* profiles = "SRTP_AES128_CM_SHA1_80";
813  if (SSL_CTX_set_tlsext_use_srtp(c->ctx, profiles)) {
814  av_log(c, AV_LOG_ERROR, "Init SSL_CTX_set_tlsext_use_srtp failed, profiles=%s, %s\n",
816  ret = AVERROR(EINVAL);
817  goto fail;
818  }
819  }
820 
821  /* The ssl should not be created unless the ctx has been initialized. */
822  c->ssl = SSL_new(c->ctx);
823  if (!c->ssl) {
824  ret = AVERROR(ENOMEM);
825  goto fail;
826  }
827 
828  if (!s->listen && !s->numerichost)
829  SSL_set_tlsext_host_name(c->ssl, s->host);
830 
831  /* Setup the callback for logging. */
832  SSL_set_ex_data(c->ssl, 0, c);
833  SSL_CTX_set_info_callback(c->ctx, openssl_info_callback);
834 
835  /**
836  * We have set the MTU to fragment the DTLS packet. It is important to note that the
837  * packet is split to ensure that each handshake packet is smaller than the MTU.
838  */
839  if (s->mtu <= 0)
840  s->mtu = 1096;
841  SSL_set_options(c->ssl, SSL_OP_NO_QUERY_MTU);
842  SSL_set_mtu(c->ssl, s->mtu);
843  DTLS_set_link_mtu(c->ssl, s->mtu);
845 
846  /* This seems to be necessary despite explicitly setting client/server method above. */
847  if (s->listen)
848  SSL_set_accept_state(c->ssl);
849  else
850  SSL_set_connect_state(c->ssl);
851 
852  /* The SSL_do_handshake can't be called if DTLS hasn't prepare for udp. */
853  if (!c->tls_shared.external_sock) {
854  ret = dtls_handshake(h);
855  // Fatal SSL error, for example, no available suite when peer is DTLS 1.0 while we are DTLS 1.2.
856  if (ret < 0) {
857  av_log(c, AV_LOG_ERROR, "Failed to drive SSL context, ret=%d\n", ret);
858  return AVERROR(EIO);
859  }
860  }
861 
862  av_log(c, AV_LOG_VERBOSE, "Setup ok, MTU=%d\n", c->tls_shared.mtu);
863 
864  return 0;
865 fail:
866  tls_close(h);
867  return ret;
868 }
869 
870 static int tls_open(URLContext *h, const char *uri, int flags, AVDictionary **options)
871 {
872  TLSContext *c = h->priv_data;
873  TLSShared *s = &c->tls_shared;
874  int ret;
875 
876  if ((ret = ff_tls_open_underlying(s, h, uri, options)) < 0)
877  goto fail;
878 
879  // We want to support all versions of TLS >= 1.0, but not the deprecated
880  // and insecure SSLv2 and SSLv3. Despite the name, TLS_*_method()
881  // enables support for all versions of SSL and TLS, and we then disable
882  // support for the old protocols immediately after creating the context.
883  c->ctx = SSL_CTX_new(s->listen ? TLS_server_method() : TLS_client_method());
884  if (!c->ctx) {
886  ret = AVERROR(EIO);
887  goto fail;
888  }
889  if (!SSL_CTX_set_min_proto_version(c->ctx, TLS1_VERSION)) {
890  av_log(h, AV_LOG_ERROR, "Failed to set minimum TLS version to TLSv1\n");
892  goto fail;
893  }
895  if (ret < 0) goto fail;
896 
897  if (s->verify)
898  SSL_CTX_set_verify(c->ctx, SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
899  c->ssl = SSL_new(c->ctx);
900  if (!c->ssl) {
902  ret = AVERROR(EIO);
903  goto fail;
904  }
905  SSL_set_ex_data(c->ssl, 0, c);
906  SSL_CTX_set_info_callback(c->ctx, openssl_info_callback);
908  if (!s->listen && !s->numerichost) {
909  // By default OpenSSL does too lax wildcard matching
910  SSL_set_hostflags(c->ssl, X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS);
911  if (!SSL_set1_host(c->ssl, s->host)) {
912  av_log(h, AV_LOG_ERROR, "Failed to set hostname for TLS/SSL verification: %s\n",
915  goto fail;
916  }
917  if (!SSL_set_tlsext_host_name(c->ssl, s->host)) {
918  av_log(h, AV_LOG_ERROR, "Failed to set hostname for SNI: %s\n", openssl_get_error(c));
920  goto fail;
921  }
922  }
923  ret = s->listen ? SSL_accept(c->ssl) : SSL_connect(c->ssl);
924  if (ret == 0) {
925  av_log(h, AV_LOG_ERROR, "Unable to negotiate TLS/SSL session\n");
926  ret = AVERROR(EIO);
927  goto fail;
928  } else if (ret < 0) {
929  ret = print_ssl_error(h, ret);
930  goto fail;
931  }
932 
933  return 0;
934 fail:
935  tls_close(h);
936  return ret;
937 }
938 
939 static int tls_read(URLContext *h, uint8_t *buf, int size)
940 {
941  TLSContext *c = h->priv_data;
942  TLSShared *s = &c->tls_shared;
943  URLContext *uc = s->is_dtls ? s->udp : s->tcp;
944  int ret;
945  // Set or clear the AVIO_FLAG_NONBLOCK on the underlying socket
946  uc->flags &= ~AVIO_FLAG_NONBLOCK;
947  uc->flags |= h->flags & AVIO_FLAG_NONBLOCK;
948  ret = SSL_read(c->ssl, buf, size);
949  if (ret > 0)
950  return ret;
951  if (ret == 0)
952  return AVERROR_EOF;
953  return print_ssl_error(h, ret);
954 }
955 
956 static int tls_write(URLContext *h, const uint8_t *buf, int size)
957 {
958  TLSContext *c = h->priv_data;
959  TLSShared *s = &c->tls_shared;
960  URLContext *uc = s->is_dtls ? s->udp : s->tcp;
961  int ret;
962 
963  // Set or clear the AVIO_FLAG_NONBLOCK on the underlying socket
964  uc->flags &= ~AVIO_FLAG_NONBLOCK;
965  uc->flags |= h->flags & AVIO_FLAG_NONBLOCK;
966 
967  if (s->is_dtls) {
968  const size_t mtu_size = DTLS_get_data_mtu(c->ssl);
969  size = FFMIN(size, mtu_size);
970  }
971 
972  ret = SSL_write(c->ssl, buf, size);
973  if (ret > 0)
974  return ret;
975  if (ret == 0)
976  return AVERROR_EOF;
977  return print_ssl_error(h, ret);
978 }
979 
981 {
982  TLSContext *c = h->priv_data;
983  TLSShared *s = &c->tls_shared;
984  return ffurl_get_file_handle(s->is_dtls ? s->udp : s->tcp);
985 }
986 
988 {
989  TLSContext *c = h->priv_data;
990  TLSShared *s = &c->tls_shared;
991  return ffurl_get_short_seek(s->is_dtls ? s->udp : s->tcp);
992 }
993 
994 static const AVOption options[] = {
995  TLS_COMMON_OPTIONS(TLSContext, tls_shared),
996  { NULL }
997 };
998 
999 static const AVClass tls_class = {
1000  .class_name = "tls",
1001  .item_name = av_default_item_name,
1002  .option = options,
1003  .version = LIBAVUTIL_VERSION_INT,
1004 };
1005 
1007  .name = "tls",
1008  .url_open2 = tls_open,
1009  .url_read = tls_read,
1010  .url_write = tls_write,
1011  .url_close = tls_close,
1012  .url_get_file_handle = tls_get_file_handle,
1013  .url_get_short_seek = tls_get_short_seek,
1014  .priv_data_size = sizeof(TLSContext),
1016  .priv_data_class = &tls_class,
1017 };
1018 
1019 static const AVClass dtls_class = {
1020  .class_name = "dtls",
1021  .item_name = av_default_item_name,
1022  .option = options,
1023  .version = LIBAVUTIL_VERSION_INT,
1024 };
1025 
1027  .name = "dtls",
1028  .url_open2 = dtls_start,
1029  .url_handshake = dtls_handshake,
1030  .url_close = tls_close,
1031  .url_read = tls_read,
1032  .url_write = tls_write,
1033  .url_get_file_handle = tls_get_file_handle,
1034  .url_get_short_seek = tls_get_short_seek,
1035  .priv_data_size = sizeof(TLSContext),
1037  .priv_data_class = &dtls_class,
1038 };
error
static void error(const char *err)
Definition: target_bsf_fuzzer.c:32
flags
const SwsFlags flags[]
Definition: swscale.c:72
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:334
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: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: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:108
tls_class
static const AVClass tls_class
Definition: tls_openssl.c:999
fail
#define fail()
Definition: checkasm.h:225
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: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:119
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:956
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:1006
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:631
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:45
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:581
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:565
tls_open
static int tls_open(URLContext *h, const char *uri, int flags, AVDictionary **options)
Definition: tls_openssl.c:870
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: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: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:335
URLProtocol::name
const char * name
Definition: url.h:52
options
static const AVOption options[]
Definition: tls_openssl.c:994
TLSContext::io_err
int io_err
Definition: tls_gnutls.c:339
openssl_info_callback
static void openssl_info_callback(const SSL *ssl, int where, int ret)
Definition: tls_openssl.c:612
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:980
init_bio_method
static av_cold void init_bio_method(URLContext *h)
Definition: tls_openssl.c:595
TLSContext::ssl
SSL * ssl
Definition: tls_openssl.c:425
TLSContext::dest_addr
struct sockaddr_storage dest_addr
Definition: tls_gnutls.c:340
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:341
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: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:987
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:939
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:57
openssl_init_ca_key_cert
static av_cold int openssl_init_ca_key_cert(URLContext *h)
Definition: tls_openssl.c:692
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:780
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:1019
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:1026
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:820
url_bio_bputs
static int url_bio_bputs(BIO *b, const char *str)
Definition: tls_openssl.c:590
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