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